+++ /dev/null
-/*
- * 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.util.concurrent.FluentFuture;
-import edu.umd.cs.findbugs.annotations.CheckReturnValue;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Write transaction that provides cursor's with write access to the data tree.
- */
-public interface CursorAwareWriteTransaction extends DataTreeCursorProvider {
- /**
- * Create a {@link DataTreeWriteCursor} anchored at the specified path.
- * There can only be one cursor open at a time.
- *
- * <p>
- * @param path Path at which the cursor is to be anchored
- * @return write cursor at the desired location.
- * @throws IllegalStateException when there's an open cursor, or this transaction is closed already.
- */
- @Override
- <T extends DataObject> DataTreeWriteCursor createCursor(DataTreeIdentifier<T> path);
-
- /**
- * Cancels the transaction.
- *
- * <p>
- * A transaction can only be cancelled if it has not yet been committed.
- *
- * <p>
- * Invoking cancel() on failed or already canceled will have no effect, and transaction is
- * considered cancelled.
- *
- * <p>
- * Invoking cancel() on finished transaction (future returned by {@link #commit()} already
- * successfully completed) will always fail (return false).
- *
- * @return {@code false} if the task could not be cancelled, typically because it has already
- * completed normally; {@code true} otherwise
- */
- boolean cancel();
-
- /**
- * Commits this transaction to be asynchronously applied to update the logical data tree. The
- * returned CheckedFuture conveys the result of applying the data changes.
- *
- * <p>
- * <b>Note:</b> It is strongly recommended to process the FluentFuture result in an
- * asynchronous manner rather than using the blocking get() method.
- *
- * <p>
- * This call logically seals the transaction, which prevents the client from further changing
- * data tree using this transaction's cursor. Any subsequent calls to
- * <code>createCursorCursor(DOMDataTreeIdentifier</code>
- * or any of the cursor's methods will fail with {@link IllegalStateException}.
- *
- * <p>
- * The transaction is marked as submitted and enqueued into the shard back-end for
- * processing.
- *
- * @return a FluentFuture containing the result of the commit information. The Future blocks until the commit
- * operation is complete. A successful commit returns nothing. On failure, the Future will fail with a
- * {@link TransactionCommitFailedException} or an exception derived from TransactionCommitFailedException.
- */
- @CheckReturnValue
- @NonNull FluentFuture<? extends @NonNull CommitInfo> commit();
-}
+++ /dev/null
-/*
- * 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 org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-
-/**
- * A cursor holding a logical position within a conceptual data tree. It allows operations relative to that position,
- * as well as moving the position up or down the tree.
- *
- * <p>
- * Implementations of this interface are expected to be inherently non-thread-safe.
- */
-@Beta
-public interface DataTreeCursor extends AutoCloseable {
- /**
- * Move the cursor to the specified child of the current position.
- *
- * @param child Child identifier
- * @throws IllegalArgumentException when specified identifier does not identify a valid child,
- * or if that child is not an instance of {@link DataContainer}.
- */
- void enter(@NonNull PathArgument child);
-
- /**
- * Move the cursor to the specified child of the current position. This is the equivalent of
- * multiple invocations of {@link #enter(PathArgument)}, except the operation is performed all
- * at once.
- *
- * @param path Nested child identifier
- * @throws IllegalArgumentException when specified path does not identify a valid child, or if
- * that child is not an instance of {@link DataContainer}.
- */
- void enter(@NonNull PathArgument... path);
-
- /**
- * Move the cursor to the specified child of the current position. This is equivalent to
- * {@link #enter(PathArgument...)}, except it takes an {@link Iterable} argument.
- *
- * @param path Nested child identifier
- * @throws IllegalArgumentException when specified path does not identify a valid child, or if
- * that child is not an instance of {@link DataContainer}.
- */
- void enter(@NonNull Iterable<PathArgument> path);
-
- /**
- * Move the cursor up to the parent of current position. This is equivalent of invoking
- * <code>exit(1)</code>.
- *
- * @throws IllegalStateException when exiting would violate containment, typically by attempting
- * to exit more levels than previously entered.
- */
- void exit();
-
- /**
- * Move the cursor up by specified amounts of steps from the current position. This is
- * equivalent of invoking {@link #exit()} multiple times, except the operation is performed
- * atomically.
- *
- * @param depth number of steps to exit
- * @throws IllegalArgumentException when depth is negative.
- * @throws IllegalStateException when exiting would violate containment, typically by attempting
- * to exit more levels than previously entered.
- */
- void exit(int depth);
-
- /**
- * Close this cursor. Attempting any further operations on the cursor will lead to undefined
- * behavior.
- */
- @Override
- void close();
-}
+++ /dev/null
-/*
- * 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.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Provides access to {#link DataTreeCursor}'s anchored at the specified path.
- */
-public interface DataTreeCursorProvider {
- /**
- * Create a new {@link DataTreeCursor} at specified path. May fail if specified path
- * does not exist.
- *
- * @param path Path at which the cursor is to be anchored
- * @return A new cursor, or null if the path does not exist.
- * @throws IllegalStateException if there is another cursor currently open, or the transaction
- * is already closed (closed or submitted).
- */
- <T extends DataObject> @Nullable DataTreeCursor createCursor(@NonNull DataTreeIdentifier<T> path);
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import java.util.Collection;
-import java.util.EventListener;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Interface implemented by data consumers, e.g. processes wanting to act on data after it has been
- * introduced to the conceptual data tree.
- */
-public interface DataTreeListener extends EventListener {
- /**
- * Invoked whenever one or more registered subtrees change. The logical changes are reported, as
- * well as the roll up of new state for all subscribed subtrees.
- *
- * @param changes The set of changes being reported. Each subscribed subtree may be present at
- * most once.
- * @param subtrees Per-subtree state as visible after the reported changes have been applied.
- * This includes all the subtrees this listener is subscribed to, even those which have
- * not changed.
- */
- void onDataTreeChanged(@NonNull Collection<DataTreeModification<?>> changes,
- @NonNull Map<DataTreeIdentifier<?>, DataObject> subtrees);
-
- /**
- * Invoked when a subtree listening failure occurs. This can be triggered, for example, when a
- * connection to external subtree source is broken. The listener will not receive any other
- * callbacks, but its registration still needs to be closed to prevent resource leak.
- *
- * @param causes Collection of failure causes, may not be null or empty.
- */
- void onDataTreeFailed(@NonNull Collection<DataTreeListeningException> causes);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * Base exception for various causes why and {@link DataTreeListener} may be terminated by the {@link DataTreeService}
- * implementation.
- */
-public class DataTreeListeningException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public DataTreeListeningException(final @NonNull String message, final @Nullable Throwable cause) {
- super(requireNonNull(message, "message"), cause);
- }
-
- public DataTreeListeningException(@NonNull final String message) {
- super(requireNonNull(message, "message"));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * Exception thrown when a loop is detected in the way {@link DataTreeListener} and {@link DataTreeProducer} instances
- * would be connected.
- */
-public class DataTreeLoopException extends DataTreeProducerException {
- private static final long serialVersionUID = 1L;
-
- public DataTreeLoopException(final @NonNull String message, final @NonNull Throwable cause) {
- super(message, cause);
- }
-
- public DataTreeLoopException(final @NonNull String message) {
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * A data producer context. It allows transactions to be submitted to the subtrees specified at
- * instantiation time. At any given time there may be a single transaction open. It needs to be
- * either submitted or cancelled before another one can be open. Once a transaction is submitted, it
- * will proceed to be committed asynchronously.
- *
- *<p>
- * Each instance has an upper bound on the number of transactions which can be in-flight, once that
- * capacity is exceeded, an attempt to create a new transaction will block until some transactions
- * complete.
- *
- *<p>
- * Each {@link DataTreeProducer} can be in two logical states, bound and unbound, which define the
- * lifecycle rules for when is it legal to create and submit transactions in relationship with
- * {@link DataTreeListener} callbacks.
- *
- *<p>
- * When a producer is first created, it is unbound. In this state the producer can be accessed by
- * any application thread to allocate or submit transactions, as long as the 'single open
- * transaction' rule is maintained. The producer and any transaction object MUST NOT be accessed,
- * directly or indirectly, from a {@link DataTreeListener} callback.
- *
- * <p>
- * When a producer is referenced in a call to
- * {@link DataTreeService#registerListener(DataTreeListener, java.util.Collection, boolean, java.util.Collection)},
- * an attempt will be made to bind the producer to the specified {@link DataTreeListener}. Such an attempt will fail
- * the producer is already bound, or it has an open transaction. Once bound, the producer can only be accessed
- * from within the {@link DataTreeListener} callback on that particular instance. Any transaction which is not submitted
- * by the time the callback returns will be implicitly cancelled. A producer becomes unbound when the listener it is
- * bound to becomes unregistered.
- */
-public interface DataTreeProducer extends DataTreeProducerFactory, AutoCloseable {
- /**
- * Allocate a new open transaction on this producer. Any and all transactions previously
- * allocated must have been either submitted or cancelled by the time this method is invoked.
- *
- * @param isolated Indicates whether this transaction should be a barrier. A barrier transaction
- * is processed separately from any preceding transactions. Non-barrier transactions may
- * be merged and processed in a batch, such that any observers see the modifications
- * contained in them as if the modifications were made in a single transaction.
- * @return A new {@link CursorAwareWriteTransaction}
- * @throws IllegalStateException if a previous transaction was not closed.
- * @throws IllegalThreadStateException if the calling thread context does not match the
- * lifecycle rules enforced by the producer state (e.g. bound or unbound). This
- * exception is thrown on a best effort basis and programs should not rely on it for
- * correct operation.
- */
- @NonNull CursorAwareWriteTransaction createTransaction(boolean isolated);
-
- /**
- * {@inheritDoc}.
- *
- *<p>
- * When invoked on a {@link DataTreeProducer}, this method has additional restrictions. There
- * may not be an open transaction from this producer. The method needs to be invoked in
- * appropriate context, e.g. bound or unbound.
- *
- *<p>
- * Specified subtrees must be accessible by this producer. Accessible means they are a subset of
- * the subtrees specified when the producer is instantiated. The set is further reduced as child
- * producers are instantiated -- if you create a producer for /a and then a child for /a/b, /a/b
- * is not accessible from the first producer.
- *
- *<p>
- * Once this method returns successfully, this (parent) producer loses the ability to access the
- * specified paths until the resulting (child) producer is shut down.
- *
- * @throws IllegalStateException if there is an open transaction
- * @throws IllegalArgumentException if subtrees contains a subtree which is not accessible by
- * this producer
- * @throws IllegalThreadStateException if the calling thread context does not match the
- * lifecycle rules enforced by the producer state (e.g. bound or unbound). This
- * exception is thrown on a best effort basis and programs should not rely on it for
- * correct operation.
- */
- @Override
- DataTreeProducer createProducer(Collection<DataTreeIdentifier<?>> subtrees);
-
- /**
- * {@inheritDoc}.
- *
- * @throws DataTreeProducerBusyException when there is an open transaction.
- */
- @Override
- void close() throws DataTreeProducerException;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * Exception indicating that the {@link DataTreeProducer} has an open user transaction and cannot be
- * closed.
- */
-public class DataTreeProducerBusyException extends DataTreeProducerException {
- private static final long serialVersionUID = 1L;
-
- public DataTreeProducerBusyException(final @NonNull String message, final @NonNull Throwable cause) {
- super(requireNonNull(message, "message"), cause);
- }
-
- public DataTreeProducerBusyException(final @NonNull String message) {
- super(requireNonNull(message, "message"));
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-public class DataTreeProducerException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public DataTreeProducerException(final @NonNull String message, final @NonNull Throwable cause) {
- super(message, cause);
- }
-
- public DataTreeProducerException(final @NonNull String message) {
- super(message);
- }
-
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-
-public interface DataTreeProducerFactory {
- /**
- * Create a producer, which is able to access to a set of trees.
- *
- * @param subtrees The collection of subtrees the resulting producer should have access to.
- * @return A {@link DataTreeProducer} instance.
- * @throws IllegalArgumentException if subtrees is empty.
- */
- @NonNull DataTreeProducer createProducer(@NonNull Collection<DataTreeIdentifier<?>> subtrees);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.binding.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * A {@link BindingService} providing access to the conceptual data tree. Interactions with the data
- * tree are split into data producers and consumers (listeners). Each of them operate on a set of
- * subtrees, which need to be declared at instantiation time.
- *
- *<p>
- * Returned instances are not thread-safe and expected to be used by a single thread at a time.
- * Furthermore, producers may not be accessed from consumer callbacks unless they were specified
- * when the listener is registered.
- *
- *<p>
- * The service maintains a loop-free topology of producers and consumers. What this means is that a
- * consumer is not allowed to access a producer, which affects any of the subtrees it is subscribed
- * to. This restriction is in place to ensure the system does not go into a feedback loop, where it
- * is impossible to block either a producer or a consumer without accumulating excess work in the
- * backlog stemming from its previous activity.
- */
-public interface DataTreeService extends DataTreeProducerFactory, BindingService {
- /**
- * Register a {@link DataTreeListener} instance. Once registered, the listener will start
- * receiving changes on the selected subtrees. If the listener cannot keep up with the rate of
- * changes, and allowRxMerges is set to true, this service is free to merge the changes, so that
- * a smaller number of them will be reported, possibly hiding some data transitions (like
- * flaps).
- *
- *<p>
- * If the listener wants to write into any producer, that producer has to be mentioned in the
- * call to this method. Those producers will be bound exclusively to the registration, so that
- * accessing them outside of this listener's callback will trigger an error. Any producers
- * mentioned must be idle, e.g. they may not have an open transaction at the time this method is
- * invoked.
- *
- *<p>
- * Each listener instance can be registered at most once. Implementations of this interface have
- * to guarantee that the listener's methods will not be invoked concurrently from multiple
- * threads.
- *
- * @param listener {@link DataTreeListener} that is being registered
- * @param subtrees Conceptual subtree identifier of subtrees which should be monitored for
- * changes. May not be null or empty.
- * @param allowRxMerges True if the backend may perform ingress state compression.
- * @param producers {@link DataTreeProducer} instances to bind to the listener.
- * @return A listener registration. Once closed, the listener will no longer be invoked and the
- * producers will be unbound.
- * @throws IllegalArgumentException if subtrees is empty or the listener is already bound
- * @throws DataTreeLoopException if the registration of the listener to the specified subtrees
- * with specified producers would form a feedback loop
- */
- <T extends DataTreeListener> @NonNull ListenerRegistration<T> registerListener(@NonNull T listener,
- @NonNull Collection<DataTreeIdentifier<?>> subtrees, boolean allowRxMerges,
- @NonNull Collection<DataTreeProducer> producers) throws DataTreeLoopException;
-}
+++ /dev/null
-/*
- * 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.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.BackendFailedException;
-
-/**
- * {@inheritDoc}.
- *
- * <p>
- * In addition this cursor also provides write operations(delete, merge, write).
- */
-public interface DataTreeWriteCursor extends DataTreeCursor {
- /**
- * Delete the specified child.
- *
- * @param child Child identifier
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- void delete(@NonNull PathArgument child);
-
- /**
- * Merge the specified data with the currently-present data at specified path.
- *
- * @param child Child identifier
- * @param data Data to be merged
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- <T extends DataObject> void merge(@NonNull PathArgument child, @NonNull T data);
-
- /**
- * Replace the data at specified path with supplied data.
- *
- * @param child Child identifier
- * @param data New node data
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- <T extends DataObject> void write(@NonNull PathArgument child, @NonNull T data);
-}
+++ /dev/null
-/*
- * 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.junit.Test;
-
-public class DataTreeListeningExceptionTest {
-
- @Test(expected = DataTreeListeningException.class)
- public void constructWithCauseTest() throws Exception {
- throw new DataTreeListeningException("test", new Throwable());
- }
-
- @Test(expected = DataTreeListeningException.class)
- public void constructTest() throws Exception {
- throw new DataTreeListeningException("test");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.junit.Test;
-
-public class DataTreeLoopExceptionTest {
-
- @Test(expected = DataTreeLoopException.class)
- public void constructWithCauseTest() throws Exception {
- throw new DataTreeLoopException("test", new Throwable());
- }
-
- @Test(expected = DataTreeLoopException.class)
- public void constructTest() throws Exception {
- throw new DataTreeLoopException("test");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.junit.Test;
-
-public class DataTreeProducerBusyExceptionTest {
-
- @Test(expected = DataTreeProducerBusyException.class)
- public void constructWithCauseTest() throws Exception {
- throw new DataTreeProducerBusyException("test", new Throwable());
- }
-
- @Test(expected = DataTreeProducerBusyException.class)
- public void constructTest() throws Exception {
- throw new DataTreeProducerBusyException("test");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.junit.Test;
-
-public class DataTreeProducerExceptionTest {
-
- @Test(expected = DataTreeProducerException.class)
- public void constructWithCauseTest() throws Exception {
- throw new DataTreeProducerException("test", new Throwable());
- }
-
- @Test(expected = DataTreeProducerException.class)
- public void constructTest() throws Exception {
- throw new DataTreeProducerException("test");
- }
-}
\ No newline at end of file
import org.opendaylight.mdsal.binding.api.ActionProviderService;
import org.opendaylight.mdsal.binding.api.ActionService;
import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.DataTreeService;
import org.opendaylight.mdsal.binding.api.MountPointService;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
import org.opendaylight.mdsal.dom.api.DOMActionService;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
import org.opendaylight.mdsal.dom.api.DOMNotificationService;
return new BindingDOMDataBrokerAdapter(context(), domService);
}
- @Override
- public final DataTreeService createDataTreeService(final DOMDataTreeService domService) {
- return new BindingDOMDataTreeServiceAdapter(context(), domService);
- }
-
@Override
public final MountPointService createMountPointService(final DOMMountPointService domService) {
return new BindingDOMMountPointServiceAdapter(context(), domService);
+++ /dev/null
-/*
- * 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.util.concurrent.FluentFuture;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.api.CursorAwareWriteTransaction;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeWriteCursor;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-final class BindingDOMCursorAwareWriteTransactionAdapter<T extends DOMDataTreeCursorAwareTransaction>
- extends AbstractBindingAdapter<T> implements CursorAwareWriteTransaction {
- BindingDOMCursorAwareWriteTransactionAdapter(final AdapterContext adapterContext, final T delegate) {
- super(adapterContext, delegate);
- }
-
- @Override
- public <P extends DataObject> DataTreeWriteCursor createCursor(final DataTreeIdentifier<P> path) {
- final YangInstanceIdentifier yPath = currentSerializer().toYangInstanceIdentifier(path.getRootIdentifier());
- final DOMDataTreeWriteCursor cursor = getDelegate().createCursor(
- new DOMDataTreeIdentifier(path.getDatastoreType(), yPath));
- return new BindingDOMDataTreeWriteCursorAdapter<>(adapterContext(), cursor, path);
- }
-
- @Override
- public boolean cancel() {
- return getDelegate().cancel();
- }
-
- @Override
- public FluentFuture<? extends @NonNull CommitInfo> commit() {
- return getDelegate().commit();
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.dom.adapter;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.Maps;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeListener;
-import org.opendaylight.mdsal.binding.api.DataTreeListeningException;
-import org.opendaylight.mdsal.binding.api.DataTreeModification;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListeningException;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-
-public class BindingDOMDataTreeListenerAdapter extends AbstractBindingAdapter<DataTreeListener>
- implements DOMDataTreeListener {
-
- private final LogicalDatastoreType store;
-
- protected BindingDOMDataTreeListenerAdapter(final DataTreeListener delegate, final AdapterContext codec,
- final LogicalDatastoreType store) {
- super(codec, delegate);
- this.store = requireNonNull(store, "store");
- }
-
- @Override
- public void onDataTreeChanged(final Collection<DataTreeCandidate> domChanges,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domSubtrees) {
- final CurrentAdapterSerializer serializer = currentSerializer();
- getDelegate().onDataTreeChanged(toBinding(serializer, domChanges), toBinding(serializer, domSubtrees));
- }
-
- private Map<DataTreeIdentifier<?>, DataObject> toBinding(final BindingNormalizedNodeSerializer serializer,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domSubtrees) {
- // FIXME: Introduce lazy translating map
- final Map<DataTreeIdentifier<?>, DataObject> ret = Maps.newHashMapWithExpectedSize(domSubtrees.size());
-
- for (final Entry<DOMDataTreeIdentifier, NormalizedNode<?, ?>> domEntry : domSubtrees.entrySet()) {
- final Entry<InstanceIdentifier<?>, DataObject> bindingEntry =
- serializer.fromNormalizedNode(domEntry.getKey().getRootIdentifier(), domEntry.getValue());
- ret.put(DataTreeIdentifier.create(store, bindingEntry.getKey()), bindingEntry.getValue());
- }
- return ret;
- }
-
- @SuppressWarnings("unchecked")
- private Collection<DataTreeModification<?>> toBinding(final CurrentAdapterSerializer serializer,
- final Collection<DataTreeCandidate> domChanges) {
- return Collection.class.cast(LazyDataTreeModification.from(serializer, domChanges, store));
- }
-
- @Override
- public void onDataTreeFailed(final Collection<DOMDataTreeListeningException> causes) {
- List<DataTreeListeningException> bindingCauses = new ArrayList<>(causes.size());
- for (DOMDataTreeListeningException cause : causes) {
- bindingCauses.add(mapException(cause));
- }
-
- getDelegate().onDataTreeFailed(bindingCauses);
- }
-
- private static DataTreeListeningException mapException(final DOMDataTreeListeningException cause) {
- // FIXME: Extend logic
- return new DataTreeListeningException(cause.getMessage(), cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.dom.adapter;
-
-import java.util.Collection;
-import org.opendaylight.mdsal.binding.api.CursorAwareWriteTransaction;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeProducer;
-import org.opendaylight.mdsal.binding.api.DataTreeProducerException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-
-final class BindingDOMDataTreeProducerAdapter extends AbstractBindingAdapter<DOMDataTreeProducer>
- implements DataTreeProducer {
- BindingDOMDataTreeProducerAdapter(final AdapterContext adapterContext, final DOMDataTreeProducer delegate) {
- super(adapterContext, delegate);
- }
-
- @Override
- public CursorAwareWriteTransaction createTransaction(final boolean isolated) {
- final DOMDataTreeCursorAwareTransaction domTx = getDelegate().createTransaction(isolated);
- return new BindingDOMCursorAwareWriteTransactionAdapter<>(adapterContext(), domTx);
- }
-
- @Override
- public DataTreeProducer createProducer(final Collection<DataTreeIdentifier<?>> subtrees) {
- final Collection<DOMDataTreeIdentifier> domSubtrees = currentSerializer().toDOMDataTreeIdentifiers(subtrees);
- final DOMDataTreeProducer domChildProducer = getDelegate().createProducer(domSubtrees);
- return new BindingDOMDataTreeProducerAdapter(adapterContext(), domChildProducer);
- }
-
- @Override
- public void close() throws DataTreeProducerException {
- try {
- getDelegate().close();
- } catch (final DOMDataTreeProducerException e) {
- throw new DataTreeProducerException(e.getMessage(), e);
- }
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.binding.dom.adapter;
-
-import java.util.Collection;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeListener;
-import org.opendaylight.mdsal.binding.api.DataTreeLoopException;
-import org.opendaylight.mdsal.binding.api.DataTreeProducer;
-import org.opendaylight.mdsal.binding.api.DataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-final class BindingDOMDataTreeServiceAdapter extends AbstractBindingAdapter<DOMDataTreeService>
- implements DataTreeService {
- BindingDOMDataTreeServiceAdapter(final AdapterContext adapterContext, final DOMDataTreeService delegate) {
- super(adapterContext, delegate);
- }
-
- @Override
- public DataTreeProducer createProducer(final Collection<DataTreeIdentifier<?>> subtrees) {
- final Collection<DOMDataTreeIdentifier> domSubtrees = currentSerializer().toDOMDataTreeIdentifiers(subtrees);
- final DOMDataTreeProducer domChildProducer = getDelegate().createProducer(domSubtrees);
- return new BindingDOMDataTreeProducerAdapter(adapterContext(), domChildProducer);
- }
-
- @Override
- public <T extends DataTreeListener> ListenerRegistration<T> registerListener(final T listener,
- final Collection<DataTreeIdentifier<?>> subtrees, final boolean allowRxMerges,
- final Collection<DataTreeProducer> producers) throws DataTreeLoopException {
- throw new UnsupportedOperationException("Not implemented yet.");
- }
-}
+++ /dev/null
-/*
- * 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.annotations.VisibleForTesting;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Map.Entry;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-final class BindingDOMDataTreeWriteCursorAdapter<T extends DOMDataTreeWriteCursor>
- extends AbstractBindingAdapter<T> implements DataTreeWriteCursor {
- private final Deque<PathArgument> stack = new ArrayDeque<>();
-
- BindingDOMDataTreeWriteCursorAdapter(final AdapterContext adapterContext, final T delegate,
- final DataTreeIdentifier<?> path) {
- super(adapterContext, delegate);
- path.getRootIdentifier().getPathArguments().forEach(stack::push);
- }
-
- private YangInstanceIdentifier.PathArgument convertToNormalized(final PathArgument child) {
- stack.push(child);
- final InstanceIdentifier<?> iid = InstanceIdentifier.create(stack);
- final YangInstanceIdentifier ret = currentSerializer().toYangInstanceIdentifier(iid);
- stack.pop();
- return ret.getLastPathArgument();
- }
-
- private <P extends DataObject> Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> convertToNormalized(
- final PathArgument child, final P data) {
- stack.push(child);
- final InstanceIdentifier<?> iid = InstanceIdentifier.create(stack);
- @SuppressWarnings({ "unchecked", "rawtypes" })
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = currentSerializer().toNormalizedNode(
- (InstanceIdentifier) iid, data);
- stack.pop();
- return entry;
- }
-
- @Override
- public void delete(final PathArgument child) {
- getDelegate().delete(convertToNormalized(child));
- }
-
- @Override
- public <P extends DataObject> void merge(final PathArgument child, final P data) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = convertToNormalized(child, data);
- getDelegate().merge(entry.getKey().getLastPathArgument(), entry.getValue());
- }
-
- @Override
- public <P extends DataObject> void write(final PathArgument child, final P data) {
- final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = convertToNormalized(child, data);
- getDelegate().write(entry.getKey().getLastPathArgument(), entry.getValue());
- }
-
- @Override
- public void enter(final PathArgument child) {
- stack.push(child);
- }
-
- @Override
- public void enter(final PathArgument... path) {
- for (final PathArgument pathArgument : path) {
- enter(pathArgument);
- }
- }
-
- @Override
- public void enter(final Iterable<PathArgument> path) {
- path.forEach(this::enter);
- }
-
- @Override
- public void exit() {
- stack.pop();
- }
-
- @Override
- public void exit(final int depth) {
- for (int i = 0; i < depth; i++) {
- exit();
- }
- }
-
- @Override
- public void close() {
- getDelegate().close();
- }
-
- @VisibleForTesting
- Deque<PathArgument> stack() {
- return stack;
- }
-}
import org.opendaylight.mdsal.binding.api.ActionService;
import org.opendaylight.mdsal.binding.api.BindingService;
import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.DataTreeService;
import org.opendaylight.mdsal.binding.api.MountPointService;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
import org.opendaylight.mdsal.dom.api.DOMActionService;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
import org.opendaylight.mdsal.dom.api.DOMNotificationService;
ComponentFactory actionProviderServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiDataBroker.FACTORY_NAME + ")")
ComponentFactory dataBrokerFactory = null;
- @Reference(target = "(component.factory=" + OSGiDataTreeService.FACTORY_NAME + ")")
- ComponentFactory dataTreeServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiMountPointService.FACTORY_NAME + ")")
ComponentFactory mountPointServiceFactory = null;
@Reference(target = "(component.factory=" + OSGiNotificationService.FACTORY_NAME + ")")
trackers = ImmutableList.of(
new AdaptingTracker<>(ctx, DOMDataBroker.class, DataBroker.class, factory::createDataBroker,
dataBrokerFactory),
- new AdaptingTracker<>(ctx, DOMDataTreeService.class, DataTreeService.class, factory::createDataTreeService,
- dataTreeServiceFactory),
new AdaptingTracker<>(ctx, DOMMountPointService.class, MountPointService.class,
factory::createMountPointService, mountPointServiceFactory),
new AdaptingTracker<>(ctx, DOMNotificationService.class, NotificationService.class,
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, 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.dom.adapter.osgi;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import java.util.Map;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.api.DataTreeListener;
-import org.opendaylight.mdsal.binding.api.DataTreeLoopException;
-import org.opendaylight.mdsal.binding.api.DataTreeProducer;
-import org.opendaylight.mdsal.binding.api.DataTreeService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-
-@Beta
-@Component(factory = OSGiDataTreeService.FACTORY_NAME)
-public final class OSGiDataTreeService extends AbstractAdaptedService<DataTreeService> implements DataTreeService {
- // OSGi DS Component Factory name
- static final String FACTORY_NAME = "org.opendaylight.mdsal.binding.dom.adapter.osgi.OSGiDataTreeService";
-
- public OSGiDataTreeService() {
- super(DataTreeService.class);
- }
-
- @Override
- public DataTreeProducer createProducer(final Collection<DataTreeIdentifier<?>> subtrees) {
- return delegate().createProducer(subtrees);
- }
-
- @Override
- public <T extends DataTreeListener> ListenerRegistration<T> registerListener(final T listener,
- final Collection<DataTreeIdentifier<?>> subtrees, final boolean allowRxMerges,
- final Collection<DataTreeProducer> producers) throws DataTreeLoopException {
- return delegate().registerListener(listener, subtrees, allowRxMerges, producers);
- }
-
- @Activate
- void activate(final Map<String, ?> properties) {
- start(properties);
- }
-
- @Deactivate
- void deactivate(final int reason) {
- stop(reason);
- }
-}
import org.opendaylight.mdsal.binding.api.ActionService;
import org.opendaylight.mdsal.binding.api.BindingService;
import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.DataTreeService;
import org.opendaylight.mdsal.binding.api.MountPointService;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
import org.opendaylight.mdsal.dom.api.DOMActionService;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
import org.opendaylight.mdsal.dom.api.DOMNotificationService;
*/
DataBroker createDataBroker(DOMDataBroker domService);
- /**
- * Create a {@link DataTreeService} backed by a {@link DOMDataTreeService}.
- *
- * @param domService Backing DOMDataTreeService
- * @return A DataTreeService
- * @throws NullPointerException if {@code domService} is null
- */
- DataTreeService createDataTreeService(DOMDataTreeService domService);
-
/**
* Create a {@link MountPointService} backed by a {@link DOMMountPointService}.
*
+++ /dev/null
-/*
- * 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 static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import org.junit.Test;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class BindingDOMCursorAwareWriteTransactionAdapterTest {
- @Test
- public void basicTest() throws Exception {
- final DOMDataTreeCursorAwareTransaction delegate = mock(DOMDataTreeCursorAwareTransaction.class);
- final BindingDOMCodecServices registry = mock(BindingDOMCodecServices.class);
- final AdapterContext codec = new ConstantAdapterContext(registry);
- final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.empty();
- doReturn(yangInstanceIdentifier).when(registry).toYangInstanceIdentifier(any());
- doReturn(mock(DOMDataTreeWriteCursor.class)).when(delegate).createCursor(any());
-
- final BindingDOMCursorAwareWriteTransactionAdapter<?> adapter =
- new BindingDOMCursorAwareWriteTransactionAdapter<>(codec, delegate);
-
- assertNotNull(adapter.createCursor(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.create(DataObject.class))));
-
- doReturn(null).when(delegate).commit();
- adapter.commit();
- verify(delegate).commit();
-
- doReturn(true).when(delegate).cancel();
- assertTrue(adapter.cancel());
- verify(delegate).cancel();
- }
-}
+++ /dev/null
-/*
- * 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 static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.MoreExecutors;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.mdsal.binding.api.DataTreeListener;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingBrokerTestFactory;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingTestContext;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListeningException;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class BindingDOMDataTreeListenerAdapterTest {
-
- private BindingDOMDataTreeListenerAdapter bindingDOMDataTreeListenerAdapter;
-
- @Mock
- private DataTreeListener delegate;
-
- @Before
- public void setUp() throws Exception {
- final BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
- testFactory.setExecutor(MoreExecutors.newDirectExecutorService());
- final BindingTestContext testContext = testFactory.getTestContext();
- testContext.start();
-
- bindingDOMDataTreeListenerAdapter =
- new BindingDOMDataTreeListenerAdapter(delegate, testContext.getCodec(), LogicalDatastoreType.OPERATIONAL);
- }
-
- @Test
- public void onDataTreeChanged() throws Exception {
- bindingDOMDataTreeListenerAdapter.onDataTreeChanged(ImmutableSet.of(), ImmutableMap.of());
- verify(delegate).onDataTreeChanged(any(), any());
- }
-
- @Test
- public void onDataTreeFailedTest() throws Exception {
- bindingDOMDataTreeListenerAdapter.onDataTreeFailed(ImmutableSet.of(new DOMDataTreeListeningException("test")));
- verify(delegate).onDataTreeFailed(any());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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 static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.MoreExecutors;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.mdsal.binding.api.DataTreeProducerException;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingBrokerTestFactory;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingTestContext;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerBusyException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class BindingDOMDataTreeProducerAdapterTest {
- private BindingDOMDataTreeProducerAdapter bindingDOMDataTreeProducerAdapter;
- private AdapterContext codec;
-
- @Mock
- private DOMDataTreeProducer delegate;
-
- @Before
- public void setUp() {
- final BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
- testFactory.setExecutor(MoreExecutors.newDirectExecutorService());
- final BindingTestContext testContext = testFactory.getTestContext();
- testContext.start();
- codec = testContext.getCodec();
- bindingDOMDataTreeProducerAdapter = new BindingDOMDataTreeProducerAdapter(codec, delegate);
- }
-
- @Test
- public void createTransactionTest() {
- doReturn(mock(DOMDataTreeCursorAwareTransaction.class)).when(delegate).createTransaction(true);
- assertNotNull(bindingDOMDataTreeProducerAdapter.createTransaction(true));
- verify(delegate).createTransaction(true);
- }
-
- @Test
- public void createProducerTest() {
- doReturn(mock(DOMDataTreeProducer.class)).when(delegate).createProducer(any());
- assertNotNull(bindingDOMDataTreeProducerAdapter.createProducer(ImmutableSet.of()));
- verify(delegate).createProducer(any());
- }
-
- @Test
- public void closeTest() throws DataTreeProducerException, DOMDataTreeProducerException {
- reset(delegate);
- bindingDOMDataTreeProducerAdapter.close();
- verify(delegate).close();
- }
-
- @Test(expected = DataTreeProducerException.class)
- public void closeTestWithException1() throws DataTreeProducerException, DOMDataTreeProducerException {
- doThrow(new DOMDataTreeProducerBusyException("test")).when(delegate).close();
- bindingDOMDataTreeProducerAdapter.close();
- }
-
- @Test(expected = DataTreeProducerException.class)
- public void closeTestWithException2() throws DataTreeProducerException, DOMDataTreeProducerException {
- doThrow(new DOMDataTreeProducerException("test")).when(delegate).close();
- bindingDOMDataTreeProducerAdapter.close();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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 static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableSet;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.mdsal.binding.api.DataTreeListener;
-import org.opendaylight.mdsal.binding.api.DataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class BindingDOMDataTreeServiceAdapterTest extends AbstractAdapterTest {
-
- private BindingDOMDataTreeServiceAdapter bindingDOMDataTreeServiceAdapter;
-
- @Mock
- private DOMDataTreeService delegate;
-
- @Override
- @Before
- public void before() {
- super.before();
-
- bindingDOMDataTreeServiceAdapter = new BindingDOMDataTreeServiceAdapter(codec, delegate);
- }
-
- @Test
- public void createProducerTest() {
- doReturn(mock(DOMDataTreeProducer.class)).when(delegate).createProducer(any());
- assertNotNull(bindingDOMDataTreeServiceAdapter.createProducer(ImmutableSet.of()));
- verify(delegate).createProducer(any());
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void registerListenerTest() throws DataTreeLoopException {
- bindingDOMDataTreeServiceAdapter.registerListener(mock(DataTreeListener.class), ImmutableSet.of(), false,
- ImmutableSet.of());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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 static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableList;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.Deque;
-import org.junit.Test;
-import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
-import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class BindingDOMDataTreeWriteCursorAdapterTest {
- @Test
- public void basicTest() throws Exception {
- final DataTreeIdentifier<?> identifier =
- DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.create(DataObject.class));
- final DOMDataTreeWriteCursor delegate = mock(DOMDataTreeWriteCursor.class);
- final BindingDOMCodecServices registry = mock(BindingDOMCodecServices.class);
- final AdapterContext codec = new ConstantAdapterContext(registry);
- final BindingDOMDataTreeWriteCursorAdapter<?> adapter =
- new BindingDOMDataTreeWriteCursorAdapter<>(codec, delegate, identifier);
-
- final PathArgument pathArgument = Item.of(DataObject.class);
- final DataObject data = mock(DataObject.class);
-
- adapter.enter(pathArgument, pathArgument);
- adapter.enter(ImmutableList.of(pathArgument));
-
- doNothing().when(delegate).write(any(), any());
- doNothing().when(delegate).merge(any(), any());
- doNothing().when(delegate).delete(any());
- doReturn(YangInstanceIdentifier.empty()).when(registry).toYangInstanceIdentifier(any());
- doNothing().when(delegate).close();
- final NormalizedNode<?, ?> normalizedNode = mock(NormalizedNode.class);
-
- doReturn(new SimpleEntry<YangInstanceIdentifier,NormalizedNode<?,?>>(YangInstanceIdentifier.empty(),
- normalizedNode)).when(registry).toNormalizedNode(any(), any());
- adapter.write(pathArgument, data);
- verify(delegate).write(any(), any());
-
- adapter.merge(pathArgument, data);
- verify(delegate).merge(any(), any());
-
- adapter.delete(pathArgument);
- verify(delegate).delete(any());
-
- final Deque<PathArgument> stack = adapter.stack();
- assertTrue(stack.contains(pathArgument));
-
- adapter.exit(stack.size());
- assertFalse(stack.contains(pathArgument));
-
- adapter.close();
- verify(delegate).close();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import com.google.common.annotations.Beta;
-import java.util.Arrays;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-/**
- * A cursor holding a logical position within a conceptual data tree. It allows operations relative
- * to that position, as well as moving the position up or down the tree.
- *
- * <p>
- * Implementations of this interface are expected to be inherently not-thread-safe.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Beta
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeCursor extends AutoCloseable {
- /**
- * Move the cursor to the specified child of the current position.
- *
- * @param child Child identifier
- * @throws IllegalArgumentException when specified identifier does not identify a valid child,
- * or if that child is not an instance of {@link NormalizedNodeContainer}.
- */
- void enter(@NonNull PathArgument child);
-
- /**
- * Move the cursor to the specified child of the current position. This is the equivalent of
- * multiple invocations of {@link #enter(PathArgument)}, except the operation is performed all
- * at once.
- *
- * @param path Nested child identifier
- * @throws IllegalArgumentException when specified path does not identify a valid child, or if
- * that child is not an instance of {@link NormalizedNodeContainer}.
- */
- default void enter(final @NonNull PathArgument... path) {
- enter(Arrays.asList(path));
- }
-
- /**
- * Move the cursor to the specified child of the current position. This is equivalent to
- * {@link #enter(PathArgument...)}, except it takes an {@link Iterable} argument.
- *
- * @param path Nested child identifier
- * @throws IllegalArgumentException when specified path does not identify a valid child, or if
- * that child is not an instance of {@link NormalizedNodeContainer}.
- */
- void enter(@NonNull Iterable<PathArgument> path);
-
- /**
- * Move the cursor up to the parent of current position. This is equivalent of invoking
- * <code>exit(1)</code>.
- *
- * @throws IllegalStateException when exiting would violate containment, typically by attempting
- * to exit more levels than previously entered.
- */
- void exit();
-
- /**
- * Move the cursor up by specified amounts of steps from the current position. This is
- * equivalent of invoking {@link #exit()} multiple times, except the operation is performed
- * atomically.
- *
- * @param depth number of steps to exit
- * @throws IllegalArgumentException when depth is negative.
- * @throws IllegalStateException when exiting would violate containment, typically by attempting
- * to exit more levels than previously entered.
- */
- void exit(int depth);
-
- /**
- * Close this cursor. Attempting any further operations on the cursor will lead to undefined
- * behavior.
- */
- @Override
- void close();
-}
+++ /dev/null
-/*
- * 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.dom.api;
-
-import com.google.common.util.concurrent.FluentFuture;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.yangtools.concepts.Identifiable;
-
-/**
- * Write transaction that provides cursor's with write access to the data tree.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeCursorAwareTransaction extends DOMDataTreeCursorProvider, Identifiable<Object> {
-
- /**
- * Create a {@link DOMDataTreeWriteCursor} anchored at the specified path.
- * There can only be one cursor open at a time.
- *
- * @param path Path at which the cursor is to be anchored
- * @return write cursor at the desired location.
- * @throws IllegalStateException when there's an open cursor, or this transaction is closed already.
- */
- @Override
- DOMDataTreeWriteCursor createCursor(DOMDataTreeIdentifier path);
-
- /**
- * Cancels the transaction.
- * A transaction can only be cancelled if it was not yet committed.
- * Invoking cancel() on a failed or already canceled will have no effect, and transaction is
- * considered cancelled.
- * Invoking cancel() on a finished transaction (future returned by {@link #commit()} already
- * successfully completed will always fail (return false).
- *
- * @return {@code false} if the task could not be cancelled, typically because it has already
- * completed normally; {@code true} otherwise
- */
- boolean cancel();
-
- /**
- * Submits this transaction to be asynchronously applied to update the logical data tree. The
- * returned CheckedFuture conveys the result of applying the data changes.
- *
- * <p>
- * <b>Note:</b> It is strongly recommended to process the CheckedFuture result in an
- * asynchronous manner rather than using the blocking get() method.
- * This call logically seals the transaction, which prevents the client from further changing
- * data tree using this transaction's cursor. Any subsequent calls to
- * <code>createCursorCursor(DOMDataTreeIdentifier</code>
- * or any of the cursor's methods will fail with {@link IllegalStateException}.
- * The transaction is marked as submitted and enqueued into the shard back-end for
- * processing.
- *
- * @return a FluentFuture containing the result of the commit information. The Future blocks until the commit
- * operation is complete. A successful commit returns nothing. On failure, the Future will fail with a
- * {@link TransactionCommitFailedException} or an exception derived from TransactionCommitFailedException.
- */
- FluentFuture<? extends @NonNull CommitInfo> commit();
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeCursorProvider {
- /**
- * Create a new {@link DataTreeModificationCursor} at specified path. May fail if specified path
- * does not exist.
- *
- * @param path Path at which the cursor is to be anchored
- * @return A new cursor, or null if the path does not exist.
- * @throws IllegalStateException if there is another cursor currently open, or the transaction
- * is already closed (closed or submitted).
- */
- @Nullable DOMDataTreeCursor createCursor(@NonNull DOMDataTreeIdentifier path);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import static java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Failure reported when a data tree is no longer accessible.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@NonNullByDefault
-public class DOMDataTreeInaccessibleException extends DOMDataTreeListeningException {
- private static final long serialVersionUID = 1L;
- private final DOMDataTreeIdentifier treeIdentifier;
-
- public DOMDataTreeInaccessibleException(final DOMDataTreeIdentifier treeIdentifier, final String message) {
- super(message);
- this.treeIdentifier = requireNonNull(treeIdentifier);
- }
-
- public DOMDataTreeInaccessibleException(final DOMDataTreeIdentifier treeIdentifier,
- final String message, final Throwable cause) {
- super(message, requireNonNull(cause));
- this.treeIdentifier = requireNonNull(treeIdentifier);
- }
-
- public final DOMDataTreeIdentifier getTreeIdentifier() {
- return treeIdentifier;
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import java.util.Collection;
-import java.util.EventListener;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-
-/**
- * Interface implemented by data consumers, e.g. processes wanting to act on data
- * after it has been introduced to the conceptual data tree.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeListener extends EventListener {
- /**
- * Invoked whenever one or more registered subtrees change. The logical changes are reported,
- * as well as the roll up of new state for all subscribed subtrees.
- *
- * @param changes The set of changes being reported. Each subscribed subtree may be present
- * at most once.
- * @param subtrees Per-subtree state as visible after the reported changes have been applied.
- * This includes all the subtrees this listener is subscribed to, even those
- * which have not changed.
- */
- void onDataTreeChanged(@NonNull Collection<DataTreeCandidate> changes,
- @NonNull Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees);
-
- /**
- * Invoked when a subtree listening failure occurs. This can be triggered, for example, when a
- * connection to external subtree source is broken. The listener will not receive any other
- * callbacks, but its registration still needs to be closed to prevent resource leak.
- *
- * @param causes Collection of failure causes, may not be null or empty.
- */
- void onDataTreeFailed(@NonNull Collection<DOMDataTreeListeningException> causes);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.opendaylight.mdsal.common.api.ReadFailedException;
-
-/**
- * Base exception for various causes why and {@link DOMDataTreeListener}
- * may be terminated by the {@link DOMDataTreeService} implementation.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public class DOMDataTreeListeningException extends ReadFailedException {
- private static final long serialVersionUID = 1L;
-
- public DOMDataTreeListeningException(final String message) {
- super(message);
- }
-
- public DOMDataTreeListeningException(final String message, final Throwable cause) {
- super(message, cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * Exception thrown when a loop is detected in the way {@link DOMDataTreeListener}
- * and {@link DOMDataTreeProducer} instances would be connected.
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public class DOMDataTreeLoopException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public DOMDataTreeLoopException(@NonNull final String message) {
- super(message);
- }
-
- public DOMDataTreeLoopException(@NonNull final String message, @NonNull final Throwable cause) {
- super(message, cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * A data producer context. It allows transactions to be submitted to the subtrees
- * specified at instantiation time. At any given time there may be a single transaction
- * open. It needs to be either submitted or cancelled before another one can be open.
- * Once a transaction is submitted, it will proceed to be committed asynchronously.
- *
- * <p>
- * Each instance has an upper bound on the number of transactions which can be in-flight,
- * once that capacity is exceeded, an attempt to create a new transaction will block
- * until some transactions complete.
- *
- * <p>
- * Each {@link DOMDataTreeProducer} can be in two logical states, bound and unbound,
- * which define the lifecycle rules for when is it legal to create and submit transactions
- * in relationship with {@link DOMDataTreeListener} callbacks.
- *
- * <p>
- * When a producer is first created, it is unbound. In this state the producer can be
- * accessed by any application thread to allocate or submit transactions, as long as
- * the 'single open transaction' rule is maintained. The producer and any transaction
- * object MUST NOT be accessed, directly or indirectly, from a {@link DOMDataTreeListener}
- * callback.
- *
- * <p>
- * When a producer is referenced in a call to {@link DOMDataTreeService#registerListener(DOMDataTreeListener,
- * Collection, boolean, Collection)},
- * an attempt will be made to bind the producer to the specified {@link DOMDataTreeListener}.
- * Such an attempt will fail the producer is already bound, or it has an open transaction.
- * Once bound, the producer can only be accessed from within the {@link DOMDataTreeListener}
- * callback on that particular instance. Any transaction which is not submitted by the
- * time the callback returns will be implicitly cancelled. A producer becomes unbound
- * when the listener it is bound to becomes unregistered.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeProducer extends DOMDataTreeProducerFactory, AutoCloseable {
- /**
- * Allocate a new open transaction on this producer. Any and all transactions previously
- * allocated must have been either submitted or cancelled by the time this method is invoked.
- *
- * @param isolated Indicates whether this transaction should be a barrier. A barrier transaction
- * is processed separately from any preceding transactions. Non-barrier transactions may
- * be merged and processed in a batch, such that any observers see the modifications
- * contained in them as if the modifications were made in a single transaction.
- * @return A new {@link DOMDataTreeCursorAwareTransaction}
- * @throws IllegalStateException if a previous transaction was not closed.
- * @throws IllegalThreadStateException if the calling thread context does not match the
- * lifecycle rules enforced by the producer state (e.g. bound or unbound). This
- * exception is thrown on a best effort basis and programs should not rely on it for
- * correct operation.
- */
- @NonNull DOMDataTreeCursorAwareTransaction createTransaction(boolean isolated);
-
- /**
- * {@inheritDoc}.
- *
- * <p>
- * When invoked on a {@link DOMDataTreeProducer}, this method has additional restrictions. There
- * may not be an open transaction from this producer. The method needs to be invoked in
- * appropriate context, e.g. bound or unbound.
- *
- * <p>
- * Specified subtrees must be accessible by this producer. Accessible means they are a subset of
- * the subtrees specified when the producer is instantiated. The set is further reduced as child
- * producers are instantiated -- if you create a producer for /a and then a child for /a/b, /a/b
- * is not accessible from the first producer.
- * Once this method returns successfully, this (parent) producer loses the ability to access the
- * specified paths until the resulting (child) producer is shut down.
- *
- * @throws IllegalStateException if there is an open transaction
- * @throws IllegalArgumentException if subtrees contains a subtree which is not accessible by
- * this producer
- * @throws IllegalThreadStateException if the calling thread context does not match the
- * lifecycle rules enforced by the producer state (e.g. bound or unbound). This
- * exception is thrown on a best effort basis and programs should not rely on it for
- * correct operation.
- */
- @Override
- DOMDataTreeProducer createProducer(Collection<DOMDataTreeIdentifier> subtrees);
-
- /**
- * {@inheritDoc}.
- *
- * @throws DOMDataTreeProducerBusyException when there is an open transaction.
- */
- @Override
- void close() throws DOMDataTreeProducerException;
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-/**
- * Exception indicating that the {@link DOMDataTreeProducer} has an open user
- * transaction and cannot be closed.
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public class DOMDataTreeProducerBusyException extends DOMDataTreeProducerException {
- private static final long serialVersionUID = 1L;
-
- public DOMDataTreeProducerBusyException(final String message) {
- super(message);
- }
-
- public DOMDataTreeProducerBusyException(final String message, final Throwable cause) {
- super(message, cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-/**
- * Base exception for all exceptions related to {@link DOMDataTreeProducer}s.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public class DOMDataTreeProducerException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public DOMDataTreeProducerException(final String message) {
- super(message);
- }
-
- public DOMDataTreeProducerException(final String message, final Throwable cause) {
- super(message, cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * Base source of {@link DOMDataTreeProducer}s. This interface is usually not used directly,
- * but rather through one of its sub-interfaces.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeProducerFactory {
- /**
- * Create a producer, which is able to access to a set of trees.
- *
- * @param subtrees The collection of subtrees the resulting producer should have access to.
- * @return A {@link DOMDataTreeProducer} instance.
- * @throws IllegalArgumentException if subtrees is empty.
- */
- @NonNull DOMDataTreeProducer createProducer(@NonNull Collection<DOMDataTreeIdentifier> subtrees);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import com.google.common.util.concurrent.FluentFuture;
-import java.util.Optional;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.ReadFailedException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeReadCursor extends DOMDataTreeCursor {
- /**
- * Read a particular node from the snapshot.
- *
- * @param child Child identifier
- * @return a FluentFuture containing the result of the read. Once complete:
- * <ul>
- * <li>If the data at the supplied path exists, the Future returns an Optional object
- * containing the data.</li>
- * <li>If the data at the supplied path does not exist, the Future returns
- * Optional#empty().</li>
- * <li>If the read of the data fails, the Future will fail with a
- * {@link ReadFailedException} or an exception derived from ReadFailedException.</li>
- * </ul>
- * @throws IllegalArgumentException when specified path does not identify a valid child.
- */
- @NonNull FluentFuture<Optional<NormalizedNode<?, ?>>> readNode(@NonNull PathArgument child);
-
- /**
- * Checks if data is available in the logical data store located at provided path.
- *
- * <p>
- * Note: a successful result from this method makes no guarantee that a subsequent call to
- * {@link #readNode(PathArgument)} will succeed. It is possible that the data resides in a data store on a remote
- * node and, if that node goes down or a network failure occurs, a subsequent read would fail.
- * Another scenario is if the data is deleted in between the calls to <code>exists</code> and
- * <code>readNode</code>
- *
- * @param child Child identifier
- * @return a FluentFuture containing the result of the read. Once complete:
- * <ul>
- * <li>If the data at the supplied path exists, the Future returns a Boolean whose value
- * is true, false otherwise</li>
- * <li>If checking for the data fails, the Future will
- * fail with a {@link ReadFailedException} or an exception derived from
- * ReadFailedException.</li>
- * </ul>
- */
- @NonNull FluentFuture<Boolean> exists(@NonNull PathArgument child);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * A {@link DOMService} providing access to the conceptual data tree. Interactions
- * with the data tree are split into data producers and consumers (listeners). Each
- * of them operate on a set of subtrees, which need to be declared at instantiation time.
- *
- * <p>
- * Returned instances are not thread-safe and expected to be used by a single thread
- * at a time. Furthermore, producers may not be accessed from consumer callbacks
- * unless they were specified when the listener is registered.
- *
- * <p>
- * The service maintains a loop-free topology of producers and consumers. What this means
- * is that a consumer is not allowed to access a producer, which affects any of the
- * subtrees it is subscribed to. This restriction is in place to ensure the system does
- * not go into a feedback loop, where it is impossible to block either a producer or
- * a consumer without accumulating excess work in the backlog stemming from its previous
- * activity.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeService extends DOMDataTreeProducerFactory,
- DOMExtensibleService<DOMDataTreeService, DOMDataTreeServiceExtension> {
- /**
- * Register a {@link DOMDataTreeListener} instance. Once registered, the listener
- * will start receiving changes on the selected subtrees. If the listener cannot
- * keep up with the rate of changes, and allowRxMerges is set to true, this service
- * is free to merge the changes, so that a smaller number of them will be reported,
- * possibly hiding some data transitions (like flaps).
- *
- * <p>
- * If the listener wants to write into any producer, that producer has to be mentioned
- * in the call to this method. Those producers will be bound exclusively to the
- * registration, so that accessing them outside of this listener's callback will trigger
- * an error. Any producers mentioned must be idle, e.g. they may not have an open
- * transaction at the time this method is invoked.
- *
- * <p>
- * Each listener instance can be registered at most once. Implementations of this
- * interface have to guarantee that the listener's methods will not be invoked
- * concurrently from multiple threads.
- *
- * @param listener {@link DOMDataTreeListener} that is being registered
- * @param subtrees Conceptual subtree identifier of subtrees which should be monitored
- * for changes. May not be null or empty.
- * @param allowRxMerges True if the backend may perform ingress state compression.
- * @param producers {@link DOMDataTreeProducer} instances to bind to the listener.
- * @return A listener registration. Once closed, the listener will no longer be
- * invoked and the producers will be unbound.
- * @throws IllegalArgumentException if subtrees is empty or the listener is already bound
- * @throws DOMDataTreeLoopException if the registration of the listener to the specified
- * subtrees with specified producers would form a
- * feedback loop
- */
- @NonNull <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(@NonNull T listener,
- @NonNull Collection<DOMDataTreeIdentifier> subtrees, boolean allowRxMerges,
- @NonNull Collection<DOMDataTreeProducer> producers) throws DOMDataTreeLoopException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 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.dom.api;
-
-/**
- * Type capture of a {@link DOMServiceExtension} applicable to {@link DOMDataTreeService} implementations.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeServiceExtension
- extends DOMServiceExtension<DOMDataTreeService, DOMDataTreeServiceExtension> {
-
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import java.util.EventListener;
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * A single shard of the conceptual data tree. This interface defines the basic notifications
- * a shard can receive. Each shard implementation is expected to also implement some of the
- * datastore-level APIs. Which interfaces are required depends on the {@link DOMDataTreeShardingService}
- * implementation.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeShard extends EventListener {
- /**
- * Invoked whenever a child is getting attached as a more specific prefix under this shard.
- *
- * @param prefix Child's prefix
- * @param child Child shard
- */
- void onChildAttached(@NonNull DOMDataTreeIdentifier prefix, @NonNull DOMDataTreeShard child);
-
- /**
- * Invoked whenever a child is getting detached as a more specific prefix under this shard.
- *
- * @param prefix Child's prefix
- * @param child Child shard
- */
- void onChildDetached(@NonNull DOMDataTreeIdentifier prefix, @NonNull DOMDataTreeShard child);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * Exception thrown when an attempt to attach a conflicting shard to the global
- * table.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public class DOMDataTreeShardingConflictException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public DOMDataTreeShardingConflictException(final @NonNull String message) {
- super(message);
- }
-
- public DOMDataTreeShardingConflictException(final @NonNull String message, final @NonNull Throwable cause) {
- super(message, cause);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * A {@link DOMService} providing access to details on how the conceptual data tree
- * is distributed among providers (also known as shards). Each shard is tied to a
- * single {@link DOMDataTreeIdentifier}. Based on those data tree identifiers, the
- * shards are organized in a tree, where there is a logical parent/child relationship.
- *
- * <p>
- * It is not allowed to attach two shards to the same data tree identifier, which means
- * the mapping of each piece of information has an unambiguous home. When accessing
- * the information, the shard with the longest matching data tree identifier is used,
- * which is why this interface treats it is a prefix.
- *
- * <p>
- * Whenever a parent/child relationship is changed, the parent is notified, so it can
- * understand that a logical child has been attached.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeShardingService extends DOMService {
- /**
- * Register a shard as responsible for a particular subtree prefix.
- *
- * @param prefix Data tree identifier, may not be null.
- * @param shard Responsible shard instance
- * @param producer Producer instance to verify namespace claim
- * @return A registration. To remove the shard's binding, close the registration.
- * @throws DOMDataTreeShardingConflictException if the prefix is already bound
- */
- <T extends DOMDataTreeShard> @NonNull ListenerRegistration<T> registerDataTreeShard(
- @NonNull DOMDataTreeIdentifier prefix, @NonNull T shard,
- @NonNull DOMDataTreeProducer producer) throws DOMDataTreeShardingConflictException;
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.BackendFailedException;
-
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeWriteCursor extends DOMDataTreeCursor {
-
- /**
- * Delete the specified child.
- *
- * @param child Child identifier
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- void delete(PathArgument child);
-
- /**
- * Merge the specified data with the currently-present data at specified path.
- *
- * @param child Child identifier
- * @param data Data to be merged
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- void merge(PathArgument child, NormalizedNode<?, ?> data);
-
- /**
- * Replace the data at specified path with supplied data.
- *
- * @param child Child identifier
- * @param data New node data
- * @throws BackendFailedException when implementation-specific errors occurs while servicing the
- * request.
- */
- void write(PathArgument child, NormalizedNode<?, ?> data);
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.api;
-
-import static org.junit.Assert.assertNotNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import java.net.URI;
-import java.util.Collections;
-import java.util.concurrent.ExecutionException;
-import org.eclipse.jdt.annotation.NonNull;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-
-/**
- * Abstract test suite demonstrating various access patterns on how a {@link DOMDataTreeService}
- * can be used.
- */
-@Deprecated
-public abstract class AbstractDOMDataTreeServiceTestSuite {
- protected static final QNameModule TEST_MODULE =
- QNameModule.create(URI.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:store"));
-
- protected static final YangInstanceIdentifier UNORDERED_CONTAINER_IID = YangInstanceIdentifier.create(
- new NodeIdentifier(QName.create(TEST_MODULE, "lists")),
- new NodeIdentifier(QName.create(TEST_MODULE, "unordered-container")));
- protected static final DOMDataTreeIdentifier UNORDERED_CONTAINER_TREE
- = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, UNORDERED_CONTAINER_IID);
-
- /**
- * Return a reference to the service used in this test. The instance
- * needs to be reused within the same test and must be isolated between
- * tests.
- *
- * @return {@link DOMDataTreeService} instance.
- */
- protected abstract @NonNull DOMDataTreeService service();
-
- /**
- * A simple unbound producer. It write some basic things into the data store based on the
- * test model.
- *
- * @throws DOMDataTreeProducerException when this exceptional condition happens
- */
- @Test
- public final void testBasicProducer() throws DOMDataTreeProducerException, InterruptedException,
- ExecutionException {
- // Create a producer. It is an AutoCloseable resource, hence the try-with pattern
- try (DOMDataTreeProducer prod =
- service().createProducer(Collections.singleton(UNORDERED_CONTAINER_TREE))) {
- assertNotNull(prod);
-
- final DOMDataTreeCursorAwareTransaction tx = prod.createTransaction(true);
- assertNotNull(tx);
-
- final DOMDataTreeWriteCursor cursor =
- tx.createCursor(new DOMDataTreeIdentifier(
- LogicalDatastoreType.OPERATIONAL, UNORDERED_CONTAINER_IID));
- assertNotNull(cursor);
- cursor.write(UNORDERED_CONTAINER_IID.getLastPathArgument(), ImmutableContainerNodeBuilder.create().build());
- cursor.close();
-
- final ListenableFuture<?> f = tx.commit();
- assertNotNull(f);
-
- f.get();
- }
- }
-
- // TODO: simple listener
-}
+++ /dev/null
-/*
- * 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.dom.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.net.URI;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-@Deprecated
-public class DOMExceptionsTest {
- private static final String TEST_MESSAGE = "TestMessage";
- private static final String TEST_LISTS = "test-lists";
- private static final QNameModule TEST_MODULE = QNameModule.create(URI.create(
- "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:store"));
- private static final YangInstanceIdentifier TEST_YI_ID = YangInstanceIdentifier.create(
- new YangInstanceIdentifier.NodeIdentifier(QName.create(TEST_MODULE, TEST_LISTS)));
- private static final DOMDataTreeIdentifier TEST_TREE = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TEST_YI_ID);
-
- @Test(expected = DOMDataTreeInaccessibleException.class)
- public void testDomDataTreeInaccessibleException() throws Exception {
- final DOMDataTreeInaccessibleException testExc = new DOMDataTreeInaccessibleException(TEST_TREE, TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
- assertNotNull(testExc.getTreeIdentifier());
- assertEquals(TEST_TREE, testExc.getTreeIdentifier());
-
- throw new DOMDataTreeInaccessibleException(TEST_TREE, TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMDataTreeListeningException.class)
- public void testDomDataTreeListeningException() throws Exception {
- final DOMDataTreeListeningException testExc = new DOMDataTreeListeningException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMDataTreeListeningException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMDataTreeLoopException.class)
- public void testDomDataTreeLoopException() throws Exception {
- final DOMDataTreeLoopException testExc = new DOMDataTreeLoopException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMDataTreeLoopException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMDataTreeProducerBusyException.class)
- public void testDomDataTreeProducerBusyException() throws Exception {
- final DOMDataTreeProducerBusyException testExc = new DOMDataTreeProducerBusyException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMDataTreeProducerBusyException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMDataTreeProducerException.class)
- public void testDOMDataTreeProducerException() throws Exception {
- final DOMDataTreeProducerException testExc = new DOMDataTreeProducerException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMDataTreeProducerException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMDataTreeShardingConflictException.class)
- public void testDOMDataTreeShardingConflictException() throws Exception {
- final DOMDataTreeShardingConflictException testExc = new DOMDataTreeShardingConflictException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMDataTreeShardingConflictException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMNotificationRejectedException.class)
- public void testDomNotificationRejectedException() throws Exception {
- final DOMNotificationRejectedException testExc = new DOMNotificationRejectedException(TEST_MESSAGE);
- assertTrue(testExc.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMNotificationRejectedException(TEST_MESSAGE, new Throwable());
- }
-
- @Test(expected = DOMRpcImplementationNotAvailableException.class)
- public void testDomRpcImplementationNotAvailableException() throws Exception {
- final DOMRpcImplementationNotAvailableException dompcImplementationNotAvailableException
- = new DOMRpcImplementationNotAvailableException(TEST_MESSAGE);
- assertTrue(dompcImplementationNotAvailableException.getMessage().contains(TEST_MESSAGE));
-
- throw new DOMRpcImplementationNotAvailableException(new Throwable(), TEST_MESSAGE, new Object());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-
-@Beta
-public final class DOMDataTreeShardRegistration<T extends DOMDataTreeShard> extends AbstractListenerRegistration<T> {
- private final DOMDataTreeIdentifier prefix;
- private final ShardedDOMDataTree tree;
-
- public DOMDataTreeShardRegistration(final ShardedDOMDataTree tree, final DOMDataTreeIdentifier prefix,
- final T shard) {
- super(shard);
- this.tree = requireNonNull(tree);
- this.prefix = requireNonNull(prefix);
- }
-
- public DOMDataTreeIdentifier getPrefix() {
- return prefix;
- }
-
- @Override
- protected void removeRegistration() {
- tree.removeShard(this);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableBiMap.Builder;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableDOMDataTreeShard;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class ProducerLayout {
- private static final Logger LOG = LoggerFactory.getLogger(ProducerLayout.class);
-
- private final BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducer;
- private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> children;
- private final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap;
-
- private ProducerLayout(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap,
- final BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducer,
- final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> children) {
- this.shardMap = ImmutableMap.copyOf(shardMap);
- this.idToProducer = requireNonNull(idToProducer);
- this.children = requireNonNull(children);
- }
-
- static ProducerLayout create(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- return new ProducerLayout(shardMap, mapIdsToProducer(shardMap), ImmutableMap.of());
- }
-
- private static BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> mapIdsToProducer(
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- final Multimap<DOMDataTreeShard, DOMDataTreeIdentifier> shardToId = ArrayListMultimap.create();
- // map which identifier belongs to which shard
- for (final Entry<DOMDataTreeIdentifier, DOMDataTreeShard> entry : shardMap.entrySet()) {
- shardToId.put(entry.getValue(), entry.getKey());
- }
-
- final Builder<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducerBuilder = ImmutableBiMap.builder();
- for (final Entry<DOMDataTreeShard, Collection<DOMDataTreeIdentifier>> entry : shardToId.asMap().entrySet()) {
- if (entry.getKey() instanceof WriteableDOMDataTreeShard) {
- //create a single producer for all prefixes in a single shard
- final DOMDataTreeShardProducer producer = ((WriteableDOMDataTreeShard) entry.getKey())
- .createProducer(entry.getValue());
- // id mapped to producers
- for (final DOMDataTreeIdentifier id : entry.getValue()) {
- idToProducerBuilder.put(id, producer);
- }
- } else {
- LOG.error("Unable to create a producer for shard that's not a WriteableDOMDataTreeShard");
- }
- }
-
- return idToProducerBuilder.build();
- }
-
- ProducerLayout addChild(final DOMDataTreeProducer producer, final Collection<DOMDataTreeIdentifier> subtrees) {
- final ImmutableMap.Builder<DOMDataTreeIdentifier, DOMDataTreeProducer> cb = ImmutableMap.builder();
- cb.putAll(children);
- for (final DOMDataTreeIdentifier s : subtrees) {
- cb.put(s, producer);
- }
-
- return new ProducerLayout(shardMap, idToProducer, cb.build());
- }
-
- ProducerLayout reshard(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> newShardMap) {
- close();
- return new ProducerLayout(newShardMap, mapIdsToProducer(newShardMap), children);
- }
-
- boolean haveSubtree(final DOMDataTreeIdentifier subtree) {
- for (final DOMDataTreeIdentifier i : shardMap.keySet()) {
- if (i.contains(subtree)) {
- return true;
- }
- }
-
- return false;
- }
-
- DOMDataTreeProducer lookupChild(final DOMDataTreeIdentifier path) {
- for (final Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> e : children.entrySet()) {
- if (e.getKey().contains(path)) {
- // FIXME: does this match wildcards?
- return e.getValue();
- }
- }
-
- return null;
- }
-
- Set<DOMDataTreeIdentifier> getChildTrees() {
- return children.keySet();
- }
-
- void checkAvailable(final Collection<PathArgument> base, final PathArgument child) {
- if (!children.isEmpty()) {
- final Collection<PathArgument> args = new ArrayList<>(base.size() + 1);
- args.addAll(base);
- args.add(child);
-
- final YangInstanceIdentifier path = YangInstanceIdentifier.create(args);
- for (final DOMDataTreeIdentifier c : children.keySet()) {
- Preconditions.checkArgument(!c.getRootIdentifier().contains(path),
- "Path {%s} is not available to this cursor since it's already claimed by a child producer", path);
- }
- }
- }
-
- Map<DOMDataTreeIdentifier, DOMDataTreeShardWriteTransaction> createTransactions() {
- Preconditions.checkState(!idToProducer.isEmpty(),
- "Cannot create transaction since the producer is not mapped to any shard");
- return Maps.transformValues(idToProducer, DOMDataTreeShardProducer::createTransaction);
- }
-
- void close() {
- idToProducer.values().forEach(DOMDataTreeShardProducer::close);
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import java.util.concurrent.atomic.AtomicLong;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
-import org.opendaylight.mdsal.dom.spi.PingPongMergingDOMDataBroker;
-
-public class ShardedDOMDataBrokerAdapter implements PingPongMergingDOMDataBroker {
- private final AtomicLong chainNum = new AtomicLong();
- private final AtomicLong txNum = new AtomicLong();
- private final DOMDataTreeService service;
-
- public ShardedDOMDataBrokerAdapter(final DOMDataTreeService service) {
- this.service = service;
- }
-
- @Override
- public DOMDataTreeReadTransaction newReadOnlyTransaction() {
- return new ShardedDOMReadTransactionAdapter(newTransactionIdentifier(), service);
- }
-
- @Override
- public DOMDataTreeWriteTransaction newWriteOnlyTransaction() {
- return new ShardedDOMWriteTransactionAdapter(newTransactionIdentifier(), service);
- }
-
- @Override
- public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
- return new ShardedDOMReadWriteTransactionAdapter(newTransactionIdentifier(), service);
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(final DOMTransactionChainListener listener) {
- return new ShardedDOMTransactionChainAdapter(newChainIdentifier(), service, listener);
- }
-
- private Object newTransactionIdentifier() {
- return "DOM-" + txNum.getAndIncrement();
- }
-
- private Object newChainIdentifier() {
- return "DOM-CHAIN-" + chainNum;
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.ListMultimap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeServiceExtension;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingConflictException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingService;
-import org.opendaylight.mdsal.dom.spi.DOMDataTreePrefixTable;
-import org.opendaylight.mdsal.dom.spi.DOMDataTreePrefixTableEntry;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeListenerAggregator;
-import org.opendaylight.mdsal.dom.spi.shard.ListenableDOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTreeShardingService {
- private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTree.class);
-
- @GuardedBy("this")
- private final DOMDataTreePrefixTable<DOMDataTreeShardRegistration<?>> shards = DOMDataTreePrefixTable.create();
- @GuardedBy("this")
- private final DOMDataTreePrefixTable<DOMDataTreeProducer> producers = DOMDataTreePrefixTable.create();
- @GuardedBy("this")
- private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> producerMap = new HashMap<>();
-
- void removeShard(final DOMDataTreeShardRegistration<?> reg) {
- final DOMDataTreeIdentifier prefix = reg.getPrefix();
- DOMDataTreeShard lookupShard = null;
- synchronized (this) {
- shards.remove(prefix);
- final DOMDataTreePrefixTableEntry<DOMDataTreeShardRegistration<?>> parentRegEntry = shards.lookup(prefix);
- if (parentRegEntry != null) {
- lookupShard = parentRegEntry.getValue().getInstance();
- }
- /*
- * FIXME: adjust all producers and listeners. This is tricky, as we need different
- * locking strategy, simply because we risk AB/BA deadlock with a producer being split
- * off from a producer.
- */
- }
-
- if (lookupShard != null) {
- lookupShard.onChildDetached(prefix, reg.getInstance());
- }
- }
-
- @Override
- public <T extends DOMDataTreeShard> DOMDataTreeShardRegistration<T> registerDataTreeShard(
- final DOMDataTreeIdentifier prefix, final T shard, final DOMDataTreeProducer producer)
- throws DOMDataTreeShardingConflictException {
- checkArgument(producer instanceof ShardedDOMDataTreeProducer, "Unsupported producer %s", producer);
- final ShardedDOMDataTreeProducer prod = (ShardedDOMDataTreeProducer) producer;
-
- final DOMDataTreeIdentifier firstSubtree = Iterables.getOnlyElement(prod.getSubtrees());
- checkArgument(firstSubtree != null, "Producer that is used to verify namespace claim can"
- + " only claim a single namespace");
- checkArgument(prefix.equals(firstSubtree), "Trying to register shard to a different namespace"
- + " than the producer has claimed");
-
- final DOMDataTreeShardRegistration<T> reg;
- final DOMDataTreeShardRegistration<?> parentReg;
-
- synchronized (this) {
- /*
- * Lookup the parent shard (e.g. the one which currently matches the prefix),
- * and if it exists, check if its registration prefix does not collide with
- * this registration.
- */
- final DOMDataTreePrefixTableEntry<DOMDataTreeShardRegistration<?>> parent = shards.lookup(prefix);
- if (parent != null) {
- parentReg = parent.getValue();
- if (parentReg != null && prefix.equals(parentReg.getPrefix())) {
- throw new DOMDataTreeShardingConflictException(String.format(
- "Prefix %s is already occupied by shard %s", prefix, parentReg.getInstance()));
- }
- } else {
- parentReg = null;
- }
-
- // FIXME: wrap the shard in a proper adaptor based on implemented interface
-
- reg = new DOMDataTreeShardRegistration<>(this, prefix, shard);
-
- shards.store(prefix, reg);
-
- prod.subshardAdded(Collections.singletonMap(prefix, shard));
- }
-
- // Notify the parent shard
- if (parentReg != null) {
- parentReg.getInstance().onChildAttached(prefix, shard);
- }
-
- return reg;
- }
-
- @GuardedBy("this")
- private DOMDataTreeProducer findProducer(final DOMDataTreeIdentifier subtree) {
-
- final DOMDataTreePrefixTableEntry<DOMDataTreeProducer> producerEntry = producers.lookup(subtree);
- if (producerEntry != null) {
- return producerEntry.getValue();
- }
- return null;
- }
-
- synchronized void destroyProducer(final ShardedDOMDataTreeProducer producer) {
- for (final DOMDataTreeIdentifier s : producer.getSubtrees()) {
- producers.remove(s);
- producerMap.remove(s);
- }
- }
-
- @Override
- public ClassToInstanceMap<DOMDataTreeServiceExtension> getExtensions() {
- return ImmutableClassToInstanceMap.of();
- }
-
- @GuardedBy("this")
- private DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees,
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- // Record the producer's attachment points
- final DOMDataTreeProducer ret = ShardedDOMDataTreeProducer.create(this, subtrees, shardMap);
- for (final DOMDataTreeIdentifier subtree : subtrees) {
- producers.store(subtree, ret);
- producerMap.put(subtree, ret);
- }
-
- return ret;
- }
-
- @Override
- public synchronized DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- checkArgument(!subtrees.isEmpty(), "Subtrees may not be empty");
-
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
- for (final DOMDataTreeIdentifier subtree : subtrees) {
- // Attempting to create a disconnected producer -- all subtrees have to be unclaimed
- final DOMDataTreeProducer producer = findProducer(subtree);
- checkArgument(producer == null, "Subtree %s is attached to producer %s", subtree, producer);
-
- for (Map.Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> producerEntry : producerMap.entrySet()) {
- checkArgument(!subtree.contains(producerEntry.getKey()),
- "Subtree %s contains subtree %s which is already attached to producer %s.",
- subtree, producerEntry.getKey(), producerEntry.getValue());
- }
-
- final DOMDataTreePrefixTableEntry<DOMDataTreeShardRegistration<?>> possibleShardReg =
- shards.lookup(subtree);
- if (possibleShardReg != null && possibleShardReg.getValue() != null) {
- shardMap.put(subtree, possibleShardReg.getValue().getInstance());
- }
- }
-
- return createProducer(subtrees, shardMap);
- }
-
- synchronized DOMDataTreeProducer createProducer(final ShardedDOMDataTreeProducer parent,
- final Collection<DOMDataTreeIdentifier> subtrees) {
- requireNonNull(parent);
-
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
- for (final DOMDataTreeIdentifier s : subtrees) {
- shardMap.put(s, shards.lookup(s).getValue().getInstance());
- }
-
- return createProducer(subtrees, shardMap);
- }
-
- @SuppressWarnings({ "checkstyle:IllegalCatch", "checkstyle:hiddenField" })
- @Override
- public synchronized <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(final T listener,
- final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges,
- final Collection<DOMDataTreeProducer> producers) throws DOMDataTreeLoopException {
- requireNonNull(listener, "listener");
-
- // Cross-check specified trees for exclusivity and eliminate duplicates, noDupSubtrees is effectively a Set
- final Collection<DOMDataTreeIdentifier> noDupSubtrees;
- switch (subtrees.size()) {
- case 0:
- throw new IllegalArgumentException("Subtrees must not be empty.");
- case 1:
- noDupSubtrees = subtrees;
- break;
- default:
- // Check subtrees for mutual inclusion, this is an O(N**2) operation
- for (DOMDataTreeIdentifier toCheck : subtrees) {
- for (DOMDataTreeIdentifier against : subtrees) {
- if (!toCheck.equals(against)) {
- checkArgument(!toCheck.contains(against), "Subtree %s contains subtree %s", toCheck,
- against);
- }
- }
- }
-
- noDupSubtrees = ImmutableSet.copyOf(subtrees);
- }
-
- LOG.trace("Requested registration of listener {} to subtrees {}", listener, noDupSubtrees);
-
- // Lookup shards corresponding to subtrees and construct a map of which subtrees we want from which shard
- final ListMultimap<DOMDataTreeShardRegistration<?>, DOMDataTreeIdentifier> needed =
- ArrayListMultimap.create();
- for (final DOMDataTreeIdentifier subtree : subtrees) {
- final DOMDataTreeShardRegistration<?> reg = verifyNotNull(shards.lookup(subtree).getValue());
- needed.put(reg, subtree);
- }
-
- LOG.trace("Listener {} is attaching to shards {}", listener, needed);
-
- // Sanity check: all selected shards have to support one of the listening interfaces
- needed.asMap().forEach((reg, trees) -> {
- final DOMDataTreeShard shard = reg.getInstance();
- checkArgument(shard instanceof ListenableDOMDataTreeShard
- || shard instanceof DOMStoreTreeChangePublisher, "Subtrees %s do not point to listenable subtree.",
- trees);
- });
-
- // Sanity check: all producers have to come from this implementation and must not form loops
- for (DOMDataTreeProducer producer : producers) {
- checkArgument(producer instanceof ShardedDOMDataTreeProducer);
- simpleLoopCheck(subtrees, ((ShardedDOMDataTreeProducer) producer).getSubtrees());
- }
-
- final ListenerRegistration<?> underlyingRegistration = createRegisteredListener(listener, needed.asMap(),
- allowRxMerges, producers);
- return new AbstractListenerRegistration<T>(listener) {
- @Override
- protected void removeRegistration() {
- ShardedDOMDataTree.this.removeListener(listener);
- underlyingRegistration.close();
- }
- };
- }
-
- private static ListenerRegistration<?> createRegisteredListener(final DOMDataTreeListener userListener,
- final Map<DOMDataTreeShardRegistration<?>, Collection<DOMDataTreeIdentifier>> needed,
- final boolean allowRxMerges, final Collection<DOMDataTreeProducer> producers) {
- // FIXME: Add attachment of producers
- for (final DOMDataTreeProducer producer : producers) {
- // FIXME: We should also unbound listeners
- ((ShardedDOMDataTreeProducer) producer).bindToListener(userListener);
- }
-
- return DOMDataTreeListenerAggregator.aggregateIfNeeded(userListener, needed, allowRxMerges,
- DOMDataTreeShardRegistration::getInstance);
- }
-
- private static void simpleLoopCheck(final Collection<DOMDataTreeIdentifier> listen,
- final Set<DOMDataTreeIdentifier> writes) throws DOMDataTreeLoopException {
- for (final DOMDataTreeIdentifier listenPath : listen) {
- for (final DOMDataTreeIdentifier writePath : writes) {
- if (listenPath.contains(writePath)) {
- throw new DOMDataTreeLoopException(String.format(
- "Listener must not listen on parent (%s), and also writes child (%s)", listenPath,
- writePath));
- } else if (writePath.contains(listenPath)) {
- throw new DOMDataTreeLoopException(
- String.format("Listener must not write parent (%s), and also listen on child (%s)",
- writePath, listenPath));
- }
- }
- }
- }
-
- void removeListener(final DOMDataTreeListener listener) {
- // FIXME: detach producers
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.checkerframework.checker.lock.qual.Holding;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerBusyException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class ShardedDOMDataTreeProducer implements DOMDataTreeProducer {
- private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTreeProducer.class);
-
- private final Set<DOMDataTreeIdentifier> subtrees;
- private final ShardedDOMDataTree dataTree;
-
- private static final AtomicReferenceFieldUpdater<ShardedDOMDataTreeProducer, ShardedDOMDataTreeWriteTransaction>
- CURRENT_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ShardedDOMDataTreeProducer.class,
- ShardedDOMDataTreeWriteTransaction.class, "currentTx");
- private volatile ShardedDOMDataTreeWriteTransaction currentTx;
-
- private static final AtomicReferenceFieldUpdater<ShardedDOMDataTreeProducer, ShardedDOMDataTreeWriteTransaction>
- OPEN_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ShardedDOMDataTreeProducer.class,
- ShardedDOMDataTreeWriteTransaction.class, "openTx");
- private volatile ShardedDOMDataTreeWriteTransaction openTx;
-
- private static final AtomicReferenceFieldUpdater<ShardedDOMDataTreeProducer, ShardedDOMDataTreeWriteTransaction>
- LAST_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ShardedDOMDataTreeProducer.class,
- ShardedDOMDataTreeWriteTransaction.class, "lastTx");
- private volatile ShardedDOMDataTreeWriteTransaction lastTx;
-
- private static final AtomicIntegerFieldUpdater<ShardedDOMDataTreeProducer> CLOSED_UPDATER =
- AtomicIntegerFieldUpdater.newUpdater(ShardedDOMDataTreeProducer.class, "closed");
- private volatile int closed;
-
- private volatile DOMDataTreeListener attachedListener;
- private volatile ProducerLayout layout;
-
- ShardedDOMDataTreeProducer(final ShardedDOMDataTree dataTree,
- final Collection<DOMDataTreeIdentifier> subtrees,
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- this.dataTree = requireNonNull(dataTree);
- this.subtrees = ImmutableSet.copyOf(subtrees);
- this.layout = ProducerLayout.create(shardMap);
- }
-
- static DOMDataTreeProducer create(final ShardedDOMDataTree dataTree,
- final Collection<DOMDataTreeIdentifier> subtrees,
- final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- return new ShardedDOMDataTreeProducer(dataTree, subtrees, shardMap);
- }
-
- private void checkNotClosed() {
- Preconditions.checkState(closed == 0, "Producer is already closed");
- }
-
- private void checkIdle() {
- Preconditions.checkState(openTx == null, "Transaction %s is still open", openTx);
- }
-
- void subshardAdded(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
- checkIdle();
- layout = layout.reshard(shardMap);
- }
-
- @Override
- public DOMDataTreeCursorAwareTransaction createTransaction(final boolean isolated) {
- checkNotClosed();
- checkIdle();
-
- LOG.debug("Creating transaction from producer {}", this);
-
- final ShardedDOMDataTreeWriteTransaction current = CURRENT_UPDATER.getAndSet(this, null);
- final ShardedDOMDataTreeWriteTransaction ret;
- if (isolated) {
- ret = createIsolatedTransaction(layout, current);
- } else {
- ret = createReusedTransaction(layout, current);
- }
-
- final boolean success = OPEN_UPDATER.compareAndSet(this, null, ret);
- Preconditions.checkState(success, "Illegal concurrent access to producer %s detected", this);
- return ret;
- }
-
- // This may look weird, but this has side-effects on local's producers, hence it needs to be properly synchronized
- // so that it happens-after submitTransaction() which may have been stolen by a callback.
- @GuardedBy("this")
- private ShardedDOMDataTreeWriteTransaction createTransaction(final ProducerLayout local) {
- return new ShardedDOMDataTreeWriteTransaction(this, local.createTransactions(), local);
-
- }
-
- // Isolated case. If we have a previous transaction, submit it before returning this one.
- private synchronized ShardedDOMDataTreeWriteTransaction createIsolatedTransaction(
- final ProducerLayout local, final ShardedDOMDataTreeWriteTransaction current) {
- if (current != null) {
- submitTransaction(current);
- }
-
- return createTransaction(local);
- }
-
- private ShardedDOMDataTreeWriteTransaction createReusedTransaction(final ProducerLayout local,
- final ShardedDOMDataTreeWriteTransaction current) {
- if (current != null) {
- // Lock-free fast path
- if (local.equals(current.getLayout())) {
- LOG.debug("Reusing previous transaction {} since there is still a transaction inflight",
- current.getIdentifier());
- return current;
- }
-
- synchronized (this) {
- submitTransaction(current);
- return createTransaction(local);
- }
- }
-
- // Null indicates we have not seen a previous transaction -- which does not mean it is ready, as it may have
- // been stolen and in is process of being submitted.
- synchronized (this) {
- return createTransaction(local);
- }
- }
-
- @Holding("this")
- private void submitTransaction(final ShardedDOMDataTreeWriteTransaction tx) {
- lastTx = tx;
- tx.doSubmit(this::transactionSuccessful, this::transactionFailed);
- }
-
- @Override
- @SuppressWarnings("checkstyle:hiddenField")
- public DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- checkNotClosed();
- checkIdle();
-
- final ProducerLayout local = layout;
-
- for (final DOMDataTreeIdentifier s : subtrees) {
- // Check if the subtree was visible at any time
- Preconditions.checkArgument(local.haveSubtree(s), "Subtree %s was never available in producer %s", s, this);
- // Check if the subtree has not been delegated to a child
- final DOMDataTreeProducer child = local.lookupChild(s);
- Preconditions.checkArgument(child == null, "Subtree %s is delegated to child producer %s", s, child);
-
- // Check if part of the requested subtree is not delegated to a child.
- for (final DOMDataTreeIdentifier c : local.getChildTrees()) {
- Preconditions.checkArgument(!s.contains(c),
- "Subtree %s cannot be delegated as it is a superset of already-delegated %s", s, c);
- }
- }
-
-
- final DOMDataTreeProducer ret;
- synchronized (this) {
- ret = dataTree.createProducer(this, subtrees);
- }
-
- layout = local.addChild(ret, subtrees);
- return ret;
- }
-
- boolean isDelegatedToChild(final DOMDataTreeIdentifier path) {
- return layout.lookupChild(path) != null;
- }
-
- @Override
- public void close() throws DOMDataTreeProducerException {
- if (openTx != null) {
- throw new DOMDataTreeProducerBusyException(String.format("Transaction %s is still open", openTx));
- }
-
- if (CLOSED_UPDATER.compareAndSet(this, 0, 1)) {
- synchronized (this) {
- dataTree.destroyProducer(this);
- layout.close();
- }
- }
- }
-
- protected Set<DOMDataTreeIdentifier> getSubtrees() {
- return subtrees;
- }
-
- void cancelTransaction(final ShardedDOMDataTreeWriteTransaction transaction) {
- final boolean success = OPEN_UPDATER.compareAndSet(this, transaction, null);
- if (success) {
- LOG.debug("Transaction {} cancelled", transaction);
- } else {
- LOG.warn("Transaction {} is not open in producer {}", transaction, this);
- }
- }
-
- // Called when the user submits a transaction
- void transactionSubmitted(final ShardedDOMDataTreeWriteTransaction transaction) {
- final boolean wasOpen = OPEN_UPDATER.compareAndSet(this, transaction, null);
- Preconditions.checkState(wasOpen, "Attempted to submit non-open transaction %s", transaction);
-
- if (lastTx == null) {
- // No transaction outstanding, we need to submit it now
- synchronized (this) {
- submitTransaction(transaction);
- }
-
- return;
- }
-
- // There is a potentially-racing submitted transaction. Publish the new one, which may end up being
- // picked up by processNextTransaction.
- final boolean success = CURRENT_UPDATER.compareAndSet(this, null, transaction);
- Verify.verify(success);
-
- // Now a quick check: if the racing transaction completed in between, it may have missed the current
- // transaction, hence we need to re-check
- if (lastTx == null) {
- submitCurrentTransaction();
- }
- }
-
- private void submitCurrentTransaction() {
- final ShardedDOMDataTreeWriteTransaction current = currentTx;
- if (current != null) {
- synchronized (this) {
- if (CURRENT_UPDATER.compareAndSet(this, current, null)) {
- submitTransaction(current);
- }
- }
- }
- }
-
- private void transactionSuccessful(final ShardedDOMDataTreeWriteTransaction tx) {
- LOG.debug("Transaction {} completed successfully", tx.getIdentifier());
-
- tx.onTransactionSuccess(CommitInfo.empty());
- transactionCompleted(tx);
- }
-
- private void transactionFailed(final ShardedDOMDataTreeWriteTransaction tx, final Throwable throwable) {
- LOG.debug("Transaction {} failed", tx.getIdentifier(), throwable);
-
- tx.onTransactionFailure(throwable);
- // FIXME: transaction failure should result in a hard error
- transactionCompleted(tx);
- }
-
- private void transactionCompleted(final ShardedDOMDataTreeWriteTransaction tx) {
- final boolean wasLast = LAST_UPDATER.compareAndSet(this, tx, null);
- if (wasLast) {
- submitCurrentTransaction();
- }
- }
-
- void bindToListener(final DOMDataTreeListener listener) {
- final DOMDataTreeListener local = attachedListener;
- Preconditions.checkState(local == null, "Producer %s is already attached to listener %s", this, local);
- this.attachedListener = requireNonNull(listener);
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class ShardedDOMDataTreeWriteTransaction implements DOMDataTreeCursorAwareTransaction {
- private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMDataTreeWriteTransaction.class);
- private static final AtomicLong COUNTER = new AtomicLong();
-
- private final Map<DOMDataTreeIdentifier, DOMDataTreeShardWriteTransaction> transactions;
- private final ShardedDOMDataTreeProducer producer;
- private final ProducerLayout layout;
- private final String identifier;
-
- private final SettableFuture<CommitInfo> future = SettableFuture.create();
-
- @GuardedBy("this")
- private boolean closed = false;
-
- @GuardedBy("this")
- private DOMDataTreeWriteCursor openCursor;
-
- ShardedDOMDataTreeWriteTransaction(final ShardedDOMDataTreeProducer producer,
- final Map<DOMDataTreeIdentifier, DOMDataTreeShardWriteTransaction> transactions, final ProducerLayout layout) {
- this.producer = requireNonNull(producer);
- this.transactions = ImmutableMap.copyOf(transactions);
- this.layout = requireNonNull(layout);
- this.identifier = "SHARDED-DOM-" + COUNTER.getAndIncrement();
- LOG.debug("Created new transaction {}", identifier);
- }
-
- private DOMDataTreeShardWriteTransaction lookup(final DOMDataTreeIdentifier prefix) {
- final DOMDataTreeShardWriteTransaction fast = transactions.get(prefix);
- if (fast != null) {
- return fast;
- }
-
- LOG.debug("Prefix {} not found in available subtrees {}, fallback to slow path", prefix, transactions.keySet());
- for (final Entry<DOMDataTreeIdentifier, DOMDataTreeShardWriteTransaction> e : transactions.entrySet()) {
- if (e.getKey().contains(prefix)) {
- return e.getValue();
- }
- }
-
- return null;
- }
-
- @Override
- public String getIdentifier() {
- return identifier;
- }
-
- @Override
- public synchronized boolean cancel() {
- if (closed) {
- return false;
- }
-
- LOG.debug("Cancelling transaction {}", identifier);
- if (openCursor != null) {
- openCursor.close();
- }
- for (final DOMDataTreeShardWriteTransaction tx : transactions.values()) {
- tx.close();
- }
-
- closed = true;
- producer.cancelTransaction(this);
- return true;
- }
-
- @Override
- public synchronized DOMDataTreeWriteCursor createCursor(final DOMDataTreeIdentifier prefix) {
- Preconditions.checkState(!closed, "Transaction is closed already");
- Preconditions.checkState(openCursor == null, "There is still a cursor open");
- Preconditions.checkArgument(!producer.isDelegatedToChild(prefix), "Path %s is delegated to child producer.",
- prefix);
-
- final DOMDataTreeShardWriteTransaction lookup = lookup(prefix);
- Preconditions.checkArgument(lookup != null, "Path %s is not accessible from transaction %s", prefix, this);
-
- openCursor = new DelegatingCursor(lookup.createCursor(prefix), prefix);
- return openCursor;
- }
-
- @Override
- public synchronized FluentFuture<? extends @NonNull CommitInfo> commit() {
- Preconditions.checkState(!closed, "Transaction %s is already closed", identifier);
- Preconditions.checkState(openCursor == null, "Cannot submit transaction while there is a cursor open");
-
- producer.transactionSubmitted(this);
- return FluentFuture.from(future);
- }
-
- void doSubmit(final Consumer<ShardedDOMDataTreeWriteTransaction> success,
- final BiConsumer<ShardedDOMDataTreeWriteTransaction, Throwable> failure) {
- LOG.debug("Readying tx {}", identifier);
-
- final ListenableFuture<?> internalFuture;
- switch (transactions.size()) {
- case 0:
- success.accept(this);
- return;
- case 1: {
- final DOMDataTreeShardWriteTransaction tx = transactions.values().iterator().next();
- tx.ready();
- internalFuture = tx.submit();
- break;
- }
- default:
- internalFuture = Futures.allAsList(transactions.values().stream().map(tx -> {
- tx.ready();
- return tx.submit();
- }).collect(Collectors.toList()));
- }
-
- Futures.addCallback(internalFuture, new FutureCallback<Object>() {
- @Override
- public void onSuccess(final Object result) {
- success.accept(ShardedDOMDataTreeWriteTransaction.this);
- }
-
- @Override
- public void onFailure(final Throwable exp) {
- failure.accept(ShardedDOMDataTreeWriteTransaction.this, exp);
- }
- }, MoreExecutors.directExecutor());
- }
-
- void onTransactionSuccess(final CommitInfo commitInfo) {
- future.set(commitInfo);
- }
-
- void onTransactionFailure(final Throwable throwable) {
- future.setException(throwable);
- }
-
- synchronized void cursorClosed() {
- openCursor = null;
- }
-
- private class DelegatingCursor implements DOMDataTreeWriteCursor {
- private final Deque<PathArgument> currentArgs = new ArrayDeque<>();
- private final DOMDataTreeWriteCursor delegate;
- private final DOMDataTreeIdentifier rootPosition;
-
- DelegatingCursor(final DOMDataTreeWriteCursor delegate, final DOMDataTreeIdentifier rootPosition) {
- this.delegate = requireNonNull(delegate);
- this.rootPosition = requireNonNull(rootPosition);
- currentArgs.addAll(rootPosition.getRootIdentifier().getPathArguments());
- }
-
- @Override
- public void enter(final PathArgument child) {
- checkAvailable(child);
- delegate.enter(child);
- currentArgs.push(child);
- }
-
- @Override
- public void enter(final PathArgument... path) {
- for (final PathArgument pathArgument : path) {
- enter(pathArgument);
- }
- }
-
- @Override
- public void enter(final Iterable<PathArgument> path) {
- for (final PathArgument pathArgument : path) {
- enter(pathArgument);
- }
- }
-
- @Override
- public void exit() {
- delegate.exit();
- currentArgs.pop();
- }
-
- @Override
- public void exit(final int depth) {
- delegate.exit(depth);
- for (int i = 0; i < depth; i++) {
- currentArgs.pop();
- }
- }
-
- @Override
- public void close() {
- int depthEntered = currentArgs.size() - rootPosition.getRootIdentifier().getPathArguments().size();
- if (depthEntered > 0) {
- // clean up existing modification cursor in case this tx will be reused for batching
- delegate.exit(depthEntered);
- }
-
- delegate.close();
- cursorClosed();
- }
-
- @Override
- public void delete(final PathArgument child) {
- checkAvailable(child);
- delegate.delete(child);
- }
-
- @Override
- public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
- checkAvailable(child);
- delegate.merge(child, data);
- }
-
- @Override
- public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
- checkAvailable(child);
- delegate.write(child, data);
- }
-
- void checkAvailable(final PathArgument child) {
- layout.checkAvailable(currentArgs, child);
- }
- }
-
- ProducerLayout getLayout() {
- return layout;
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListeningException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ShardedDOMReadTransactionAdapter implements DOMDataTreeReadTransaction {
- private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMReadTransactionAdapter.class.getName());
-
- private final List<ListenerRegistration<DOMDataTreeListener>> registrations = new ArrayList<>();
- private final @NonNull DOMDataTreeService service;
- private final @NonNull Object txIdentifier;
-
- private boolean finished = false;
-
- ShardedDOMReadTransactionAdapter(final Object identifier, final DOMDataTreeService service) {
- this.service = requireNonNull(service);
- this.txIdentifier = requireNonNull(identifier);
- }
-
- @Override
- public void close() {
- LOG.debug("{}: Closing read transaction", txIdentifier);
- if (finished) {
- return;
- }
-
- registrations.forEach(ListenerRegistration::close);
- // TODO should we also cancel all read futures?
- finished = true;
- }
-
- @Override
- public Object getIdentifier() {
- return txIdentifier;
- }
-
- @Override
- public FluentFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- checkRunning();
- LOG.debug("{}: Invoking read at {}:{}", txIdentifier, store, path);
- final ListenerRegistration<DOMDataTreeListener> reg;
- final SettableFuture<Optional<NormalizedNode<?, ?>>> initialDataTreeChangeFuture = SettableFuture.create();
- try {
- reg = service.registerListener(new ReadShardedListener(initialDataTreeChangeFuture),
- Collections.singleton(new DOMDataTreeIdentifier(store, path)), false, Collections.emptyList());
- registrations.add(reg);
- } catch (final DOMDataTreeLoopException e) {
- // This should not happen, we are not specifying any producers when registering listener
- throw new IllegalStateException("Loop in listener and producers detected", e);
- }
-
- // After data tree change future is finished, we can close the listener registration
- initialDataTreeChangeFuture.addListener(reg::close, MoreExecutors.directExecutor());
- return FluentFuture.from(initialDataTreeChangeFuture);
- }
-
- @Override
- public FluentFuture<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- checkRunning();
- LOG.debug("{}: Invoking exists at {}:{}", txIdentifier, store, path);
- return read(store, path).transform(Optional::isPresent, MoreExecutors.directExecutor());
- }
-
- private void checkRunning() {
- checkState(!finished, "Transaction is already closed");
- }
-
- static final class ReadShardedListener implements DOMDataTreeListener {
- private final SettableFuture<Optional<NormalizedNode<?, ?>>> readResultFuture;
-
- ReadShardedListener(final SettableFuture<Optional<NormalizedNode<?, ?>>> future) {
- this.readResultFuture = requireNonNull(future);
- }
-
- @Override
- public void onDataTreeChanged(final Collection<DataTreeCandidate> changes,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees) {
- checkState(changes.size() == 1 && subtrees.size() == 1,
- "DOMDataTreeListener registered exactly on one subtree");
- if (changes.iterator().next().getRootNode().getModificationType().equals(ModificationType.UNMODIFIED)) {
- readResultFuture.set(Optional.empty());
- } else {
- readResultFuture.set(Optional.of(subtrees.values().iterator().next()));
- }
- }
-
- @Override
- public void onDataTreeFailed(final Collection<DOMDataTreeListeningException> causes) {
- // TODO If we get just one exception, we don't need to do chaining
-
- // We chain all exceptions and return aggregated one
- readResultFuture.setException(new DOMDataTreeListeningException("Aggregated DOMDataTreeListening exception",
- causes.stream().reduce((e1, e2) -> {
- e1.addSuppressed(e2);
- return e1;
- }).get()));
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Brocade Communications 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.dom.broker;
-
-import com.google.common.util.concurrent.FluentFuture;
-import java.util.Optional;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-final class ShardedDOMReadWriteTransactionAdapter extends ShardedDOMWriteTransactionAdapter
- implements DOMDataTreeReadWriteTransaction {
-
- private final ShardedDOMReadTransactionAdapter readAdapter;
-
- ShardedDOMReadWriteTransactionAdapter(final Object identifier, final DOMDataTreeService transactionDelegator) {
- super(identifier, transactionDelegator);
- readAdapter = new ShardedDOMReadTransactionAdapter(identifier, transactionDelegator);
- }
-
- @Override
- public FluentFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- return readAdapter.read(store, path);
- }
-
- @Override
- public FluentFuture<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- return readAdapter.exists(store, path);
- }
-
- @Override
- public boolean cancel() {
- readAdapter.close();
- return super.cancel();
- }
-
- ShardedDOMReadTransactionAdapter getReadAdapter() {
- return readAdapter;
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
-import org.opendaylight.mdsal.dom.spi.ForwardingDOMDataTreeService;
-
-public class ShardedDOMTransactionChainAdapter implements DOMTransactionChain {
-
- private final DOMDataTreeService dataTreeService;
- private final Object txChainIdentifier;
- private final AtomicLong txNum = new AtomicLong();
- private final DOMTransactionChainListener txChainListener;
- private final CachedDataTreeService cachedDataTreeService;
- private TransactionChainWriteTransaction writeTx;
- private TransactionChainReadTransaction readTx;
- private FluentFuture<? extends CommitInfo> writeTxCommitFuture;
- private boolean finished = false;
-
- public ShardedDOMTransactionChainAdapter(final Object txChainIdentifier,
- final DOMDataTreeService dataTreeService, final DOMTransactionChainListener txChainListener) {
- this.dataTreeService = requireNonNull(dataTreeService);
- this.txChainIdentifier = requireNonNull(txChainIdentifier);
- this.txChainListener = txChainListener;
- this.cachedDataTreeService = new CachedDataTreeService(dataTreeService);
- }
-
- @Override
- public DOMDataTreeReadTransaction newReadOnlyTransaction() {
- checkRunning();
- checkReadTxClosed();
- checkWriteTxClosed();
- readTx = new TransactionChainReadTransaction(newTransactionIdentifier(),
- new ShardedDOMReadTransactionAdapter(newTransactionIdentifier(), dataTreeService),
- writeTxCommitFuture, this);
-
- return readTx;
- }
-
- @Override
- public DOMDataTreeWriteTransaction newWriteOnlyTransaction() {
- checkRunning();
- checkWriteTxClosed();
- checkReadTxClosed();
- writeTx = new TransactionChainWriteTransaction(newTransactionIdentifier(),
- new ShardedDOMWriteTransactionAdapter(newTransactionIdentifier(),
- cachedDataTreeService), this);
-
- return writeTx;
- }
-
- @Override
- public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
- checkRunning();
- checkWriteTxClosed();
- checkReadTxClosed();
- ShardedDOMReadWriteTransactionAdapter adapter = new ShardedDOMReadWriteTransactionAdapter(
- newTransactionIdentifier(), cachedDataTreeService);
- TransactionChainReadWriteTransaction readWriteTx = new TransactionChainReadWriteTransaction(
- newTransactionIdentifier(), adapter, adapter.getReadAdapter(), writeTxCommitFuture, this);
-
- writeTx = readWriteTx;
- return readWriteTx;
- }
-
- @Override
- public void close() {
- if (finished) {
- // already closed, do nothing
- return;
- }
-
- checkReadTxClosed();
- checkWriteTxClosed();
- writeTxCommitFuture.addCallback(new FutureCallback<CommitInfo>() {
- @Override
- public void onSuccess(final CommitInfo result) {
- txChainListener.onTransactionChainSuccessful(ShardedDOMTransactionChainAdapter.this);
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- // We don't have to do nothing here,
- // tx should take car of it
- }
- }, MoreExecutors.directExecutor());
-
- cachedDataTreeService.closeProducers();
- finished = true;
- }
-
- public void closeReadTransaction() {
- readTx = null;
- }
-
- public void closeWriteTransaction(final FluentFuture<? extends CommitInfo> commitFuture) {
- writeTxCommitFuture = commitFuture;
- writeTx = null;
- }
-
- private Object newTransactionIdentifier() {
- return "DOM-CHAIN-" + txChainIdentifier + "-" + txNum.getAndIncrement();
- }
-
- private void checkWriteTxClosed() {
- checkState(writeTx == null);
- }
-
- private void checkReadTxClosed() {
- checkState(readTx == null);
- }
-
- private void checkRunning() {
- checkState(!finished);
- }
-
- public void transactionFailed(final DOMDataTreeTransaction tx, final Throwable cause) {
- txChainListener.onTransactionChainFailed(this, tx, cause);
- if (writeTx != null) {
- writeTx.cancel();
- }
- if (readTx != null) {
- readTx.close();
- }
- cachedDataTreeService.closeProducers();
- finished = true;
- }
-
- private static final class CachedDataTreeService extends ForwardingDOMDataTreeService {
- private final Map<LogicalDatastoreType, NoopCloseDataProducer> producersMap =
- new EnumMap<>(LogicalDatastoreType.class);
- private final DOMDataTreeService delegate;
-
- CachedDataTreeService(final DOMDataTreeService delegate) {
- this.delegate = requireNonNull(delegate);
- }
-
- @Override
- public DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- checkState(subtrees.size() == 1);
- DOMDataTreeIdentifier treeId = subtrees.iterator().next();
- NoopCloseDataProducer producer = new NoopCloseDataProducer(delegate.createProducer(
- Collections.singleton(treeId)));
- producersMap.putIfAbsent(treeId.getDatastoreType(), producer);
- return producer;
- }
-
- @Override
- protected DOMDataTreeService delegate() {
- return delegate;
- }
-
- void closeProducers() {
- producersMap.values().forEach(NoopCloseDataProducer::closeDelegate);
- }
- }
-
- private static final class NoopCloseDataProducer implements DOMDataTreeProducer {
- private final DOMDataTreeProducer delegateTreeProducer;
-
- NoopCloseDataProducer(final DOMDataTreeProducer delegateTreeProducer) {
- this.delegateTreeProducer = delegateTreeProducer;
- }
-
- @Override
- public DOMDataTreeCursorAwareTransaction createTransaction(final boolean isolated) {
- return delegateTreeProducer.createTransaction(isolated);
- }
-
- @Override
- public DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- return delegateTreeProducer.createProducer(subtrees);
- }
-
- @Override
- public void close() {
- // noop
- }
-
- public void closeDelegate() {
- try {
- delegateTreeProducer.close();
- } catch (final DOMDataTreeProducerException e) {
- throw new IllegalStateException("Trying to close DOMDataTreeProducer with open transaction", e);
- }
- }
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ShardedDOMWriteTransactionAdapter implements DOMDataTreeWriteTransaction {
- private static final Logger LOG = LoggerFactory.getLogger(ShardedDOMWriteTransactionAdapter.class);
-
- private final Map<LogicalDatastoreType, DOMDataTreeCursorAwareTransaction> transactionMap = new EnumMap<>(
- LogicalDatastoreType.class);
- private final Map<LogicalDatastoreType, DOMDataTreeWriteCursor> cursorMap = new EnumMap<>(
- LogicalDatastoreType.class);
- private final Map<LogicalDatastoreType, DOMDataTreeProducer> producerMap = new EnumMap<>(
- LogicalDatastoreType.class);
-
- private final @NonNull DOMDataTreeService treeService;
- private final @NonNull Object txIdentifier;
-
- private boolean finished = false;
- private boolean initialized = false;
-
- ShardedDOMWriteTransactionAdapter(final Object identifier, final DOMDataTreeService transactionDelegator) {
- this.treeService = requireNonNull(transactionDelegator);
- this.txIdentifier = requireNonNull(identifier);
- }
-
- @Override
- public boolean cancel() {
- LOG.debug("{}: Cancelling transaction", txIdentifier);
- if (finished) {
- return false;
- }
-
- // We close cursor, cancel transactions and close producers and
- // mark transaction as finished
- cursorMap.values().forEach(DOMDataTreeWriteCursor::close);
- transactionMap.values().forEach(domDataTreeCursorAwareTransaction ->
- checkState(domDataTreeCursorAwareTransaction.cancel()));
- closeProducers();
- finished = true;
- return true;
- }
-
- @Override
- public @NonNull FluentFuture<? extends @NonNull CommitInfo> commit() {
- checkRunning();
- LOG.debug("{}: Submitting transaction", txIdentifier);
- if (!initialized) {
- // If underlying producers, transactions and cursors are
- // not even initialized just seal this transaction and
- // return immediate future
- finished = true;
- return CommitInfo.emptyFluentFuture();
- }
- // First we need to close cursors
- cursorMap.values().forEach(DOMDataTreeWriteCursor::close);
- final FluentFuture<List<CommitInfo>> aggregatedSubmit = FluentFuture.from(Futures.allAsList(
- transactionMap.get(LogicalDatastoreType.CONFIGURATION).commit(),
- transactionMap.get(LogicalDatastoreType.OPERATIONAL).commit()));
-
- // Now we can close producers and mark transaction as finished
- closeProducers();
- finished = true;
-
- return aggregatedSubmit.transform(unused -> CommitInfo.empty(), MoreExecutors.directExecutor());
- }
-
- @Override
- public Object getIdentifier() {
- return txIdentifier;
- }
-
- @Override
- public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- checkRunning();
- LOG.debug("{}: Invoking put operation at {}:{}", txIdentifier, store, path);
- LOG.trace("{}: payload is {}", txIdentifier, data);
- if (!initialized) {
- initializeDataTreeProducerLayer(path.getParent());
- }
-
- final DOMDataTreeWriteCursor cursor = cursorMap.get(store);
- cursor.write(path.getLastPathArgument(), data);
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- checkRunning();
- LOG.debug("{}: Invoking merge operation at {}:{}", txIdentifier, store, path);
- LOG.trace("{}: payload is {}", txIdentifier, data);
- if (!initialized) {
- initializeDataTreeProducerLayer(path.getParent());
- }
-
- final DOMDataTreeWriteCursor cursor = cursorMap.get(store);
- cursor.merge(path.getLastPathArgument(), data);
- }
-
- @Override
- public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- checkRunning();
- LOG.debug("{}: Invoking delete operation at {}:{}", txIdentifier, store, path);
- if (!initialized) {
- initializeDataTreeProducerLayer(path.getParent());
- }
-
- final DOMDataTreeWriteCursor cursor = cursorMap.get(store);
- cursor.delete(path.getLastPathArgument());
- }
-
- // TODO initialize producer, transaction and cursor for only
- // for necessary data store at one time
- private void initializeDataTreeProducerLayer(final YangInstanceIdentifier path) {
- checkState(producerMap.isEmpty(), "Producers already initialized");
- checkState(transactionMap.isEmpty(), "Transactions already initialized");
- checkState(cursorMap.isEmpty(), "Cursors already initialized");
-
- LOG.debug("{}: Creating data tree producers on path {}", txIdentifier, path);
- producerMap.put(LogicalDatastoreType.CONFIGURATION,
- treeService.createProducer(
- Collections.singleton(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, path))));
- producerMap.put(LogicalDatastoreType.OPERATIONAL,
- treeService.createProducer(
- Collections.singleton(new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, path))));
-
- LOG.debug("{}: Creating DOMDataTreeCursorAwareTransactions delegates on {}", txIdentifier, path);
- transactionMap.put(LogicalDatastoreType.CONFIGURATION,
- producerMap.get(LogicalDatastoreType.CONFIGURATION).createTransaction(true));
- transactionMap.put(LogicalDatastoreType.OPERATIONAL,
- producerMap.get(LogicalDatastoreType.OPERATIONAL).createTransaction(true));
-
- LOG.debug("{}: Creating DOMDataTreeWriteCursors delegates", txIdentifier);
- cursorMap.put(LogicalDatastoreType.CONFIGURATION,
- transactionMap.get(LogicalDatastoreType.CONFIGURATION)
- .createCursor(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, path)));
- cursorMap.put(LogicalDatastoreType.OPERATIONAL,
- transactionMap.get(LogicalDatastoreType.OPERATIONAL)
- .createCursor(new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, path)));
-
- initialized = true;
- }
-
- private void checkRunning() {
- checkState(!finished, "{}: Transaction already finished");
- }
-
- private void closeProducers() {
- producerMap.values().forEach(domDataTreeProducer -> {
- try {
- domDataTreeProducer.close();
- } catch (final DOMDataTreeProducerException e) {
- throw new IllegalStateException("Trying to close DOMDataTreeProducer with open transaction", e);
- }
- });
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.Optional;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class TransactionChainReadTransaction implements DOMDataTreeReadTransaction {
-
- private final DOMDataTreeReadTransaction delegateReadTx;
- private final FluentFuture<? extends CommitInfo> previousWriteTxFuture;
- private final Object identifier;
- private final ShardedDOMTransactionChainAdapter txChain;
-
- TransactionChainReadTransaction(final Object txIdentifier, final DOMDataTreeReadTransaction delegateReadTx,
- final FluentFuture<? extends CommitInfo> previousWriteTxFuture,
- final ShardedDOMTransactionChainAdapter txChain) {
- this.delegateReadTx = delegateReadTx;
- this.previousWriteTxFuture = previousWriteTxFuture;
- this.identifier = txIdentifier;
- this.txChain = txChain;
- }
-
- @Override
- public FluentFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- final SettableFuture<Optional<NormalizedNode<?, ?>>> readResult = SettableFuture.create();
-
- previousWriteTxFuture.addCallback(new FutureCallback<CommitInfo>() {
- @Override
- public void onSuccess(final CommitInfo result) {
- delegateReadTx.read(store, path).addCallback(new FutureCallback<Optional<NormalizedNode<?, ?>>>() {
- @Override
- public void onSuccess(final Optional<NormalizedNode<?, ?>> result) {
- readResult.set(result);
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- txChain.transactionFailed(TransactionChainReadTransaction.this, throwable);
- readResult.setException(throwable);
- }
- }, MoreExecutors.directExecutor());
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- // we don't have to notify txchain about this failure
- // failed write transaction should do this
- readResult.setException(throwable);
- }
- }, MoreExecutors.directExecutor());
-
- return FluentFuture.from(readResult);
- }
-
- @Override
- public FluentFuture<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- return read(store, path).transform(Optional::isPresent, MoreExecutors.directExecutor());
- }
-
- @Override
- public void close() {
- delegateReadTx.close();
- txChain.closeReadTransaction();
- }
-
- @Override
- public Object getIdentifier() {
- return identifier;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Brocade Communications 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.dom.broker;
-
-import com.google.common.util.concurrent.FluentFuture;
-import java.util.Optional;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-final class TransactionChainReadWriteTransaction extends TransactionChainWriteTransaction
- implements DOMDataTreeReadWriteTransaction {
- private final TransactionChainReadTransaction readTx;
-
- TransactionChainReadWriteTransaction(final Object identifier,
- final DOMDataTreeReadWriteTransaction delegateWriteTx, final DOMDataTreeReadTransaction delegateReadTx,
- final FluentFuture<? extends CommitInfo> previousWriteTxFuture,
- final ShardedDOMTransactionChainAdapter txChain) {
- super(identifier, delegateWriteTx, txChain);
- readTx = new TransactionChainReadTransaction(identifier, delegateReadTx, previousWriteTxFuture, txChain);
- }
-
- @Override
- public FluentFuture<Optional<NormalizedNode<?, ?>>> read(final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- return readTx.read(store, path);
- }
-
- @Override
- public FluentFuture<Boolean> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- return readTx.exists(store, path);
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.MoreExecutors;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class TransactionChainWriteTransaction implements DOMDataTreeWriteTransaction {
- private final DOMDataTreeWriteTransaction delegateTx;
- private final Object identifier;
- private final ShardedDOMTransactionChainAdapter txChain;
-
- public TransactionChainWriteTransaction(final Object identifier, final DOMDataTreeWriteTransaction delegateTx,
- final ShardedDOMTransactionChainAdapter txChain) {
- this.delegateTx = requireNonNull(delegateTx);
- this.identifier = requireNonNull(identifier);
- this.txChain = requireNonNull(txChain);
- }
-
-
- @Override
- public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- delegateTx.put(store, path, data);
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- delegateTx.merge(store, path, data);
- }
-
- @Override
- public boolean cancel() {
- txChain.closeWriteTransaction(FluentFutures.immediateNullFluentFuture());
- return delegateTx.cancel();
- }
-
- @Override
- public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- delegateTx.delete(store, path);
- }
-
- @Override
- public @NonNull FluentFuture<? extends @NonNull CommitInfo> commit() {
- final FluentFuture<? extends CommitInfo> writeResultFuture = delegateTx.commit();
- writeResultFuture.addCallback(new FutureCallback<CommitInfo>() {
- @Override
- public void onSuccess(final CommitInfo result) {
- // NOOP
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- txChain.transactionFailed(TransactionChainWriteTransaction.this, throwable);
- }
- }, MoreExecutors.directExecutor());
-
- txChain.closeWriteTransaction(writeResultFuture);
- return writeResultFuture;
- }
-
- @Override
- public Object getIdentifier() {
- return identifier;
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-
-public class ShardedDOMDataBrokerAdapterTest {
-
- @Test
- public void basicTest() throws Exception {
- DOMDataTreeService dataTreeService = mock(DOMDataTreeService.class);
- final ShardedDOMDataBrokerAdapter shardedDOMDataBrokerAdapter =
- new ShardedDOMDataBrokerAdapter(dataTreeService);
-
- assertTrue(shardedDOMDataBrokerAdapter.getExtensions().isEmpty());
- assertNotNull(shardedDOMDataBrokerAdapter.newWriteOnlyTransaction());
- assertNotNull(shardedDOMDataBrokerAdapter.newReadOnlyTransaction());
- assertNotNull(shardedDOMDataBrokerAdapter.createTransactionChain(null));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.broker.MockingUtilities.captorFor;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingConflictException;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-
-public class ShardedDOMDataTreeListenerTest {
-
-
- private static final DOMDataTreeIdentifier ROOT_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TestModel.TEST_PATH);
-
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_ROOT = Collections.singleton(ROOT_ID);
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_TEST = Collections.singleton(TEST_ID);
- private static final ContainerNode TEST_CONTAINER = ImmutableNodes.containerNode(TestModel.TEST_QNAME);
-
- private interface ListenableShard extends DOMDataTreeShard, DOMStoreTreeChangePublisher {
-
-
- }
-
- @Mock(name = "rootShard")
- private ListenableShard rootShard;
-
- @Mock(name = "childShard")
- private ListenableShard childShard;
-
- @Mock(name = "listener")
- private DOMDataTreeListener listener;
-
- @Mock
- private ShardedDOMDataTreeProducer producer;
-
- @Mock
- private ListenerRegistration<?> storeListenerReg;
-
- private DOMDataTreeService treeService;
- private ListenerRegistration<ListenableShard> shardReg;
-
- @Before
- public void setUp() throws DOMDataTreeShardingConflictException {
- MockitoAnnotations.initMocks(this);
- final ShardedDOMDataTree impl = new ShardedDOMDataTree();
- doReturn(Collections.singleton(ROOT_ID)).when(producer).getSubtrees();
- doNothing().when(producer).subshardAdded(anyMap());
- treeService = impl;
- shardReg = impl.registerDataTreeShard(ROOT_ID, rootShard, producer);
- doReturn("rootShard").when(rootShard).toString();
- doReturn("childShard").when(childShard).toString();
-
- doReturn(storeListenerReg).when(rootShard).registerTreeChangeListener(any(YangInstanceIdentifier.class),
- any(DOMDataTreeChangeListener.class));
- doNothing().when(storeListenerReg).close();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void registerListenerWithEmptySubtrees() throws DOMDataTreeLoopException {
- treeService.registerListener(listener, Collections.emptyList(), true, Collections.emptyList());
- }
-
- @Test
- public void registerRootListener() throws DOMDataTreeLoopException {
- treeService.registerListener(listener, SUBTREES_ROOT, true, Collections.emptyList());
- verify(rootShard, times(1)).registerTreeChangeListener(eq(ROOT_ID.getRootIdentifier()),
- any(DOMDataTreeChangeListener.class));
- }
-
- @Test
- public void registerTreeListener() throws DOMDataTreeLoopException {
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.emptyList());
- verify(rootShard, times(1)).registerTreeChangeListener(eq(TEST_ID.getRootIdentifier()),
- any(DOMDataTreeChangeListener.class));
- }
-
- @Test
- public void registerAndCloseListener() throws DOMDataTreeLoopException {
- final ListenerRegistration<DOMDataTreeListener> reg =
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.emptyList());
- reg.close();
- verify(storeListenerReg, times(1)).close();
- }
-
- @Test
- public void receiveChangeEvent() throws DOMDataTreeLoopException {
- final ArgumentCaptor<DOMDataTreeChangeListener> storeListener =
- ArgumentCaptor.forClass(DOMDataTreeChangeListener.class);
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.emptyList());
- verify(rootShard, times(1)).registerTreeChangeListener(eq(TEST_ID.getRootIdentifier()),
- storeListener.capture());
-
- final DataTreeCandidate sentStoreCandidate =
- DataTreeCandidates.fromNormalizedNode(TEST_ID.getRootIdentifier(), TEST_CONTAINER);
- final Collection<DataTreeCandidate> changes = Collections.singleton(sentStoreCandidate);
-
- doNothing().when(listener).onDataTreeChanged(Mockito.any(), Mockito.anyMap());
- storeListener.getValue().onDataTreeChanged(changes);
-
- final ArgumentCaptor<Collection<DataTreeCandidate>> candidateCapture = captorFor(Collection.class);
- final ArgumentCaptor<Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>>> mapCapture = captorFor(Map.class);
- verify(listener, times(1)).onDataTreeChanged(candidateCapture.capture(), mapCapture.capture());
-
- final Collection<DataTreeCandidate> receivedCandidate = candidateCapture.getValue();
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> receivedMap = mapCapture.getValue();
-
- assertNotNull("receivedCandidate", receivedCandidate);
- assertNotNull("receivedMap", receivedMap);
- assertFalse("candidate collection must not be empty", receivedCandidate.isEmpty());
- assertEquals(1, receivedCandidate.size());
- final DataTreeCandidate firstItem = receivedCandidate.iterator().next();
- assertEquals(TEST_ID.getRootIdentifier(), firstItem.getRootPath());
- assertEquals(TEST_CONTAINER, receivedMap.get(TEST_ID));
- }
-
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.broker.MockingUtilities.captorFor;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingConflictException;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.mdsal.dom.spi.store.DOMStore;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-
-public class ShardedDOMDataTreeListenerWithProducerTest {
-
-
- private static final DOMDataTreeIdentifier ROOT_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TestModel.TEST_PATH);
-
- private static final DOMDataTreeIdentifier TEST2_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TestModel.TEST2_PATH);
-
-
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_ROOT = Collections.singleton(ROOT_ID);
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_TEST = Collections.singleton(TEST_ID);
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_TEST2 = Collections.singleton(TEST2_ID);
- private static final ContainerNode TEST_CONTAINER = ImmutableNodes.containerNode(TestModel.TEST_QNAME);
-
- private interface ListenableShard extends DOMDataTreeShard, DOMStoreTreeChangePublisher, DOMStore {
-
-
- }
-
- @Mock(name = "rootShard")
- private ListenableShard rootShard;
-
- @Mock(name = "childShard")
- private ListenableShard childShard;
-
- @Mock
- private ListenerRegistration<?> storeListenerReg;
-
- @Mock(name = "storeWriteTx")
- private DOMStoreWriteTransaction writeTxMock;
-
- @Mock(name = "storeTxChain")
- private DOMStoreTransactionChain txChainMock;
-
- @Mock
- private ShardedDOMDataTreeProducer rootProducer;
-
- private DOMDataTreeService treeService;
-
- private ListenerRegistration<ListenableShard> shardReg;
-
- @Before
- public void setUp() throws DOMDataTreeShardingConflictException {
- MockitoAnnotations.initMocks(this);
- doReturn(Collections.singleton(ROOT_ID)).when(rootProducer).getSubtrees();
- doNothing().when(rootProducer).subshardAdded(anyMap());
- final ShardedDOMDataTree impl = new ShardedDOMDataTree();
- treeService = impl;
- shardReg = impl.registerDataTreeShard(ROOT_ID, rootShard, rootProducer);
- doReturn("rootShard").when(rootShard).toString();
- doReturn("childShard").when(childShard).toString();
-
- doReturn(txChainMock).when(rootShard).createTransactionChain();
- doReturn(writeTxMock).when(txChainMock).newWriteOnlyTransaction();
- doReturn(TestCommitCohort.ALLWAYS_SUCCESS).when(writeTxMock).ready();
-
- doReturn(storeListenerReg).when(rootShard).registerTreeChangeListener(any(YangInstanceIdentifier.class),
- any(DOMDataTreeChangeListener.class));
- doNothing().when(storeListenerReg).close();
- }
-
- @Test
- public void registerListenerWithOneProducer() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- final DOMDataTreeProducer producer = treeService.createProducer(SUBTREES_TEST2);
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.singleton(producer));
- }
-
- @Test(expected = IllegalStateException.class)
- public void registerListenerWithAlreadyBoundProducer() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener1 = MockingUtilities.mock(DOMDataTreeListener.class, "listener1");
- final DOMDataTreeProducer producer = treeService.createProducer(SUBTREES_TEST2);
- treeService.registerListener(listener1, SUBTREES_TEST, true, Collections.singleton(producer));
-
- final DOMDataTreeListener listener2 = MockingUtilities.mock(DOMDataTreeListener.class, "listener2");
- treeService.registerListener(listener2, SUBTREES_TEST, true, Collections.singleton(producer));
- }
-
- @Test(expected = DOMDataTreeLoopException.class)
- public void loopSameSubtree() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- final DOMDataTreeProducer producer = treeService.createProducer(SUBTREES_TEST);
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.singleton(producer));
- }
-
- @Test(expected = DOMDataTreeLoopException.class)
- public void loopListenParentWritesChild() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- final DOMDataTreeProducer producer = treeService.createProducer(SUBTREES_TEST);
- treeService.registerListener(listener, SUBTREES_ROOT, true, Collections.singleton(producer));
- }
-
- @Test(expected = DOMDataTreeLoopException.class)
- public void loopListenChildWritesParent() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- final DOMDataTreeProducer producer = treeService.createProducer(SUBTREES_ROOT);
- treeService.registerListener(listener, SUBTREES_ROOT, true, Collections.singleton(producer));
- }
-
- @Test
- public void receiveChangeEvent() throws DOMDataTreeLoopException {
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- final ArgumentCaptor<DOMDataTreeChangeListener> storeListener =
- ArgumentCaptor.forClass(DOMDataTreeChangeListener.class);
- treeService.registerListener(listener, SUBTREES_TEST, true, Collections.emptyList());
- verify(rootShard, times(1)).registerTreeChangeListener(eq(TEST_ID.getRootIdentifier()),
- storeListener.capture());
-
- final DataTreeCandidate sentStoreCandidate =
- DataTreeCandidates.fromNormalizedNode(TEST_ID.getRootIdentifier(), TEST_CONTAINER);
- final Collection<DataTreeCandidate> changes = Collections.singleton(sentStoreCandidate);
-
- doNothing().when(listener).onDataTreeChanged(any(), anyMap());
- storeListener.getValue().onDataTreeChanged(changes);
-
- final ArgumentCaptor<Collection<DataTreeCandidate>> candidateCapture = captorFor(Collection.class);
- final ArgumentCaptor<Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>>> mapCapture = captorFor(Map.class);
- verify(listener, times(1)).onDataTreeChanged(candidateCapture.capture(), mapCapture.capture());
-
- final Collection<DataTreeCandidate> receivedCandidate = candidateCapture.getValue();
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> receivedMap = mapCapture.getValue();
-
- assertNotNull("receivedCandidate", receivedCandidate);
- assertNotNull("receivedMap", receivedMap);
- assertFalse("candidate collection must not be empty", receivedCandidate.isEmpty());
- assertEquals(1, receivedCandidate.size());
- final DataTreeCandidate firstItem = receivedCandidate.iterator().next();
- assertEquals(TEST_ID.getRootIdentifier(), firstItem.getRootPath());
- assertEquals(TEST_CONTAINER, receivedMap.get(TEST_ID));
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyCollection;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.Futures;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.InOrder;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableDOMDataTreeShard;
-import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-
-public class ShardedDOMDataTreeProducerMultiShardTest extends AbstractDatastoreTest {
-
- private static final DOMDataTreeIdentifier ROOT_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, TestModel.TEST_PATH);
-
- private static final DOMDataTreeIdentifier TEST2_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, TestModel.TEST2_PATH);
-
- private static final DOMDataTreeIdentifier INNER_CONTAINER_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, TestModel.INNER_CONTAINER_PATH);
- private static final DOMDataTreeIdentifier ANOTHER_SHARD_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, TestModel.ANOTHER_SHARD_PATH);
-
- private InMemoryDOMDataTreeShard rootShard;
- private InMemoryDOMDataTreeShard anotherInnerShard;
-
- private ShardedDOMDataTree dataTreeService;
- private ListenerRegistration<InMemoryDOMDataTreeShard> rootShardReg;
- private ListenerRegistration<InMemoryDOMDataTreeShard> innerShardReg;
-
- private final ExecutorService executor = Executors.newSingleThreadExecutor();
-
- @Captor
- private ArgumentCaptor<Collection<DataTreeCandidate>> captorForChanges;
- @Captor
- private ArgumentCaptor<Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>>> captorForSubtrees;
-
- private final ContainerNode crossShardContainer = createCrossShardContainer();
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- rootShard = InMemoryDOMDataTreeShard.create(ROOT_ID, executor, 1);
- rootShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final ShardedDOMDataTree dataTree = new ShardedDOMDataTree();
- final DOMDataTreeProducer shardRegProducer = dataTree.createProducer(Collections.singletonList(ROOT_ID));
- rootShardReg = dataTree.registerDataTreeShard(ROOT_ID, rootShard, shardRegProducer);
- shardRegProducer.close();
-
- dataTreeService = dataTree;
- }
-
- @Test(expected = IllegalStateException.class)
- public void testTxReadyMultiples() throws Exception {
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .build();
- cursor.write(TestModel.TEST_PATH.getLastPathArgument(), testContainer);
- transaction.ready();
-
- transaction.ready();
- }
-
- @Test(expected = IllegalStateException.class)
- public void testSubmitUnclosedCursor() throws Exception {
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .build();
-
- cursor.write(TestModel.TEST_PATH.getLastPathArgument(), testContainer);
- transaction.ready();
- }
-
- @Test
- public void testMultipleCursorsFromOneTx() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(INNER_CONTAINER_ID),
- true, Collections.emptyList());
-
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .build();
-
- cursor.write(TestModel.TEST_PATH.getLastPathArgument(), testContainer);
- cursor.close();
-
- final DOMDataTreeWriteCursor newCursor = transaction.createCursor(ROOT_ID);
- newCursor.enter(TestModel.TEST_PATH.getLastPathArgument());
- final ContainerNode innerContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_CONTAINER))
- .withChild(ImmutableLeafNodeBuilder.<String>create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.SHARDED_VALUE_1))
- .withValue("inner-value")
- .build())
- .build();
-
- newCursor.write(TestModel.INNER_CONTAINER_PATH.getLastPathArgument(), innerContainer);
- newCursor.close();
- transaction.ready();
- transaction.submit();
-
- verify(mockedDataTreeListener, timeout(1000).times(2)).onDataTreeChanged(
- captorForChanges.capture(), captorForSubtrees.capture());
- final Collection<DataTreeCandidate> capturedValue = captorForChanges.getValue();
- assertTrue(capturedValue.size() == 1);
-
- final ContainerNode dataAfter =
- (ContainerNode) capturedValue.iterator().next().getRootNode().getDataAfter().get();
- assertEquals(innerContainer, dataAfter);
- verifyNoMoreInteractions(mockedDataTreeListener);
- }
-
- @Test
- public void testSingleShardListener() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(INNER_CONTAINER_ID), true,
- Collections.emptyList());
-
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- writeCrossShardContainer(transaction);
-
- verify(mockedDataTreeListener, timeout(1000).times(2)).onDataTreeChanged(
- captorForChanges.capture(), captorForSubtrees.capture());
- final Collection<DataTreeCandidate> capturedValue = captorForChanges.getValue();
- assertTrue(capturedValue.size() == 1);
-
- final ContainerNode dataAfter =
- (ContainerNode) capturedValue.iterator().next().getRootNode().getDataAfter().get();
- assertEquals(crossShardContainer.getChild(
- TestModel.INNER_CONTAINER_PATH.getLastPathArgument()).get(), dataAfter);
-
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> capturedSubtrees = captorForSubtrees.getValue();
- assertTrue(capturedSubtrees.size() == 1);
- assertTrue(capturedSubtrees.containsKey(INNER_CONTAINER_ID));
- assertEquals(crossShardContainer.getChild(TestModel.INNER_CONTAINER_PATH.getLastPathArgument()).get(),
- capturedSubtrees.get(INNER_CONTAINER_ID));
-
- verifyNoMoreInteractions(mockedDataTreeListener);
- }
-
- @Test
- public void testMultipleShards() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
- final DOMDataTreeProducer shardRegProducer =
- dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- innerShardReg = dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, shardRegProducer);
- shardRegProducer.close();
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(TEST_ID),
- true, Collections.emptyList());
-
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- writeCrossShardContainer(transaction);
-
- final ContainerNode testContainerVerificationNode = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .build();
-
- //verify listeners have been notified
- verify(mockedDataTreeListener, timeout(1000).times(4)).onDataTreeChanged(
- captorForChanges.capture(), captorForSubtrees.capture());
- final List<Collection<DataTreeCandidate>> capturedChanges = captorForChanges.getAllValues();
- final List<Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>>> capturedSubtrees =
- captorForSubtrees.getAllValues();
- final DataTreeCandidate firstNotificationCandidate = capturedChanges.get(2).iterator().next();
-
- assertTrue(capturedSubtrees.get(2).size() == 1);
- assertEquals(testContainerVerificationNode, firstNotificationCandidate.getRootNode().getDataAfter().get());
- assertEquals(testContainerVerificationNode, capturedSubtrees.get(2).get(TEST_ID));
-
- final DataTreeCandidate secondNotificationCandidate = capturedChanges.get(3).iterator().next();
- assertTrue(capturedSubtrees.get(3).size() == 1);
- assertEquals(crossShardContainer, secondNotificationCandidate.getRootNode().getDataAfter().get());
- assertEquals(crossShardContainer, capturedSubtrees.get(3).get(TEST_ID));
-
- verifyNoMoreInteractions(mockedDataTreeListener);
- }
-
- @Test
- public void testMultipleShardsProducerClose() throws Exception {
- final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- assertTrue(rootShard.getProducers().isEmpty());
-
- final DOMDataTreeProducer innerShardRegProducer =
- dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- assertTrue(rootShard.getProducers().size() == 1);
- final DOMDataTreeShardProducer rootShardProducer = Iterables.getOnlyElement(rootShard.getProducers());
- assertEquals(rootShardProducer.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
-
- dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, innerShardRegProducer);
-
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().size() == 1);
- final DOMDataTreeShardProducer innerShardProducer = Iterables.getOnlyElement(innerShard.getProducers());
- assertEquals(innerShardProducer.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
-
- innerShardRegProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().isEmpty());
-
- final DOMDataTreeProducer testProducer =
- dataTreeService.createProducer(Collections.singletonList(TEST_ID));
- assertTrue(rootShard.getProducers().size() == 1);
- final DOMDataTreeShardProducer rootShardProducer2 = Iterables.getOnlyElement(rootShard.getProducers());
- assertEquals(rootShardProducer2.getPrefixes().toString(),
- Collections.singletonList(TEST_ID).toString());
-
- assertTrue(innerShard.getProducers().size() == 1);
- final DOMDataTreeShardProducer innerShardProducer2 = Iterables.getOnlyElement(innerShard.getProducers());
- assertEquals(innerShardProducer2.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
-
- testProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().isEmpty());
- }
-
- @Test
- public void testMultipleShardsChildProducerClose() throws Exception {
- final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final DOMDataTreeProducer innerShardRegProducer =
- dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, innerShardRegProducer);
- innerShardRegProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().isEmpty());
-
- final DOMDataTreeProducer testProducer =
- dataTreeService.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeProducer testChildProducer = testProducer.createProducer(
- Collections.singletonList(INNER_CONTAINER_ID));
- assertTrue(rootShard.getProducers().size() == 1);
- assertTrue(innerShard.getProducers().size() == 2);
-
- final DOMDataTreeShardProducer rootShardProducer = Iterables.getOnlyElement(rootShard.getProducers());
- assertEquals(rootShardProducer.getPrefixes().toString(),
- Collections.singletonList(TEST_ID).toString());
-
- for (DOMDataTreeShardProducer producer : innerShard.getProducers()) {
- assertEquals(producer.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
- }
-
- testProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().size() == 1);
- final DOMDataTreeShardProducer innerShardProducer = Iterables.getOnlyElement(innerShard.getProducers());
- assertEquals(innerShardProducer.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
-
- testChildProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().isEmpty());
- }
-
- @Test
- public void testMultipleShardsProducerCloseForSubshardAttached() throws Exception {
- final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final DOMDataTreeProducer innerShardRegProducer =
- dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, innerShardRegProducer);
- innerShardRegProducer.close();
- assertTrue(rootShard.getProducers().isEmpty());
- assertTrue(innerShard.getProducers().isEmpty());
-
- final DOMDataTreeProducer testProducer =
- dataTreeService.createProducer(Collections.singletonList(TEST_ID));
- assertTrue(rootShard.getProducers().size() == 1);
- assertTrue(innerShard.getProducers().size() == 1);
-
- final DOMDataTreeShardProducer rootShardProducer = Iterables.getOnlyElement(rootShard.getProducers());
- assertEquals(rootShardProducer.getPrefixes().toString(),
- Collections.singletonList(TEST_ID).toString());
-
- final DOMDataTreeShardProducer innerShardProducer = Iterables.getOnlyElement(innerShard.getProducers());
- assertEquals(innerShardProducer.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
-
- final InMemoryDOMDataTreeShard test2Shard = InMemoryDOMDataTreeShard.create(TEST2_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final DOMDataTreeProducer test2ShardRegProducer =
- dataTreeService.createProducer(Collections.singletonList(TEST2_ID));
- dataTreeService.registerDataTreeShard(TEST2_ID, test2Shard, test2ShardRegProducer);
- test2ShardRegProducer.close();
-
- assertTrue(rootShard.getProducers().size() == 1);
- assertTrue(innerShard.getProducers().size() == 1);
-
- final DOMDataTreeShardProducer rootShardProducer2 = Iterables.getOnlyElement(rootShard.getProducers());
- assertEquals(rootShardProducer2.getPrefixes().toString(),
- Collections.singletonList(TEST_ID).toString());
-
- final DOMDataTreeShardProducer innerShardProducer2 = Iterables.getOnlyElement(innerShard.getProducers());
- assertEquals(innerShardProducer2.getPrefixes().toString(),
- Collections.singletonList(INNER_CONTAINER_ID).toString());
- }
-
- @Test
- public void testMultipleWritesIntoSingleShard() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(INNER_CONTAINER_ID),
- true, Collections.emptyList());
-
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- writeCrossShardContainer(transaction);
-
- final DOMDataTreeShardWriteTransaction newTx = producer.createTransaction();
- final DOMDataTreeWriteCursor newCursor = newTx.createCursor(ROOT_ID);
-
- newCursor.delete(TestModel.TEST_PATH.getLastPathArgument());
- }
-
- @Test
- public void testMockedSubshards() throws Exception {
- final WriteableDOMDataTreeShard mockedInnerShard = mock(WriteableDOMDataTreeShard.class);
- final DOMDataTreeShardProducer mockedProducer = mock(DOMDataTreeShardProducer.class);
- doReturn(mockedProducer).when(mockedInnerShard).createProducer(anyCollection());
- final ShardedDOMDataTreeProducer shardRegProducer = mock(ShardedDOMDataTreeProducer.class);
- doReturn(Collections.singleton(INNER_CONTAINER_ID)).when(shardRegProducer).getSubtrees();
- doNothing().when(shardRegProducer).subshardAdded(anyMap());
-
- dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, mockedInnerShard, shardRegProducer);
-
- final DOMDataTreeShardProducer producer = rootShard.createProducer(Collections.singletonList(TEST_ID));
-
- final DOMDataTreeShardWriteTransaction transaction = producer.createTransaction();
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
- cursor.enter(TestModel.TEST_PATH.getLastPathArgument());
-
- final LeafNode<String> shardedValue1 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(
- new NodeIdentifier(TestModel.SHARDED_VALUE_1)).withValue("sharded value 1").build();
- final LeafNode<String> shardedValue2 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(
- new NodeIdentifier(TestModel.SHARDED_VALUE_2)).withValue("sharded value 2").build();
-
- final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> containerNodeBuilder =
- ImmutableContainerNodeBuilder.create();
- final ContainerNode containerNode =
- containerNodeBuilder
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_CONTAINER))
- .withChild(shardedValue1)
- .withChild(shardedValue2)
- .build();
-
- final DOMDataTreeShardWriteTransaction mockedTx = mock(DOMDataTreeShardWriteTransaction.class);
- doReturn(mockedTx).when(mockedProducer).createTransaction();
-
- doNothing().when(mockedTx).ready();
- doReturn(Futures.immediateFuture(true)).when(mockedTx).validate();
- doReturn(Futures.immediateFuture(null)).when(mockedTx).prepare();
- doReturn(Futures.immediateFuture(null)).when(mockedTx).commit();
-
- final DOMDataTreeWriteCursor mockedCursor = mock(DOMDataTreeWriteCursor.class);
- doNothing().when(mockedCursor).write(any(PathArgument.class), any(NormalizedNode.class));
- doNothing().when(mockedCursor).close();
- doReturn(mockedCursor).when(mockedTx).createCursor(any(DOMDataTreeIdentifier.class));
-
- cursor.write(TestModel.INNER_CONTAINER_PATH.getLastPathArgument(), containerNode);
- cursor.enter(TestModel.INNER_CONTAINER_PATH.getLastPathArgument());
-
- final ContainerNode lowerShardContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.ANOTHER_SHARD_CONTAINER))
- .withChild(ImmutableLeafNodeBuilder.create().withNodeIdentifier(
- new NodeIdentifier(TestModel.ANOTHER_SHARD_VALUE)).withValue("").build())
- .build();
-
- cursor.write(TestModel.ANOTHER_SHARD_PATH.getLastPathArgument(), lowerShardContainer);
- cursor.close();
- transaction.ready();
- transaction.submit().get();
-
- final InOrder inOrder = inOrder(mockedTx);
- inOrder.verify(mockedTx).ready();
- inOrder.verify(mockedTx).validate();
- inOrder.verify(mockedTx).prepare();
- inOrder.verify(mockedTx).commit();
-
- }
-
- private static ContainerNode createCrossShardContainer() {
- final LeafNode<String> shardedValue1 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(
- new NodeIdentifier(TestModel.SHARDED_VALUE_1)).withValue("sharded value 1").build();
- final LeafNode<String> shardedValue2 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(new NodeIdentifier(
- TestModel.SHARDED_VALUE_2)).withValue("sharded value 2").build();
-
-
- final ContainerNode lowerShardContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.ANOTHER_SHARD_CONTAINER))
- .withChild(ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.ANOTHER_SHARD_VALUE))
- .withValue("testing-value")
- .build())
- .build();
-
- final ContainerNode containerNode =
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_CONTAINER))
- .withChild(shardedValue1)
- .withChild(shardedValue2)
- .withChild(lowerShardContainer)
- .build();
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .withChild(containerNode)
- .build();
-
- return testContainer;
- }
-
- private void writeCrossShardContainer(final DOMDataTreeShardWriteTransaction transaction) throws Exception {
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
-
- cursor.write(TestModel.TEST_PATH.getLastPathArgument(), crossShardContainer);
-
- cursor.close();
- transaction.ready();
- transaction.submit().get();
- }
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-
-import com.google.common.util.concurrent.Futures;
-import java.util.Collection;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerBusyException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingConflictException;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableDOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class ShardedDOMDataTreeProducerSingleShardTest {
-
-
- private static final DOMDataTreeIdentifier ROOT_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TestModel.TEST_PATH);
-
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_ROOT = Collections.singleton(ROOT_ID);
- private static final Collection<DOMDataTreeIdentifier> SUBTREES_TEST = Collections.singleton(TEST_ID);
-
- interface MockTestShard extends WriteableDOMDataTreeShard {
-
- }
-
- @Mock(name = "rootShard")
- private MockTestShard rootShard;
-
-
- @Mock(name = "storeWriteTx")
- private DOMStoreWriteTransaction writeTxMock;
-
- @Mock
- private DOMDataTreeShardProducer producerMock;
-
- @Mock
- private DOMDataTreeShardWriteTransaction shardTxMock;
-
- @Mock(name = "storeTxChain")
- private DOMStoreTransactionChain txChainMock;
-
- @Mock
- private ShardedDOMDataTreeProducer rootProducer;
-
- private DOMDataTreeService treeService;
- private ListenerRegistration<MockTestShard> shardReg;
- private DOMDataTreeProducer producer;
-
- @Before
- public void setUp() throws DOMDataTreeShardingConflictException {
- MockitoAnnotations.initMocks(this);
- doReturn(Collections.singleton(ROOT_ID)).when(rootProducer).getSubtrees();
- doNothing().when(rootProducer).subshardAdded(anyMap());
- final ShardedDOMDataTree impl = new ShardedDOMDataTree();
- treeService = impl;
- shardReg = impl.registerDataTreeShard(ROOT_ID, rootShard, rootProducer);
-
- doReturn("rootShard").when(rootShard).toString();
- doReturn(producerMock).when(rootShard).createProducer(any(Collection.class));
- doReturn(shardTxMock).when(producerMock).createTransaction();
- doNothing().when(producerMock).close();
- doNothing().when(shardTxMock).ready();
- doReturn(Futures.immediateFuture(null)).when(shardTxMock).submit();
-
- producer = treeService.createProducer(SUBTREES_ROOT);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void createProducerWithEmptyList() {
- treeService.createProducer(Collections.emptySet());
- }
-
- @Test(expected = DOMDataTreeProducerBusyException.class)
- public void closeWithTxOpened() throws DOMDataTreeProducerException {
- producer.createTransaction(false);
- producer.close();
- }
-
- @Test
- public void closeWithTxSubmitted() throws DOMDataTreeProducerException {
- final DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
- tx.commit();
- producer.close();
- }
-
- @Test(expected = IllegalStateException.class)
- public void allocateTxWithTxOpen() {
- producer.createTransaction(false);
- producer.createTransaction(false);
- }
-
-
- @Test(expected = IllegalStateException.class)
- public void allocateChildProducerWithTxOpen() {
- producer.createTransaction(false);
- producer.createProducer(SUBTREES_TEST);
- }
-
- @Test
- public void allocateChildProducerWithTxSubmmited() {
- producer.createTransaction(false).commit();
- final DOMDataTreeProducer childProducer = producer.createProducer(SUBTREES_TEST);
- assertNotNull(childProducer);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void writeChildProducerDataToParentTx() {
- final DOMDataTreeProducer childProducer = producer.createProducer(SUBTREES_TEST);
- assertNotNull(childProducer);
- final DOMDataTreeCursorAwareTransaction parentTx = producer.createTransaction(true);
- parentTx.createCursor(TEST_ID);
- }
-
- @Test
- public void allocateTxWithTxSubmitted() {
- producer.createTransaction(false).commit();
- producer.createTransaction(false);
- }
-
-}
+++ /dev/null
-/*
- * 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.mdsal.dom.broker;
-
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingConflictException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShardingService;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class ShardedDOMDataTreeShardTest {
-
-
- private static final DOMDataTreeIdentifier ROOT_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
- TestModel.TEST_PATH);
-
- @Mock(name = "rootShard")
- private DOMDataTreeShard rootShard;
-
- @Mock(name = "rootShard")
- private DOMDataTreeShard childShard;
-
- @Mock
- private ShardedDOMDataTreeProducer rootProducer;
-
- @Mock
- private ShardedDOMDataTreeProducer testProducer;
-
- private DOMDataTreeShardingService shardingService;
- private ListenerRegistration<DOMDataTreeShard> shardReg;
-
- @Before
- public void setUp() throws DOMDataTreeShardingConflictException {
- MockitoAnnotations.initMocks(this);
- doReturn(Collections.singleton(ROOT_ID)).when(rootProducer).getSubtrees();
- doReturn(Collections.singleton(TEST_ID)).when(testProducer).getSubtrees();
- doNothing().when(rootProducer).subshardAdded(anyMap());
- doNothing().when(testProducer).subshardAdded(anyMap());
- final ShardedDOMDataTree impl = new ShardedDOMDataTree();
- shardingService = impl;
- shardReg = impl.registerDataTreeShard(ROOT_ID, rootShard, rootProducer);
- doReturn("rootShard").when(rootShard).toString();
- doReturn("childShard").when(childShard).toString();
- }
-
- @Test
- public void attachChildShard() throws DOMDataTreeShardingConflictException {
- doNothing().when(rootShard).onChildAttached(TEST_ID, childShard);
- shardingService.registerDataTreeShard(TEST_ID, childShard, testProducer);
- verify(rootShard, times(1)).onChildAttached(TEST_ID, childShard);
- }
-
- @Test
- public void attachAndRemoveShard() throws DOMDataTreeShardingConflictException {
- doNothing().when(rootShard).onChildAttached(TEST_ID, childShard);
- final ListenerRegistration<DOMDataTreeShard> reg =
- shardingService.registerDataTreeShard(TEST_ID, childShard, testProducer);
- verify(rootShard, times(1)).onChildAttached(TEST_ID, childShard);
-
- doNothing().when(rootShard).onChildDetached(TEST_ID, childShard);
- doNothing().when(childShard).onChildDetached(TEST_ID, childShard);
-
- reg.close();
- verify(rootShard, times(1)).onChildDetached(TEST_ID, childShard);
- }
-
- @Test
- public void removeShard() {
- doNothing().when(rootShard).onChildDetached(ROOT_ID, rootShard);
- shardReg.close();
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyCollection;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
-
-public class ShardedDOMDataTreeTest extends AbstractDatastoreTest {
-
- private static final DOMDataTreeIdentifier ROOT_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.empty());
- private static final DOMDataTreeIdentifier TEST_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
-
- private static final DOMDataTreeIdentifier INNER_CONTAINER_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, TestModel.INNER_CONTAINER_PATH);
-
- private static final YangInstanceIdentifier OUTER_LIST_YID = TestModel.OUTER_LIST_PATH.node(
- NodeIdentifierWithPredicates.of(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1));
- private static final DOMDataTreeIdentifier OUTER_LIST_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, OUTER_LIST_YID);
-
- private InMemoryDOMDataTreeShard rootShard;
-
- private ShardedDOMDataTree dataTreeService;
- private ListenerRegistration<InMemoryDOMDataTreeShard> rootShardReg;
-
- private final ExecutorService executor = Executors.newSingleThreadExecutor();
-
- @Captor
- private ArgumentCaptor<Collection<DataTreeCandidate>> captorForChanges;
- @Captor
- private ArgumentCaptor<Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>>> captorForSubtrees;
-
- private final ContainerNode crossShardContainer = createCrossShardContainer();
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- rootShard = InMemoryDOMDataTreeShard.create(ROOT_ID, executor, 1);
- rootShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final ShardedDOMDataTree dataTree = new ShardedDOMDataTree();
- final DOMDataTreeProducer shardRegProducer = dataTree.createProducer(Collections.singletonList(ROOT_ID));
- rootShardReg = dataTree.registerDataTreeShard(ROOT_ID, rootShard, shardRegProducer);
- shardRegProducer.close();
-
- dataTreeService = dataTree;
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testProducerPathContention() throws Exception {
- dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- dataTreeService.createProducer(Collections.singletonList(TEST_ID));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testProducerPathContentionReverse() throws Exception {
- dataTreeService.createProducer(Collections.singletonList(TEST_ID));
- dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- }
-
- @Test
- public void testShardRegistrationClose() throws Exception {
- rootShardReg.close();
-
- final InMemoryDOMDataTreeShard newRootShard = InMemoryDOMDataTreeShard.create(ROOT_ID, executor, 1);
- newRootShard.onModelContextUpdated(SCHEMA_CONTEXT);
- final DOMDataTreeProducer shardRegProducer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
-
- final ListenerRegistration<InMemoryDOMDataTreeShard> newRootShardReg =
- dataTreeService.registerDataTreeShard(ROOT_ID, newRootShard, shardRegProducer);
- shardRegProducer.close();
-
- final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1);
- innerShard.onModelContextUpdated(SCHEMA_CONTEXT);
- final DOMDataTreeProducer shardRegProducer2 =
- dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- ListenerRegistration<InMemoryDOMDataTreeShard> innerShardReg =
- dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, shardRegProducer2);
-
- innerShardReg.close();
- // try to register the shard again
- innerShardReg = dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, shardRegProducer2);
- final DOMDataTreeCursorAwareTransaction tx = shardRegProducer2.createTransaction(false);
- final DOMDataTreeWriteCursor cursor = tx.createCursor(INNER_CONTAINER_ID);
- assertNotNull(cursor);
-
- cursor.close();
- tx.cancel();
- shardRegProducer2.close();
-
- innerShardReg.close();
- newRootShardReg.close();
- }
-
- @Test(expected = IllegalStateException.class)
- public void testEmptyShardMapProducer() throws Exception {
- final ShardedDOMDataTree dataTree = new ShardedDOMDataTree();
- final DOMDataTreeProducer producer = dataTree.createProducer(Collections.singletonList(ROOT_ID));
- producer.createTransaction(false);
- }
-
- @Test
- public void testSingleShardWrite() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(INNER_CONTAINER_ID),
- true, Collections.emptyList());
-
- final DOMDataTreeProducer producer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
- DOMDataTreeWriteCursor cursor = tx.createCursor(ROOT_ID);
- assertNotNull(cursor);
-
- cursor.write(TEST_ID.getRootIdentifier().getLastPathArgument(), crossShardContainer);
-
- try {
- tx.commit().get();
- fail("There's still an open cursor");
- } catch (final IllegalStateException e) {
- assertTrue(e.getMessage().contains("cursor open"));
- }
-
- cursor.close();
- tx.commit().get();
-
- tx = producer.createTransaction(false);
- cursor = tx.createCursor(TEST_ID);
- assertNotNull(cursor);
-
- cursor.delete(TestModel.INNER_CONTAINER_PATH.getLastPathArgument());
- cursor.close();
- tx.commit().get();
-
- verify(mockedDataTreeListener, timeout(1000).times(3)).onDataTreeChanged(captorForChanges.capture(),
- captorForSubtrees.capture());
- final List<Collection<DataTreeCandidate>> capturedValue = captorForChanges.getAllValues();
- assertTrue(capturedValue.size() == 3);
-
- final ContainerNode capturedChange =
- (ContainerNode) capturedValue.get(1).iterator().next().getRootNode().getDataAfter().get();
- final ContainerNode innerContainerVerify = (ContainerNode) crossShardContainer.getChild(
- TestModel.INNER_CONTAINER_PATH.getLastPathArgument()).get();
- assertEquals(innerContainerVerify, capturedChange);
-
- verifyNoMoreInteractions(mockedDataTreeListener);
- }
-
- @Test
- // TODO extract common logic from testSingleSubshardWrite and
- // testSingleShardWrite tests
- public void testSingleSubshardWrite() throws Exception {
- final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
- doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
-
- InMemoryDOMDataTreeShard testShard = InMemoryDOMDataTreeShard.create(TEST_ID, executor, 1);
- testShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final DOMDataTreeProducer regProducer = dataTreeService.createProducer(Collections.singleton(TEST_ID));
- dataTreeService.registerDataTreeShard(TEST_ID, testShard, regProducer);
- regProducer.close();
-
- dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(TEST_ID),
- true, Collections.emptyList());
-
- final DOMDataTreeProducer producer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
- DOMDataTreeWriteCursor cursor = tx.createCursor(ROOT_ID);
- assertNotNull(cursor);
-
- cursor.write(TEST_ID.getRootIdentifier().getLastPathArgument(), crossShardContainer);
-
- cursor.close();
- tx.commit().get();
-
- tx = producer.createTransaction(false);
- cursor = tx.createCursor(TEST_ID);
- assertNotNull(cursor);
-
- cursor.delete(TestModel.INNER_CONTAINER_PATH.getLastPathArgument());
- cursor.close();
- tx.commit().get();
-
- verify(mockedDataTreeListener, timeout(5000).times(3)).onDataTreeChanged(captorForChanges.capture(),
- captorForSubtrees.capture());
-
- final List<Collection<DataTreeCandidate>> capturedValue = captorForChanges.getAllValues();
- final ContainerNode capturedChange =
- (ContainerNode) capturedValue.get(1).iterator().next().getRootNode().getDataAfter().get();
- final ContainerNode innerContainerVerify = crossShardContainer;
- assertEquals(innerContainerVerify, capturedChange);
- }
-
- @Test
- public void testMultipleWritesIntoSingleMapEntry() throws Exception {
-
- final YangInstanceIdentifier oid1 = TestModel.OUTER_LIST_PATH.node(NodeIdentifierWithPredicates.of(
- TestModel.OUTER_LIST_QNAME, QName.create(TestModel.OUTER_LIST_QNAME, "id"), 0));
- final DOMDataTreeIdentifier outerListPath = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, oid1);
-
- final DOMDataTreeProducer shardProducer = dataTreeService.createProducer(
- Collections.singletonList(outerListPath));
- final InMemoryDOMDataTreeShard outerListShard = InMemoryDOMDataTreeShard.create(outerListPath, executor, 1000);
- outerListShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- final ListenerRegistration<InMemoryDOMDataTreeShard> oid1ShardRegistration =
- dataTreeService.registerDataTreeShard(outerListPath, outerListShard, shardProducer);
-
- final DOMDataTreeCursorAwareTransaction tx = shardProducer.createTransaction(false);
- final DOMDataTreeWriteCursor cursor =
- tx.createCursor(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, oid1));
- assertNotNull(cursor);
-
- MapNode innerList = ImmutableMapNodeBuilder
- .create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_LIST_QNAME))
- .build();
-
- cursor.write(new NodeIdentifier(TestModel.INNER_LIST_QNAME), innerList);
- cursor.close();
- tx.commit().get();
-
- final ArrayList<ListenableFuture<?>> futures = new ArrayList<>();
- for (int i = 0; i < 1000; i++) {
- final Collection<MapEntryNode> innerListMapEntries = createInnerListMapEntries(1000, "run-" + i);
- for (final MapEntryNode innerListMapEntry : innerListMapEntries) {
- final DOMDataTreeCursorAwareTransaction tx1 = shardProducer.createTransaction(false);
- final DOMDataTreeWriteCursor cursor1 = tx1.createCursor(
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
- oid1.node(new NodeIdentifier(TestModel.INNER_LIST_QNAME))));
- cursor1.write(innerListMapEntry.getIdentifier(), innerListMapEntry);
- cursor1.close();
- futures.add(tx1.commit());
- }
- }
-
- futures.get(futures.size() - 1).get();
-
- }
-
- private static Collection<MapEntryNode> createInnerListMapEntries(final int amount, final String valuePrefix) {
- final Collection<MapEntryNode> ret = new ArrayList<>();
- for (int i = 0; i < amount; i++) {
- ret.add(ImmutableNodes.mapEntryBuilder()
- .withNodeIdentifier(NodeIdentifierWithPredicates.of(TestModel.INNER_LIST_QNAME,
- QName.create(TestModel.OUTER_LIST_QNAME, "name"), Integer.toString(i)))
- .withChild(ImmutableNodes
- .leafNode(QName.create(TestModel.INNER_LIST_QNAME, "name"), Integer.toString(i)))
- .withChild(ImmutableNodes
- .leafNode(QName.create(TestModel.INNER_LIST_QNAME, "value"), valuePrefix + "-" + i))
- .build());
- }
-
- return ret;
- }
-
- @Test
- public void testMultipleProducerCursorCreation() throws Exception {
-
- final DOMDataTreeProducer rootProducer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- DOMDataTreeCursorAwareTransaction rootTx = rootProducer.createTransaction(false);
- //check if we can create cursor where the new producer will be
- DOMDataTreeWriteCursor rootTxCursor = rootTx.createCursor(INNER_CONTAINER_ID);
- assertNotNull(rootTxCursor);
- rootTxCursor.close();
-
- try {
- rootProducer.createProducer(Collections.singletonList(INNER_CONTAINER_ID));
- fail("Should've failed there is still a tx open");
- } catch (final IllegalStateException e) {
- assertTrue(e.getMessage().contains("open"));
- }
-
- assertTrue(rootTx.cancel());
-
- final DOMDataTreeProducer innerContainerProducer = rootProducer.createProducer(
- Collections.singletonList(INNER_CONTAINER_ID));
-
- rootTx = rootProducer.createTransaction(false);
- try {
- rootTx.createCursor(INNER_CONTAINER_ID);
- fail("Subtree should not be available to this producer");
- } catch (final IllegalArgumentException e) {
- assertTrue(e.getMessage().contains("delegated to child producer"));
- }
-
- rootTxCursor = rootTx.createCursor(TEST_ID);
- assertNotNull(rootTxCursor);
- try {
- rootTxCursor.enter(INNER_CONTAINER_ID.getRootIdentifier().getLastPathArgument());
- fail("Cursor should not have this subtree available");
- } catch (final IllegalArgumentException e) {
- assertTrue(e.getMessage().contains("not available to this cursor"));
- }
-
- try {
- rootTxCursor.write(TestModel.INNER_CONTAINER_PATH.getLastPathArgument(),
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_CONTAINER))
- .build());
- fail("Cursor should not have this subtree available");
- } catch (final IllegalArgumentException e) {
- assertTrue(e.getMessage().contains("not available to this cursor"));
- }
-
- final DOMDataTreeCursorAwareTransaction innerShardTx = innerContainerProducer.createTransaction(false);
- final DOMDataTreeWriteCursor innerShardCursor = innerShardTx.createCursor(INNER_CONTAINER_ID);
- assertNotNull(innerShardCursor);
- }
-
- private static ContainerNode createCrossShardContainer() {
- final LeafNode<String> shardedValue1 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(new NodeIdentifier(
- TestModel.SHARDED_VALUE_1)).withValue("sharded value 1").build();
- final LeafNode<String> shardedValue2 =
- ImmutableLeafNodeBuilder.<String>create().withNodeIdentifier(new NodeIdentifier(
- TestModel.SHARDED_VALUE_2)).withValue("sharded value 2").build();
-
-
- final ContainerNode lowerShardContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.ANOTHER_SHARD_CONTAINER))
- .withChild(ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.ANOTHER_SHARD_VALUE))
- .withValue("testing-value")
- .build())
- .build();
-
- final ContainerNode containerNode =
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_CONTAINER))
- .withChild(shardedValue1)
- .withChild(shardedValue2)
- .withChild(lowerShardContainer)
- .build();
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .withChild(containerNode)
- .build();
-
- return testContainer;
- }
-
- //test multiple vertical levels between the shards
- @Test
- public void testLargerSubshardSpace() throws Exception {
-
- final InMemoryDOMDataTreeShard outerListShard = InMemoryDOMDataTreeShard.create(OUTER_LIST_ID, executor, 1, 1);
- outerListShard.onModelContextUpdated(SCHEMA_CONTEXT);
-
- try (DOMDataTreeProducer producer =
- dataTreeService.createProducer(Collections.singletonList(OUTER_LIST_ID))) {
- dataTreeService.registerDataTreeShard(OUTER_LIST_ID, outerListShard, producer);
- }
-
- final DOMDataTreeProducer producer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
- final DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
- final DOMDataTreeWriteCursor cursor = tx.createCursor(ROOT_ID);
-
- assertNotNull(cursor);
- cursor.write(TestModel.TEST_PATH.getLastPathArgument(), createCrossShardContainer2());
- cursor.close();
-
- tx.commit().get();
-
- final DOMDataTreeListener listener = mock(DOMDataTreeListener.class);
- doNothing().when(listener).onDataTreeChanged(any(), any());
- dataTreeService.registerListener(listener,
- Collections.singletonList(
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.empty())),
- false, Collections.emptyList());
-
- verify(listener, times(2)).onDataTreeChanged(any(), any());
-
-
- }
-
- private static ContainerNode createCrossShardContainer2() {
-
- final MapEntryNode
- innerListEntry1 = ImmutableNodes
- .mapEntryBuilder(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "name-1")
- .withChild(ImmutableNodes.leafNode(TestModel.NAME_QNAME, "name-1"))
- .withChild(ImmutableNodes.leafNode(TestModel.VALUE_QNAME, "value-1"))
- .build();
- final MapEntryNode innerListEntry2 = ImmutableNodes
- .mapEntryBuilder(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "name-2")
- .withChild(ImmutableNodes.leafNode(TestModel.NAME_QNAME, "name-2"))
- .withChild(ImmutableNodes.leafNode(TestModel.VALUE_QNAME, "value-2"))
- .build();
-
- final MapNode innerList1 = ImmutableNodes
- .mapNodeBuilder(TestModel.INNER_LIST_QNAME).withChild(innerListEntry1).build();
- final MapNode innerList2 = ImmutableNodes
- .mapNodeBuilder(TestModel.INNER_LIST_QNAME).withChild(innerListEntry2).build();
-
- final MapEntryNode outerListEntry1 = ImmutableNodes
- .mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
- .withChild(innerList1)
- .build();
- final MapEntryNode outerListEntry2 = ImmutableNodes
- .mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2)
- .withChild(innerList2)
- .build();
-
- final MapNode outerList = ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
- .withChild(outerListEntry1)
- .withChild(outerListEntry2)
- .build();
-
- final ContainerNode testContainer = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
- .withChild(outerList)
- .build();
-
- return testContainer;
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayDeque;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableDOMDataTreeShard;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ShardedDOMDataWriteTransactionTest {
- private static final Map<YangInstanceIdentifier, List<NormalizedNode<?, ?>>> TEST_MAP = new HashMap<>();
-
- private static final DOMDataTreeIdentifier ROOT_ID =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
-
- @Mock
- private WriteableDOMDataTreeShard rootShard;
-
- @Mock
- private DOMDataTreeShardProducer mockedProducer;
-
- @Test
- public void basicTests() throws Exception {
-
- initMocks(this);
-
- doReturn(new TestDOMShardWriteTransaction()).when(mockedProducer).createTransaction();
- doReturn(mockedProducer).when(rootShard).createProducer(any(Collection.class));
- doNothing().when(mockedProducer).close();
-
- final ShardedDOMDataTree shardedDOMDataTree =
- new ShardedDOMDataTree();
- final DOMDataTreeProducer shardRegProducer = shardedDOMDataTree.createProducer(
- Collections.singletonList(ROOT_ID));
- shardedDOMDataTree.registerDataTreeShard(ROOT_ID, rootShard, shardRegProducer);
- shardRegProducer.close();
- final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.of(QName.create("", "test"));
-
- final DOMDataTreeProducer producer = shardedDOMDataTree.createProducer(Collections.singletonList(ROOT_ID));
- final DOMDataTreeCursorAwareTransaction transaction = producer.createTransaction(false);
- final DOMDataTreeWriteCursor cursor = transaction.createCursor(ROOT_ID);
-
- assertNotNull(cursor);
- assertFalse(TEST_MAP.containsKey(yangInstanceIdentifier));
- cursor.write(yangInstanceIdentifier.getLastPathArgument(), TestUtils.TEST_CONTAINER);
- assertTrue(TEST_MAP.containsKey(yangInstanceIdentifier));
-
- cursor.delete(yangInstanceIdentifier.getLastPathArgument());
- assertFalse(TEST_MAP.containsKey(yangInstanceIdentifier));
-
- cursor.merge(yangInstanceIdentifier.getLastPathArgument(), TestUtils.TEST_CONTAINER);
- assertTrue(TEST_MAP.get(yangInstanceIdentifier).contains(TestUtils.TEST_CONTAINER));
-
- try {
- producer.createTransaction(false);
- fail("Should have failed, there's still a tx open");
- } catch (final IllegalStateException e) {
- assertTrue(e.getMessage().contains("open"));
- }
-
- cursor.close();
- try {
- transaction.createCursor(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
- YangInstanceIdentifier.empty()));
- fail("Should have failed, config ds not available to this tx");
- } catch (final IllegalArgumentException e) {
- assertTrue(e.getMessage().contains("not accessible"));
- }
-
- assertTrue(transaction.cancel());
- assertFalse(transaction.cancel());
-
- final DOMDataTreeCursorAwareTransaction newTx = producer.createTransaction(false);
- assertTrue("Transaction identifier incorrect " + transaction.getIdentifier(), (
- (String) transaction.getIdentifier()).contains("SHARDED-DOM-"));
- assertNotEquals(transaction.getIdentifier(),
- newTx.getIdentifier());
- }
-
- private final class TestDOMShardWriteTransaction implements DOMDataTreeShardWriteTransaction {
- @Override
- public DOMDataTreeWriteCursor createCursor(final DOMDataTreeIdentifier prefix) {
- return new TestCursor();
- }
-
- @Override
- public void ready() {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public ListenableFuture<Void> submit() {
- return null;
- }
-
- @Override
- public ListenableFuture<Boolean> validate() {
- return null;
- }
-
- @Override
- public ListenableFuture<Void> prepare() {
- return null;
- }
-
- @Override
- public ListenableFuture<Void> commit() {
- return null;
- }
- }
-
- private final class TestCursor implements DOMDataTreeWriteCursor {
-
- private final Deque<PathArgument> stack = new ArrayDeque<>();
-
- @Override
- public void delete(final PathArgument child) {
- final ArrayDeque<PathArgument> newPath = new ArrayDeque<>(stack);
- newPath.push(child);
- TEST_MAP.remove(YangInstanceIdentifier.create(newPath));
- }
-
- @Override
- public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
- final ArrayDeque<PathArgument> newPath = new ArrayDeque<>(stack);
- newPath.push(child);
- final List<NormalizedNode<?, ?>> dataList = TEST_MAP.get(YangInstanceIdentifier.create(newPath));
- if (dataList != null) {
- dataList.add(data);
- } else {
- TEST_MAP.put(YangInstanceIdentifier.create(newPath), Lists.newArrayList(data));
- }
- }
-
- @Override
- public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
- final ArrayDeque<PathArgument> newPath = new ArrayDeque<>(stack);
- newPath.push(child);
- TEST_MAP.put(YangInstanceIdentifier.create(newPath), Lists.newArrayList(data));
- }
-
- @Override
- public void enter(final PathArgument child) {
- stack.push(child);
- }
-
- @Override
- public void enter(final PathArgument... path) {
- for (final PathArgument pathArgument : path) {
- stack.push(pathArgument);
- }
- }
-
- @Override
- public void enter(final Iterable<PathArgument> path) {
- path.forEach(stack::push);
- }
-
- @Override
- public void exit() {
- stack.pop();
- }
-
- @Override
- public void exit(final int depth) {
- stack.pop();
- }
-
- @Override
- public void close() {
-
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeServiceExtension;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-
-public class ShardedDOMReadTransactionAdapterTest {
-
- private ShardedDOMReadTransactionAdapter readTx;
-
- @Before
- public void setUp() {
- readTx = new ShardedDOMReadTransactionAdapter("TEST-TX", new TestTreeService());
- }
-
- @Test
- public void testGetIdentifier() {
- assertEquals("TEST-TX", readTx.getIdentifier());
- }
-
- @Test
- public void testRead() throws InterruptedException, ExecutionException {
- final ListenableFuture<Optional<NormalizedNode<?, ?>>> readResult =
- readTx.read(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
- assertTrue(readTx.exists(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH).get());
- assertEquals(readResult.get().get(), TestUtils.TEST_CONTAINER);
- }
-
- @After
- public void close() {
- readTx.close();
- }
-
- private static class TestTreeService implements DOMDataTreeService {
- @Override
- public ClassToInstanceMap<DOMDataTreeServiceExtension> getExtensions() {
- return ImmutableClassToInstanceMap.of();
- }
-
- @Override
- public <T extends DOMDataTreeListener> ListenerRegistration<T>
- registerListener(final T listener, final Collection<DOMDataTreeIdentifier> subtrees,
- final boolean allowRxMerges, final Collection<DOMDataTreeProducer> producers)
- throws DOMDataTreeLoopException {
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtree = new HashMap<>();
- subtree.put(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH),
- TestUtils.TEST_CONTAINER);
-
- listener.onDataTreeChanged(Collections.singleton(
- DataTreeCandidates.fromNormalizedNode(TestModel.TEST_PATH, TestUtils.TEST_CONTAINER)), subtree);
-
- return new ListenerRegistration<T>() {
- @Override
- public void close() {
- // NOOP
- }
-
- @Override
- public T getInstance() {
- return listener;
- }
- };
- }
-
- @Override
- public DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- throw new UnsupportedOperationException();
- }
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.OPERATIONAL;
-
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorAwareTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
-import org.opendaylight.mdsal.dom.broker.util.TestModel;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-
-public class ShardedDOMTransactionChainAdapterTest {
-
- @Test
- public void basicTest() throws Exception {
- String identifier = "TestIdent";
- DOMDataTreeService dataTreeService = mock(DOMDataTreeService.class);
- DOMDataTreeProducer producer = mock(DOMDataTreeProducer.class);
- DOMDataTreeCursorAwareTransaction transaction = mock(DOMDataTreeCursorAwareTransaction.class);
- DOMDataTreeWriteCursor cursor = mock(DOMDataTreeWriteCursor.class);
- doReturn(producer).when(dataTreeService).createProducer(any());
- doReturn(transaction).when(producer).createTransaction(true);
- doReturn(cursor).when(transaction).createCursor(any());
- doNothing().when(producer).close();
-
-
- DOMTransactionChainListener chainListener = new BlockingTransactionChainListener();
- ShardedDOMTransactionChainAdapter transactionChainAdapter =
- new ShardedDOMTransactionChainAdapter(identifier, dataTreeService, chainListener);
-
- DOMDataTreeWriteTransaction writeTransaction = transactionChainAdapter.newWriteOnlyTransaction();
- assertNotNull(writeTransaction);
- assertNotNull(writeTransaction.getIdentifier());
-
- doNothing().when(cursor).write(any(), any());
- writeTransaction.put(OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
- verify(cursor).write(any(), any());
-
- doNothing().when(cursor).merge(any(), any());
- writeTransaction.merge(OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
- verify(cursor).merge(any(), any());
-
- doNothing().when(cursor).delete(any());
- writeTransaction.delete(OPERATIONAL, TestModel.TEST_PATH);
- verify(cursor).delete(any());
-
- doNothing().when(cursor).close();
- doReturn(CommitInfo.emptyFluentFuture()).when(transaction).commit();
- doReturn(true).when(transaction).cancel();
- assertTrue(writeTransaction.cancel());
- transactionChainAdapter.closeWriteTransaction(FluentFutures.immediateNullFluentFuture());
-
- transactionChainAdapter = new ShardedDOMTransactionChainAdapter(identifier, dataTreeService, chainListener);
- writeTransaction = transactionChainAdapter.newWriteOnlyTransaction();
- writeTransaction.put(OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
- assertNotNull(writeTransaction.commit());
- assertFalse(writeTransaction.cancel());
- transactionChainAdapter.closeWriteTransaction(FluentFutures.immediateNullFluentFuture());
-
- assertNotNull(transactionChainAdapter.newWriteOnlyTransaction().commit());
-
- DOMDataTreeReadTransaction readTransaction = transactionChainAdapter.newReadOnlyTransaction();
- assertNotNull(readTransaction);
- transactionChainAdapter.closeReadTransaction();
- transactionChainAdapter.close();
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.FluentFuture;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class TransactionChainReadTransactionTest {
-
- @Test
- public void basicTest() throws Exception {
- final String identifier = "testIdent";
- final DOMDataTreeReadTransaction readTransaction = mock(DOMDataTreeReadTransaction.class);
- final ShardedDOMTransactionChainAdapter chainAdapter = mock(ShardedDOMTransactionChainAdapter.class);
- FluentFuture<? extends CommitInfo> previousWriteTxFuture = FluentFutures.immediateNullFluentFuture();
-
- TransactionChainReadTransaction transactionChainReadTransaction =
- new TransactionChainReadTransaction(identifier, readTransaction, previousWriteTxFuture, chainAdapter);
-
- assertEquals(identifier, transactionChainReadTransaction.getIdentifier());
-
- doNothing().when(readTransaction).close();
- doNothing().when(chainAdapter).closeReadTransaction();
- transactionChainReadTransaction.close();
- verify(readTransaction).close();
- verify(chainAdapter).closeReadTransaction();
-
- doReturn(FluentFutures.immediateNullFluentFuture()).when(readTransaction).read(any(), any());
- assertNotNull(transactionChainReadTransaction.exists(
- LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty()));
- transactionChainReadTransaction.read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
- verify(readTransaction, atLeastOnce()).read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
-
- doReturn(FluentFutures.immediateFailedFluentFuture(
- new NullPointerException())).when(readTransaction).read(any(), any());
- doNothing().when(chainAdapter).transactionFailed(any(), any());
- assertNotNull(transactionChainReadTransaction.read(
- LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty()));
- previousWriteTxFuture = FluentFutures.immediateFailedFluentFuture(new NullPointerException());
- transactionChainReadTransaction =
- new TransactionChainReadTransaction(identifier, readTransaction, previousWriteTxFuture, chainAdapter);
- assertNotNull(transactionChainReadTransaction.read(
- LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty()));
- }
-}
+++ /dev/null
-/*
- * 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.dom.broker;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-
-public class TransactionChainWriteTransactionTest {
-
- @Test
- public void basicTest() throws Exception {
- final String identifier = "testIdent";
- final DOMDataTreeWriteTransaction writeTransaction = mock(DOMDataTreeWriteTransaction.class);
- final ShardedDOMTransactionChainAdapter chainAdapter = mock(ShardedDOMTransactionChainAdapter.class);
-
- final TransactionChainWriteTransaction transactionChainWriteTransaction =
- new TransactionChainWriteTransaction(identifier, writeTransaction, chainAdapter);
-
- assertEquals(identifier, transactionChainWriteTransaction.getIdentifier());
-
- doNothing().when(writeTransaction).put(any(), any(), any());
- transactionChainWriteTransaction.put(any(), any(), any());
- verify(writeTransaction).put(any(), any(), any());
-
- doNothing().when(writeTransaction).merge(any(), any(), any());
- transactionChainWriteTransaction.merge(any(), any(), any());
- verify(writeTransaction).merge(any(), any(), any());
-
- doReturn(false).when(writeTransaction).cancel();
- doNothing().when(chainAdapter).closeWriteTransaction(any());
- transactionChainWriteTransaction.cancel();
- verify(writeTransaction).cancel();
-
- doNothing().when(writeTransaction).delete(any(), any());
- transactionChainWriteTransaction.delete(any(), any());
- verify(writeTransaction).delete(any(), any());
-
- ListenableFuture<? extends CommitInfo> writeResult = CommitInfo.emptyFluentFuture();
- doReturn(writeResult).when(writeTransaction).commit();
- assertEquals(writeResult, transactionChainWriteTransaction.commit());
-
- writeResult = FluentFutures.immediateFailedFluentFuture(mock(TransactionCommitFailedException.class));
- doNothing().when(chainAdapter).transactionFailed(any(), any());
- doReturn(writeResult).when(writeTransaction).commit();
- assertEquals(writeResult, transactionChainWriteTransaction.commit());
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.AbstractDOMDataTreeChangeListenerRegistration;
-import org.opendaylight.mdsal.dom.spi.RegistrationTreeNode;
-import org.opendaylight.mdsal.dom.spi.shard.ChildShardContext;
-import org.opendaylight.mdsal.dom.spi.store.AbstractDOMStoreTreeChangePublisher;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-abstract class AbstractDOMShardTreeChangePublisher extends AbstractDOMStoreTreeChangePublisher {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractDOMShardTreeChangePublisher.class);
-
- private final YangInstanceIdentifier shardPath;
- private final Map<DOMDataTreeIdentifier, ChildShardContext> childShards;
- private final DataTree dataTree;
-
- protected AbstractDOMShardTreeChangePublisher(final DataTree dataTree,
- final YangInstanceIdentifier shardPath, final Map<DOMDataTreeIdentifier, ChildShardContext> childShards) {
- this.dataTree = requireNonNull(dataTree);
- this.shardPath = requireNonNull(shardPath);
- this.childShards = requireNonNull(childShards);
- }
-
- @Override
- public <L extends DOMDataTreeChangeListener> AbstractDOMDataTreeChangeListenerRegistration<L>
- registerTreeChangeListener(final YangInstanceIdentifier path, final L listener) {
- takeLock();
- try {
- return setupListenerContext(path, listener);
- } finally {
- releaseLock();
- }
- }
-
- private <L extends DOMDataTreeChangeListener> AbstractDOMDataTreeChangeListenerRegistration<L>
- setupListenerContext(final YangInstanceIdentifier listenerPath, final L listener) {
- // we need to register the listener registration path based on the shards root
- // we have to strip the shard path from the listener path and then register
- YangInstanceIdentifier strippedIdentifier = listenerPath;
- if (!shardPath.isEmpty()) {
- strippedIdentifier = YangInstanceIdentifier.create(stripShardPath(listenerPath));
- }
-
- final DOMDataTreeListenerWithSubshards subshardListener =
- new DOMDataTreeListenerWithSubshards(dataTree, strippedIdentifier, listener);
- final AbstractDOMDataTreeChangeListenerRegistration<L> reg =
- setupContextWithoutSubshards(strippedIdentifier, subshardListener);
-
- for (final ChildShardContext maybeAffected : childShards.values()) {
- if (listenerPath.contains(maybeAffected.getPrefix().getRootIdentifier())) {
- // consumer has initialDataChangeEvent subshard somewhere on lower level
- // register to the notification manager with snapshot and forward child notifications to parent
- LOG.debug("Adding new subshard{{}} to listener at {}", maybeAffected.getPrefix(), listenerPath);
- subshardListener.addSubshard(maybeAffected);
- } else if (maybeAffected.getPrefix().getRootIdentifier().contains(listenerPath)) {
- // bind path is inside subshard
- // TODO can this happen? seems like in ShardedDOMDataTree we are
- // already registering to the lowest shard possible
- throw new UnsupportedOperationException("Listener should be registered directly "
- + "into initialDataChangeEvent subshard");
- }
- }
-
- initialDataChangeEvent(listenerPath, listener);
-
- return reg;
- }
-
- private <L extends DOMDataTreeChangeListener> void initialDataChangeEvent(
- final YangInstanceIdentifier listenerPath, final L listener) {
- // FIXME Add support for wildcard listeners
- final Optional<NormalizedNode<?, ?>> preExistingData = dataTree.takeSnapshot()
- .readNode(YangInstanceIdentifier.create(stripShardPath(listenerPath)));
- final DataTreeCandidate initialCandidate;
-
- if (preExistingData.isPresent()) {
- final NormalizedNode<?, ?> data = preExistingData.get();
- checkState(data instanceof DataContainerNode, "Expected DataContainer node, but was {}", data.getClass());
- // if we are listening on root of some shard we still get
- // empty normalized node, root is always present
- if (((DataContainerNode<?>) data).getValue().isEmpty()) {
- initialCandidate = DataTreeCandidates.newDataTreeCandidate(listenerPath,
- DataTreeCandidateNodes.empty(data.getIdentifier()));
- } else {
- initialCandidate = DataTreeCandidates.fromNormalizedNode(listenerPath,
- translateRootShardIdentifierToListenerPath(listenerPath, preExistingData.get()));
- }
- } else {
- initialCandidate = DataTreeCandidates.newDataTreeCandidate(listenerPath,
- DataTreeCandidateNodes.empty(listenerPath.getLastPathArgument()));
- }
-
- listener.onDataTreeChanged(Collections.singleton(initialCandidate));
- }
-
- private static NormalizedNode<?, ?> translateRootShardIdentifierToListenerPath(
- final YangInstanceIdentifier listenerPath, final NormalizedNode<?, ?> node) {
- if (listenerPath.isEmpty()) {
- return node;
- }
-
- final NormalizedNodeBuilder nodeBuilder;
- if (node instanceof ContainerNode) {
- nodeBuilder = ImmutableContainerNodeBuilder.create().withValue(((ContainerNode) node).getValue());
- } else if (node instanceof MapEntryNode) {
- nodeBuilder = ImmutableMapEntryNodeBuilder.create().withValue(((MapEntryNode) node).getValue());
- } else {
- throw new IllegalArgumentException("Expected ContainerNode or MapEntryNode, but was " + node.getClass());
- }
- nodeBuilder.withNodeIdentifier(listenerPath.getLastPathArgument());
- return nodeBuilder.build();
- }
-
- private <L extends DOMDataTreeChangeListener> AbstractDOMDataTreeChangeListenerRegistration<L>
- setupContextWithoutSubshards(final YangInstanceIdentifier listenerPath,
- final DOMDataTreeListenerWithSubshards listener) {
- LOG.debug("Registering root listener at {}", listenerPath);
- final RegistrationTreeNode<AbstractDOMDataTreeChangeListenerRegistration<?>> node =
- findNodeFor(listenerPath.getPathArguments());
- @SuppressWarnings("unchecked")
- final var registration = new AbstractDOMDataTreeChangeListenerRegistration<>((L) listener) {
- @Override
- protected void removeRegistration() {
- listener.close();
- AbstractDOMShardTreeChangePublisher.this.removeRegistration(node, this);
- registrationRemoved(this);
- }
- };
- addRegistration(node, registration);
- return registration;
- }
-
- private Iterable<PathArgument> stripShardPath(final YangInstanceIdentifier listenerPath) {
- if (shardPath.isEmpty()) {
- return listenerPath.getPathArguments();
- }
-
- final List<PathArgument> listenerPathArgs = new ArrayList<>(listenerPath.getPathArguments());
- final Iterator<PathArgument> shardIter = shardPath.getPathArguments().iterator();
- final Iterator<PathArgument> listenerIter = listenerPathArgs.iterator();
-
- while (shardIter.hasNext()) {
- if (shardIter.next().equals(listenerIter.next())) {
- listenerIter.remove();
- } else {
- break;
- }
- }
-
- return listenerPathArgs;
- }
-
- private static final class DOMDataTreeListenerWithSubshards implements DOMDataTreeChangeListener {
-
- private final DataTree dataTree;
- private final YangInstanceIdentifier listenerPath;
- private final DOMDataTreeChangeListener delegate;
-
- private final Map<YangInstanceIdentifier, ListenerRegistration<DOMDataTreeChangeListener>> registrations =
- new HashMap<>();
-
- DOMDataTreeListenerWithSubshards(final DataTree dataTree, final YangInstanceIdentifier listenerPath,
- final DOMDataTreeChangeListener delegate) {
- this.dataTree = requireNonNull(dataTree);
- this.listenerPath = requireNonNull(listenerPath);
- this.delegate = requireNonNull(delegate);
- }
-
- @Override
- public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
- LOG.debug("Received data changed {}", changes);
- delegate.onDataTreeChanged(changes);
- }
-
- void onDataTreeChanged(final YangInstanceIdentifier rootPath, final Collection<DataTreeCandidate> changes) {
- final List<DataTreeCandidate> newCandidates = changes.stream()
- .map(candidate -> DataTreeCandidates.newDataTreeCandidate(rootPath, candidate.getRootNode()))
- .collect(Collectors.toList());
- delegate.onDataTreeChanged(Collections.singleton(applyChanges(newCandidates)));
- }
-
- void addSubshard(final ChildShardContext context) {
- checkState(context.getShard() instanceof DOMStoreTreeChangePublisher,
- "All subshards that are initialDataChangeEvent part of ListenerContext need to be listenable");
-
- final DOMStoreTreeChangePublisher listenableShard = (DOMStoreTreeChangePublisher) context.getShard();
- // since this is going into subshard we want to listen for ALL changes in the subshard
- registrations.put(context.getPrefix().getRootIdentifier(),
- listenableShard.registerTreeChangeListener(
- context.getPrefix().getRootIdentifier(), changes -> onDataTreeChanged(
- context.getPrefix().getRootIdentifier(), changes)));
- }
-
- void close() {
- for (final ListenerRegistration<DOMDataTreeChangeListener> registration : registrations.values()) {
- registration.close();
- }
- registrations.clear();
- }
-
- private DataTreeCandidate applyChanges(final Collection<DataTreeCandidate> changes) {
- final DataTreeModification modification = dataTree.takeSnapshot().newModification();
- for (final DataTreeCandidate change : changes) {
- DataTreeCandidates.applyToModification(modification, change);
- }
-
- modification.ready();
- DataTreeCandidateNode modifiedChild;
- try {
- dataTree.validate(modification);
- modifiedChild = dataTree.prepare(modification).getRootNode();
- } catch (final DataValidationFailedException e) {
- LOG.error("Validation failed for built modification", e);
- throw new IllegalStateException("Notification validation failed", e);
- }
-
- // strip nodes we do not need since this listener doesn't have to be registered at the root of the DataTree
- for (final PathArgument pathArgument : listenerPath.getPathArguments()) {
- modifiedChild = modifiedChild.getModifiedChild(pathArgument).orElse(null);
- }
-
- if (modifiedChild == null) {
- modifiedChild = DataTreeCandidateNodes.empty(listenerPath.getLastPathArgument());
- }
-
- return DataTreeCandidates.newDataTreeCandidate(listenerPath, modifiedChild);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ForwardingObject;
-import java.util.Optional;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-final class DataTreeModificationCursorAdaptor extends ForwardingObject implements DOMDataTreeWriteCursor {
-
- private final DataTreeModificationCursor delegate;
-
- private DataTreeModificationCursorAdaptor(final DataTreeModificationCursor delegate) {
- this.delegate = requireNonNull(delegate);
- }
-
- static DataTreeModificationCursorAdaptor of(final DataTreeModificationCursor dataTreeCursor) {
- return new DataTreeModificationCursorAdaptor(dataTreeCursor);
- }
-
- @Override
- protected DataTreeModificationCursor delegate() {
- return delegate;
- }
-
- @Override
- public void delete(final PathArgument child) {
- delegate.delete(child);
- }
-
- @Override
- public void enter(final PathArgument child) {
- delegate.enter(child);
- }
-
- @Override
- public void enter(final Iterable<PathArgument> path) {
- delegate.enter(path);
- }
-
- @Override
- public void enter(final PathArgument... path) {
- delegate.enter(path);
- }
-
- @Override
- public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
- delegate.merge(child, data);
- }
-
- @Override
- public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
- delegate.write(child, data);
- }
-
- @Override
- public void exit() {
- delegate.exit();
- }
-
- @Override
- public void exit(final int depth) {
- delegate.exit(depth);
- }
-
- public Optional<NormalizedNode<?, ?>> readNode(final PathArgument child) {
- return delegate.readNode(child);
- }
-
- @Override
- public void close() {
- delegate.close();
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.Executor;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.DOMDataTreePrefixTable;
-import org.opendaylight.mdsal.dom.spi.shard.ChildShardContext;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.ReadableWriteableDOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.shard.SubshardProducerSpecification;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableDOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.util.concurrent.CountingRejectedExecutionHandler;
-import org.opendaylight.yangtools.util.concurrent.FastThreadPoolExecutor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Beta
-public class InMemoryDOMDataTreeShard implements ReadableWriteableDOMDataTreeShard, EffectiveModelContextListener {
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataTreeShard.class);
- private static final int DEFAULT_SUBMIT_QUEUE_SIZE = 1000;
-
- private final DOMDataTreePrefixTable<ChildShardContext> childShardsTable = DOMDataTreePrefixTable.create();
- private final Map<DOMDataTreeIdentifier, ChildShardContext> childShards = new HashMap<>();
- private final Collection<InMemoryDOMDataTreeShardProducer> producers = new HashSet<>();
- private final InMemoryDOMDataTreeShardChangePublisher shardChangePublisher;
- private final ListeningExecutorService executor;
- private final DOMDataTreeIdentifier prefix;
- private final DataTree dataTree;
-
- InMemoryDOMDataTreeShard(final DOMDataTreeIdentifier prefix, final Executor dataTreeChangeExecutor,
- final int maxDataChangeListenerQueueSize, final int submitQueueSize) {
- this.prefix = requireNonNull(prefix);
-
- final DataTreeConfiguration treeBaseConfig = treeTypeFor(prefix.getDatastoreType());
- final DataTreeConfiguration treeConfig = new DataTreeConfiguration.Builder(treeBaseConfig.getTreeType())
- .setMandatoryNodesValidation(treeBaseConfig.isMandatoryNodesValidationEnabled())
- .setUniqueIndexes(treeBaseConfig.isUniqueIndexEnabled())
- .setRootPath(prefix.getRootIdentifier())
- .build();
-
- this.dataTree = new InMemoryDataTreeFactory().create(treeConfig);
-
- this.shardChangePublisher = new InMemoryDOMDataTreeShardChangePublisher(dataTreeChangeExecutor,
- maxDataChangeListenerQueueSize, dataTree, prefix.getRootIdentifier(), childShards);
-
- final FastThreadPoolExecutor fte = new FastThreadPoolExecutor(1, submitQueueSize, "Shard[" + prefix + "]",
- InMemoryDOMDataTreeShard.class);
- fte.setRejectedExecutionHandler(CountingRejectedExecutionHandler.newCallerWaitsPolicy());
- this.executor = MoreExecutors.listeningDecorator(fte);
- }
-
- public static InMemoryDOMDataTreeShard create(final DOMDataTreeIdentifier id,
- final Executor dataTreeChangeExecutor,
- final int maxDataChangeListenerQueueSize) {
- return new InMemoryDOMDataTreeShard(id.toOptimized(), dataTreeChangeExecutor,
- maxDataChangeListenerQueueSize, DEFAULT_SUBMIT_QUEUE_SIZE);
- }
-
- public static InMemoryDOMDataTreeShard create(final DOMDataTreeIdentifier id,
- final Executor dataTreeChangeExecutor,
- final int maxDataChangeListenerQueueSize,
- final int submitQueueSize) {
- return new InMemoryDOMDataTreeShard(id.toOptimized(), dataTreeChangeExecutor,
- maxDataChangeListenerQueueSize, submitQueueSize);
- }
-
- @Override
- public void onModelContextUpdated(final EffectiveModelContext newModelContext) {
- dataTree.setEffectiveModelContext(newModelContext);
- }
-
- @Override
- public void onChildAttached(final DOMDataTreeIdentifier childPrefix, final DOMDataTreeShard child) {
- checkArgument(child != this, "Attempted to attach child %s onto self", this);
- reparentChildShards(childPrefix, child);
-
- final ChildShardContext context = createContextFor(childPrefix, child);
- childShards.put(childPrefix, context);
- childShardsTable.store(childPrefix, context);
- updateProducers();
- }
-
- @Override
- public void onChildDetached(final DOMDataTreeIdentifier childPrefix, final DOMDataTreeShard child) {
- childShards.remove(childPrefix);
- childShardsTable.remove(childPrefix);
- //FIXME: Producers not being affected could be skipped over.
- updateProducers();
- }
-
- private void updateProducers() {
- for (InMemoryDOMDataTreeShardProducer p : producers) {
- p.setModificationFactory(createModificationFactory(p.getPrefixes()));
- }
- }
-
- @VisibleForTesting
- InMemoryShardDataModificationFactory createModificationFactory(final Collection<DOMDataTreeIdentifier> prefixes) {
- final Map<DOMDataTreeIdentifier, SubshardProducerSpecification> affected = new HashMap<>();
- for (final DOMDataTreeIdentifier producerPrefix : prefixes) {
- for (final ChildShardContext child : childShards.values()) {
- final DOMDataTreeIdentifier bindPath;
- if (producerPrefix.contains(child.getPrefix())) {
- bindPath = child.getPrefix();
- } else if (child.getPrefix().contains(producerPrefix)) {
- // Bound path is inside subshard
- bindPath = producerPrefix;
- } else {
- continue;
- }
-
- SubshardProducerSpecification spec = affected.get(child.getPrefix());
- if (spec == null) {
- spec = new SubshardProducerSpecification(child);
- affected.put(child.getPrefix(), spec);
- }
- spec.addPrefix(bindPath);
- }
- }
-
- final InmemoryShardDataModificationFactoryBuilder builder =
- new InmemoryShardDataModificationFactoryBuilder(prefix);
- for (final SubshardProducerSpecification spec : affected.values()) {
- final ForeignShardModificationContext foreignContext =
- new ForeignShardModificationContext(spec.getPrefix(), spec.createProducer());
- builder.addSubshard(foreignContext);
- builder.addSubshard(spec.getPrefix(), foreignContext);
- }
-
- return builder.build();
- }
-
- @Override
- public InMemoryDOMDataTreeShardProducer createProducer(final Collection<DOMDataTreeIdentifier> prefixes) {
- for (final DOMDataTreeIdentifier prodPrefix : prefixes) {
- checkArgument(prefix.contains(prodPrefix), "Prefix %s is not contained under shard root", prodPrefix,
- prefix);
- }
-
- final InMemoryDOMDataTreeShardProducer ret = new InMemoryDOMDataTreeShardProducer(this, prefixes,
- createModificationFactory(prefixes));
- producers.add(ret);
- return ret;
- }
-
- void closeProducer(final InMemoryDOMDataTreeShardProducer producer) {
- synchronized (this) {
- if (!producers.remove(producer)) {
- LOG.warn("Producer {} not found in shard {}", producer, this);
- }
- }
- }
-
- @Override
- public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerTreeChangeListener(
- final YangInstanceIdentifier treeId, final L listener) {
- return shardChangePublisher.registerTreeChangeListener(treeId, listener);
- }
-
- private void reparentChildShards(final DOMDataTreeIdentifier newChildPrefix, final DOMDataTreeShard newChild) {
- final Iterator<Entry<DOMDataTreeIdentifier, ChildShardContext>> actualChildren =
- childShards.entrySet().iterator();
- final Map<DOMDataTreeIdentifier, ChildShardContext> reparented = new HashMap<>();
- while (actualChildren.hasNext()) {
- final Entry<DOMDataTreeIdentifier, ChildShardContext> actualChild = actualChildren.next();
- final DOMDataTreeIdentifier actualPrefix = actualChild.getKey();
- checkArgument(!newChildPrefix.equals(actualPrefix), "Child shard with prefix %s already attached",
- newChildPrefix);
- if (newChildPrefix.contains(actualPrefix)) {
- final ChildShardContext actualContext = actualChild.getValue();
- actualChildren.remove();
- newChild.onChildAttached(actualPrefix, actualContext.getShard());
- reparented.put(actualChild.getKey(), actualContext);
- childShardsTable.remove(actualPrefix);
- }
- }
- updateProducersAndListeners(reparented);
- }
-
- private void updateProducersAndListeners(final Map<DOMDataTreeIdentifier, ChildShardContext> reparented) {
- // FIXME: remove reparenting of producers, shards have to be registered from top to bottom
- if (reparented.isEmpty()) {
- //nothing was reparented no need to update anything
- return;
- }
- throw new UnsupportedOperationException();
- }
-
- private static ChildShardContext createContextFor(final DOMDataTreeIdentifier prefix,
- final DOMDataTreeShard child) {
- checkArgument(child instanceof WriteableDOMDataTreeShard, "Child %s is not a writable shared", child);
- return new ChildShardContext(prefix, (WriteableDOMDataTreeShard) child);
- }
-
- private static DataTreeConfiguration treeTypeFor(final LogicalDatastoreType dsType) {
- switch (dsType) {
- case CONFIGURATION:
- return DataTreeConfiguration.DEFAULT_CONFIGURATION;
- case OPERATIONAL:
- return DataTreeConfiguration.DEFAULT_OPERATIONAL;
- default:
- throw new IllegalArgumentException("Unsupported Data Store type:" + dsType);
- }
- }
-
- @VisibleForTesting
- Map<DOMDataTreeIdentifier, DOMDataTreeShard> getChildShards() {
- return ImmutableMap.copyOf(Maps.transformValues(childShards, ChildShardContext::getShard));
- }
-
- DataTreeSnapshot takeSnapshot() {
- return dataTree.takeSnapshot();
- }
-
- InmemoryDOMDataTreeShardWriteTransaction createTransaction(final String transactionId,
- final InMemoryDOMDataTreeShardProducer producer, final DataTreeSnapshot snapshot) {
- checkArgument(snapshot instanceof CursorAwareDataTreeSnapshot);
- return new InmemoryDOMDataTreeShardWriteTransaction(producer,
- producer.getModificationFactory().createModification((CursorAwareDataTreeSnapshot) snapshot), dataTree,
- shardChangePublisher, executor);
- }
-
- @VisibleForTesting
- public Collection<InMemoryDOMDataTreeShardProducer> getProducers() {
- return producers;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.AbstractDOMDataTreeChangeListenerRegistration;
-import org.opendaylight.mdsal.dom.spi.shard.ChildShardContext;
-import org.opendaylight.yangtools.util.concurrent.QueuedNotificationManager;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class InMemoryDOMDataTreeShardChangePublisher extends AbstractDOMShardTreeChangePublisher {
-
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataTreeShardChangePublisher.class);
-
- private final QueuedNotificationManager<AbstractDOMDataTreeChangeListenerRegistration<?>, DataTreeCandidate>
- notificationManager;
-
- InMemoryDOMDataTreeShardChangePublisher(final Executor executor,
- final int maxQueueSize,
- final DataTree dataTree,
- final YangInstanceIdentifier rootPath,
- final Map<DOMDataTreeIdentifier, ChildShardContext> childShards) {
- super(dataTree, rootPath, childShards);
- notificationManager = QueuedNotificationManager.create(executor, (listener, notifications) -> {
- if (!listener.isClosed()) {
- listener.getInstance().onDataTreeChanged(notifications);
- }
- }, maxQueueSize, "DataTreeChangeListenerQueueMgr");
- }
-
- @Override
- protected void notifyListener(final AbstractDOMDataTreeChangeListenerRegistration<?> registration,
- final Collection<DataTreeCandidate> changes) {
- LOG.debug("Enqueueing candidates {} for registration {}", changes, registration);
- notificationManager.submitNotifications(registration, changes);
- }
-
- @Override
- protected void registrationRemoved(final AbstractDOMDataTreeChangeListenerRegistration<?> registration) {
- LOG.debug("Closing registration {}", registration);
-
- }
-
- synchronized void publishChange(final DataTreeCandidate candidate) {
- processCandidateTree(candidate);
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer {
-
- private abstract static class State {
- /**
- * Allocate a new snapshot.
- *
- * @return A new snapshot
- */
- protected abstract DataTreeSnapshot getSnapshot(Object transactionId);
- }
-
- private static final class Idle extends State {
- private final InMemoryDOMDataTreeShardProducer producer;
-
- Idle(final InMemoryDOMDataTreeShardProducer producer) {
- this.producer = requireNonNull(producer);
- }
-
- @Override
- protected DataTreeSnapshot getSnapshot(final Object transactionId) {
- return producer.takeSnapshot();
- }
- }
-
- /**
- * We have a transaction out there.
- */
- private static final class Allocated extends State {
- private static final AtomicReferenceFieldUpdater<Allocated, DataTreeSnapshot> SNAPSHOT_UPDATER =
- AtomicReferenceFieldUpdater.newUpdater(Allocated.class, DataTreeSnapshot.class, "snapshot");
- private final InmemoryDOMDataTreeShardWriteTransaction transaction;
- private volatile DataTreeSnapshot snapshot;
-
- Allocated(final InmemoryDOMDataTreeShardWriteTransaction transaction) {
- this.transaction = requireNonNull(transaction);
- }
-
- InmemoryDOMDataTreeShardWriteTransaction getTransaction() {
- return transaction;
- }
-
- @Override
- protected DataTreeSnapshot getSnapshot(final Object transactionId) {
- final DataTreeSnapshot ret = snapshot;
- checkState(ret != null,
- "Could not get snapshot for transaction %s - previous transaction %s is not ready yet",
- transactionId, transaction.getIdentifier());
- return ret;
- }
-
- void setSnapshot(final DataTreeSnapshot snapshot) {
- final boolean success = SNAPSHOT_UPDATER.compareAndSet(this, null, snapshot);
- checkState(success, "Transaction %s has already been marked as ready",
- transaction.getIdentifier());
- }
- }
-
- /**
- * Producer is logically shut down, no further allocation allowed.
- */
- private static final class Shutdown extends State {
- private final String message;
-
- Shutdown(final String message) {
- this.message = requireNonNull(message);
- }
-
- @Override
- protected DataTreeSnapshot getSnapshot(final Object transactionId) {
- throw new IllegalStateException(message);
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataTreeShardProducer.class);
- private static final AtomicLong COUNTER = new AtomicLong();
-
- private final InMemoryDOMDataTreeShard parentShard;
- private final Collection<DOMDataTreeIdentifier> prefixes;
- private final Idle idleState = new Idle(this);
-
- private static final AtomicReferenceFieldUpdater<InMemoryDOMDataTreeShardProducer, State> STATE_UPDATER =
- AtomicReferenceFieldUpdater.newUpdater(InMemoryDOMDataTreeShardProducer.class, State.class, "state");
- private volatile State state;
-
- private InMemoryShardDataModificationFactory modificationFactory;
-
- InMemoryDOMDataTreeShardProducer(final InMemoryDOMDataTreeShard parentShard,
- final Collection<DOMDataTreeIdentifier> prefixes,
- final InMemoryShardDataModificationFactory modificationFactory) {
- this.parentShard = requireNonNull(parentShard);
- this.prefixes = ImmutableSet.copyOf(prefixes);
- this.modificationFactory = requireNonNull(modificationFactory);
- state = idleState;
- }
-
- @Override
- public InmemoryDOMDataTreeShardWriteTransaction createTransaction() {
- final String transactionId = nextIdentifier();
-
- State localState;
- InmemoryDOMDataTreeShardWriteTransaction ret;
- do {
- localState = state;
- ret = parentShard.createTransaction(transactionId, this, localState.getSnapshot(transactionId));
- } while (!STATE_UPDATER.compareAndSet(this, localState, new Allocated(ret)));
-
- return ret;
- }
-
- @Override
- public void close() {
- final Shutdown shutdown = new Shutdown("Producer closed");
- if (!STATE_UPDATER.compareAndSet(this, idleState, shutdown)) {
- throw new IllegalStateException("Producer " + this + " in unexpected state " + state);
- }
-
- // FIXME: This call is ugly, it's better to clean up all by exposing only one entrance,
- // 'closeProducer' of shard or this 'close'.
- getParentShard().closeProducer(this);
- getModificationFactory().close();
- }
-
- void transactionReady(final InmemoryDOMDataTreeShardWriteTransaction tx, final DataTreeModification modification) {
- final State localState = state;
- LOG.debug("Transaction was readied {}, current state {}", tx.getIdentifier(), localState);
-
- if (localState instanceof Allocated) {
- final Allocated allocated = (Allocated) localState;
- final InmemoryDOMDataTreeShardWriteTransaction transaction = allocated.getTransaction();
- checkState(tx.equals(transaction), "Mis-ordered ready transaction %s last allocated was %s", tx,
- transaction);
- allocated.setSnapshot(modification);
- } else {
- LOG.debug("Ignoring transaction {} readiness due to state {}", tx, localState);
- }
- }
-
- /**
- * Notify the base logic that a previously-submitted transaction has been committed successfully.
- *
- * @param transaction Transaction which completed successfully.
- */
- void onTransactionCommited(final InmemoryDOMDataTreeShardWriteTransaction transaction) {
- // If the committed transaction was the one we allocated last,
- // we clear it and the ready snapshot, so the next transaction
- // allocated refers to the data tree directly.
- final State localState = state;
- LOG.debug("Transaction {} commit done, current state {}", transaction.getIdentifier(), localState);
-
- if (!(localState instanceof Allocated)) {
- // This can legally happen if the chain is shut down before the transaction was committed
- // by the backend.
- LOG.debug("Ignoring successful transaction {} in state {}", transaction, localState);
- return;
- }
-
- final Allocated allocated = (Allocated) localState;
- final InmemoryDOMDataTreeShardWriteTransaction tx = allocated.getTransaction();
- if (!tx.equals(transaction)) {
- LOG.debug("Ignoring non-latest successful transaction {} in state {}", transaction, allocated);
- return;
- }
-
- if (!STATE_UPDATER.compareAndSet(this, localState, idleState)) {
- LOG.debug("Producer {} has already transitioned from {} to {}, not making it idle", this,
- localState, state);
- }
- }
-
- void transactionAborted(final InmemoryDOMDataTreeShardWriteTransaction tx) {
- final State localState = state;
- if (localState instanceof Allocated) {
- final Allocated allocated = (Allocated) localState;
- if (allocated.getTransaction().equals(tx)) {
- final boolean success = STATE_UPDATER.compareAndSet(this, localState, idleState);
- if (!success) {
- LOG.warn("Transaction {} aborted, but producer {} state already transitioned from {} to {}",
- tx, this, localState, state);
- }
- }
- }
- }
-
- private static String nextIdentifier() {
- return "INMEMORY-SHARD-TX-" + COUNTER.getAndIncrement();
- }
-
- DataTreeSnapshot takeSnapshot() {
- return parentShard.takeSnapshot();
- }
-
- @Override
- public Collection<DOMDataTreeIdentifier> getPrefixes() {
- return prefixes;
- }
-
- @NonNull InMemoryDOMDataTreeShard getParentShard() {
- return parentShard;
- }
-
- InMemoryShardDataModificationFactory getModificationFactory() {
- return modificationFactory;
- }
-
- void setModificationFactory(final InMemoryShardDataModificationFactory modificationFactory) {
- this.getModificationFactory().close();
- this.modificationFactory = requireNonNull(modificationFactory);
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class InMemoryDOMDataTreeShardThreePhaseCommitCohort implements DOMStoreThreePhaseCommitCohort {
-
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataTreeShardThreePhaseCommitCohort.class);
- private static final ListenableFuture<Void> SUCCESSFUL_FUTURE = Futures.immediateFuture(null);
- private static final ListenableFuture<Boolean> CAN_COMMIT_FUTURE = Futures.immediateFuture(Boolean.TRUE);
-
- private final DataTree dataTree;
- private final DataTreeModification modification;
- private DataTreeCandidate candidate;
- private final InMemoryDOMDataTreeShardChangePublisher changePublisher;
-
- InMemoryDOMDataTreeShardThreePhaseCommitCohort(final DataTree dataTree,
- final DataTreeModification modification,
- final InMemoryDOMDataTreeShardChangePublisher changePublisher) {
- this.dataTree = requireNonNull(dataTree);
- this.modification = requireNonNull(modification);
- this.changePublisher = requireNonNull(changePublisher);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public ListenableFuture<Boolean> canCommit() {
- try {
- dataTree.validate(modification);
- LOG.debug("DataTreeModification {} validated", modification);
-
- return CAN_COMMIT_FUTURE;
- } catch (DataValidationFailedException e) {
- LOG.warn("Data validation failed for {}", modification);
- LOG.trace("dataTree : {}", dataTree);
-
- return Futures.immediateFailedFuture(new TransactionCommitFailedException(
- "Data did not pass validation.", e));
- } catch (Exception e) {
- LOG.warn("Unexpected failure in validation phase", e);
- return Futures.immediateFailedFuture(e);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- @Override
- public ListenableFuture<Void> preCommit() {
- try {
- candidate = dataTree.prepare(modification);
- LOG.debug("DataTreeModification {} prepared", modification);
- return SUCCESSFUL_FUTURE;
- } catch (Exception e) {
- LOG.warn("Unexpected failure in preparation phase", e);
- return Futures.immediateFailedFuture(e);
- }
- }
-
- @Override
- public ListenableFuture<Void> abort() {
- candidate = null;
- return SUCCESSFUL_FUTURE;
- }
-
- @Override
- public ListenableFuture<Void> commit() {
- Preconditions.checkState(candidate != null, "Attempted to commit an aborted transaction");
- LOG.debug("Commiting candidate {}", candidate);
- dataTree.commit(candidate);
- // publish this change for listeners
- changePublisher.publishChange(candidate);
- return SUCCESSFUL_FUTURE;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import org.opendaylight.mdsal.dom.spi.shard.AbstractDataModificationCursor;
-import org.opendaylight.mdsal.dom.spi.shard.WriteCursorStrategy;
-
-class InMemoryShardDataModificationCursor extends AbstractDataModificationCursor<ShardDataModification> {
-
- private InmemoryDOMDataTreeShardWriteTransaction parent;
-
- InMemoryShardDataModificationCursor(final ShardDataModification root,
- final InmemoryDOMDataTreeShardWriteTransaction parent) {
- super(root);
- this.parent = requireNonNull(parent);
- }
-
- @Override
- protected WriteCursorStrategy getRootOperation(final ShardDataModification root) {
- return root.createOperation(null);
- }
-
- @Override
- public void close() {
- parent.cursorClosed();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardProducer;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableModificationNode;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-
-final class InMemoryShardDataModificationFactory {
- private final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> childShards;
- private final Map<PathArgument, WriteableModificationNode> children;
- private final DOMDataTreeIdentifier root;
-
- InMemoryShardDataModificationFactory(
- final DOMDataTreeIdentifier root,
- final Map<PathArgument, WriteableModificationNode> children,
- final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> childShards) {
- this.root = requireNonNull(root);
- this.children = ImmutableMap.copyOf(children);
- this.childShards = ImmutableMap.copyOf(childShards);
- }
-
- @VisibleForTesting
- Map<PathArgument, WriteableModificationNode> getChildren() {
- return children;
- }
-
- @VisibleForTesting
- Map<DOMDataTreeIdentifier, ForeignShardModificationContext> getChildShards() {
- return childShards;
- }
-
- ShardDataModification createModification(final CursorAwareDataTreeSnapshot snapshot) {
- return new ShardDataModification(new ShardRootModificationContext(root, snapshot), children, childShards);
- }
-
- void close() {
- childShards.values().stream().map(ForeignShardModificationContext::getProducer)
- .forEach(DOMDataTreeShardProducer::close);
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicLong;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.DOMDataTreeShardWriteTransaction;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardThreePhaseCommitCohort;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class InmemoryDOMDataTreeShardWriteTransaction implements DOMDataTreeShardWriteTransaction, Identifiable<String> {
-
- private static final Logger LOG = LoggerFactory.getLogger(InmemoryDOMDataTreeShardWriteTransaction.class);
-
- private enum SimpleCursorOperation {
- MERGE {
- @Override
- void applyOnLeaf(final DOMDataTreeWriteCursor cur, final PathArgument child,
- final NormalizedNode<?, ?> data) {
- cur.merge(child, data);
- }
- },
- DELETE {
- @Override
- void applyOnLeaf(final DOMDataTreeWriteCursor cur, final PathArgument child,
- final NormalizedNode<?, ?> data) {
- cur.delete(child);
- }
- },
- WRITE {
- @Override
- void applyOnLeaf(final DOMDataTreeWriteCursor cur, final PathArgument child,
- final NormalizedNode<?, ?> data) {
- cur.write(child, data);
- }
- };
-
- abstract void applyOnLeaf(DOMDataTreeWriteCursor cur, PathArgument child, NormalizedNode<?, ?> data);
-
- void apply(final DOMDataTreeWriteCursor cur, final YangInstanceIdentifier path,
- final NormalizedNode<?, ?> data) {
- int enterCount = 0;
- final Iterator<PathArgument> it = path.getPathArguments().iterator();
- if (it.hasNext()) {
- while (true) {
- final PathArgument currentArg = it.next();
- if (!it.hasNext()) {
- applyOnLeaf(cur, currentArg, data);
- break;
- }
-
- // We need to enter one level deeper, we are not at leaf (modified) node
- cur.enter(currentArg);
- enterCount++;
- }
- }
-
- cur.exit(enterCount);
- }
- }
-
- private static final AtomicLong COUNTER = new AtomicLong();
-
- private final ArrayList<DOMStoreThreePhaseCommitCohort> cohorts = new ArrayList<>();
- private final InMemoryDOMDataTreeShardChangePublisher changePublisher;
- private final InMemoryDOMDataTreeShardProducer producer;
- private final ShardDataModification modification;
- private final ListeningExecutorService executor;
- private final DataTree rootShardDataTree;
- private final String identifier;
-
- private DataTreeModification rootModification = null;
- private DOMDataTreeWriteCursor cursor;
- private boolean finished = false;
-
- InmemoryDOMDataTreeShardWriteTransaction(final InMemoryDOMDataTreeShardProducer producer,
- final ShardDataModification root,
- final DataTree rootShardDataTree,
- final InMemoryDOMDataTreeShardChangePublisher changePublisher,
- final ListeningExecutorService executor) {
- this.producer = producer;
- this.modification = requireNonNull(root);
- this.rootShardDataTree = requireNonNull(rootShardDataTree);
- this.changePublisher = requireNonNull(changePublisher);
- this.identifier = "INMEMORY-SHARD-TX-" + COUNTER.getAndIncrement();
- LOG.debug("Shard transaction{} created", identifier);
- this.executor = executor;
- }
-
- @Override
- public String getIdentifier() {
- return identifier;
- }
-
- private DOMDataTreeWriteCursor getCursor() {
- if (cursor == null) {
- cursor = new InMemoryShardDataModificationCursor(modification, this);
- }
- return cursor;
- }
-
- void delete(final YangInstanceIdentifier path) {
- final YangInstanceIdentifier relativePath = toRelative(path);
- checkArgument(!relativePath.isEmpty(), "Deletion of shard root is not allowed");
- SimpleCursorOperation.DELETE.apply(getCursor(), relativePath, null);
- }
-
- void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- SimpleCursorOperation.MERGE.apply(getCursor(), toRelative(path), data);
- }
-
- void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- SimpleCursorOperation.WRITE.apply(getCursor(), toRelative(path), data);
- }
-
- private YangInstanceIdentifier toRelative(final YangInstanceIdentifier path) {
- final Optional<YangInstanceIdentifier> relative =
- path.relativeTo(modification.getPrefix().getRootIdentifier());
- checkArgument(relative.isPresent());
- return relative.get();
- }
-
- @Override
- public void close() {
- checkState(!finished, "Attempting to close an already finished transaction.");
- modification.closeTransactions();
- if (cursor != null) {
- cursor.close();
- }
- producer.transactionAborted(this);
- finished = true;
- }
-
- void cursorClosed() {
- requireNonNull(cursor);
- modification.closeCursor();
- cursor = null;
- }
-
- public boolean isFinished() {
- return finished;
- }
-
- @Override
- public void ready() {
- checkState(!finished, "Attempting to ready an already finished transaction.");
- checkState(cursor == null, "Attempting to ready a transaction that has an open cursor.");
- requireNonNull(modification, "Attempting to ready an empty transaction.");
-
- LOG.debug("Readying open transaction on shard {}", modification.getPrefix());
- rootModification = modification.seal();
-
- producer.transactionReady(this, rootModification);
- cohorts.add(new InMemoryDOMDataTreeShardThreePhaseCommitCohort(
- rootShardDataTree, rootModification, changePublisher));
- for (final Entry<DOMDataTreeIdentifier, ForeignShardModificationContext> entry :
- modification.getChildShards().entrySet()) {
- cohorts.add(new ForeignShardThreePhaseCommitCohort(entry.getKey(), entry.getValue()));
- }
- finished = true;
- }
-
- @Override
- public ListenableFuture<Void> submit() {
- LOG.debug("Submitting open transaction on shard {}", modification.getPrefix());
-
- requireNonNull(cohorts);
- checkState(!cohorts.isEmpty(), "Transaction was not readied yet.");
-
- return executor.submit(new ShardSubmitCoordinationTask(modification.getPrefix(), cohorts, this));
- }
-
- @Override
- public ListenableFuture<Boolean> validate() {
- LOG.debug("CanCommit on open transaction on shard {}", modification.getPrefix());
- return executor.submit(new ShardCanCommitCoordinationTask(modification.getPrefix(), cohorts));
- }
-
- @Override
- public ListenableFuture<Void> prepare() {
- LOG.debug("PreCommit on open transaction on shard {}", modification.getPrefix());
- return executor.submit(new ShardPreCommitCoordinationTask(modification.getPrefix(), cohorts));
- }
-
- @Override
- public ListenableFuture<Void> commit() {
- LOG.debug("Commit open transaction on shard {}", modification.getPrefix());
- return executor.submit(new ShardCommitCoordinationTask(modification.getPrefix(), cohorts, this));
- }
-
- DataTreeModification getRootModification() {
- requireNonNull(rootModification, "Transaction wasn't sealed yet");
- return rootModification;
- }
-
- void transactionCommited(final InmemoryDOMDataTreeShardWriteTransaction tx) {
- producer.onTransactionCommited(tx);
- }
-
- @Override
- public DOMDataTreeWriteCursor createCursor(final DOMDataTreeIdentifier prefix) {
- checkState(!finished, "Transaction is finished/closed already.");
- checkState(cursor == null, "Previous cursor wasn't closed");
- final YangInstanceIdentifier relativePath = toRelative(prefix.getRootIdentifier());
- final DOMDataTreeWriteCursor ret = getCursor();
- ret.enter(relativePath.getPathArguments());
- return ret;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.shard.AbstractShardModificationFactoryBuilder;
-
-class InmemoryShardDataModificationFactoryBuilder
- extends AbstractShardModificationFactoryBuilder<InMemoryShardDataModificationFactory> {
-
- InmemoryShardDataModificationFactoryBuilder(final DOMDataTreeIdentifier root) {
- super(root);
- }
-
- @Override
- public InMemoryShardDataModificationFactory build() {
- return new InMemoryShardDataModificationFactory(root, buildChildren(), childShards);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Task that coordinates the CanCommit phase of the provided {@link DOMStoreThreePhaseCommitCohort}'s.
- */
-@Beta
-public class ShardCanCommitCoordinationTask implements Callable<Boolean> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ShardCanCommitCoordinationTask.class);
-
- private final DOMDataTreeIdentifier rootShardPrefix;
- private final Collection<DOMStoreThreePhaseCommitCohort> cohorts;
-
- public ShardCanCommitCoordinationTask(final DOMDataTreeIdentifier rootShardPrefix,
- final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
- this.rootShardPrefix = requireNonNull(rootShardPrefix);
- this.cohorts = requireNonNull(cohorts);
- }
-
- @Override
- public Boolean call() throws TransactionCommitFailedException {
-
- try {
- LOG.debug("Shard {}, canCommit started", rootShardPrefix);
- canCommitBlocking();
-
- return true;
- } catch (final TransactionCommitFailedException e) {
- LOG.warn("Shard: {} Submit Error during phase CanCommit, starting Abort", rootShardPrefix, e);
- //FIXME abort here
- throw e;
- }
- }
-
- void canCommitBlocking() throws TransactionCommitFailedException {
- for (final ListenableFuture<?> canCommit : canCommitAll()) {
- try {
- final Boolean result = (Boolean)canCommit.get();
- if (result == null || !result) {
- throw new TransactionCommitFailedException("CanCommit failed, no detailed cause available.");
- }
- } catch (InterruptedException | ExecutionException e) {
- throw new TransactionCommitFailedException("CanCommit failed", e);
- }
- }
- }
-
- private ListenableFuture<?>[] canCommitAll() {
- final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
- int index = 0;
- for (final DOMStoreThreePhaseCommitCohort cohort : cohorts) {
- ops[index++] = cohort.canCommit();
- }
- return ops;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Task that coordinates the Commit phase of the provided {@link DOMStoreThreePhaseCommitCohort}'s.
- */
-@Beta
-public class ShardCommitCoordinationTask implements Callable<Void> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ShardCommitCoordinationTask.class);
-
- private final DOMDataTreeIdentifier rootShardPrefix;
- private final Collection<DOMStoreThreePhaseCommitCohort> cohorts;
- private InmemoryDOMDataTreeShardWriteTransaction transaction;
-
- public ShardCommitCoordinationTask(final DOMDataTreeIdentifier rootShardPrefix,
- final Collection<DOMStoreThreePhaseCommitCohort> cohorts,
- final InmemoryDOMDataTreeShardWriteTransaction transaction) {
- this.rootShardPrefix = requireNonNull(rootShardPrefix);
- this.cohorts = requireNonNull(cohorts);
- this.transaction = requireNonNull(transaction);
- }
-
- @Override
- public Void call() throws TransactionCommitFailedException {
-
- try {
- LOG.debug("Shard {}, commit started", rootShardPrefix);
- commitBlocking();
- transaction.transactionCommited(transaction);
-
- return null;
- } catch (final TransactionCommitFailedException e) {
- LOG.warn("Shard: {} Submit Error during phase Commit, starting Abort", rootShardPrefix, e);
- //FIXME abort here
- throw e;
- }
- }
-
- void commitBlocking() throws TransactionCommitFailedException {
- for (final ListenableFuture<?> commit : commitAll()) {
- try {
- commit.get();
- } catch (InterruptedException | ExecutionException e) {
- throw new TransactionCommitFailedException("Commit failed", e);
- }
- }
- }
-
- private ListenableFuture<?>[] commitAll() {
- final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
- int index = 0;
- for (final DOMStoreThreePhaseCommitCohort cohort : cohorts) {
- ops[index++] = cohort.commit();
- }
- return ops;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.WritableNodeOperation;
-import org.opendaylight.mdsal.dom.spi.shard.WriteCursorStrategy;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableModificationNode;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableNodeWithSubshard;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-
-public final class ShardDataModification extends WriteableNodeWithSubshard {
-
- private final ShardRootModificationContext rootContext;
- private final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> childShards;
-
- ShardDataModification(final ShardRootModificationContext boundary,
- final Map<PathArgument, WriteableModificationNode> subshards,
- final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> childShards) {
- super(subshards);
- this.rootContext = requireNonNull(boundary);
- this.childShards = ImmutableMap.copyOf(childShards);
- }
-
- @Override
- public WriteCursorStrategy createOperation(final DOMDataTreeWriteCursor parentCursor) {
- return new WritableNodeOperation(this, rootContext.cursor()) {
- @Override
- public void exit() {
- throw new IllegalStateException("Can not exit data tree root");
- }
- };
- }
-
- @Override
- public PathArgument getIdentifier() {
- return rootContext.getIdentifier().getRootIdentifier().getLastPathArgument();
- }
-
- DOMDataTreeIdentifier getPrefix() {
- return rootContext.getIdentifier();
- }
-
- Map<DOMDataTreeIdentifier, ForeignShardModificationContext> getChildShards() {
- return childShards;
- }
-
- DataTreeModification seal() {
- final DataTreeModification rootModification = rootContext.ready();
- for (ForeignShardModificationContext childShard : childShards.values()) {
- childShard.ready();
- }
-
- return rootModification;
- }
-
- void closeTransactions() {
- for (final ForeignShardModificationContext childShard : childShards.values()) {
- childShard.closeForeignTransaction();
- }
- }
-
- void closeCursor() {
- rootContext.closeCursor();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Task that coordinates the PreCommit phase of the provided {@link DOMStoreThreePhaseCommitCohort}'s.
- */
-@Beta
-public class ShardPreCommitCoordinationTask implements Callable<Void> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ShardPreCommitCoordinationTask.class);
-
- private final DOMDataTreeIdentifier rootShardPrefix;
- private final Collection<DOMStoreThreePhaseCommitCohort> cohorts;
-
- public ShardPreCommitCoordinationTask(final DOMDataTreeIdentifier rootShardPrefix,
- final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
- this.rootShardPrefix = requireNonNull(rootShardPrefix);
- this.cohorts = requireNonNull(cohorts);
- }
-
- @Override
- public Void call() throws TransactionCommitFailedException {
-
- try {
- LOG.debug("Shard {}, preCommit started", rootShardPrefix);
- preCommitBlocking();
-
- return null;
- } catch (final TransactionCommitFailedException e) {
- LOG.warn("Shard: {} Submit Error during phase PreCommit, starting Abort", rootShardPrefix, e);
- //FIXME abort here
- throw e;
- }
- }
-
- void preCommitBlocking() throws TransactionCommitFailedException {
- for (final ListenableFuture<?> preCommit : preCommitAll()) {
- try {
- preCommit.get();
- } catch (InterruptedException | ExecutionException e) {
- throw new TransactionCommitFailedException("PreCommit failed", e);
- }
- }
- }
-
- private ListenableFuture<?>[] preCommitAll() {
- final ListenableFuture<?>[] ops = new ListenableFuture<?>[cohorts.size()];
- int index = 0;
- for (final DOMStoreThreePhaseCommitCohort cohort : cohorts) {
- ops[index++] = cohort.preCommit();
- }
- return ops;
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-// Non-final for mocking
-class ShardRootModificationContext implements Identifiable<DOMDataTreeIdentifier> {
-
- private final DOMDataTreeIdentifier identifier;
- private final CursorAwareDataTreeSnapshot snapshot;
-
- private CursorAwareDataTreeModification modification = null;
- private DataTreeModificationCursorAdaptor cursor = null;
-
- ShardRootModificationContext(final DOMDataTreeIdentifier identifier,
- final CursorAwareDataTreeSnapshot snapshot) {
- this.identifier = requireNonNull(identifier);
- this.snapshot = requireNonNull(snapshot);
- }
-
- @Override
- public DOMDataTreeIdentifier getIdentifier() {
- return identifier;
- }
-
- DataTreeModificationCursorAdaptor cursor() {
- if (cursor == null) {
- if (modification == null) {
- modification = snapshot.newModification();
- }
-
- // FIXME: Should there be non-root path?
- DataTreeModificationCursor dataTreeCursor = modification.openCursor(YangInstanceIdentifier.empty()).get();
- cursor = DataTreeModificationCursorAdaptor.of(dataTreeCursor);
- }
- return cursor;
- }
-
- boolean isModified() {
- return modification != null;
- }
-
- DataTreeModification ready() {
- if (cursor != null) {
- cursor.close();
- cursor = null;
- }
- DataTreeModification ret = null;
- if (modification != null) {
- modification.ready();
- ret = modification;
- modification = null;
- }
-
- return ret;
- }
-
- void closeCursor() {
- cursor.close();
- cursor = null;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Task that coordinates all phases of transaction submit from the provided {@link DOMStoreThreePhaseCommitCohort}'s.
- * Each phase will only be started once all cohorts have finished the previous phase.
- */
-@Beta
-public class ShardSubmitCoordinationTask implements Callable<Void> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ShardSubmitCoordinationTask.class);
-
- private final DOMDataTreeIdentifier rootShardPrefix;
- private final ShardCanCommitCoordinationTask canCommitCoordinationTask;
- private final ShardPreCommitCoordinationTask preCommitCoordinationTask;
- private final ShardCommitCoordinationTask commitCoordinationTask;
- private final InmemoryDOMDataTreeShardWriteTransaction transaction;
-
-
- public ShardSubmitCoordinationTask(final DOMDataTreeIdentifier rootShardPrefix,
- final Collection<DOMStoreThreePhaseCommitCohort> cohorts,
- final InmemoryDOMDataTreeShardWriteTransaction transaction) {
- this.rootShardPrefix = requireNonNull(rootShardPrefix);
- this.transaction = transaction;
-
- canCommitCoordinationTask = new ShardCanCommitCoordinationTask(rootShardPrefix, cohorts);
- preCommitCoordinationTask = new ShardPreCommitCoordinationTask(rootShardPrefix, cohorts);
- commitCoordinationTask = new ShardCommitCoordinationTask(rootShardPrefix, cohorts, transaction);
- }
-
- @Override
- public Void call() throws TransactionCommitFailedException {
-
- LOG.debug("Shard {}, tx{} CanCommit started", transaction.getIdentifier(), rootShardPrefix);
- canCommitCoordinationTask.canCommitBlocking();
-
- LOG.debug("Shard {}, tx{} PreCommit started", transaction.getIdentifier(), rootShardPrefix);
- preCommitCoordinationTask.preCommitBlocking();
-
- LOG.debug("Shard {}, tx{} commit started", transaction.getIdentifier(), rootShardPrefix);
- commitCoordinationTask.commitBlocking();
-
- transaction.transactionCommited(transaction);
-
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DATA_TREE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Optional;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.AbstractDOMDataTreeChangeListenerRegistration;
-import org.opendaylight.mdsal.dom.spi.shard.ChildShardContext;
-import org.opendaylight.mdsal.dom.spi.shard.ReadableWriteableDOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-
-public class AbstractDOMShardTreeChangePublisherTest extends AbstractDOMShardTreeChangePublisher {
-
- private static final YangInstanceIdentifier YANG_INSTANCE_IDENTIFIER =
- YangInstanceIdentifier.of(QName.create("", "test"));
-
- private static final DOMDataTreeIdentifier DOM_DATA_TREE_IDENTIFIER =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YANG_INSTANCE_IDENTIFIER);
-
- private static final ReadableWriteableDOMDataTreeShard READABLE_WRITEABLE_DOM_DATA_TREE_SHARD =
- mock(ReadableWriteableDOMDataTreeShard.class);
-
- private static final ChildShardContext CHILD_SHARD_CONTEXT =
- new ChildShardContext(DOM_DATA_TREE_IDENTIFIER, READABLE_WRITEABLE_DOM_DATA_TREE_SHARD);
-
- private static final Map<DOMDataTreeIdentifier, ChildShardContext> CHILD_SHARDS =
- ImmutableMap.of(DOM_DATA_TREE_IDENTIFIER, CHILD_SHARD_CONTEXT);
-
- @Captor
- private ArgumentCaptor<Collection<DataTreeCandidate>> captorForChanges;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void registerTreeChangeListenerTest() throws Exception {
- final DOMDataTreeChangeListener domDataTreeChangeListener = mock(DOMDataTreeChangeListener.class);
- final ListenerRegistration<?> listenerRegistration = mock(ListenerRegistration.class);
- final DataTreeSnapshot initialSnapshot = mock(DataTreeSnapshot.class);
- final DataContainerNode<?> initialData =
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create("", "test")))
- .build();
- doReturn(initialSnapshot).when(DATA_TREE).takeSnapshot();
- doReturn(Optional.of(initialData)).when(initialSnapshot).readNode(any());
- doNothing().when(domDataTreeChangeListener).onDataTreeChanged(any());
-
- doReturn(listenerRegistration)
- .when(READABLE_WRITEABLE_DOM_DATA_TREE_SHARD).registerTreeChangeListener(any(), any());
-
- assertNotNull(this.registerTreeChangeListener(YANG_INSTANCE_IDENTIFIER, domDataTreeChangeListener));
- verify(READABLE_WRITEABLE_DOM_DATA_TREE_SHARD).registerTreeChangeListener(any(), any());
-
- verify(domDataTreeChangeListener)
- .onDataTreeChanged(captorForChanges.capture());
-
- final Collection<DataTreeCandidate> initialChange = captorForChanges.getValue();
-
- assertTrue(initialChange.size() == 1);
- initialChange.forEach(dataTreeCandidate ->
- assertEquals(dataTreeCandidate.getRootPath(), YANG_INSTANCE_IDENTIFIER));
- initialChange.forEach(dataTreeCandidate ->
- assertEquals(dataTreeCandidate.getRootNode().getModificationType(), ModificationType.UNMODIFIED));
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void registerTreeChangeListenerTestWithException() throws Exception {
- final DOMDataTreeChangeListener domDataTreeChangeListener = mock(DOMDataTreeChangeListener.class);
- final ListenerRegistration<?> listenerRegistration = mock(ListenerRegistration.class);
- doReturn(listenerRegistration)
- .when(READABLE_WRITEABLE_DOM_DATA_TREE_SHARD).registerTreeChangeListener(any(), any());
- final DOMDataTreeIdentifier domDataTreeIdentifier =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
- final ChildShardContext childShardContext =
- new ChildShardContext(domDataTreeIdentifier, READABLE_WRITEABLE_DOM_DATA_TREE_SHARD);
- final Map<DOMDataTreeIdentifier, ChildShardContext> childShardContextMap =
- ImmutableMap.of(domDataTreeIdentifier, childShardContext);
-
- final AbstractDOMShardTreeChangePublisherTest abstractDOMShardTreeChangePublisherTest =
- new AbstractDOMShardTreeChangePublisherTest(childShardContextMap);
- abstractDOMShardTreeChangePublisherTest
- .registerTreeChangeListener(YANG_INSTANCE_IDENTIFIER, domDataTreeChangeListener);
- }
-
- public AbstractDOMShardTreeChangePublisherTest() {
- super(DATA_TREE, YANG_INSTANCE_IDENTIFIER, CHILD_SHARDS);
- }
-
- private AbstractDOMShardTreeChangePublisherTest(
- final Map<DOMDataTreeIdentifier, ChildShardContext> childShardContextMap) {
- super(DATA_TREE, YANG_INSTANCE_IDENTIFIER, childShardContextMap);
- }
-
- @Override
- protected void notifyListener(final AbstractDOMDataTreeChangeListenerRegistration<?> registration,
- final Collection<DataTreeCandidate> changes) {
- // NOOP
- }
-
- @Override
- protected void registrationRemoved(final AbstractDOMDataTreeChangeListenerRegistration<?> registration) {
- // NOOP
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.PATH_ARGUMENT;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-public class DataTreeModificationCursorAdaptorTest {
-
- @Test
- public void basicTest() throws Exception {
- final DataTreeModificationCursor dataTreeModificationCursor = mock(DataTreeModificationCursor.class);
- final DataTreeModificationCursorAdaptor dataTreeModificationCursorAdaptor =
- DataTreeModificationCursorAdaptor.of(dataTreeModificationCursor);
- final Iterable<PathArgument> iterable = mock(Iterable.class);
- doReturn("test").when(PATH_ARGUMENT).toString();
-
- assertEquals(dataTreeModificationCursorAdaptor.delegate(), dataTreeModificationCursor);
-
- doNothing().when(dataTreeModificationCursor).delete(PATH_ARGUMENT);
- dataTreeModificationCursorAdaptor.delete(PATH_ARGUMENT);
- verify(dataTreeModificationCursor).delete(PATH_ARGUMENT);
-
- doNothing().when(dataTreeModificationCursor).enter(PATH_ARGUMENT);
- dataTreeModificationCursorAdaptor.enter(PATH_ARGUMENT);
- verify(dataTreeModificationCursor).enter(PATH_ARGUMENT);
-
- doNothing().when(dataTreeModificationCursor).enter(PATH_ARGUMENT, PATH_ARGUMENT);
- dataTreeModificationCursorAdaptor.enter(PATH_ARGUMENT, PATH_ARGUMENT);
- verify(dataTreeModificationCursor).enter(PATH_ARGUMENT, PATH_ARGUMENT);
-
- doNothing().when(dataTreeModificationCursor).enter(iterable);
- dataTreeModificationCursorAdaptor.enter(iterable);
- verify(dataTreeModificationCursor).enter(iterable);
-
- doNothing().when(dataTreeModificationCursor).merge(PATH_ARGUMENT, null);
- dataTreeModificationCursorAdaptor.merge(PATH_ARGUMENT,null);
- verify(dataTreeModificationCursor).merge(PATH_ARGUMENT, null);
-
- doNothing().when(dataTreeModificationCursor).write(PATH_ARGUMENT, null);
- dataTreeModificationCursorAdaptor.write(PATH_ARGUMENT, null);
- verify(dataTreeModificationCursor).write(PATH_ARGUMENT, null);
-
- doNothing().when(dataTreeModificationCursor).exit(1);
- dataTreeModificationCursorAdaptor.exit(1);
- verify(dataTreeModificationCursor).exit(1);
-
- doNothing().when(dataTreeModificationCursor).exit();
- dataTreeModificationCursorAdaptor.exit();
- verify(dataTreeModificationCursor).exit();
-
- doReturn(null).when(dataTreeModificationCursor).readNode(PATH_ARGUMENT);
- dataTreeModificationCursorAdaptor.readNode(PATH_ARGUMENT);
- verify(dataTreeModificationCursor).readNode(PATH_ARGUMENT);
-
- doNothing().when(dataTreeModificationCursor).close();
- dataTreeModificationCursorAdaptor.close();
- verify(dataTreeModificationCursor).close();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-
-public class InMemoryDOMDataTreeShardProducerTest {
-
- @Test
- public void basicTest() throws Exception {
- final InMemoryDOMDataTreeShard inMemoryDOMDataTreeShard = mock(InMemoryDOMDataTreeShard.class);
- final InmemoryDOMDataTreeShardWriteTransaction inmemoryDOMDataTreeShardWriteTransaction =
- mock(InmemoryDOMDataTreeShardWriteTransaction.class);
- final CursorAwareDataTreeSnapshot snapshot = mock(CursorAwareDataTreeSnapshot.class);
- doReturn(snapshot).when(inMemoryDOMDataTreeShard).takeSnapshot();
-
- doReturn(inmemoryDOMDataTreeShardWriteTransaction).when(inMemoryDOMDataTreeShard)
- .createTransaction(any(String.class), any(InMemoryDOMDataTreeShardProducer.class),
- any(CursorAwareDataTreeSnapshot.class));
-
- final InMemoryDOMDataTreeShardProducer inMemoryDOMDataTreeShardProducer =
- new InMemoryDOMDataTreeShardProducer(inMemoryDOMDataTreeShard,
- ImmutableSet.of(DOM_DATA_TREE_IDENTIFIER),
- new InMemoryShardDataModificationFactory(DOM_DATA_TREE_IDENTIFIER, ImmutableMap.of(),
- ImmutableMap.of()));
-
- assertNotNull(inMemoryDOMDataTreeShardProducer.createTransaction());
- verify(inMemoryDOMDataTreeShard).createTransaction(
- any(String.class),
- any(InMemoryDOMDataTreeShardProducer.class),
- any(CursorAwareDataTreeSnapshot.class));
- resetMocks();
- }
-}
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestModel.createTestContext;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_SHARD_PRODUCER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-
-public class InMemoryDOMDataTreeShardTest {
-
- @Test
- public void basicTest() {
- final InMemoryDOMDataTreeShard inMemoryDOMDataTreeShard =
- InMemoryDOMDataTreeShard.create(DOM_DATA_TREE_IDENTIFIER,
- MoreExecutors.directExecutor(), 1);
-
- final DOMDataTreeIdentifier domDataTreeIdentifier =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
- YangInstanceIdentifier.of(QName.create("", "Test")));
-
- final InMemoryDOMDataTreeShard domDataTreeShard = mock(InMemoryDOMDataTreeShard.class);
- doReturn("testReadableWriteableDOMDataTreeShard").when(domDataTreeShard).toString();
- doReturn(DOM_DATA_TREE_SHARD_PRODUCER).when(domDataTreeShard).createProducer(any());
- doReturn(domDataTreeShard).when(DOM_DATA_TREE_SHARD_PRODUCER).getParentShard();
- doNothing().when(DOM_DATA_TREE_SHARD_PRODUCER).close();
-
- assertFalse(inMemoryDOMDataTreeShard.getChildShards().containsValue(domDataTreeShard));
- inMemoryDOMDataTreeShard.onChildAttached(DOM_DATA_TREE_IDENTIFIER, domDataTreeShard);
- assertTrue(inMemoryDOMDataTreeShard.getChildShards().containsValue(domDataTreeShard));
- inMemoryDOMDataTreeShard.onChildAttached(domDataTreeIdentifier, domDataTreeShard);
-
- final Collection<DOMDataTreeIdentifier> prefixes = ImmutableList.of(DOM_DATA_TREE_IDENTIFIER);
- assertEquals(prefixes.toString(), inMemoryDOMDataTreeShard.createProducer(prefixes).getPrefixes().toString());
-
- final InMemoryDOMDataTreeShardProducer mockProducer = mock(InMemoryDOMDataTreeShardProducer.class);
- doReturn(prefixes).when(mockProducer).getPrefixes();
- doReturn(inMemoryDOMDataTreeShard.createModificationFactory(prefixes))
- .when(mockProducer).getModificationFactory();
-
- inMemoryDOMDataTreeShard.onModelContextUpdated(createTestContext());
- inMemoryDOMDataTreeShard.createTransaction("", mockProducer, mock(CursorAwareDataTreeSnapshot.class));
-
- final DOMDataTreeChangeListener domDataTreeChangeListener = mock(DOMDataTreeChangeListener.class);
- final ListenerRegistration<?> listenerRegistration = mock(ListenerRegistration.class);
- doReturn(listenerRegistration).when(domDataTreeShard).registerTreeChangeListener(any(), any());
- doNothing().when(domDataTreeChangeListener).onDataTreeChanged(any());
- inMemoryDOMDataTreeShard.registerTreeChangeListener(YangInstanceIdentifier.empty(), domDataTreeChangeListener);
- verify(domDataTreeShard, atLeastOnce()).registerTreeChangeListener(any(), any());
-
- inMemoryDOMDataTreeShard.onChildDetached(DOM_DATA_TREE_IDENTIFIER, domDataTreeShard);
- assertFalse(inMemoryDOMDataTreeShard.getChildShards().containsKey(DOM_DATA_TREE_IDENTIFIER));
- }
-
- @Test
- public void createTransactionWithException() {
- final DOMDataTreeIdentifier domDataTreeIdentifier =
- new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.empty());
-
- final InMemoryDOMDataTreeShard inMemoryDOMDataTreeShard =
- InMemoryDOMDataTreeShard.create(domDataTreeIdentifier,
- MoreExecutors.newDirectExecutorService(), 1);
- final CursorAwareDataTreeModification dataTreeModification = mock(CursorAwareDataTreeModification.class);
-
- final InmemoryDOMDataTreeShardWriteTransaction inmemoryDOMDataTreeShardWriteTransaction =
- mock(InmemoryDOMDataTreeShardWriteTransaction.class);
- doReturn(dataTreeModification).when(inmemoryDOMDataTreeShardWriteTransaction).getRootModification();
- final Collection<DOMDataTreeIdentifier> prefixes = ImmutableList.of(DOM_DATA_TREE_IDENTIFIER);
- final InMemoryDOMDataTreeShardProducer mockProducer = mock(InMemoryDOMDataTreeShardProducer.class);
- doReturn(prefixes).when(mockProducer).getPrefixes();
- doReturn(inMemoryDOMDataTreeShard.createModificationFactory(prefixes))
- .when(mockProducer).getModificationFactory();
-
- inMemoryDOMDataTreeShard.createTransaction("", mockProducer, mock(CursorAwareDataTreeSnapshot.class));
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DATA_TREE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.concurrent.ExecutionException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-
-public class InMemoryDOMDataTreeShardThreePhaseCommitCohortTest {
-
- private static final DataTreeCandidateTip DATA_TREE_CANDIDATE = mock(DataTreeCandidateTip.class);
- private static final DataTreeCandidateNode DATA_TREE_CANDIDATE_NODE = mock(DataTreeCandidateNode.class);
- private static final DataTreeModification DATA_TREE_MODIFICATION = mock(DataTreeModification.class);
- private static final InMemoryDOMDataTreeShardChangePublisher IN_MEMORY_DOM_DATA_TREE_SHARD_CHANGE_PUBLISHER =
- new InMemoryDOMDataTreeShardChangePublisher(MoreExecutors.directExecutor(), 1, DATA_TREE,
- YangInstanceIdentifier.of(QName.create("", "test")), ImmutableMap.of());
- private static final InMemoryDOMDataTreeShardThreePhaseCommitCohort
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT =
- new InMemoryDOMDataTreeShardThreePhaseCommitCohort(DATA_TREE, DATA_TREE_MODIFICATION,
- IN_MEMORY_DOM_DATA_TREE_SHARD_CHANGE_PUBLISHER);
-
- @Before
- public void setUp() throws Exception {
- doReturn(YangInstanceIdentifier.empty()).when(DATA_TREE_CANDIDATE).getRootPath();
- doReturn("testDataTreeCandidate").when(DATA_TREE_CANDIDATE).toString();
- doReturn(DATA_TREE_CANDIDATE_NODE).when(DATA_TREE_CANDIDATE).getRootNode();
- doReturn(DATA_TREE_CANDIDATE).when(DATA_TREE).prepare(any());
-
- doReturn(ModificationType.WRITE).when(DATA_TREE_CANDIDATE_NODE).getModificationType();
- doReturn(ImmutableSet.of()).when(DATA_TREE_CANDIDATE_NODE).getChildNodes();
-
- doNothing().when(DATA_TREE).validate(any());
- doNothing().when(DATA_TREE).commit(any());
-
- doReturn("testDataTreeModification").when(DATA_TREE_MODIFICATION).toString();
- }
-
- @Test
- public void basicTest() throws Exception {
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.canCommit();
- verify(DATA_TREE).validate(any());
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.preCommit();
- verify(DATA_TREE).prepare(any());
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.commit();
- verify(DATA_TREE).commit(any());
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.abort();
- }
-
- @Test(expected = IllegalStateException.class)
- public void abortWithExceptionTest() throws Exception {
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.abort();
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.commit();
- }
-
- @Test
- public void preCommitWithExceptionTest() throws Exception {
- doThrow(new RuntimeException("testException")).when(DATA_TREE).prepare(any());
- try {
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.preCommit().get();
- fail("Expected Exception");
- } catch (ExecutionException e) {
- assertTrue(e.getCause().getMessage().contains("testException"));
- }
- }
-
- @Test
- public void canCommitWithDataValidationFailedExceptionTest() throws Exception {
- doThrow(new DataValidationFailedException(YangInstanceIdentifier.empty(), "testException"))
- .when(DATA_TREE).validate(any());
- try {
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.canCommit().get();
- } catch (ExecutionException e) {
- assertTrue(e.getCause() instanceof TransactionCommitFailedException);
- }
- }
-
- @Test
- public void canCommitWithExceptionTest() throws Exception {
- doThrow(new RuntimeException("testException")).when(DATA_TREE).validate(any());
- try {
- IN_MEMORY_DOM_DATA_TREE_SHARD_THREE_PHASE_COMMIT_COHORT.canCommit().get();
- fail("Expected Exception");
- } catch (ExecutionException e) {
- assertTrue(e.getCause().getMessage().contains("testException"));
- }
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.NORMALIZED_NODE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.PATH_ARGUMENT;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.WRITEABLE_MODIFICATION_NODE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.WRITE_CURSOR_STRATEGY;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.lang.reflect.Field;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.spi.shard.AbstractDataModificationCursor;
-import org.opendaylight.mdsal.dom.spi.shard.WriteCursorStrategy;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableModificationNode;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-public class InMemoryShardDataModificationCursorTest {
-
- @Test
- public void basicTest() throws Exception {
- final DataTreeModificationCursor dataTreeModificationCursor = mock(DataTreeModificationCursor.class);
- final DataTreeModificationCursorAdaptor dataTreeModificationCursorAdaptor =
- DataTreeModificationCursorAdaptor.of(dataTreeModificationCursor);
- final ShardRootModificationContext shardRootModificationContext = mock(ShardRootModificationContext.class);
- final Map<PathArgument, WriteableModificationNode> children = new HashMap<>();
- children.put(PATH_ARGUMENT, WRITEABLE_MODIFICATION_NODE);
- final ShardDataModification root = new ShardDataModification(shardRootModificationContext, children,
- ImmutableMap.of());
-
- doReturn(dataTreeModificationCursorAdaptor).when(shardRootModificationContext).cursor();
- InmemoryDOMDataTreeShardWriteTransaction inmemoryDOMDataTreeShardWriteTransaction =
- mock(InmemoryDOMDataTreeShardWriteTransaction.class);
- InMemoryShardDataModificationCursor shardDataModificationCursor =
- new InMemoryShardDataModificationCursor(root, inmemoryDOMDataTreeShardWriteTransaction);
-
- final Field stackField = AbstractDataModificationCursor.class.getDeclaredField("stack");
- stackField.setAccessible(true);
-
- final Deque<WriteCursorStrategy> stack =
- (Deque<WriteCursorStrategy>) stackField.get(shardDataModificationCursor);
- stack.clear();
- stack.push(WRITE_CURSOR_STRATEGY);
- stackField.set(shardDataModificationCursor, stack);
-
- doNothing().when(WRITE_CURSOR_STRATEGY).delete(PATH_ARGUMENT);
- doNothing().when(WRITE_CURSOR_STRATEGY).merge(PATH_ARGUMENT, NORMALIZED_NODE);
- doNothing().when(WRITE_CURSOR_STRATEGY).write(PATH_ARGUMENT, NORMALIZED_NODE);
- doReturn("testPathArgument").when(PATH_ARGUMENT).toString();
-
- shardDataModificationCursor.delete(PATH_ARGUMENT);
- verify(WRITE_CURSOR_STRATEGY).delete(PATH_ARGUMENT);
- shardDataModificationCursor.merge(PATH_ARGUMENT, NORMALIZED_NODE);
- verify(WRITE_CURSOR_STRATEGY).merge(PATH_ARGUMENT, NORMALIZED_NODE);
- shardDataModificationCursor.write(PATH_ARGUMENT, NORMALIZED_NODE);
- verify(WRITE_CURSOR_STRATEGY).write(PATH_ARGUMENT, NORMALIZED_NODE);
-
- doReturn(WRITE_CURSOR_STRATEGY).when(WRITE_CURSOR_STRATEGY).enter(PATH_ARGUMENT);
- shardDataModificationCursor.enter(ImmutableList.of(PATH_ARGUMENT));
- shardDataModificationCursor.enter(PATH_ARGUMENT, PATH_ARGUMENT);
- verify(WRITE_CURSOR_STRATEGY, times(3)).enter(PATH_ARGUMENT);
-
- doNothing().when(inmemoryDOMDataTreeShardWriteTransaction).cursorClosed();
- shardDataModificationCursor.close();
- verify(inmemoryDOMDataTreeShardWriteTransaction).cursorClosed();
-
- doNothing().when(WRITE_CURSOR_STRATEGY).exit();
- shardDataModificationCursor.exit(1);
- verify(WRITE_CURSOR_STRATEGY).exit();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DATA_TREE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_SHARD_PRODUCER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.lang.reflect.Field;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.ChildShardContext;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.ReadableWriteableDOMDataTreeShard;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-
-public class InmemoryDOMDataTreeShardWriteTransactionTest {
-
- private static InmemoryDOMDataTreeShardWriteTransaction inmemoryDOMDataTreeShardWriteTransaction;
- private static ShardDataModification shardDataModification;
- private static final ShardRootModificationContext SHARD_ROOT_MODIFICATION_CONTEXT =
- mock(ShardRootModificationContext.class);
- private static final YangInstanceIdentifier YANG_INSTANCE_IDENTIFIER =
- YangInstanceIdentifier.of(QName.create("", "test"));
- private static final DOMDataTreeIdentifier DOM_DATA_TREE_IDENTIFIER =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YANG_INSTANCE_IDENTIFIER);
- private static final ForeignShardModificationContext FOREIGN_SHARD_MODIFICATION_CONTEXT =
- new ForeignShardModificationContext(DOM_DATA_TREE_IDENTIFIER, DOM_DATA_TREE_SHARD_PRODUCER);
- private static final ReadableWriteableDOMDataTreeShard READABLE_WRITEABLE_DOM_DATA_TREE_SHARD =
- mock(ReadableWriteableDOMDataTreeShard.class);
- private static final ChildShardContext CHILD_SHARD_CONTEXT =
- new ChildShardContext(DOM_DATA_TREE_IDENTIFIER, READABLE_WRITEABLE_DOM_DATA_TREE_SHARD);
- private static final Map<DOMDataTreeIdentifier, ChildShardContext> CHILD_SHARDS =
- ImmutableMap.of(DOM_DATA_TREE_IDENTIFIER, CHILD_SHARD_CONTEXT);
- private InMemoryDOMDataTreeShardProducer mockProducer;
-
- @Before
- public void setUp() throws Exception {
- final DataTreeModification dataTreeModification = mock(DataTreeModification.class);
- doReturn("testDataTreeModification").when(dataTreeModification).toString();
- doReturn(dataTreeModification).when(SHARD_ROOT_MODIFICATION_CONTEXT).ready();
- doReturn(DOM_DATA_TREE_IDENTIFIER).when(SHARD_ROOT_MODIFICATION_CONTEXT).getIdentifier();
- shardDataModification = TestUtils.createModification(SHARD_ROOT_MODIFICATION_CONTEXT,
- ImmutableMap.of(YANG_INSTANCE_IDENTIFIER, FOREIGN_SHARD_MODIFICATION_CONTEXT));
- final DataTreeModificationCursor dataTreeModificationCursor = mock(DataTreeModificationCursor.class);
- doReturn(DataTreeModificationCursorAdaptor.of(dataTreeModificationCursor))
- .when(SHARD_ROOT_MODIFICATION_CONTEXT).cursor();
- doNothing().when(SHARD_ROOT_MODIFICATION_CONTEXT).closeCursor();
- final DataTreeCandidateTip dataTreeCandidate = mock(DataTreeCandidateTip.class);
- final DataTreeCandidateNode dataTreeCandidateNode = mock(DataTreeCandidateNode.class);
- doReturn(dataTreeCandidateNode).when(dataTreeCandidate).getRootNode();
- doReturn(ModificationType.WRITE).when(dataTreeCandidateNode).getModificationType();
- doReturn(YANG_INSTANCE_IDENTIFIER).when(dataTreeCandidate).getRootPath();
- doReturn("testDataTreeCandidate").when(dataTreeCandidate).toString();
- doReturn(dataTreeCandidate).when(DATA_TREE).prepare(any());
- final InMemoryDOMDataTreeShardChangePublisher inMemoryDOMDataTreeShardChangePublisher =
- new InMemoryDOMDataTreeShardChangePublisher(MoreExecutors.directExecutor(), 1, DATA_TREE,
- YANG_INSTANCE_IDENTIFIER, CHILD_SHARDS);
- mockProducer = mock(InMemoryDOMDataTreeShardProducer.class);
- doNothing().when(mockProducer).transactionReady(any(), any());
- doNothing().when(mockProducer).onTransactionCommited(any());
- doNothing().when(mockProducer).transactionAborted(any());
-
- inmemoryDOMDataTreeShardWriteTransaction =
- new InmemoryDOMDataTreeShardWriteTransaction(mockProducer, shardDataModification, DATA_TREE,
- inMemoryDOMDataTreeShardChangePublisher,
- MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
- }
-
- @Test
- public void close() throws Exception {
- inmemoryDOMDataTreeShardWriteTransaction.createCursor(DOM_DATA_TREE_IDENTIFIER);
- inmemoryDOMDataTreeShardWriteTransaction.close();
- assertTrue(inmemoryDOMDataTreeShardWriteTransaction.isFinished());
- }
-
- @Test
- public void cursorClosed() throws Exception {
- final Field cursorField = InmemoryDOMDataTreeShardWriteTransaction.class.getDeclaredField("cursor");
- cursorField.setAccessible(true);
- DOMDataTreeWriteCursor cursor;
-
- inmemoryDOMDataTreeShardWriteTransaction.createCursor(DOM_DATA_TREE_IDENTIFIER);
- cursor = (DOMDataTreeWriteCursor) cursorField.get(inmemoryDOMDataTreeShardWriteTransaction);
- assertNotNull(cursor);
-
- inmemoryDOMDataTreeShardWriteTransaction.cursorClosed();
- cursor = (DOMDataTreeWriteCursor) cursorField.get(inmemoryDOMDataTreeShardWriteTransaction);
- assertNull(cursor);
- }
-
- @Test
- public void isFinished() throws Exception {
- assertFalse(inmemoryDOMDataTreeShardWriteTransaction.isFinished());
- inmemoryDOMDataTreeShardWriteTransaction.ready();
- assertTrue(inmemoryDOMDataTreeShardWriteTransaction.isFinished());
- }
-
- @Test
- public void ready() throws Exception {
- final Field childShardsField = ShardDataModification.class.getDeclaredField("childShards");
- childShardsField.setAccessible(true);
- childShardsField.set(shardDataModification,
- ImmutableMap.of(DOM_DATA_TREE_IDENTIFIER, FOREIGN_SHARD_MODIFICATION_CONTEXT));
-
- inmemoryDOMDataTreeShardWriteTransaction.ready();
- verify(SHARD_ROOT_MODIFICATION_CONTEXT).ready();
- }
-
- @Test
- public void submit() throws Exception {
- doNothing().when(DATA_TREE).validate(any());
- doNothing().when(DATA_TREE).commit(any());
- inmemoryDOMDataTreeShardWriteTransaction.ready();
- assertNull(inmemoryDOMDataTreeShardWriteTransaction.submit().get());
- verify(DATA_TREE).commit(any());
- verify(DATA_TREE).validate(any());
- }
-
- @Test
- public void validate() throws Exception {
- inmemoryDOMDataTreeShardWriteTransaction.ready();
- doNothing().when(DATA_TREE).validate(any());
- assertTrue(inmemoryDOMDataTreeShardWriteTransaction.validate().get());
- verify(DATA_TREE).validate(any());
- }
-
- @Test
- public void prepare() throws Exception {
- inmemoryDOMDataTreeShardWriteTransaction.ready();
- assertNull(inmemoryDOMDataTreeShardWriteTransaction.prepare().get());
- verify(DATA_TREE).prepare(any());
- }
-
- @Test
- public void commit() throws Exception {
- assertNull(inmemoryDOMDataTreeShardWriteTransaction.commit().get());
- }
-
- @Test
- public void createCursor() throws Exception {
- assertNotNull(inmemoryDOMDataTreeShardWriteTransaction.createCursor(DOM_DATA_TREE_IDENTIFIER));
- }
-
- @After
- public void mocksReset() {
- resetMocks();
- reset(SHARD_ROOT_MODIFICATION_CONTEXT);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.COHORTS;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_STORE_THREE_PHASE_COMMIT_COHORT;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.LISTENABLE_FUTURE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-
-public class ShardCanCommitCoordinationTaskTest {
-
- @Test
- public void basicTest() throws Exception {
- doReturn(true).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).canCommit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
-
- ShardCanCommitCoordinationTask shardCanCommitCoordinationTask =
- new ShardCanCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS);
-
- shardCanCommitCoordinationTask.call();
- verify(DOM_STORE_THREE_PHASE_COMMIT_COHORT).canCommit();
- }
-
- @Test(expected = TransactionCommitFailedException.class)
- public void exceptionCallTest() throws Exception {
- doThrow(new InterruptedException()).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).canCommit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
- ShardCanCommitCoordinationTask shardCanCommitCoordinationTask =
- new ShardCanCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS);
- shardCanCommitCoordinationTask.call();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.COHORTS;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_STORE_THREE_PHASE_COMMIT_COHORT;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.LISTENABLE_FUTURE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-
-public class ShardCommitCoordinationTaskTest {
-
- final InmemoryDOMDataTreeShardWriteTransaction mockTx = mock(InmemoryDOMDataTreeShardWriteTransaction.class);
-
- @Before
- public void setUp() throws Exception {
- doReturn("MockedTx").when(mockTx).toString();
- doNothing().when(mockTx).transactionCommited(any());
- }
-
- @Test
- public void basicTest() throws Exception {
- doReturn(Void.TYPE).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).commit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
-
- ShardCommitCoordinationTask shardCommitCoordinationTask =
- new ShardCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS, mockTx);
-
- shardCommitCoordinationTask.call();
- verify(DOM_STORE_THREE_PHASE_COMMIT_COHORT).commit();
- }
-
- @Test(expected = TransactionCommitFailedException.class)
- public void exceptionCallTest() throws Exception {
- doThrow(new InterruptedException()).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).commit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
- ShardCommitCoordinationTask shardCommitCoordinationTask =
- new ShardCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS, mockTx);
- shardCommitCoordinationTask.call();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_SHARD_PRODUCER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_WRITE_CURSOR;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import com.google.common.collect.ImmutableMap;
-import java.lang.reflect.Field;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-public class ShardDataModificationTest {
- private static final ShardRootModificationContext SHARD_ROOT_MODIFICATION_CONTEXT =
- mock(ShardRootModificationContext.class);
- private static final ForeignShardModificationContext FOREIGN_SHARD_MODIFICATION_CONTEXT =
- new ForeignShardModificationContext(DOM_DATA_TREE_IDENTIFIER, DOM_DATA_TREE_SHARD_PRODUCER);
-
- private static ShardDataModification shardDataModification = null;
-
- @Before
- public void setUp() throws Exception {
- doReturn(DOM_DATA_TREE_IDENTIFIER).when(SHARD_ROOT_MODIFICATION_CONTEXT).getIdentifier();
- shardDataModification = TestUtils.createModification(SHARD_ROOT_MODIFICATION_CONTEXT,
- ImmutableMap.of(YangInstanceIdentifier.of(QName.create("", "test")),
- FOREIGN_SHARD_MODIFICATION_CONTEXT));
-
- final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> children =
- ImmutableMap.of(DOM_DATA_TREE_IDENTIFIER, FOREIGN_SHARD_MODIFICATION_CONTEXT);
-
- final Field childShardsField = ShardDataModification.class.getDeclaredField("childShards");
- childShardsField.setAccessible(true);
- childShardsField.set(shardDataModification, children);
- }
-
- @Test
- public void basicTest() throws Exception {
- assertEquals(DOM_DATA_TREE_IDENTIFIER.getRootIdentifier().getLastPathArgument(),
- shardDataModification.getIdentifier());
-
- assertEquals(DOM_DATA_TREE_IDENTIFIER, shardDataModification.getPrefix());
-
- assertNotNull(shardDataModification.getChildShards());
-
- DataTreeModification dataTreeModification = mock(DataTreeModification.class);
- doReturn(dataTreeModification).when(SHARD_ROOT_MODIFICATION_CONTEXT).ready();
- doReturn(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).when(DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- doReturn(DOM_DATA_TREE_WRITE_CURSOR).when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(any());
- FOREIGN_SHARD_MODIFICATION_CONTEXT.getCursor();
- doNothing().when(DOM_DATA_TREE_WRITE_CURSOR).close();
- doNothing().when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).close();
- doNothing().when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
-
- shardDataModification.seal();
- verify(SHARD_ROOT_MODIFICATION_CONTEXT).ready();
- verify(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
- verify(DOM_DATA_TREE_WRITE_CURSOR).close();
-
- shardDataModification.closeTransactions();
- verify(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).close();
- }
-
- @Test(expected = IllegalStateException.class)
- public void createWithException() throws Exception {
- final DataTreeModificationCursor dataTreeModificationCursor = mock(DataTreeModificationCursor.class);
- final DataTreeModificationCursorAdaptor dataTreeModificationCursorAdaptor =
- DataTreeModificationCursorAdaptor.of(dataTreeModificationCursor);
- doReturn(dataTreeModificationCursorAdaptor).when(SHARD_ROOT_MODIFICATION_CONTEXT).cursor();
- shardDataModification.createOperation(null).exit();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.COHORTS;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_STORE_THREE_PHASE_COMMIT_COHORT;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.LISTENABLE_FUTURE;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.resetMocks;
-
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
-
-public class ShardPreCommitCoordinationTaskTest {
-
- @Test
- public void basicTest() throws Exception {
- doReturn(Void.TYPE).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).preCommit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
-
- ShardPreCommitCoordinationTask shardPreCommitCoordinationTask =
- new ShardPreCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS);
-
- shardPreCommitCoordinationTask.call();
- verify(DOM_STORE_THREE_PHASE_COMMIT_COHORT).preCommit();
- }
-
- @Test(expected = TransactionCommitFailedException.class)
- public void exceptionCallTest() throws Exception {
- doThrow(new InterruptedException()).when(LISTENABLE_FUTURE).get();
- doReturn(LISTENABLE_FUTURE).when(DOM_STORE_THREE_PHASE_COMMIT_COHORT).preCommit();
-
- COHORTS.add(DOM_STORE_THREE_PHASE_COMMIT_COHORT);
- ShardPreCommitCoordinationTask shardPreCommitCoordinationTask =
- new ShardPreCommitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, COHORTS);
- shardPreCommitCoordinationTask.call();
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-
-import java.util.Optional;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
-
-public class ShardRootModificationContextTest {
-
- @Test
- public void basicTest() throws Exception {
- final CursorAwareDataTreeSnapshot cursorAwareDataTreeSnapshot = mock(CursorAwareDataTreeSnapshot.class);
- final CursorAwareDataTreeModification cursorAwareDataTreeModification =
- mock(CursorAwareDataTreeModification.class);
- final DataTreeModificationCursor dataTreeModificationCursor = mock(DataTreeModificationCursor.class);
- doReturn(cursorAwareDataTreeModification).when(cursorAwareDataTreeSnapshot).newModification();
- doNothing().when(cursorAwareDataTreeModification).ready();
- doReturn(Optional.of(dataTreeModificationCursor))
- .when(cursorAwareDataTreeModification).openCursor(YangInstanceIdentifier.empty());
- doNothing().when(dataTreeModificationCursor).close();
-
- final ShardRootModificationContext shardRootModificationContext =
- new ShardRootModificationContext(DOM_DATA_TREE_IDENTIFIER, cursorAwareDataTreeSnapshot);
- assertEquals(DOM_DATA_TREE_IDENTIFIER, shardRootModificationContext.getIdentifier());
- assertFalse(shardRootModificationContext.isModified());
-
- final DataTreeModificationCursorAdaptor dataTreeModificationCursorAdaptor =
- shardRootModificationContext.cursor();
- assertNotNull(dataTreeModificationCursorAdaptor);
- assertTrue(shardRootModificationContext.isModified());
- verify(cursorAwareDataTreeSnapshot).newModification();
- verify(cursorAwareDataTreeModification).openCursor(YangInstanceIdentifier.empty());
-
- shardRootModificationContext.ready();
- verify(cursorAwareDataTreeModification).ready();
- verify(dataTreeModificationCursor).close();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.store.inmemory.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-
-import java.lang.reflect.Field;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ShardSubmitCoordinationTaskTest {
-
- private final InmemoryDOMDataTreeShardWriteTransaction tx = mock(InmemoryDOMDataTreeShardWriteTransaction.class);
-
- @Before
- public void setUp() throws Exception {
- doReturn("TestTx").when(tx).getIdentifier();
- doReturn("TestTx").when(tx).toString();
- doNothing().when(tx).transactionCommited(any());
- }
-
- @Test
- public void basicTest() throws Exception {
- final ShardSubmitCoordinationTask shardSubmitCoordinationTask =
- new ShardSubmitCoordinationTask(DOM_DATA_TREE_IDENTIFIER, Collections.emptySet(), tx);
-
- final ShardCanCommitCoordinationTask canCommitCoordinationTask = mock(ShardCanCommitCoordinationTask.class);
- doNothing().when(canCommitCoordinationTask).canCommitBlocking();
- final ShardPreCommitCoordinationTask preCommitCoordinationTask = mock(ShardPreCommitCoordinationTask.class);
- doNothing().when(preCommitCoordinationTask).preCommitBlocking();
- final ShardCommitCoordinationTask commitCoordinationTask = mock(ShardCommitCoordinationTask.class);
- doNothing().when(commitCoordinationTask).commitBlocking();
-
- Field canCommitCoordinationTaskField =
- ShardSubmitCoordinationTask.class.getDeclaredField("canCommitCoordinationTask");
- Field preCommitCoordinationTaskField =
- ShardSubmitCoordinationTask.class.getDeclaredField("preCommitCoordinationTask");
- Field commitCoordinationTaskField =
- ShardSubmitCoordinationTask.class.getDeclaredField("commitCoordinationTask");
-
- canCommitCoordinationTaskField.setAccessible(true);
- preCommitCoordinationTaskField.setAccessible(true);
- commitCoordinationTaskField.setAccessible(true);
-
- canCommitCoordinationTaskField.set(shardSubmitCoordinationTask, canCommitCoordinationTask);
- preCommitCoordinationTaskField.set(shardSubmitCoordinationTask, preCommitCoordinationTask);
- commitCoordinationTaskField.set(shardSubmitCoordinationTask, commitCoordinationTask);
-
- shardSubmitCoordinationTask.call();
-
- verify(canCommitCoordinationTask).canCommitBlocking();
- verify(preCommitCoordinationTask).preCommitBlocking();
- verify(commitCoordinationTask).commitBlocking();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.store.inmemory;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.shard.ForeignShardModificationContext;
-import org.opendaylight.mdsal.dom.spi.shard.WriteCursorStrategy;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableModificationNode;
-import org.opendaylight.mdsal.dom.spi.shard.WriteableSubshardBoundaryNode;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-
-final class TestUtils {
-
- static final DOMDataTreeIdentifier DOM_DATA_TREE_IDENTIFIER =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
-
- static final PathArgument PATH_ARGUMENT = mock(PathArgument.class);
-
- static final NormalizedNode<?, ?> NORMALIZED_NODE = mock(NormalizedNode.class);
-
- static final NormalizedNodeContainer NORMALIZED_NODE_CONTAINER = mock(NormalizedNodeContainer.class);
-
- static final DOMStoreThreePhaseCommitCohort DOM_STORE_THREE_PHASE_COMMIT_COHORT =
- mock(DOMStoreThreePhaseCommitCohort.class);
-
- static final Collection<DOMStoreThreePhaseCommitCohort> COHORTS = new HashSet<>();
-
- static final ListenableFuture<?> LISTENABLE_FUTURE = mock(ListenableFuture.class);
-
- static final WriteableModificationNode WRITEABLE_MODIFICATION_NODE = mock(WriteableSubshardBoundaryNode.class);
-
- static final DOMDataTreeWriteCursor DOM_DATA_TREE_WRITE_CURSOR = mock(DOMDataTreeWriteCursor.class);
-
- static final WriteCursorStrategy WRITE_CURSOR_STRATEGY = mock(WriteCursorStrategy.class);
-
- static final InMemoryDOMDataTreeShardProducer DOM_DATA_TREE_SHARD_PRODUCER =
- mock(InMemoryDOMDataTreeShardProducer.class);
-
- static final InmemoryDOMDataTreeShardWriteTransaction DOM_DATA_TREE_SHARD_WRITE_TRANSACTION =
- mock(InmemoryDOMDataTreeShardWriteTransaction.class);
-
- static final DataTree DATA_TREE = mock(DataTree.class);
-
- static void resetMocks() {
- reset(WRITE_CURSOR_STRATEGY, DOM_DATA_TREE_WRITE_CURSOR, WRITEABLE_MODIFICATION_NODE, LISTENABLE_FUTURE,
- DOM_STORE_THREE_PHASE_COMMIT_COHORT, NORMALIZED_NODE_CONTAINER, NORMALIZED_NODE, PATH_ARGUMENT,
- DOM_DATA_TREE_SHARD_PRODUCER, DOM_DATA_TREE_SHARD_WRITE_TRANSACTION, DATA_TREE);
- }
-
- private TestUtils() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- static ShardDataModification createModification(final ShardRootModificationContext root,
- final Map<YangInstanceIdentifier, ForeignShardModificationContext> shards) {
-
- final InmemoryShardDataModificationFactoryBuilder builder = new InmemoryShardDataModificationFactoryBuilder(
- root.getIdentifier());
- for (ForeignShardModificationContext subshard : shards.values()) {
- builder.addSubshard(subshard);
- }
-
- final InMemoryShardDataModificationFactory factory = builder.build();
- return new ShardDataModification(root, factory.getChildren(), factory.getChildShards());
- }
-
-}
module org.opendaylight.mdsal.dom.spi {
exports org.opendaylight.mdsal.dom.spi;
exports org.opendaylight.mdsal.dom.spi.query;
- exports org.opendaylight.mdsal.dom.spi.shard;
exports org.opendaylight.mdsal.dom.spi.store;
requires transitive org.opendaylight.mdsal.dom.api;
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, 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.dom.spi;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeServiceExtension;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-@Beta
-public abstract class ForwardingDOMDataTreeService
- extends ForwardingDOMExtensibleService<DOMDataTreeService, DOMDataTreeServiceExtension>
- implements DOMDataTreeService {
- @Override
- public DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees) {
- return delegate().createProducer(subtrees);
- }
-
- @Override
- public <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(final T listener,
- final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges,
- final Collection<DOMDataTreeProducer> producers) throws DOMDataTreeLoopException {
- return delegate().registerListener(listener, subtrees, allowRxMerges, producers);
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Abstract base class for {@link DOMDataTreeWriteCursor} implementations.
- *
- * @param <M> Modification type
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class AbstractDataModificationCursor<M> implements DOMDataTreeWriteCursor {
- private final Deque<WriteCursorStrategy> stack = new ArrayDeque<>();
-
- public AbstractDataModificationCursor(final M root) {
- stack.push(getRootOperation(root));
- }
-
- protected abstract WriteCursorStrategy getRootOperation(M root);
-
- private WriteCursorStrategy getCurrent() {
- return stack.peek();
- }
-
- @Override
- public void enter(final PathArgument child) {
- WriteCursorStrategy nextOp = getCurrent().enter(child);
- stack.push(nextOp);
- }
-
- @Override
- public void enter(final PathArgument... path) {
- for (PathArgument pathArgument : path) {
- enter(pathArgument);
- }
- }
-
- @Override
- public void enter(final Iterable<PathArgument> path) {
- for (PathArgument pathArgument : path) {
- enter(pathArgument);
- }
- }
-
- @Override
- public void exit() {
- WriteCursorStrategy op = stack.pop();
- op.exit();
- }
-
- @Override
- public void exit(final int depth) {
- for (int i = 0; i < depth; i++) {
- exit();
- }
- }
-
- @Override
- public abstract void close();
-
- @Override
- public void delete(final PathArgument child) {
- getCurrent().delete(child);
- }
-
- @Override
- public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
- getCurrent().merge(child, data);
- }
-
- @Override
- public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
- getCurrent().write(child, data);
- }
-
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class AbstractShardModificationFactoryBuilder<T> extends ModificationContextNodeBuilder
- implements Builder<T> {
- protected final Map<DOMDataTreeIdentifier, ForeignShardModificationContext> childShards = new HashMap<>();
- protected final DOMDataTreeIdentifier root;
-
- public AbstractShardModificationFactoryBuilder(final DOMDataTreeIdentifier root) {
- this.root = requireNonNull(root);
- }
-
- public void addSubshard(final ForeignShardModificationContext value) {
- WriteableSubshardBoundaryNode leafNode = WriteableSubshardBoundaryNode.from(value);
- putNode(value.getIdentifier().getRootIdentifier(), leafNode);
- }
-
- public void addSubshard(final DOMDataTreeIdentifier prefix, final ForeignShardModificationContext value) {
- childShards.put(prefix, value);
- }
-
- @Override
- public abstract T build();
-
- private void putNode(final YangInstanceIdentifier key, final WriteableSubshardBoundaryNode subshardNode) {
- final Iterator<PathArgument> toBoundary = toRelative(key).getPathArguments().iterator();
- if (toBoundary.hasNext()) {
- ModificationContextNodeBuilder current = this;
- while (true) {
- final PathArgument nextArg = toBoundary.next();
- if (!toBoundary.hasNext()) {
- current.addBoundary(nextArg, subshardNode);
- break;
- }
-
- current = current.getInterior(nextArg);
- }
- }
- }
-
- private YangInstanceIdentifier toRelative(final YangInstanceIdentifier key) {
- return key.relativeTo(root.getRootIdentifier()).get();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Verify;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterators;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Function;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.concepts.Mutable;
-
-/**
- * Aggregator which combines state reported by potentially multiple threads into a single state report. State is
- * received concurrently to reports and reporter threads are hijacked when there is state to be reported and no thread
- * is reporting it.
- *
- * @param <S> State type
- * @author Robert Varga
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class AbstractStateAggregator<S extends AbstractStateAggregator.State> {
-
- /**
- * Marker interface for state as both reported up and down.
- */
- public abstract static class State implements Immutable {
-
- }
-
- /**
- * State aggregator, which receives state chunks and creates an aggregated state object via the build method.
- * Note all internal state must be protected by the the lock on the builder project itself.
- *
- * @param <S> State type
- */
- protected abstract static class StateBuilder<S extends State> implements Builder<S>, Mutable {
-
- protected abstract void append(S state);
-
- protected abstract void appendInitial(S state);
- }
-
- protected abstract static class Behavior<B extends Behavior<B, S>, S extends State> {
-
- abstract Collection<StateBuilder<S>> builders();
-
- abstract void receiveState(StateBuilder<S> builder, S state);
- }
-
- private static final class Starting<S extends State> extends Behavior<Starting<S>, S> {
- private final Collection<StateBuilder<S>> builders;
- @GuardedBy("this")
- private Started<S> successor;
-
- Starting(final int sizeHint) {
- builders = new ArrayList<>(sizeHint);
- }
-
- void add(final StateBuilder<S> builder) {
- builders.add(requireNonNull(builder));
- }
-
- @Override
- Collection<StateBuilder<S>> builders() {
- return builders;
- }
-
- @Override
- synchronized void receiveState(final StateBuilder<S> builder, final S state) {
- if (successor != null) {
- successor.receiveState(builder, state);
- return;
- }
-
- builder.appendInitial(state);
- }
-
- synchronized Started<S> start(final Function<Collection<StateBuilder<S>>, Started<S>> function) {
- checkState(successor == null, "Attempted to start an already-started aggregator");
- final Started<S> next = Verify.verifyNotNull(function.apply(ImmutableList.copyOf(builders)));
- successor = next;
- return next;
- }
- }
-
- protected abstract static class Started<S extends State> extends Behavior<Started<S>, S> {
- private final Collection<StateBuilder<S>> builders;
-
- Started(final Collection<? extends StateBuilder<S>> builders) {
- this.builders = ImmutableList.copyOf(builders);
- }
-
- @Override
- final Collection<StateBuilder<S>> builders() {
- return builders;
- }
- }
-
- protected static final class Failed<S extends State> extends Started<S> {
- protected Failed(final Collection<? extends StateBuilder<S>> builders) {
- super(builders);
- }
-
- @Override
- void receiveState(final StateBuilder<S> builder, final S state) {
- // Intentional no-op
- }
- }
-
- protected abstract static class Operational<S extends State> extends Started<S> {
- // Locking is a combination of a generation counter and a semaphore. Generation is bumped and remembered
- // on stack when new state is being appended. Processed generations are recorded separately. This can cause
- // false-positives when we loop on empty state, but that should not happen often and is harmless.
- private final AtomicBoolean semaphore = new AtomicBoolean();
- private final AtomicLong generation = new AtomicLong();
-
- private volatile long processed;
-
- protected Operational(final Collection<? extends StateBuilder<S>> builders) {
- super(builders);
- }
-
- protected abstract void notifyListener(Iterator<S> iterator);
-
- @Override
- final void receiveState(final StateBuilder<S> builder, final S state) {
- synchronized (builder) {
- // Generation has to be bumbed atomically with state delivery, otherwise tryNotifyListener could
- // observe state with after generation was bumped and before the state was appended
- final long gen = generation.incrementAndGet();
- try {
- builder.append(state);
- } finally {
- tryNotifyListener(gen);
- }
- }
- }
-
- private void tryNotifyListener(final long initGen) {
- long gen = initGen;
-
- // We now have to re-sync, as we may end up being the last thread in position to observe the complete state
- // of the queues. Since queues are updated independently to iteration, notifyListener() may have missed
- // some updates, in which case we must eventually run it.
- //
- // Check if this generation was processed by someone else (while we were inserting items) or if there is
- // somebody else already running this loop (which means they will re-check and spin again).
- while (gen != processed && semaphore.compareAndSet(false, true)) {
- try {
- processed = gen;
- notifyListener(Iterators.transform(builders().iterator(), StateBuilder::build));
- } finally {
- semaphore.set(false);
- }
-
- final long nextGen = generation.get();
- if (nextGen == gen) {
- // No modifications happened, we are done
- return;
- }
-
- gen = nextGen;
- }
- }
- }
-
- private volatile Behavior<?, S> behavior;
-
- protected AbstractStateAggregator(final int sizeHint) {
- this.behavior = new Starting<>(sizeHint);
- }
-
- protected final void addBuilder(final StateBuilder<S> builder) {
- checkStarting().add(builder);
- }
-
- protected final synchronized Started<S> start(final Function<Collection<StateBuilder<S>>, Started<S>> function) {
- final Started<S> ret = checkStarting().start(function);
- behavior = ret;
- return ret;
- }
-
- protected final void receiveState(final StateBuilder<S> builder, final S state) {
- behavior.receiveState(builder, state);
- }
-
- @SuppressWarnings("unchecked")
- private Starting<S> checkStarting() {
- final Behavior<?, S> local = behavior;
- checkState(local instanceof Starting, "Unexpected behavior %s", local);
- return (Starting<S>) local;
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-
-/**
- * Definition of a subshard containing the prefix and the subshard.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-@NonNullByDefault
-public final class ChildShardContext {
- private final WriteableDOMDataTreeShard shard;
- private final DOMDataTreeIdentifier prefix;
-
- public ChildShardContext(final DOMDataTreeIdentifier prefix, final WriteableDOMDataTreeShard shard) {
- this.prefix = requireNonNull(prefix);
- this.shard = requireNonNull(shard);
- }
-
- public WriteableDOMDataTreeShard getShard() {
- return shard;
- }
-
- public DOMDataTreeIdentifier getPrefix() {
- return prefix;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Optional;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Compatibility bridge between {@link DOMDataTreeListenerRegistry} and {@link DOMStoreTreeChangePublisher}.
- */
-@Beta
-@Deprecated(forRemoval = true)
-public final class CompatDOMDataTreeListenerRegistry implements DOMDataTreeListenerRegistry {
-
- private final DOMStoreTreeChangePublisher publisher;
-
- public CompatDOMDataTreeListenerRegistry(final DOMStoreTreeChangePublisher publisher) {
- this.publisher = requireNonNull(publisher);
- }
-
- @Override
- public <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(final T listener,
- final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges) {
- if (subtrees.size() == 1) {
- final DOMDataTreeIdentifier treeId = Iterables.getOnlyElement(subtrees);
-
- final ListenerRegistration<?> reg = publisher.registerTreeChangeListener(treeId.getRootIdentifier(),
- changes -> {
- final Optional<NormalizedNode<?, ?>> last = Iterables.getLast(changes).getRootNode().getDataAfter();
- if (last.isPresent()) {
- listener.onDataTreeChanged(changes, ImmutableMap.of(treeId, last.get()));
- } else {
- listener.onDataTreeChanged(changes, ImmutableMap.of());
- }
- });
- return new AbstractListenerRegistration<>(listener) {
- @Override
- protected void removeRegistration() {
- reg.close();
- }
- };
- }
-
- final int size = subtrees.size();
- final Collection<ListenerRegistration<?>> regs = new ArrayList<>(size);
- final DOMDataTreeChangeListenerAggregator aggregator = new DOMDataTreeChangeListenerAggregator(size,
- allowRxMerges);
- for (DOMDataTreeIdentifier treeId : subtrees) {
- regs.add(publisher.registerTreeChangeListener(treeId.getRootIdentifier(),
- aggregator.createListener(treeId)));
- }
-
- return aggregator.start(listener, regs);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ForwardingObject;
-import java.util.Collection;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Compatibility layer between {@link DOMStoreTreeChangePublisher} and {@link ListenableDOMDataTreeShard}. Required
- * for migration purposes.
- *
- * @author Robert Varga
- *
- * @deprecated This class is scheduled for removal when we remove compatibility with dom.spi.store APIs.
- */
-@Deprecated(forRemoval = true)
-public final class CompatListenableDOMDataTreeShard extends ForwardingObject implements ListenableDOMDataTreeShard {
- private static final Logger LOG = LoggerFactory.getLogger(CompatListenableDOMDataTreeShard.class);
-
- private final CompatDOMDataTreeListenerRegistry publisher;
- private final DOMDataTreeShard delegate;
-
- private CompatListenableDOMDataTreeShard(final DOMDataTreeShard delegate) {
- this.delegate = requireNonNull(delegate);
- checkArgument(delegate instanceof DOMStoreTreeChangePublisher);
- this.publisher = new CompatDOMDataTreeListenerRegistry((DOMStoreTreeChangePublisher) delegate);
- }
-
- public static ListenableDOMDataTreeShard createIfNeeded(final DOMDataTreeShard delegate) {
- if (delegate instanceof ListenableDOMDataTreeShard) {
- return (ListenableDOMDataTreeShard) delegate;
- }
-
- LOG.debug("Using compatibility adaptor for {}", delegate);
- return new CompatListenableDOMDataTreeShard(delegate);
- }
-
- @Override
- protected DOMDataTreeShard delegate() {
- return delegate;
- }
-
- @Override
- public void onChildAttached(final DOMDataTreeIdentifier prefix, final DOMDataTreeShard child) {
- delegate.onChildAttached(prefix, child);
- }
-
- @Override
- public void onChildDetached(final DOMDataTreeIdentifier prefix, final DOMDataTreeShard child) {
- delegate.onChildDetached(prefix, child);
- }
-
- @Override
- public <L extends DOMDataTreeListener> ListenerRegistration<L> registerListener(final L listener,
- final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges) {
- return publisher.registerListener(listener, subtrees, allowRxMerges);
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-@Deprecated(forRemoval = true)
-interface CursorStrategy {
-
- CursorStrategy enter(PathArgument arg);
-
- void exit();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A compatibility class for bridging DOMDataTreeChangeListener, which can listen on only single subtree with
- * {@link DOMDataTreeListener} interface.
- *
- * @author Robert Varga
- * @deprecated This class is scheduled for removal when we remove compatibility with dom.spi.store APIs.
- */
-@Deprecated(forRemoval = true)
-final class DOMDataTreeChangeListenerAggregator
- extends AbstractStateAggregator<DOMDataTreeChangeListenerAggregator.State> {
-
- static final class State extends AbstractStateAggregator.State implements Identifiable<DOMDataTreeIdentifier> {
- private final DOMDataTreeIdentifier identifier;
- final List<DataTreeCandidate> changes;
-
- State(final DOMDataTreeIdentifier identifier, final List<DataTreeCandidate> changes) {
- this.identifier = requireNonNull(identifier);
- this.changes = requireNonNull(changes);
- }
-
- @Override
- public DOMDataTreeIdentifier getIdentifier() {
- return identifier;
- }
- }
-
- private static final class StateBuilder extends AbstractStateAggregator.StateBuilder<State> {
- @GuardedBy("this")
- private final List<DataTreeCandidate> changes = new ArrayList<>();
- private final DOMDataTreeIdentifier identifier;
-
- StateBuilder(final DOMDataTreeIdentifier identifier) {
- this.identifier = requireNonNull(identifier);
- }
-
- @Override
- protected synchronized void append(final State state) {
- changes.addAll(state.changes);
- }
-
- @Override
- protected synchronized void appendInitial(final State state) {
- // We are still starting up, so all we need to do is squash reported changes to an initial write event
- final DataTreeCandidate last = Iterables.getLast(state.changes);
- changes.clear();
- final Optional<NormalizedNode<?, ?>> lastData = last.getRootNode().getDataAfter();
- if (lastData.isPresent()) {
- changes.add(DataTreeCandidates.fromNormalizedNode(last.getRootPath(), lastData.get()));
- }
- }
-
- @Override
- public synchronized State build() {
- final State ret = new State(identifier, ImmutableList.copyOf(changes));
- changes.clear();
- return ret;
- }
- }
-
- private static final class Operational extends AbstractStateAggregator.Operational<State> {
- private final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees = new HashMap<>();
- private final DOMDataTreeListener listener;
-
- Operational(final Collection<AbstractStateAggregator.StateBuilder<State>> builders,
- final DOMDataTreeListener listener) {
- super(builders);
- this.listener = requireNonNull(listener);
- }
-
- @Override
- protected void notifyListener(final Iterator<State> iterator) {
- final Stopwatch clock = Stopwatch.createStarted();
- final List<DataTreeCandidate> changes = new ArrayList<>();
- while (iterator.hasNext()) {
- final State state = iterator.next();
- final List<DataTreeCandidate> candidates = state.changes;
- if (!candidates.isEmpty()) {
- // Update current subtree snapshot based on last candidate node
- final DataTreeCandidateNode lastRoot = candidates.get(candidates.size() - 1).getRootNode();
- final Optional<NormalizedNode<?, ?>> optData = lastRoot.getDataAfter();
- if (optData.isPresent()) {
- subtrees.put(state.getIdentifier(), optData.get());
- } else {
- subtrees.remove(state.getIdentifier());
- }
-
- // Append changes
- changes.addAll(candidates);
- }
- }
-
- final int size = changes.size();
- if (size != 0) {
- // Note: it is okay to leak changes, we must never leak mutable subtrees.
- listener.onDataTreeChanged(changes, ImmutableMap.copyOf(subtrees));
- LOG.trace("Listener {} processed {} changes in {}", listener, size, clock);
- }
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(DOMDataTreeChangeListenerAggregator.class);
-
- private final boolean allowRxMerges;
-
- DOMDataTreeChangeListenerAggregator(final int sizeHint, final boolean allowRxMerges) {
- super(sizeHint);
- this.allowRxMerges = allowRxMerges;
- }
-
- DOMDataTreeChangeListener createListener(final DOMDataTreeIdentifier treeId) {
- // TODO: do not ignore allowRxMerges, but rather create a dedicated subclass or something
- final StateBuilder builder = new StateBuilder(treeId);
- addBuilder(builder);
-
- return changes -> receiveState(builder, new State(treeId, ImmutableList.copyOf(changes)));
- }
-
- <L extends DOMDataTreeListener> ListenerRegistration<L> start(final L listener,
- final Collection<ListenerRegistration<?>> regs) {
- start(builders -> {
- final Operational ret = new Operational(builders, listener);
- ret.notifyListener(Iterators.transform(builders.iterator(), AbstractStateAggregator.StateBuilder::build));
- return ret;
- });
-
- return new AbstractListenerRegistration<>(listener) {
- @Override
- protected void removeRegistration() {
- regs.forEach(ListenerRegistration::close);
- }
- };
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Verify;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.function.Function;
-import org.checkerframework.checker.lock.qual.GuardedBy;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListeningException;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Aggregator which combines multiple disjunct {@link DOMDataTreeListener} and forwards their changes to a central
- * listener.
- *
- * @author Robert Varga
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public final class DOMDataTreeListenerAggregator
- extends AbstractStateAggregator<DOMDataTreeListenerAggregator.State> {
-
- abstract static class State extends AbstractStateAggregator.State {
-
- }
-
- private static final class Aggregated extends State {
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees;
- final Collection<DOMDataTreeListeningException> failures;
- final Collection<DataTreeCandidate> changes;
-
- Aggregated(final Collection<DataTreeCandidate> changes,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees,
- final Collection<DOMDataTreeListeningException> failures) {
- this.changes = requireNonNull(changes);
- this.subtrees = requireNonNull(subtrees);
- this.failures = requireNonNull(failures);
- }
- }
-
- private static final class Changes extends State {
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees;
- final Collection<DataTreeCandidate> changes;
-
- Changes(final Collection<DataTreeCandidate> changes,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees) {
- this.changes = requireNonNull(changes);
- this.subtrees = requireNonNull(subtrees);
- }
- }
-
- private static final class Failure extends State {
- final Collection<DOMDataTreeListeningException> causes;
-
- Failure(final Collection<DOMDataTreeListeningException> causes) {
- this.causes = requireNonNull(causes);
- }
- }
-
- private static final class StateBuilder extends AbstractStateAggregator.StateBuilder<State> {
- @GuardedBy("this")
- private final Collection<DOMDataTreeListeningException> causes = new ArrayList<>(0);
- @GuardedBy("this")
- private final Collection<DataTreeCandidate> changes = new ArrayList<>();
- @GuardedBy("this")
- private Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees = ImmutableMap.of();
-
- @Override
- protected synchronized void append(final State state) {
- if (state instanceof Changes) {
- final Changes changesState = (Changes) state;
- this.changes.addAll(changesState.changes);
- subtrees = ImmutableMap.copyOf(changesState.subtrees);
- } else if (state instanceof Failure) {
- causes.addAll(((Failure) state).causes);
- } else {
- throw new IllegalStateException("Unexpected state " + state);
- }
- }
-
- @Override
- protected synchronized void appendInitial(final State state) {
- // TODO: we could index and compress state changes here
- if (state instanceof Changes) {
- final Changes changesState = (Changes) state;
- this.changes.addAll(changesState.changes);
- subtrees = ImmutableMap.copyOf(changesState.subtrees);
- } else if (state instanceof Failure) {
- causes.addAll(((Failure) state).causes);
- } else {
- throw new IllegalStateException("Unexpected state " + state);
- }
- }
-
- @Override
- public synchronized Aggregated build() {
- final Aggregated ret = new Aggregated(ImmutableList.copyOf(changes), subtrees,
- ImmutableList.copyOf(causes));
- changes.clear();
- causes.clear();
- return ret;
- }
- }
-
- private static final class Operational extends AbstractStateAggregator.Operational<State> {
- private final DOMDataTreeListener listener;
- private boolean failed;
-
- Operational(final Collection<AbstractStateAggregator.StateBuilder<State>> builders,
- final DOMDataTreeListener listener) {
- super(builders);
- this.listener = requireNonNull(listener);
- }
-
- @Override
- protected void notifyListener(final Iterator<State> iterator) {
- if (failed) {
- iterator.forEachRemaining(state -> LOG.debug("Listener {} failed, ignoring state {}", listener, state));
- return;
- }
-
- final Stopwatch clock = Stopwatch.createStarted();
- final List<DataTreeCandidate> changes = new ArrayList<>();
- final List<DOMDataTreeListeningException> failures = new ArrayList<>(0);
- final Builder<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees = ImmutableMap.builder();
- while (iterator.hasNext()) {
- collectState(iterator.next(), changes, subtrees, failures);
- }
-
- if (!changes.isEmpty()) {
- // Note: it is okay to leak changes, we must never leak mutable subtrees.
- callListener(listener, changes, subtrees.build());
- }
- if (!failures.isEmpty()) {
- failed = true;
- listener.onDataTreeFailed(failures);
- }
-
- LOG.trace("Listener {} notification completed in {}", listener, clock);
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(DOMDataTreeListenerAggregator.class);
-
- // Because a component listener may report a failure before we finish registering all listeners, we need a way
- // to trigger a failure report from the thread *not* performing the registration.
- private static final Executor FAILURE_NOTIFIER;
-
- static {
- final ThreadFactoryBuilder tfb = new ThreadFactoryBuilder().setDaemon(true)
- .setNameFormat(DOMDataTreeListenerAggregator.class.getSimpleName() + "-failure-%s");
- FAILURE_NOTIFIER = Executors.newSingleThreadExecutor(tfb.build());
- }
-
- private final boolean allowRxMerges;
-
- public DOMDataTreeListenerAggregator(final int sizeHint, final boolean allowRxMerges) {
- super(sizeHint);
- this.allowRxMerges = allowRxMerges;
- }
-
- public static <L extends DOMDataTreeListener, T> ListenerRegistration<L> aggregateIfNeeded(final L listener,
- final Map<T, Collection<DOMDataTreeIdentifier>> subtrees, final boolean allowRxMerges,
- final Function<T, DOMDataTreeShard> keyToShard) {
- if (subtrees.size() == 1) {
- final Entry<T, Collection<DOMDataTreeIdentifier>> entry = subtrees.entrySet().iterator()
- .next();
- return CompatListenableDOMDataTreeShard.createIfNeeded(keyToShard.apply(entry.getKey()))
- .registerListener(listener, entry.getValue(), allowRxMerges);
- }
-
- // Alright, this the real deal, we have to aggregate.
- final int size = subtrees.size();
- final DOMDataTreeListenerAggregator aggregator = new DOMDataTreeListenerAggregator(size, allowRxMerges);
- final Collection<ListenerRegistration<DOMDataTreeListener>> regs = new ArrayList<>(size);
- for (Entry<T, Collection<DOMDataTreeIdentifier>> entry : subtrees.entrySet()) {
- regs.add(CompatListenableDOMDataTreeShard.createIfNeeded(keyToShard.apply(entry.getKey()))
- .registerListener(aggregator.createListener(), entry.getValue(), allowRxMerges));
- }
-
- return aggregator.start(listener, regs);
- }
-
- public DOMDataTreeListener createListener() {
- // TODO: do not ignore allowRxMerges, but rather create a dedicated subclass or something
- final StateBuilder builder = new StateBuilder();
- addBuilder(builder);
-
- return new DOMDataTreeListener() {
- @Override
- public void onDataTreeFailed(final Collection<DOMDataTreeListeningException> causes) {
- receiveState(builder, new Failure(causes));
- }
-
- @Override
- public void onDataTreeChanged(final Collection<DataTreeCandidate> changes,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees) {
- receiveState(builder, new Changes(changes, subtrees));
- }
- };
- }
-
- public <L extends DOMDataTreeListener> ListenerRegistration<L> start(final L listener,
- final Collection<ListenerRegistration<DOMDataTreeListener>> regs) {
-
- final Started<State> result = start(builders -> start(listener, regs, builders));
- if (result instanceof Failed) {
- return new AbstractListenerRegistration<>(listener) {
- @Override
- protected void removeRegistration() {
- // Listeners have already been closed, this is a no-op
- }
- };
- }
-
- return new AbstractListenerRegistration<>(listener) {
- @Override
- protected void removeRegistration() {
- regs.forEach(ListenerRegistration::close);
- }
- };
- }
-
- static Started<State> start(final DOMDataTreeListener listener,
- final Collection<ListenerRegistration<DOMDataTreeListener>> regs,
- final Collection<AbstractStateAggregator.StateBuilder<State>> builders) {
-
- final List<DataTreeCandidate> changes = new ArrayList<>();
- final List<DOMDataTreeListeningException> failures = new ArrayList<>(0);
- final Builder<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees = ImmutableMap.builder();
- for (AbstractStateAggregator.StateBuilder<State> builder : builders) {
- collectState(builder.build(), changes, subtrees, failures);
- }
-
- if (!failures.isEmpty()) {
- regs.forEach(ListenerRegistration::close);
- FAILURE_NOTIFIER.execute(() -> listener.onDataTreeFailed(failures));
- return new Failed<>(builders);
- }
- if (!changes.isEmpty()) {
- callListener(listener, changes, subtrees.build());
- }
-
- return new Operational(builders, listener);
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- static void callListener(final DOMDataTreeListener listener, final Collection<DataTreeCandidate> changes,
- final Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees) {
- try {
- listener.onDataTreeChanged(changes, subtrees);
- } catch (Exception e) {
- LOG.error("Listener {} failed to process initial changes", listener, e);
- }
- }
-
- static void collectState(final State state, final Collection<DataTreeCandidate> changes,
- final Builder<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees,
- final Collection<DOMDataTreeListeningException> failures) {
- Verify.verify(state instanceof Aggregated, "Unexpected state %s", state);
- final Aggregated aggregated = (Aggregated) state;
-
- subtrees.putAll(aggregated.subtrees);
- changes.addAll(aggregated.changes);
- failures.addAll(aggregated.failures);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeListener;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * Utility interface for objects dispatching events to {@link DOMDataTreeListener}.
- *
- * @author Robert Varga
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public interface DOMDataTreeListenerRegistry {
- <T extends DOMDataTreeListener> @NonNull ListenerRegistration<T> registerListener(@NonNull T listener,
- @NonNull Collection<DOMDataTreeIdentifier> subtrees, boolean allowRxMerges);
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.concepts.Registration;
-
-@Beta
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeShardProducer extends Registration {
- /**
- * Return the collection of tree identifiers to which this producer is bound. This collection
- * is constant during the lifetime of a producer.
- *
- * @return Collection of data tree identifiers.
- */
- @NonNull Collection<DOMDataTreeIdentifier> getPrefixes();
-
- /**
- * Create a new write transaction for this producer. Any previous transactions need to be closed either via
- * {@link DOMDataTreeShardWriteTransaction#ready()} or cancelled.
- *
- * @return A new write transaction
- * @throws IllegalStateException if a previous transaction has not been closed
- */
- @NonNull DOMDataTreeShardWriteTransaction createTransaction();
-
- /**
- * Close this producer, releasing all resources.
- */
- @Override
- void close();
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCursorProvider;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-
-@Beta
-@Deprecated(forRemoval = true)
-public interface DOMDataTreeShardWriteTransaction extends DOMDataTreeCursorProvider {
- /**
- * Create a new write cursor. Any previous cursors have to be {@link DOMDataTreeWriteCursor#close()}d.
- *
- * @param prefix Tree identifier of the apex at which the cursor is rooted.
- * @return A new cursor rooted at specified prefx.
- * @throws IllegalStateException if a previous cursor has not been closed.
- * @throws NullPointerException if prefix is null.
- */
- @Override
- // FIXME: 6.0.0: reconcile @NonNull vs. super @Nullable
- @NonNull DOMDataTreeWriteCursor createCursor(@NonNull DOMDataTreeIdentifier prefix);
-
- /**
- * Finish this transaction and submit it for processing.
- *
- *<p>
- * FIXME: this method should accept a callback which will report success/failure. Let's not use a CheckedFuture
- * due to overhead associated with attaching listeners to them.
- * @throws IllegalStateException if this transaction has an unclosed cursor.
- */
- void ready();
-
- /**
- * Close this transaction and all other foreign shard transactions that were opened as a part of this transaction.
- */
- void close();
-
- ListenableFuture<Void> submit();
-
- ListenableFuture<Boolean> validate();
-
- ListenableFuture<Void> prepare();
-
- ListenableFuture<Void> commit();
-
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.collect.ForwardingObject;
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshotCursor;
-
-/**
- * Delegating implementation of a {@link ReadableCursorOperation}.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-abstract class DelegatingReadableCursorOperation extends ForwardingObject implements ReadableCursorOperation {
-
- @Override
- protected abstract DataTreeSnapshotCursor delegate();
-
- @Override
- public Optional<NormalizedNode<?, ?>> readNode(final PathArgument arg) {
- return delegate().readNode(arg);
- }
-
- @Override
- public void exit() {
- delegate().exit();
- }
-
- @Override
- public DelegatingReadableCursorOperation enter(final PathArgument arg) {
- delegate().enter(arg);
- return this;
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ForwardingObject;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-/**
- * Delegating implementation of a {@link WriteCursorStrategy}.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public abstract class DelegatingWriteCursorStrategy extends ForwardingObject implements WriteCursorStrategy {
-
- @Override
- protected abstract DOMDataTreeWriteCursor delegate();
-
- /**
- * Returns strategy to be used on child nodes. Default implementation is to reuse same instance.
- *
- * @return Strategy to be used for child nodes.
- */
- protected DelegatingWriteCursorStrategy childStrategy() {
- return this;
- }
-
- @Override
- public WriteCursorStrategy enter(final PathArgument arg) {
- delegate().enter(arg);
- return childStrategy();
- }
-
- @Override
- public void delete(final PathArgument arg) {
- delegate().delete(arg);
- }
-
- @Override
- public void merge(final PathArgument arg, final NormalizedNode<?, ?> data) {
- delegate().merge(arg, data);
- }
-
- @Override
- public void write(final PathArgument arg, final NormalizedNode<?, ?> data) {
- delegate().write(arg, data);
- }
-
- @Override
- public void mergeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
- for (NormalizedNode<?, ?> child : data.getValue()) {
- delegate().merge(child.getIdentifier(), child);
- }
- }
-
- @Override
- public void writeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
- for (NormalizedNode<?, ?> child : data.getValue()) {
- delegate().write(child.getIdentifier(), child);
- }
- }
-
- /**
- * Operation performed to exit current logical level, default implementation calls
- * {@link DOMDataTreeWriteCursor#exit()} on underlaying cursor.
- *
- *<p>
- * Subclasses may override this to customize exit strategy.
- *
- */
- @Override
- public void exit() {
- delegate().exit();
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.concepts.Mutable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A handle for a transaction being done on a different shard. This class is not thread-safe.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public final class ForeignShardModificationContext implements Identifiable<DOMDataTreeIdentifier>, Mutable {
- private static final Logger LOG = LoggerFactory.getLogger(ForeignShardModificationContext.class);
-
- private final DOMDataTreeIdentifier identifier;
- private final DOMDataTreeShardProducer producer;
-
- private DOMDataTreeShardWriteTransaction tx;
- private DOMDataTreeWriteCursor cursor;
-
- private volatile boolean ready = false;
-
- public ForeignShardModificationContext(final DOMDataTreeIdentifier identifier,
- final DOMDataTreeShardProducer producer) {
- this.identifier = requireNonNull(identifier);
- this.producer = requireNonNull(producer);
- }
-
- public DOMDataTreeWriteCursor getCursor() {
- checkState(!ready, "Context %s has been readied", this);
-
- if (cursor == null) {
- if (tx == null) {
- tx = producer.createTransaction();
- }
- cursor = tx.createCursor(getIdentifier());
- }
- return cursor;
- }
-
- public boolean isModified() {
- return tx != null;
- }
-
- public void ready() {
- if (ready) {
- // Idempotent, but emit a debug
- LOG.debug("Duplicate ready() of context {}", this);
- return;
- }
-
- ready = true;
- if (cursor != null) {
- cursor.close();
- cursor = null;
- }
- if (tx != null) {
- tx.ready();
- // TODO: it would be nice if we could clear this reference
- // tx = null;
- }
- }
-
- @Override
- public DOMDataTreeIdentifier getIdentifier() {
- return identifier;
- }
-
- public DOMDataTreeShardProducer getProducer() {
- return producer;
- }
-
- public ListenableFuture<Boolean> validate() {
- return tx.validate();
- }
-
- public ListenableFuture<Void> prepare() {
- return tx.prepare();
- }
-
- public ListenableFuture<Void> submit() {
- checkState(ready, "Modification context %s has to be ready before submit", this);
- final ListenableFuture<Void> commit = tx.commit();
- ready = false;
- tx = null;
- return commit;
- }
-
- public void closeForeignTransaction() {
- if (cursor != null) {
- cursor.close();
- cursor = null;
- }
-
- if (tx != null) {
- tx.close();
- tx = null;
- }
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Beta
-@Deprecated(forRemoval = true)
-public class ForeignShardThreePhaseCommitCohort implements DOMStoreThreePhaseCommitCohort {
- private static final Logger LOG = LoggerFactory.getLogger(ForeignShardThreePhaseCommitCohort.class);
-
- private final DOMDataTreeIdentifier prefix;
- private final ForeignShardModificationContext shard;
-
- public ForeignShardThreePhaseCommitCohort(final DOMDataTreeIdentifier prefix,
- final ForeignShardModificationContext shard) {
- this.prefix = requireNonNull(prefix);
- this.shard = requireNonNull(shard);
- }
-
- @Override
- public ListenableFuture<Boolean> canCommit() {
- LOG.debug("Validating transaction on foreign shard {}", prefix);
- return shard.isModified() ? shard.validate() : FluentFutures.immediateTrueFluentFuture();
- }
-
- @Override
- public ListenableFuture<Void> preCommit() {
- LOG.debug("Preparing transaction on foreign shard {}", prefix);
- return shard.isModified() ? shard.prepare() : FluentFutures.immediateNullFluentFuture();
- }
-
- @Override
- public ListenableFuture<Void> abort() {
- LOG.debug("Aborting transaction of foreign shard {}", prefix);
- shard.closeForeignTransaction();
- return FluentFutures.immediateNullFluentFuture();
- }
-
- @Override
- public ListenableFuture<Void> commit() {
- LOG.debug("Submitting transaction on foreign shard {}", prefix);
- return shard.isModified() ? shard.submit() : FluentFutures.immediateNullFluentFuture();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies, s.ro. 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-
-/**
- * A {@link DOMDataTreeShard} which allows registration of listeners, allowing realization of the DOMDataTreeService's
- * registerListener contract. Note that producer/consumer as well as the logical data store type are taken care of
- * by the caller, hence implementations of this interface only need to take care of communicating with their subshards.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public interface ListenableDOMDataTreeShard extends DOMDataTreeShard, DOMDataTreeListenerRegistry {
-
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class ModificationContextNodeBuilder {
-
- private final Map<PathArgument, InteriorNodeBuilder> interiorChildren = new LinkedHashMap<>();
- private final Map<PathArgument, WriteableSubshardBoundaryNode> boundaryChildren = new HashMap<>();
-
- public ModificationContextNodeBuilder getInterior(final PathArgument arg) {
- InteriorNodeBuilder potential = interiorChildren.get(arg);
- if (potential == null) {
- potential = new InteriorNodeBuilder(arg);
- interiorChildren.put(arg, potential);
- }
- return potential;
- }
-
- public void addBoundary(final PathArgument arg, final WriteableSubshardBoundaryNode subshardNode) {
- boundaryChildren.put(arg, subshardNode);
- }
-
- public final Map<PathArgument, WriteableModificationNode> buildChildren() {
- final Map<PathArgument, WriteableModificationNode> builtChildren = new HashMap<>(boundaryChildren);
- for (InteriorNodeBuilder interiorNode : interiorChildren.values()) {
- WriteableModificationNode builded = interiorNode.build();
- builtChildren.put(builded.getIdentifier(), builded);
- }
-
- return builtChildren;
- }
-
- public static final class InteriorNodeBuilder extends ModificationContextNodeBuilder {
- private final PathArgument arg;
-
- InteriorNodeBuilder(final PathArgument arg) {
- this.arg = requireNonNull(arg);
- }
-
- WritableInteriorNode build() {
- return new WritableInteriorNode(arg, buildChildren());
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-@Deprecated(forRemoval = true)
-interface ReadableCursorOperation extends CursorStrategy {
-
- Optional<NormalizedNode<?, ?>> readNode(PathArgument arg);
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
-
-/**
- * Marker interface for readable/writeable DOMDataTreeShard.
- *
- * @deprecated Use {@link ListenableDOMDataTreeShard} instead.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public interface ReadableWriteableDOMDataTreeShard extends DOMStoreTreeChangePublisher, WriteableDOMDataTreeShard {
-
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.ArrayList;
-import java.util.Collection;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.yangtools.concepts.Mutable;
-
-/**
- * Specification of subshard producer context that's used for building modification factories that span into the
- * subshards. This class is not thread-safe.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-@NonNullByDefault
-public final class SubshardProducerSpecification implements Mutable {
- private final Collection<DOMDataTreeIdentifier> prefixes = new ArrayList<>(1);
- private final ChildShardContext shard;
-
- public SubshardProducerSpecification(final ChildShardContext subshard) {
- this.shard = requireNonNull(subshard);
- }
-
- public void addPrefix(final DOMDataTreeIdentifier prefix) {
- prefixes.add(prefix);
- }
-
- public DOMDataTreeShardProducer createProducer() {
- return shard.getShard().createProducer(prefixes);
- }
-
- public DOMDataTreeIdentifier getPrefix() {
- return shard.getPrefix();
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-@Deprecated(forRemoval = true)
-class WritableInteriorNode extends WriteableNodeWithSubshard {
-
- private final PathArgument identifier;
-
- WritableInteriorNode(final PathArgument identifier, final Map<PathArgument, WriteableModificationNode> children) {
- super(children);
- this.identifier = requireNonNull(identifier);
- }
-
- @Override
- public PathArgument getIdentifier() {
- return identifier;
- }
-
- @Override
- public WriteCursorStrategy createOperation(final DOMDataTreeWriteCursor parentCursor) {
- return new WritableNodeOperation(this, parentCursor) {
- @Override
- public void exit() {
- // We are not root, so we can safely exit our level.
- getCursor().exit();
- }
- };
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import java.util.Optional;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class WritableNodeOperation implements WriteCursorStrategy {
- private final WriteableModificationNode node;
- private final DOMDataTreeWriteCursor cursor;
-
- protected WritableNodeOperation(final WriteableModificationNode node, final DOMDataTreeWriteCursor cursor) {
- this.node = requireNonNull(node);
- this.cursor = requireNonNull(cursor);
- }
-
- protected final DOMDataTreeWriteCursor getCursor() {
- return cursor;
- }
-
- private void delete(final PathArgument arg, final WriteableModificationNode potentialChild) {
- cursor.delete(arg);
- if (potentialChild != null) {
- potentialChild.markDeleted();
- }
- }
-
- @Override
- public final void delete(final PathArgument arg) {
- delete(arg, node.getChild(arg));
- }
-
- @Override
- public final void merge(final PathArgument arg, final NormalizedNode<?, ?> data) {
- WriteableModificationNode potentialChild = node.getChild(arg);
- if (potentialChild == null) {
- cursor.merge(arg, data);
- } else {
- potentialChild.createOperation(cursor).mergeToCurrent((NormalizedNodeContainer<?, ?, ?>) data);
- }
- }
-
- @Override
- public final void write(final PathArgument arg, final NormalizedNode<?, ?> data) {
- WriteableModificationNode potentialChild = node.getChild(arg);
- if (potentialChild == null) {
- cursor.write(arg, data);
- } else {
- potentialChild.createOperation(cursor).writeToCurrent((NormalizedNodeContainer<?, ?, ?>) data);
- }
- }
-
- @Override
- public final WriteCursorStrategy enter(final PathArgument arg) {
- cursor.enter(arg);
- WriteableModificationNode child = node.getChild(arg);
- if (child != null) {
- return child.createOperation(cursor);
- }
- return new DelegatingWriteCursorStrategy() {
- @Override
- protected DOMDataTreeWriteCursor delegate() {
- return cursor;
- }
- };
- }
-
- @Override
- public final void mergeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
- for (NormalizedNode<?, ?> child : data.getValue()) {
- PathArgument childId = child.getIdentifier();
- WriteableModificationNode shardChild = node.getChild(childId);
- if (shardChild != null) {
- // FIXME: Decompose somehow
- throw new UnsupportedOperationException("Not implemented yet");
- }
-
- cursor.merge(childId, child);
- }
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- public final void writeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
- // write the entire thing into the cursor
- write(data.getIdentifier(), data);
- // write the children with subshard check and subshard write if we are going into subshard
- cursor.enter(data.getIdentifier());
- for (NormalizedNode<?, ?> writtenChild : data.getValue()) {
- write(writtenChild.getIdentifier(), writtenChild);
- }
- // Delete step - remove subshard data that was written into current shard
- // delete from current
- node.getChildrenWithSubshards().entrySet()
- .stream().filter(entry -> entry.getValue() instanceof WriteableSubshardBoundaryNode).forEach(entry -> {
- @SuppressWarnings("unchecked")
- Optional<NormalizedNode<?, ?>> writtenValue =
- ((NormalizedNodeContainer) data).getChild(entry.getKey());
- if (writtenValue.isPresent()) {
- // delete from current
- cursor.delete(entry.getKey());
- }
- });
-
- cursor.exit();
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-@Deprecated(forRemoval = true)
-public interface WriteCursorStrategy extends CursorStrategy {
-
- @Override
- WriteCursorStrategy enter(PathArgument arg);
-
- void delete(PathArgument arg);
-
- void merge(PathArgument arg, NormalizedNode<?, ?> data);
-
- void write(PathArgument arg, NormalizedNode<?, ?> data);
-
- void mergeToCurrent(NormalizedNodeContainer<?, ?, ?> data);
-
- void writeToCurrent(NormalizedNodeContainer<?, ?, ?> data);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
-
-/**
- * Indicates that a shard is writable via the provided {@link #createProducer(Collection) createProducer} method.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public interface WriteableDOMDataTreeShard extends DOMDataTreeShard {
-
- /**
- * Create a producer that has the ability to write into the provided subtrees.
- *
- * @param paths Subtrees that the caller wants to write into.
- * @return Producer.
- */
- DOMDataTreeShardProducer createProducer(Collection<DOMDataTreeIdentifier> paths);
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-/**
- * Writable node that can have subshard children somewhere on lower level.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-public abstract class WriteableModificationNode implements Identifiable<PathArgument> {
-
- /**
- * Gets child which is on path towards subshard.
- *
- * @return null if requested child is not subshard or enclosing node of any subshard.
- */
- public abstract @Nullable WriteableModificationNode getChild(@NonNull PathArgument node);
-
- public abstract Map<PathArgument, WriteableModificationNode> getChildrenWithSubshards();
-
- /**
- * Creates operation used to modify this node and its children.
- *
- * @param parentCursor Cursor associated with parent shard
- * @return WriteableOperation for this node.
- */
- public abstract WriteCursorStrategy createOperation(DOMDataTreeWriteCursor parentCursor);
-
- public abstract void markDeleted();
-
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-@Beta
-@Deprecated(forRemoval = true)
-public abstract class WriteableNodeWithSubshard extends WriteableModificationNode {
-
- private final Map<PathArgument, WriteableModificationNode> children;
-
- protected WriteableNodeWithSubshard(final Map<PathArgument, WriteableModificationNode> children) {
- this.children = ImmutableMap.copyOf(children);
- }
-
- @Override
- public Map<PathArgument, WriteableModificationNode> getChildrenWithSubshards() {
- return children;
- }
-
- @Override
- public WriteableModificationNode getChild(final PathArgument node) {
- return children.get(node);
- }
-
- @Override
- public void markDeleted() {
- for (WriteableModificationNode child : children.values()) {
- child.markDeleted();
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-/**
- * Writable node that is located at a boundary to a subshard.
- *
- * @deprecated This interface is scheduled for removal in the next major release.
- */
-@Deprecated(forRemoval = true)
-@Beta
-public class WriteableSubshardBoundaryNode extends WriteableModificationNode {
-
- private final ForeignShardModificationContext boundary;
-
- WriteableSubshardBoundaryNode(final ForeignShardModificationContext boundary) {
- this.boundary = requireNonNull(boundary);
- }
-
- public static WriteableSubshardBoundaryNode from(final ForeignShardModificationContext value) {
- return new WriteableSubshardBoundaryNode(value);
- }
-
- @Override
- public PathArgument getIdentifier() {
- return boundary.getIdentifier().getRootIdentifier().getLastPathArgument();
- }
-
- @Override
- public WriteCursorStrategy createOperation(final DOMDataTreeWriteCursor parentCursor) {
- return new DelegatingWriteCursorStrategy() {
- @Override
- public void exit() {
- parentCursor.exit();
- }
-
- @Override
- protected DelegatingWriteCursorStrategy childStrategy() {
- return new DelegatingWriteCursorStrategy() {
- @Override
- protected DOMDataTreeWriteCursor delegate() {
- return boundary.getCursor();
- }
- };
- }
-
- @Override
- protected DOMDataTreeWriteCursor delegate() {
- return boundary.getCursor();
- }
- };
- }
-
- @Override
- public WriteableModificationNode getChild(final PathArgument node) {
- // Another level of nesting should be taken care of by underlying cursor.
- return null;
- }
-
- @Override
- public void markDeleted() {
- // FIXME: Should we delete all data or disconnect?
- }
-
- @Override
- public Map<PathArgument, WriteableModificationNode> getChildrenWithSubshards() {
- return ImmutableMap.of();
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ChildShardContextTest {
-
- @Test
- public void basicTest() throws Exception {
- final WriteableDOMDataTreeShard writeableDOMDataTreeShard = mock(WriteableDOMDataTreeShard.class);
- final ChildShardContext childShardContext =
- new ChildShardContext(TestUtils.DOM_DATA_TREE_IDENTIFIER, writeableDOMDataTreeShard);
-
- Assert.assertEquals(childShardContext.getPrefix(), TestUtils.DOM_DATA_TREE_IDENTIFIER);
- assertEquals(childShardContext.getShard(), writeableDOMDataTreeShard);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import java.util.Optional;
-import org.junit.After;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshotCursor;
-
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class DelegatingReadableCursorOperationTest {
- @Mock
- public DataTreeSnapshotCursor mockCursorSnapshot;
-
- @Test
- public void basicTest() throws Exception {
- doReturn(Optional.empty()).when(mockCursorSnapshot).readNode(TestUtils.PATH_ARGUMENT);
- doNothing().when(mockCursorSnapshot).exit();
- doNothing().when(mockCursorSnapshot).enter(TestUtils.PATH_ARGUMENT);
- doReturn("test").when(TestUtils.PATH_ARGUMENT).toString();
-
- final var op = new DelegatingReadableCursorOperation() {
- @Override
- protected DataTreeSnapshotCursor delegate() {
- return mockCursorSnapshot;
- }
- };
-
- assertFalse(op.readNode(TestUtils.PATH_ARGUMENT).isPresent());
- verify(mockCursorSnapshot).readNode(TestUtils.PATH_ARGUMENT);
-
- op.exit();
- verify(mockCursorSnapshot).exit();
-
- assertEquals(op, op.enter(TestUtils.PATH_ARGUMENT));
- verify(mockCursorSnapshot).enter(TestUtils.PATH_ARGUMENT);
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableList;
-import org.junit.After;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-
-public class DelegatingWriteCursorStrategyTest extends DelegatingWriteCursorStrategy {
-
- @Test
- public void basicTest() throws Exception {
- doReturn("TestPathArgument").when(TestUtils.PATH_ARGUMENT).toString();
- assertEquals(this, this.childStrategy());
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).enter(TestUtils.PATH_ARGUMENT);
- this.enter(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).enter(TestUtils.PATH_ARGUMENT);
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).delete(TestUtils.PATH_ARGUMENT);
- this.delete(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).delete(TestUtils.PATH_ARGUMENT);
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- this.merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
-
- doReturn(ImmutableList.of(TestUtils.NORMALIZED_NODE)).when(TestUtils.NORMALIZED_NODE_CONTAINER).getValue();
- doReturn(TestUtils.PATH_ARGUMENT).when(TestUtils.NORMALIZED_NODE).getIdentifier();
- this.mergeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR, times(2))
- .merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- this.write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
-
- this.writeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR, times(2))
- .write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- this.exit();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- }
-
- @Override
- protected DOMDataTreeWriteCursor delegate() {
- return TestUtils.DOM_DATA_TREE_WRITE_CURSOR;
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.only;
-import static org.mockito.Mockito.verify;
-
-import org.junit.After;
-import org.junit.Test;
-
-public class ForeignShardModificationContextTest {
-
- @Test
- public void basicTest() throws Exception {
- final ForeignShardModificationContext foreignShardModificationContext =
- new ForeignShardModificationContext(TestUtils.DOM_DATA_TREE_IDENTIFIER,
- TestUtils.DOM_DATA_TREE_SHARD_PRODUCER);
- doReturn("testTransaction").when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).toString();
- assertFalse(foreignShardModificationContext.isModified());
- doReturn(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION)
- .when(TestUtils.DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- doReturn(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(TestUtils.DOM_DATA_TREE_IDENTIFIER);
- foreignShardModificationContext.getCursor();
- verify(TestUtils.DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(TestUtils.DOM_DATA_TREE_IDENTIFIER);
- assertTrue(foreignShardModificationContext.isModified());
-
- doNothing().when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).close();
- foreignShardModificationContext.ready();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR, only()).close();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
-
- doReturn(null).when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).validate();
- foreignShardModificationContext.validate();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).validate();
-
- doReturn(null).when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).prepare();
- foreignShardModificationContext.prepare();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).prepare();
-
- doReturn(null).when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).commit();
- foreignShardModificationContext.submit();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).commit();
- }
-
- @Test
- public void basicTestClose() throws Exception {
- final ForeignShardModificationContext foreignShardModificationContext =
- new ForeignShardModificationContext(TestUtils.DOM_DATA_TREE_IDENTIFIER,
- TestUtils.DOM_DATA_TREE_SHARD_PRODUCER);
- doReturn(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION)
- .when(TestUtils.DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- doReturn(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(TestUtils.DOM_DATA_TREE_IDENTIFIER);
- doNothing().when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).close();
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).close();
- foreignShardModificationContext.getCursor();
- foreignShardModificationContext.closeForeignTransaction();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).close();
- verify(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).close();
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.mdsal.dom.spi.shard.TestUtils.DOM_DATA_TREE_IDENTIFIER;
-import static org.opendaylight.mdsal.dom.spi.shard.TestUtils.DOM_DATA_TREE_SHARD_PRODUCER;
-import static org.opendaylight.mdsal.dom.spi.shard.TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION;
-import static org.opendaylight.mdsal.dom.spi.shard.TestUtils.DOM_DATA_TREE_WRITE_CURSOR;
-import static org.opendaylight.mdsal.dom.spi.shard.TestUtils.resetMocks;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ForeignShardThreePhaseCommitCohortTest {
- @Before
- public void setUp() throws Exception {
- doNothing().when(DOM_DATA_TREE_WRITE_CURSOR).close();
- }
-
- @Test
- public void basicTest() throws Exception {
- final ForeignShardModificationContext foreignShardModificationContext =
- new ForeignShardModificationContext(DOM_DATA_TREE_IDENTIFIER, DOM_DATA_TREE_SHARD_PRODUCER);
- doReturn(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).when(DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- doReturn(DOM_DATA_TREE_WRITE_CURSOR)
- .when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(DOM_DATA_TREE_IDENTIFIER);
- doNothing().when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
-
- foreignShardModificationContext.getCursor();
- foreignShardModificationContext.ready();
- final ForeignShardThreePhaseCommitCohort foreignShardThreePhaseCommitCohort =
- new ForeignShardThreePhaseCommitCohort(DOM_DATA_TREE_IDENTIFIER, foreignShardModificationContext);
-
- doReturn(null).when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).prepare();
- foreignShardThreePhaseCommitCohort.preCommit();
- verify(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).prepare();
-
- doReturn(null).when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).validate();
- foreignShardThreePhaseCommitCohort.canCommit();
- verify(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).validate();
-
- doReturn(null).when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).commit();
- foreignShardThreePhaseCommitCohort.commit();
- verify(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).commit();
-
- assertNull(foreignShardThreePhaseCommitCohort.abort().get());
- }
-
- @After
- public void reset() {
- resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-
-public class ModificationContextNodeBuilderTest extends ModificationContextNodeBuilder {
-
- @Test
- public void basicTest() throws Exception {
- final ForeignShardModificationContext foreignShardModificationContext =
- new ForeignShardModificationContext(
- TestUtils.DOM_DATA_TREE_IDENTIFIER, TestUtils.DOM_DATA_TREE_SHARD_PRODUCER);
- final WriteableSubshardBoundaryNode writeableSubshardBoundaryNode =
- WriteableSubshardBoundaryNode.from(foreignShardModificationContext);
- super.addBoundary(TestUtils.PATH_ARGUMENT, writeableSubshardBoundaryNode);
-
- assertNotNull(super.getInterior(TestUtils.PATH_ARGUMENT));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import java.util.HashSet;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-
-final class TestUtils {
-
- static final DOMDataTreeIdentifier DOM_DATA_TREE_IDENTIFIER =
- new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty());
-
- static final PathArgument PATH_ARGUMENT = mock(PathArgument.class);
-
- static final NodeIdentifier NODE_IDENTIFIER = NodeIdentifier.create(QName.create("", "test"));
-
- static final NormalizedNode<?, ?> NORMALIZED_NODE = mock(NormalizedNode.class);
-
- static final NormalizedNodeContainer NORMALIZED_NODE_CONTAINER = mock(NormalizedNodeContainer.class);
-
- static final DOMStoreThreePhaseCommitCohort DOM_STORE_THREE_PHASE_COMMIT_COHORT =
- mock(DOMStoreThreePhaseCommitCohort.class);
-
- static final Collection<DOMStoreThreePhaseCommitCohort> COHORTS = new HashSet<>();
-
- static final ListenableFuture<?> LISTENABLE_FUTURE = mock(ListenableFuture.class);
-
- static final WriteableModificationNode WRITEABLE_MODIFICATION_NODE = mock(WriteableSubshardBoundaryNode.class);
-
- static final DOMDataTreeWriteCursor DOM_DATA_TREE_WRITE_CURSOR = mock(DOMDataTreeWriteCursor.class);
-
- static final WriteCursorStrategy WRITE_CURSOR_STRATEGY = mock(WriteCursorStrategy.class);
-
- static final DOMDataTreeShardProducer DOM_DATA_TREE_SHARD_PRODUCER = mock(DOMDataTreeShardProducer.class);
-
- static final DOMDataTreeShardWriteTransaction DOM_DATA_TREE_SHARD_WRITE_TRANSACTION =
- mock(DOMDataTreeShardWriteTransaction.class);
-
- static final DataTree DATA_TREE = mock(DataTree.class);
-
- static void resetMocks() {
- reset(WRITE_CURSOR_STRATEGY, DOM_DATA_TREE_WRITE_CURSOR, WRITEABLE_MODIFICATION_NODE, LISTENABLE_FUTURE,
- DOM_STORE_THREE_PHASE_COMMIT_COHORT, NORMALIZED_NODE_CONTAINER, NORMALIZED_NODE, PATH_ARGUMENT,
- DOM_DATA_TREE_SHARD_PRODUCER, DOM_DATA_TREE_SHARD_WRITE_TRANSACTION, DATA_TREE);
- }
-
- private TestUtils() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-}
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.verify;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-public class WritableInteriorNodeTest {
-
- @Test
- public void basicTest() throws Exception {
- doNothing().when(TestUtils.WRITEABLE_MODIFICATION_NODE).markDeleted();
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
-
- final Map<PathArgument, WriteableModificationNode> children = new HashMap<>();
- children.put(TestUtils.NODE_IDENTIFIER, TestUtils.WRITEABLE_MODIFICATION_NODE);
-
- final WritableInteriorNode writableInteriorNode = new WritableInteriorNode(TestUtils.NODE_IDENTIFIER, children);
- Assert.assertEquals(writableInteriorNode.getIdentifier(), TestUtils.NODE_IDENTIFIER);
-
- writableInteriorNode.createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Optional;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-public class WritableNodeOperationTest extends WritableNodeOperation {
-
- @Test
- public void enterTest() throws Exception {
- Assert.assertEquals(TestUtils.DOM_DATA_TREE_WRITE_CURSOR, this.getCursor());
-
- returnNull();
- Assert.assertEquals(TestUtils.DOM_DATA_TREE_WRITE_CURSOR.toString(),
- this.enter(TestUtils.PATH_ARGUMENT).toString());
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).enter(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.WRITEABLE_MODIFICATION_NODE).getChild(TestUtils.PATH_ARGUMENT);
-
- returnNoNull();
- this.enter(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.WRITEABLE_MODIFICATION_NODE).createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR);
- }
-
- @Test
- public void writeTest() throws Exception {
- returnNull();
- this.write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
-
- returnNoNull(TestUtils.NORMALIZED_NODE_CONTAINER);
- this.write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.WRITE_CURSOR_STRATEGY).writeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- }
-
- @Test
- public void writeToCurrentTest() throws Exception {
- returnNull();
- Map<PathArgument, WriteableModificationNode> childrenWithSubShards = new HashMap<>();
- childrenWithSubShards.put(TestUtils.PATH_ARGUMENT, TestUtils.WRITEABLE_MODIFICATION_NODE);
- doReturn(childrenWithSubShards).when(TestUtils.WRITEABLE_MODIFICATION_NODE).getChildrenWithSubshards();
- doReturn(Optional.of(TestUtils.NORMALIZED_NODE))
- .when(TestUtils.NORMALIZED_NODE_CONTAINER).getChild(TestUtils.PATH_ARGUMENT);
- this.writeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).delete(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- }
-
- @Test
- public void mergeTest() throws Exception {
- returnNull();
- this.merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
-
- returnNoNull(TestUtils.NORMALIZED_NODE_CONTAINER);
- this.merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.WRITE_CURSOR_STRATEGY).mergeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- }
-
- @Test
- public void deleteTest() throws Exception {
- returnNoNull();
- this.delete(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).delete(TestUtils.PATH_ARGUMENT);
- verify(TestUtils.WRITEABLE_MODIFICATION_NODE).markDeleted();
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void mergeToCurrentTestWithException() throws Exception {
- returnNoNull();
- this.mergeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- }
-
- @Test
- public void mergeToCurrentTest() throws Exception {
- returnNull();
- this.mergeToCurrent(TestUtils.NORMALIZED_NODE_CONTAINER);
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- }
-
- private static void returnNull() {
- doReturn(null).when(TestUtils.WRITEABLE_MODIFICATION_NODE).getChild(TestUtils.PATH_ARGUMENT);
- doReturn(null).when(TestUtils.WRITEABLE_MODIFICATION_NODE)
- .createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR);
- }
-
- private static void returnNoNull() {
- returnNoNull(null);
- }
-
- private static void returnNoNull(final NormalizedNodeContainer<?, ?, ?> normalizedNode) {
- if (normalizedNode != null) {
- doNothing().when(TestUtils.WRITE_CURSOR_STRATEGY).writeToCurrent(normalizedNode);
- doNothing().when(TestUtils.WRITE_CURSOR_STRATEGY).mergeToCurrent(normalizedNode);
- doReturn(TestUtils.WRITE_CURSOR_STRATEGY)
- .when(TestUtils.WRITEABLE_MODIFICATION_NODE).createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR);
- }
-
- doReturn(TestUtils.WRITEABLE_MODIFICATION_NODE)
- .when(TestUtils.WRITEABLE_MODIFICATION_NODE).getChild(TestUtils.PATH_ARGUMENT);
- doNothing().when(TestUtils.WRITEABLE_MODIFICATION_NODE).markDeleted();
- }
-
- @Before
- public void setUp() {
- final Collection<NormalizedNode<?, ?>> collectionNodes = new HashSet<>();
- doReturn("testArgument").when(TestUtils.PATH_ARGUMENT).toString();
- doReturn("testCursor").when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).toString();
- doReturn("testNode").when(TestUtils.NORMALIZED_NODE).toString();
- doReturn("testNodeContainer").when(TestUtils.NORMALIZED_NODE_CONTAINER).toString();
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).enter(TestUtils.PATH_ARGUMENT);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .write(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .merge(TestUtils.PATH_ARGUMENT, TestUtils.NORMALIZED_NODE_CONTAINER);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).delete(TestUtils.PATH_ARGUMENT);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
-
- collectionNodes.add(TestUtils.NORMALIZED_NODE);
- doReturn(collectionNodes).when(TestUtils.NORMALIZED_NODE_CONTAINER).getValue();
- doReturn(TestUtils.PATH_ARGUMENT).when(TestUtils.NORMALIZED_NODE_CONTAINER).getIdentifier();
- doReturn(TestUtils.PATH_ARGUMENT).when(TestUtils.NORMALIZED_NODE).getIdentifier();
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-
- public WritableNodeOperationTest() {
- super(TestUtils.WRITEABLE_MODIFICATION_NODE, TestUtils.DOM_DATA_TREE_WRITE_CURSOR);
- }
-
- @Override
- public void exit() {
- // NOOP
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-public class WriteableNodeWithSubshardTest {
-
- @Test
- public void basicTest() throws Exception {
- doReturn("test").when(TestUtils.WRITEABLE_MODIFICATION_NODE).toString();
- doNothing().when(TestUtils.WRITEABLE_MODIFICATION_NODE).markDeleted();
-
- final Map<PathArgument, WriteableModificationNode> children = new HashMap<>();
- children.put(TestUtils.NODE_IDENTIFIER, TestUtils.WRITEABLE_MODIFICATION_NODE);
-
- final WriteableNodeWithSubshard writeableNodeWithSubshard = new WriteableNodeWithSubshardImpl(children);
-
- assertEquals(writeableNodeWithSubshard.getChildrenWithSubshards(), children);
-
- final WriteableModificationNode TestWriteableModificationNode =
- writeableNodeWithSubshard.getChild(TestUtils.NODE_IDENTIFIER);
- assertNotNull(TestWriteableModificationNode);
- Assert.assertEquals(TestWriteableModificationNode, TestUtils.WRITEABLE_MODIFICATION_NODE);
-
- writeableNodeWithSubshard.markDeleted();
- verify(TestUtils.WRITEABLE_MODIFICATION_NODE).markDeleted();
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-
- private static final class WriteableNodeWithSubshardImpl extends WriteableNodeWithSubshard {
-
- WriteableNodeWithSubshardImpl(final Map<PathArgument, WriteableModificationNode> children) {
- super(children);
- }
-
- @Override
- public WriteCursorStrategy createOperation(final DOMDataTreeWriteCursor parentCursor) {
- return null;
- }
-
- @Override
- public PathArgument getIdentifier() {
- throw new UnsupportedOperationException();
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.dom.spi.shard;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-
-public class WriteableSubshardBoundaryNodeTest {
-
- private static final ForeignShardModificationContext FOREIGN_SHARD_MODIFICATION_CONTEXT =
- new ForeignShardModificationContext(
- TestUtils.DOM_DATA_TREE_IDENTIFIER, TestUtils.DOM_DATA_TREE_SHARD_PRODUCER);
-
- @Test
- public void createOperation() throws Exception {
- final WriteableSubshardBoundaryNode writeableSubshardBoundaryNode =
- WriteableSubshardBoundaryNode.from(FOREIGN_SHARD_MODIFICATION_CONTEXT);
-
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- doReturn(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION)
- .when(TestUtils.DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
- doReturn(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .when(TestUtils.DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(TestUtils.DOM_DATA_TREE_IDENTIFIER);
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR)
- .enter(TestUtils.DOM_DATA_TREE_IDENTIFIER.getRootIdentifier().getLastPathArgument());
- doNothing().when(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
-
- writeableSubshardBoundaryNode.createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR).exit();
-
- WriteCursorStrategy writeCursorStrategy =
- writeableSubshardBoundaryNode.createOperation(TestUtils.DOM_DATA_TREE_WRITE_CURSOR);
- assertNotNull(writeCursorStrategy);
-
- WriteCursorStrategy childWriteCursorStrategy =
- writeCursorStrategy.enter(TestUtils.DOM_DATA_TREE_IDENTIFIER.getRootIdentifier().getLastPathArgument());
- childWriteCursorStrategy.exit();
- verify(TestUtils.DOM_DATA_TREE_WRITE_CURSOR, times(2)).exit();
- }
-
- @Test
- public void getChildrenWithSubshards() throws Exception {
- final WriteableSubshardBoundaryNode writeableSubshardBoundaryNode =
- WriteableSubshardBoundaryNode.from(FOREIGN_SHARD_MODIFICATION_CONTEXT);
-
- assertNotNull(writeableSubshardBoundaryNode.getChildrenWithSubshards());
- assertSame(ImmutableMap.of(), writeableSubshardBoundaryNode.getChildrenWithSubshards());
- Assert.assertEquals(TestUtils.DOM_DATA_TREE_IDENTIFIER.getRootIdentifier().getLastPathArgument(),
- writeableSubshardBoundaryNode.getIdentifier());
- assertNull(writeableSubshardBoundaryNode.getChild(mock(PathArgument.class)));
- }
-
- @After
- public void reset() {
- TestUtils.resetMocks();
- }
-}
\ No newline at end of file