d16170ba481d7d1a295a6acdcf33ae83b73b8a7d
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / BindingTranslatedTransactionChain.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.md.sal.binding.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
23 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
25 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
26 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
27 import org.opendaylight.yangtools.concepts.Delegator;
28
29 class BindingTranslatedTransactionChain implements BindingTransactionChain, Delegator<DOMTransactionChain> {
30
31     private final DOMTransactionChain delegate;
32     private final BindingToNormalizedNodeCodec codec;
33     private final DelegateChainListener delegatingListener;
34     private final TransactionChainListener listener;
35
36     public BindingTranslatedTransactionChain(final DOMDataBroker chainFactory,
37             final BindingToNormalizedNodeCodec codec, final TransactionChainListener listener) {
38         Preconditions.checkNotNull(chainFactory, "DOM Transaction chain factory must not be null");
39         this.delegatingListener = new DelegateChainListener();
40         this.listener = listener;
41         this.delegate = chainFactory.createTransactionChain(listener);
42         this.codec = codec;
43     }
44
45     @Override
46     public DOMTransactionChain getDelegate() {
47         return delegate;
48     }
49
50     @Override
51     public ReadOnlyTransaction newReadOnlyTransaction() {
52         DOMDataReadOnlyTransaction delegateTx = delegate.newReadOnlyTransaction();
53         ReadOnlyTransaction bindingTx = new BindingDataReadTransactionImpl(delegateTx, codec);
54         return bindingTx;
55     }
56
57     @Override
58     public ReadWriteTransaction newReadWriteTransaction() {
59         DOMDataReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
60         ReadWriteTransaction bindingTx = new BindingDataReadWriteTransactionImpl(delegateTx, codec) {
61
62             @Override
63             public CheckedFuture<Void, TransactionCommitFailedException> submit() {
64                 return listenForFailure(this,super.submit());
65             }
66
67         };
68         return bindingTx;
69     }
70
71     @Override
72     public WriteTransaction newWriteOnlyTransaction() {
73         final DOMDataWriteTransaction delegateTx = delegate.newWriteOnlyTransaction();
74         WriteTransaction bindingTx = new BindingDataWriteTransactionImpl<DOMDataWriteTransaction>(delegateTx, codec) {
75
76             @Override
77             public CheckedFuture<Void,TransactionCommitFailedException> submit() {
78                 return listenForFailure(this,super.submit());
79             };
80
81         };
82         return bindingTx;
83     }
84
85     protected CheckedFuture<Void, TransactionCommitFailedException> listenForFailure(
86             final WriteTransaction tx, CheckedFuture<Void, TransactionCommitFailedException> future) {
87         Futures.addCallback(future, new FutureCallback<Void>() {
88             @Override
89             public void onFailure(Throwable t) {
90                 failTransactionChain(tx,t);
91             }
92
93             @Override
94             public void onSuccess(Void result) {
95                 // Intentionally NOOP
96             }
97         });
98
99         return future;
100     }
101
102     protected void failTransactionChain(WriteTransaction tx, Throwable t) {
103         // We asume correct state change for underlaying transaction
104         // chain, so we are not changing any of our internal state
105         // to mark that we failed.
106         this.delegatingListener.onTransactionChainFailed(this, tx, t);
107     }
108
109     @Override
110     public void close() {
111         delegate.close();
112     }
113
114     private final class DelegateChainListener implements TransactionChainListener {
115
116         @Override
117         public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
118                 final AsyncTransaction<?, ?> transaction, final Throwable cause) {
119             /*
120              * Intentionally NOOP, callback for failure, since we
121              * are also listening on each transaction for failure.
122              *
123              * by listening on submit future for Binding transaction
124              * in order to provide Binding transaction (which was seen by client
125              * of this transaction chain, instead of
126             */
127         }
128
129         @Override
130         public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
131             Preconditions.checkState(delegate.equals(chain),
132                     "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
133             listener.onTransactionChainSuccessful(BindingTranslatedTransactionChain.this);
134         }
135     }
136
137 }