2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.sal.connect.netconf.sal.tx;
10 import com.google.common.base.Preconditions;
11 import java.util.HashMap;
13 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
14 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
15 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
16 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
17 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
18 import org.opendaylight.mdsal.dom.api.DOMTransactionChainClosedException;
19 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * {@link DOMTransactionChain} implementation for Netconf connector.
26 public class TxChain implements DOMTransactionChain, TxListener {
28 private static final Logger LOG = LoggerFactory.getLogger(TxChain.class);
30 private final DOMDataBroker dataBroker;
31 private final DOMTransactionChainListener listener;
33 * Submitted transactions that haven't completed yet.
35 private final Map<DOMDataTreeWriteTransaction, AutoCloseable> pendingTransactions = new HashMap<>();
38 * Transaction created by this chain that hasn't been submitted or cancelled yet.
40 private AbstractWriteTx currentTransaction = null;
41 private boolean closed = false;
42 private boolean successful = true;
44 public TxChain(final DOMDataBroker dataBroker, final DOMTransactionChainListener listener) {
45 this.dataBroker = dataBroker;
46 this.listener = listener;
50 public synchronized DOMDataTreeReadTransaction newReadOnlyTransaction() {
51 checkOperationPermitted();
52 return dataBroker.newReadOnlyTransaction();
56 public synchronized AbstractWriteTx newWriteOnlyTransaction() {
57 checkOperationPermitted();
58 final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
59 Preconditions.checkState(writeTransaction instanceof AbstractWriteTx);
60 final AbstractWriteTx pendingWriteTx = (AbstractWriteTx) writeTransaction;
61 pendingTransactions.put(pendingWriteTx, pendingWriteTx.addListener(this));
62 currentTransaction = pendingWriteTx;
63 return pendingWriteTx;
67 public synchronized DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
68 return new ReadWriteTx(dataBroker.newReadOnlyTransaction(), newWriteOnlyTransaction());
72 public synchronized void close() {
75 notifyChainListenerSuccess();
80 public synchronized void onTransactionSuccessful(final AbstractWriteTx transaction) {
81 removePendingTx(transaction);
82 notifyChainListenerSuccess();
86 public synchronized void onTransactionFailed(final AbstractWriteTx transaction, final Throwable cause) {
87 removePendingTx(transaction);
89 if (currentTransaction != null) {
90 currentTransaction.cancel();
92 listener.onTransactionChainFailed(this, transaction, cause);
96 public synchronized void onTransactionSubmitted(final AbstractWriteTx transaction) {
97 currentTransaction = null;
101 public synchronized void onTransactionCancelled(final AbstractWriteTx transaction) {
102 removePendingTx(transaction);
103 currentTransaction = null;
106 @SuppressWarnings("checkstyle:IllegalCatch")
107 private void removePendingTx(final AbstractWriteTx transaction) {
109 pendingTransactions.remove(transaction).close();
110 } catch (final Exception e) {
111 LOG.error("Can't remove transaction listener registration", e);
116 * Checks, if chain isn't closed and if there is no not submitted write transaction waiting.
118 private void checkOperationPermitted() {
120 throw new DOMTransactionChainClosedException("Transaction chain was closed");
122 Preconditions.checkState(currentTransaction == null, "Last write transaction has not finished yet");
125 private void notifyChainListenerSuccess() {
126 if (closed && pendingTransactions.isEmpty() && successful) {
127 listener.onTransactionChainSuccessful(this);