BUG-650: speedup DOMDataBrokerTransactionChainImpl
[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 com.google.common.base.Optional;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import java.util.Map;
13 import java.util.concurrent.atomic.AtomicLong;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
16 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
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.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * NormalizedNode implementation of {@link org.opendaylight.controller.md.sal.common.api.data.TransactionChain} which is backed
26  * by several {@link DOMStoreTransactionChain} differentiated by provided
27  * {@link org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType} type.
28  *
29  */
30 public class DOMDataBrokerTransactionChainImpl extends AbstractDOMForwardedTransactionFactory<DOMStoreTransactionChain>
31         implements DOMTransactionChain, DOMDataCommitErrorListener {
32
33     private static final Logger LOG = LoggerFactory.getLogger(DOMDataBrokerTransactionChainImpl.class);
34     private final AtomicLong txNum = new AtomicLong();
35     private final DOMDataCommitExecutor coordinator;
36     private final TransactionChainListener listener;
37     private final long chainId;
38
39     private volatile boolean failed = false;
40
41     /**
42      *
43      * @param chainId
44      *            ID of transaction chain
45      * @param chains
46      *            Backing {@link DOMStoreTransactionChain}s.
47      * @param coordinator
48      *            Commit Coordinator which should be used to coordinate commits
49      *            of transaction
50      *            produced by this chain.
51      * @param listener
52      *            Listener, which listens on transaction chain events.
53      * @throws NullPointerException
54      *             If any of arguments is null.
55      */
56     public DOMDataBrokerTransactionChainImpl(final long chainId,
57             final Map<LogicalDatastoreType, DOMStoreTransactionChain> chains,
58             final DOMDataCommitExecutor coordinator, final TransactionChainListener listener) {
59         super(chains);
60         this.chainId = chainId;
61         this.coordinator = Preconditions.checkNotNull(coordinator);
62         this.listener = Preconditions.checkNotNull(listener);
63     }
64
65     @Override
66     protected Object newTransactionIdentifier() {
67         return "DOM-CHAIN-" + chainId + "-" + txNum.getAndIncrement();
68     }
69
70     @Override
71     public CheckedFuture<Void,TransactionCommitFailedException> submit(
72             final DOMDataWriteTransaction transaction, final Iterable<DOMStoreThreePhaseCommitCohort> cohorts) {
73         checkNotClosed();
74
75         return coordinator.submit(transaction, cohorts, Optional.<DOMDataCommitErrorListener> of(this));
76     }
77
78     @Override
79     public void close() {
80         super.close();
81
82         for (DOMStoreTransactionChain subChain : getTxFactories().values()) {
83             subChain.close();
84         }
85
86         if (!failed) {
87             LOG.debug("Transaction chain {}¬†successfully finished.", this);
88             // FIXME: this event should be emitted once all operations complete
89             listener.onTransactionChainSuccessful(this);
90         }
91     }
92
93     @Override
94     public void onCommitFailed(final DOMDataWriteTransaction tx, final Throwable cause) {
95         failed = true;
96         LOG.debug("Transaction chain {}¬†failed.", this, cause);
97         listener.onTransactionChainFailed(this, tx, cause);
98     }
99 }