X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-netconf-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fconnect%2Fnetconf%2Fsal%2FNetconfDeviceDatastoreAdapter.java;h=fc69a7e253c4dfe056396c7920d89366471d825d;hp=e491496eed79af22628301f3497437d33aefa4b0;hb=4b65b104779988ca197bbf8797afdc3e9b1e6ee4;hpb=c0e4638d5f1f29249b3fe74b64e7d85dd388c489 diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDatastoreAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDatastoreAdapter.java index e491496eed..fc69a7e253 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDatastoreAdapter.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDatastoreAdapter.java @@ -8,27 +8,28 @@ package org.opendaylight.controller.sal.connect.netconf.sal; import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.FluentIterable; +import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import org.opendaylight.controller.md.sal.common.api.TransactionStatus; -import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNodeBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,123 +43,86 @@ final class NetconfDeviceDatastoreAdapter implements AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(NetconfDeviceDatastoreAdapter.class); private final RemoteDeviceId id; - private final DataProviderService dataService; - private final ListeningExecutorService executor; + private final DataBroker dataService; - NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final DataProviderService dataService, - final ExecutorService executor) { + NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final DataBroker dataService) { this.id = Preconditions.checkNotNull(deviceId); this.dataService = Preconditions.checkNotNull(dataService); - this.executor = MoreExecutors.listeningDecorator(Preconditions.checkNotNull(executor)); - // Initial data change scheduled - submitDataChangeToExecutor(this.executor, new Runnable() { - @Override - public void run() { - initDeviceData(); - } - }, deviceId); + initDeviceData(); } public void updateDeviceState(final boolean up, final Set capabilities) { - submitDataChangeToExecutor(this.executor, new Runnable() { - @Override - public void run() { - updateDeviceStateInternal(up, capabilities); - } - }, id); - } - - private void updateDeviceStateInternal(final boolean up, final Set capabilities) { final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node data = buildDataForDeviceState( up, capabilities, id); - final DataModificationTransaction transaction = dataService.beginTransaction(); - logger.trace("{}: Update device state transaction {} putting operational data started.", id, transaction.getIdentifier()); - transaction.removeOperationalData(id.getBindingPath()); - transaction.putOperationalData(id.getBindingPath(), data); - logger.trace("{}: Update device state transaction {} putting operational data ended.", id, transaction.getIdentifier()); + final ReadWriteTransaction transaction = dataService.newReadWriteTransaction(); + logger.trace("{}: Update device state transaction {} merging operational data started.", id, transaction.getIdentifier()); + transaction.put(LogicalDatastoreType.OPERATIONAL, id.getBindingPath(), data); + logger.trace("{}: Update device state transaction {} merging operational data ended.", id, transaction.getIdentifier()); commitTransaction(transaction, "update"); } private void removeDeviceConfigAndState() { - final DataModificationTransaction transaction = dataService.beginTransaction(); + final WriteTransaction transaction = dataService.newWriteOnlyTransaction(); logger.trace("{}: Close device state transaction {} removing all data started.", id, transaction.getIdentifier()); - transaction.removeConfigurationData(id.getBindingPath()); - transaction.removeOperationalData(id.getBindingPath()); + transaction.delete(LogicalDatastoreType.CONFIGURATION, id.getBindingPath()); + transaction.delete(LogicalDatastoreType.OPERATIONAL, id.getBindingPath()); logger.trace("{}: Close device state transaction {} removing all data ended.", id, transaction.getIdentifier()); commitTransaction(transaction, "close"); } private void initDeviceData() { - final DataModificationTransaction transaction = dataService.beginTransaction(); + final WriteTransaction transaction = dataService.newWriteOnlyTransaction(); - final InstanceIdentifier path = id.getBindingPath(); + createNodesListIfNotPresent(transaction); + final InstanceIdentifier path = id.getBindingPath(); final Node nodeWithId = getNodeWithId(id); - if (operationalNodeNotExisting(transaction, path)) { - transaction.putOperationalData(path, nodeWithId); - } - if (configurationNodeNotExisting(transaction, path)) { - transaction.putConfigurationData(path, nodeWithId); - } - commitTransaction(transaction, "init"); - } + logger.trace("{}: Init device state transaction {} putting if absent operational data started.", id, transaction.getIdentifier()); + transaction.put(LogicalDatastoreType.OPERATIONAL, path, nodeWithId); + logger.trace("{}: Init device state transaction {} putting operational data ended.", id, transaction.getIdentifier()); - private void commitTransaction(final DataModificationTransaction transaction, final String txType) { - // attempt commit - final RpcResult result; - try { - result = transaction.commit().get(); - } catch (InterruptedException | ExecutionException e) { - logger.error("{}: Transaction({}) failed", id, txType, e); - throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly", e); - } - - // verify success result + committed state - if (isUpdateSuccessful(result)) { - logger.trace("{}: Transaction({}) {} SUCCESSFUL", id, txType, transaction.getIdentifier()); - } else { - logger.error("{}: Transaction({}) {} FAILED!", id, txType, transaction.getIdentifier()); - throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly, " + - "Errors: " + result.getErrors()); - } - } + logger.trace("{}: Init device state transaction {} putting if absent config data started.", id, transaction.getIdentifier()); + transaction.put(LogicalDatastoreType.CONFIGURATION, path, nodeWithId); + logger.trace("{}: Init device state transaction {} putting config data ended.", id, transaction.getIdentifier()); - @Override - public void close() throws Exception { - // Remove device data from datastore - submitDataChangeToExecutor(executor, new Runnable() { - @Override - public void run() { - removeDeviceConfigAndState(); - } - }, id); + commitTransaction(transaction, "init"); } - private static boolean isUpdateSuccessful(final RpcResult result) { - return result.getResult() == TransactionStatus.COMMITED && result.isSuccessful(); + private void createNodesListIfNotPresent(final WriteTransaction writeTx) { + final Nodes nodes = new NodesBuilder().build(); + final InstanceIdentifier path = InstanceIdentifier.builder(Nodes.class).build(); + logger.trace("{}: Merging {} container to ensure its presence", id, Nodes.QNAME, writeTx.getIdentifier()); + writeTx.merge(LogicalDatastoreType.CONFIGURATION, path, nodes); + writeTx.merge(LogicalDatastoreType.OPERATIONAL, path, nodes); } - private static void submitDataChangeToExecutor(final ListeningExecutorService executor, final Runnable r, - final RemoteDeviceId id) { - // Submit data change - final ListenableFuture f = executor.submit(r); - // Verify update execution - Futures.addCallback(f, new FutureCallback() { + private void commitTransaction(final WriteTransaction transaction, final String txType) { + logger.trace("{}: Committing Transaction {}:{}", id, txType, transaction.getIdentifier()); + final CheckedFuture result = transaction.submit(); + + Futures.addCallback(result, new FutureCallback() { @Override - public void onSuccess(final Object result) { - logger.debug("{}: Device data updated successfully", id); + public void onSuccess(final Void result) { + logger.trace("{}: Transaction({}) {} SUCCESSFUL", id, txType, transaction.getIdentifier()); } @Override public void onFailure(final Throwable t) { - logger.warn("{}: Device data update failed", id, t); + logger.error("{}: Transaction({}) {} FAILED!", id, txType, transaction.getIdentifier(), t); + throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly", t); } }); + + } + + @Override + public void close() throws Exception { + removeDeviceConfigAndState(); } public static org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node buildDataForDeviceState( @@ -179,14 +143,11 @@ final class NetconfDeviceDatastoreAdapter implements AutoCloseable { return nodeBuilder.build(); } - private static boolean configurationNodeNotExisting(final DataModificationTransaction transaction, - final InstanceIdentifier path) { - return null == transaction.readConfigurationData(path); - } - - private static boolean operationalNodeNotExisting(final DataModificationTransaction transaction, + private static ListenableFuture> readNodeData( + final LogicalDatastoreType store, + final ReadWriteTransaction transaction, final InstanceIdentifier path) { - return null == transaction.readOperationalData(path); + return transaction.read(store, path); } private static Node getNodeWithId(final RemoteDeviceId id) {