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 static com.google.common.base.Preconditions.checkState;
12 import java.util.HashMap;
14 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
15 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
16 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
17 import org.opendaylight.mdsal.dom.api.DOMTransactionChainClosedException;
18 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
23 * {@link DOMTransactionChain} implementation for Netconf connector.
25 abstract class AbstractTxChain implements DOMTransactionChain, TxListener {
26 private static final Logger LOG = LoggerFactory.getLogger(AbstractTxChain.class);
29 * Submitted transactions that haven't completed yet.
31 private final Map<DOMDataTreeWriteTransaction, AutoCloseable> pendingTransactions = new HashMap<>();
33 final DOMDataBroker dataBroker;
34 final DOMTransactionChainListener listener;
37 * Transaction created by this chain that hasn't been submitted or cancelled yet.
39 private AbstractWriteTx currentTransaction = null;
40 private boolean closed = false;
41 private boolean successful = true;
43 AbstractTxChain(final DOMDataBroker dataBroker, final DOMTransactionChainListener listener) {
44 this.dataBroker = dataBroker;
45 this.listener = listener;
49 public final synchronized AbstractWriteTx newWriteOnlyTransaction() {
50 checkOperationPermitted();
51 final DOMDataTreeWriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
52 checkState(writeTransaction instanceof AbstractWriteTx);
53 final AbstractWriteTx pendingWriteTx = (AbstractWriteTx) writeTransaction;
54 pendingTransactions.put(pendingWriteTx, pendingWriteTx.addListener(this));
55 currentTransaction = pendingWriteTx;
56 return pendingWriteTx;
60 public final synchronized void close() {
63 notifyChainListenerSuccess();
68 public final synchronized void onTransactionSuccessful(final AbstractWriteTx transaction) {
69 removePendingTx(transaction);
70 notifyChainListenerSuccess();
74 public final synchronized void onTransactionFailed(final AbstractWriteTx transaction, final Throwable cause) {
75 removePendingTx(transaction);
77 if (currentTransaction != null) {
78 currentTransaction.cancel();
80 listener.onTransactionChainFailed(this, transaction, cause);
84 public final synchronized void onTransactionSubmitted(final AbstractWriteTx transaction) {
85 currentTransaction = null;
89 public final synchronized void onTransactionCancelled(final AbstractWriteTx transaction) {
90 removePendingTx(transaction);
91 currentTransaction = null;
95 * Checks, if chain isn't closed and if there is no not submitted write transaction waiting.
97 final void checkOperationPermitted() {
99 throw new DOMTransactionChainClosedException("Transaction chain was closed");
101 checkState(currentTransaction == null, "Last write transaction has not finished yet");
104 @SuppressWarnings("checkstyle:IllegalCatch")
105 private void removePendingTx(final AbstractWriteTx transaction) {
107 pendingTransactions.remove(transaction).close();
108 } catch (final Exception e) {
109 LOG.error("Can't remove transaction listener registration", e);
113 private void notifyChainListenerSuccess() {
114 if (closed && pendingTransactions.isEmpty() && successful) {
115 listener.onTransactionChainSuccessful(this);