2 * Copyright (c) 2015 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
9 package org.opendaylight.netconf.mdsal.connector;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.controller.config.util.xml.DocumentedException;
17 import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
18 import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
19 import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 public class TransactionProvider implements AutoCloseable {
28 private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class);
30 private final DOMDataBroker dataBroker;
32 private DOMDataReadWriteTransaction candidateTransaction = null;
33 private DOMDataReadWriteTransaction runningTransaction = null;
34 private final List<DOMDataReadWriteTransaction> allOpenReadWriteTransactions = new ArrayList<>();
36 private final String netconfSessionIdForReporting;
38 private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No candidateTransaction found for session ";
40 public TransactionProvider(final DOMDataBroker dataBroker, final String netconfSessionIdForReporting) {
41 this.dataBroker = dataBroker;
42 this.netconfSessionIdForReporting = netconfSessionIdForReporting;
46 public synchronized void close() throws Exception {
47 for (final DOMDataReadWriteTransaction rwt : allOpenReadWriteTransactions) {
51 allOpenReadWriteTransactions.clear();
54 public synchronized Optional<DOMDataReadWriteTransaction> getCandidateTransaction() {
55 if (candidateTransaction == null) {
56 return Optional.absent();
59 return Optional.of(candidateTransaction);
62 public synchronized DOMDataReadWriteTransaction getOrCreateTransaction() {
63 if (getCandidateTransaction().isPresent()) {
64 return getCandidateTransaction().get();
67 candidateTransaction = dataBroker.newReadWriteTransaction();
68 allOpenReadWriteTransactions.add(candidateTransaction);
69 return candidateTransaction;
72 public synchronized boolean commitTransaction() throws DocumentedException {
73 if (!getCandidateTransaction().isPresent()) {
74 //making empty commit without prior opened transaction, just return true
75 LOG.debug("Making commit without open candidate transaction for session {}", netconfSessionIdForReporting);
79 final CheckedFuture<Void, TransactionCommitFailedException> future = candidateTransaction.submit();
82 } catch (final TransactionCommitFailedException e) {
83 LOG.debug("Transaction {} failed on", candidateTransaction, e);
84 final String cause = e.getCause() != null ? (" Cause: " + e.getCause().getMessage()) : "";
85 throw new DocumentedException(
86 "Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting + cause, e,
87 ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR);
89 allOpenReadWriteTransactions.remove(candidateTransaction);
90 candidateTransaction = null;
96 public synchronized void abortTransaction() {
97 LOG.debug("Aborting current candidateTransaction");
98 final Optional<DOMDataReadWriteTransaction> otx = getCandidateTransaction();
99 if (!otx.isPresent()) {
100 LOG.warn("discard-changes triggerd on an empty transaction for session: {}", netconfSessionIdForReporting);
103 candidateTransaction.cancel();
104 allOpenReadWriteTransactions.remove(candidateTransaction);
105 candidateTransaction = null;
108 public synchronized DOMDataReadWriteTransaction createRunningTransaction() {
109 runningTransaction = dataBroker.newReadWriteTransaction();
110 allOpenReadWriteTransactions.add(runningTransaction);
111 return runningTransaction;
114 public synchronized void abortRunningTransaction(final DOMDataReadWriteTransaction tx) {
115 LOG.debug("Aborting current running Transaction");
116 Preconditions.checkState(runningTransaction != null,
117 NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
119 allOpenReadWriteTransactions.remove(tx);