Bug 8153: Enforce check-style rules for netconf - sal-netconf-connector
[netconf.git] / netconf / sal-netconf-connector / src / main / java / org / opendaylight / netconf / sal / connect / netconf / sal / tx / TxChain.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
10
11 import com.google.common.base.Preconditions;
12 import java.util.HashMap;
13 import java.util.Map;
14 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
15 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
16 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
20 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * {@link DOMTransactionChain} implementation for Netconf connector.
26  */
27 public class TxChain implements DOMTransactionChain, TxListener {
28
29     private static final Logger LOG = LoggerFactory.getLogger(TxChain.class);
30
31     private final DOMDataBroker dataBroker;
32     private final TransactionChainListener listener;
33     /**
34      * Submitted transactions that haven't completed yet.
35      */
36     private final Map<DOMDataWriteTransaction, AutoCloseable> pendingTransactions = new HashMap<>();
37
38     /**
39      * Transaction created by this chain that hasn't been submitted or cancelled yet.
40      */
41     private AbstractWriteTx currentTransaction = null;
42     private boolean closed = false;
43     private boolean successful = true;
44
45     public TxChain(final DOMDataBroker dataBroker, final TransactionChainListener listener) {
46         this.dataBroker = dataBroker;
47         this.listener = listener;
48     }
49
50     @Override
51     public synchronized DOMDataReadOnlyTransaction newReadOnlyTransaction() {
52         checkOperationPermitted();
53         return dataBroker.newReadOnlyTransaction();
54     }
55
56     @Override
57     public synchronized AbstractWriteTx newWriteOnlyTransaction() {
58         checkOperationPermitted();
59         final DOMDataWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
60         Preconditions.checkState(writeTransaction instanceof AbstractWriteTx);
61         final AbstractWriteTx pendingWriteTx = (AbstractWriteTx) writeTransaction;
62         pendingTransactions.put(pendingWriteTx, pendingWriteTx.addListener(this));
63         currentTransaction = pendingWriteTx;
64         return pendingWriteTx;
65     }
66
67     @Override
68     public synchronized DOMDataReadWriteTransaction newReadWriteTransaction() {
69         return new ReadWriteTx(dataBroker.newReadOnlyTransaction(), newWriteOnlyTransaction());
70     }
71
72     @Override
73     public synchronized void close() {
74         if (!closed) {
75             closed = true;
76             notifyChainListenerSuccess();
77         }
78     }
79
80     @Override
81     public synchronized void onTransactionSuccessful(final AbstractWriteTx transaction) {
82         removePendingTx(transaction);
83         notifyChainListenerSuccess();
84     }
85
86     @Override
87     public synchronized void onTransactionFailed(final AbstractWriteTx transaction, final Throwable cause) {
88         removePendingTx(transaction);
89         successful = false;
90         if (currentTransaction != null) {
91             currentTransaction.cancel();
92         }
93         listener.onTransactionChainFailed(this, transaction, cause);
94     }
95
96     @Override
97     public synchronized void onTransactionSubmitted(final AbstractWriteTx transaction) {
98         currentTransaction = null;
99     }
100
101     @Override
102     public synchronized void onTransactionCancelled(final AbstractWriteTx transaction) {
103         removePendingTx(transaction);
104         currentTransaction = null;
105     }
106
107     @SuppressWarnings("checkstyle:IllegalCatch")
108     private void removePendingTx(final AbstractWriteTx transaction) {
109         try {
110             pendingTransactions.remove(transaction).close();
111         } catch (final Exception e) {
112             LOG.error("Can't remove transaction listener registration", e);
113         }
114     }
115
116     /**
117      * Checks, if chain isn't closed and if there is no not submitted write transaction waiting.
118      */
119     private void checkOperationPermitted() {
120         if (closed) {
121             throw new TransactionChainClosedException("Transaction chain was closed");
122         }
123         Preconditions.checkState(currentTransaction == null, "Last write transaction has not finished yet");
124     }
125
126     private void notifyChainListenerSuccess() {
127         if (closed && pendingTransactions.isEmpty() && successful) {
128             listener.onTransactionChainSuccessful(this);
129         }
130     }
131
132 }