All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opendaylight.ocpplugin.impl.device.TransactionChainManager Maven / Gradle / Ivy
/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.ocpplugin.impl.device;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* Package protected class for controlling WriteTransaction life cycle. It is
* a TransactionChainListener and provide package protected methods for writeToTransaction
* method (wrapped WriteTransaction#put(LogicalDatastoreType, InstanceIdentifier, DataObject))
* and submitTransaction method (wrapped WriteTransaction#submit())
*/
class TransactionChainManager implements TransactionChainListener, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(TransactionChainManager.class);
private final Object txLock = new Object();
private final DataBroker dataBroker;
private WriteTransaction wTx;
private BindingTransactionChain txChainFactory;
private boolean submitIsEnabled;
public TransactionChainManagerStatus getTransactionChainManagerStatus() {
return transactionChainManagerStatus;
}
private TransactionChainManagerStatus transactionChainManagerStatus;
private ReadyForNewTransactionChainHandler readyForNewTransactionChainHandler;
private final KeyedInstanceIdentifier nodeII;
private Registration managerRegistration;
TransactionChainManager(@Nonnull final DataBroker dataBroker,
@Nonnull final KeyedInstanceIdentifier nodeII,
@Nonnull final Registration managerRegistration) {
this.dataBroker = Preconditions.checkNotNull(dataBroker);
this.nodeII = Preconditions.checkNotNull(nodeII);
this.managerRegistration = Preconditions.checkNotNull(managerRegistration);
this.transactionChainManagerStatus = TransactionChainManagerStatus.WORKING;
createTxChain(dataBroker);
LOG.debug("created txChainManager");
}
private void createTxChain(final DataBroker dataBroker) {
txChainFactory = dataBroker.createTransactionChain(TransactionChainManager.this);
}
void initialSubmitWriteTransaction() {
enableSubmit();
submitWriteTransaction();
}
public synchronized boolean attemptToRegisterHandler(final ReadyForNewTransactionChainHandler readyForNewTransactionChainHandler) {
if (TransactionChainManagerStatus.SHUTTING_DOWN.equals(this.transactionChainManagerStatus)
&& null == this.readyForNewTransactionChainHandler) {
this.readyForNewTransactionChainHandler = readyForNewTransactionChainHandler;
if (managerRegistration == null) {
this.readyForNewTransactionChainHandler.onReadyForNewTransactionChain();
}
return true;
} else {
return false;
}
}
boolean submitWriteTransaction() {
if (!submitIsEnabled) {
LOG.trace("transaction not committed - submit block issued");
return false;
}
synchronized (txLock) {
if (wTx == null) {
LOG.trace("nothing to commit - submit returns true");
return true;
}
wTx.submit();
wTx = null;
}
return true;
}
void addDeleteOperationTotTxChain(final LogicalDatastoreType store,
final InstanceIdentifier path) {
final WriteTransaction writeTx = getTransactionSafely();
writeTx.delete(store, path);
}
void writeToTransaction(final LogicalDatastoreType store,
final InstanceIdentifier path, final T data) {
final WriteTransaction writeTx = getTransactionSafely();
writeTx.put(store, path, data);
}
@Override
public void onTransactionChainFailed(final TransactionChain, ?> chain,
final AsyncTransaction, ?> transaction, final Throwable cause) {
LOG.warn("txChain failed -> recreating", cause);
recreateTxChain();
}
@Override
public void onTransactionChainSuccessful(final TransactionChain, ?> chain) {
// NOOP - only yet, here is probably place for notification to get new WriteTransaction
}
private void recreateTxChain() {
txChainFactory.close();
createTxChain(dataBroker);
synchronized (txLock) {
wTx = null;
}
}
private WriteTransaction getTransactionSafely() {
if (wTx == null && !TransactionChainManagerStatus.SHUTTING_DOWN.equals(transactionChainManagerStatus)) {
synchronized (txLock) {
if (wTx == null) {
wTx = txChainFactory.newWriteOnlyTransaction();
}
}
}
return wTx;
}
@VisibleForTesting
void enableSubmit() {
submitIsEnabled = true;
}
@Override
public void close() {
LOG.debug("Removing node {} from operational DS.", nodeII);
synchronized (txLock) {
final WriteTransaction writeTx = getTransactionSafely();
this.transactionChainManagerStatus = TransactionChainManagerStatus.SHUTTING_DOWN;
writeTx.delete(LogicalDatastoreType.OPERATIONAL, nodeII);
LOG.debug("Delete node {} from operational DS put to write transaction.", nodeII);
CheckedFuture submitsFuture = writeTx.submit();
LOG.debug("Delete node {} from operational DS write transaction submitted.", nodeII);
Futures.addCallback(submitsFuture, new FutureCallback() {
@Override
public void onSuccess(final Void aVoid) {
LOG.debug("Removing node {} from operational DS successful .", nodeII);
notifyReadyForNewTransactionChainAndCloseFactory();
}
@Override
public void onFailure(final Throwable throwable) {
LOG.info("Attempt to close transaction chain factory failed.", throwable);
notifyReadyForNewTransactionChainAndCloseFactory();
}
});
wTx = null;
}
}
private void notifyReadyForNewTransactionChainAndCloseFactory() {
synchronized (this) {
try {
LOG.debug("Closing registration in manager.");
managerRegistration.close();
} catch (Exception e) {
LOG.warn("Failed to close transaction chain manager's registration.", e);
}
managerRegistration = null;
if (null != readyForNewTransactionChainHandler) {
readyForNewTransactionChainHandler.onReadyForNewTransactionChain();
}
}
txChainFactory.close();
LOG.debug("Transaction chain factory closed.");
}
public enum TransactionChainManagerStatus {
WORKING, SHUTTING_DOWN;
}
}