Fixup "Leader should always apply modifications as local" regression
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / AbstractShardDataTreeTransaction.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.base.MoreObjects;
14 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
15 import org.opendaylight.controller.cluster.datastore.persisted.AbortTransactionPayload;
16 import org.opendaylight.yangtools.concepts.Identifiable;
17 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
18
19 /**
20  * Abstract base for transactions running on SharrdDataTree. This class is NOT thread-safe.
21  *
22  * @param <T> Backing transaction type.
23  */
24 abstract class AbstractShardDataTreeTransaction<T extends DataTreeSnapshot>
25         implements Identifiable<TransactionIdentifier> {
26     private final ShardDataTreeTransactionParent parent;
27     private final TransactionIdentifier id;
28     private final T snapshot;
29
30     private boolean closed;
31
32     AbstractShardDataTreeTransaction(final ShardDataTreeTransactionParent parent, final TransactionIdentifier id,
33         final T snapshot) {
34         this.parent = requireNonNull(parent);
35         this.snapshot = requireNonNull(snapshot);
36         this.id = requireNonNull(id);
37     }
38
39     @Override
40     public final TransactionIdentifier getIdentifier() {
41         return id;
42     }
43
44     final ShardDataTreeTransactionParent getParent() {
45         return parent;
46     }
47
48     final T getSnapshot() {
49         return snapshot;
50     }
51
52     final boolean isClosed() {
53         return closed;
54     }
55
56     /**
57      * Close this transaction and mark it as closed, allowing idempotent invocations.
58      *
59      * @return True if the transaction got closed by this method invocation.
60      */
61     protected final boolean close() {
62         if (closed) {
63             return false;
64         }
65
66         closed = true;
67         return true;
68     }
69
70     final void abort(final Runnable callback) {
71         checkState(close(), "Transaction is already closed");
72         parent.abortTransaction(this, callback);
73     }
74
75     /**
76      * This method is exposed for sake of {@link ShardTransaction}, which is an actor. We need to ensure that
77      * the parent is updated to reflect the transaction has been closed, but no journal actions may be invoked.
78      *
79      * <p>
80      * ShardTransaction is responsible for additionally sending a request to persist an {@link AbortTransactionPayload}
81      * via a message to the Shard actor.
82      */
83     final void abortFromTransactionActor() {
84         if (close()) {
85             parent.abortFromTransactionActor(this);
86         }
87     }
88
89     @Override
90     public final String toString() {
91         return MoreObjects.toStringHelper(this).add("id", id).add("closed", closed).add("snapshot", snapshot)
92                 .toString();
93     }
94 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.