2 * Copyright (c) 2014 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.controller.md.sal.common.impl.service;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.AsyncFunction;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import java.util.concurrent.Future;
16 import java.util.concurrent.TimeUnit;
17 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
18 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
19 import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
20 import org.opendaylight.yangtools.concepts.Path;
21 import org.opendaylight.yangtools.yang.common.RpcResult;
22 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 public abstract class AbstractDataTransaction<P extends Path<P>, D extends Object> extends
27 AbstractDataModification<P, D> {
28 private static final Logger LOG = LoggerFactory.getLogger(AbstractDataTransaction.class);
29 private static final ListenableFuture<RpcResult<TransactionStatus>> SUCCESS_FUTURE =
30 Futures.immediateFuture(RpcResultBuilder.success(TransactionStatus.COMMITED).build());
32 private final Object identifier;
33 private final long allocationTime;
34 private long readyTime = 0;
35 private long completeTime = 0;
37 private TransactionStatus status = TransactionStatus.NEW;
39 private final AbstractDataBroker<P, D, ? extends Object> broker;
41 protected AbstractDataTransaction(final Object identifier,
42 final AbstractDataBroker<P, D, ? extends Object> dataBroker) {
44 this.identifier = Preconditions.checkNotNull(identifier);
45 this.broker = Preconditions.checkNotNull(dataBroker);
46 this.allocationTime = System.nanoTime();
47 LOG.debug("Transaction {} Allocated.", identifier);
51 public Object getIdentifier() {
52 return this.identifier;
56 public Future<RpcResult<TransactionStatus>> commit() {
57 readyTime = System.nanoTime();
58 if (LOG.isDebugEnabled()) {
59 LOG.debug("Transaction {} Ready after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(readyTime - allocationTime));
61 changeStatus(TransactionStatus.SUBMITED);
62 return this.broker.commit(this);
66 public D readConfigurationData(final P path) {
67 final D local = getUpdatedConfigurationData().get(path);
71 return this.broker.readConfigurationData(path);
75 public D readOperationalData(final P path) {
76 final D local = this.getUpdatedOperationalData().get(path);
80 return this.broker.readOperationalData(path);
84 public int hashCode() {
87 result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
92 public boolean equals(final Object obj) {
99 if (getClass() != obj.getClass()) {
102 AbstractDataTransaction<?, ?> other = (AbstractDataTransaction<?, ?>) obj;
103 if (identifier == null) {
104 if (other.identifier != null) {
107 } else if (!identifier.equals(other.identifier)) {
114 public TransactionStatus getStatus() {
118 protected abstract void onStatusChange(final TransactionStatus status);
120 public void succeeded() {
121 this.completeTime = System.nanoTime();
122 if (LOG.isDebugEnabled()) {
123 LOG.debug("Transaction {} Committed after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(completeTime - readyTime));
125 changeStatus(TransactionStatus.COMMITED);
128 public void failed() {
129 this.completeTime = System.nanoTime();
131 if (LOG.isDebugEnabled()) {
132 LOG.debug("Transaction {} Failed after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(completeTime - readyTime));
134 changeStatus(TransactionStatus.FAILED);
137 private void changeStatus(final TransactionStatus status) {
138 LOG.debug("Transaction {} transitioned from {} to {}", getIdentifier(), this.status, status);
139 this.status = status;
140 this.onStatusChange(status);
143 public static ListenableFuture<RpcResult<TransactionStatus>> convertToLegacyCommitFuture(final CheckedFuture<Void,TransactionCommitFailedException> from) {
144 return Futures.transform(from, new AsyncFunction<Void, RpcResult<TransactionStatus>>() {
146 public ListenableFuture<RpcResult<TransactionStatus>> apply(final Void input) {
147 return SUCCESS_FUTURE;