Bug 1073: Added support to DOMBrokerImpl for Transaction Chaining
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / DOMDataBrokerTransactionChainImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  */
7 package org.opendaylight.controller.md.sal.dom.broker.impl;
8
9 import java.util.concurrent.atomic.AtomicLong;
10
11 import javax.annotation.concurrent.GuardedBy;
12
13 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
16 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
19 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
20 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
21 import org.opendaylight.yangtools.yang.common.RpcResult;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import com.google.common.base.Optional;
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.ImmutableMap;
28 import com.google.common.util.concurrent.ListenableFuture;
29
30 /**
31  * NormalizedNode implementation of {@link TransactionChain} which is backed
32  * by several {@link DOMStoreTransactionChain} differentiated by provided
33  * {@link LogicalDatastoreType} type.
34  *
35  */
36 public class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTransactionFactory<DOMStoreTransactionChain>
37         implements DOMTransactionChain, DOMDataCommitErrorListener {
38
39     private static final Logger LOG = LoggerFactory.getLogger(DOMDataBrokerTransactionChainImpl.class);
40     private final DOMDataCommitExecutor coordinator;
41     private final TransactionChainListener listener;
42     private final long chainId;
43     private final AtomicLong txNum = new AtomicLong();
44     @GuardedBy("this")
45     private boolean failed = false;
46
47     /**
48      *
49      * @param chainId
50      *            ID of transaction chain
51      * @param chains
52      *            Backing {@link DOMStoreTransactionChain}s.
53      * @param coordinator
54      *            Commit Coordinator which should be used to coordinate commits
55      *            of transaction
56      *            produced by this chain.
57      * @param listener
58      *            Listener, which listens on transaction chain events.
59      * @throws NullPointerException
60      *             If any of arguments is null.
61      */
62     public DOMDataBrokerTransactionChainImpl(final long chainId,
63             final ImmutableMap<LogicalDatastoreType, DOMStoreTransactionChain> chains,
64             final DOMDataCommitExecutor coordinator, final TransactionChainListener listener) {
65         super(chains);
66         this.chainId = chainId;
67         this.coordinator = Preconditions.checkNotNull(coordinator);
68         this.listener = Preconditions.checkNotNull(listener);
69     }
70
71     @Override
72     protected Object newTransactionIdentifier() {
73         return "DOM-CHAIN-" + chainId + "-" + txNum.getAndIncrement();
74     }
75
76     @Override
77     public synchronized ListenableFuture<RpcResult<TransactionStatus>> commit(
78             final DOMDataWriteTransaction transaction, final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
79         return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> of(this));
80     }
81
82     @Override
83     public synchronized void close() {
84         super.close();
85         for (DOMStoreTransactionChain subChain : getTxFactories().values()) {
86             subChain.close();
87         }
88
89         if (!failed) {
90             LOG.debug("Transaction chain {} successfully finished.", this);
91             listener.onTransactionChainSuccessful(this);
92         }
93     }
94
95     @Override
96     public synchronized void onCommitFailed(final DOMDataWriteTransaction tx, final Throwable cause) {
97         failed = true;
98         LOG.debug("Transaction chain {} failed.", this, cause);
99         listener.onTransactionChainFailed(this, tx, cause);
100     }
101 }