Search in sources :

Example 26 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project genius by opendaylight.

the class LockManagerServiceImpl method readWriteLock.

/**
 * Read and write the lock immediately if available. Returns true if
 * successfully locked.
 */
private boolean readWriteLock(final InstanceIdentifier<Lock> lockInstanceIdentifier, final Lock lockData) throws InterruptedException, ExecutionException {
    String lockName = lockData.getLockName();
    synchronized (lockName.intern()) {
        ReadWriteTransaction tx = broker.newReadWriteTransaction();
        Optional<Lock> result = tx.read(LogicalDatastoreType.OPERATIONAL, lockInstanceIdentifier).get();
        if (!result.isPresent()) {
            LOG.debug("Writing lock lockData {}", lockData);
            tx.put(LogicalDatastoreType.OPERATIONAL, lockInstanceIdentifier, lockData, true);
            tx.submit().get();
            return true;
        } else {
            String lockDataOwner = result.get().getLockOwner();
            String currentOwner = lockData.getLockOwner();
            if (currentOwner.equals(lockDataOwner)) {
                return true;
            }
        }
        tx.cancel();
        return false;
    }
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) Lock(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock)

Example 27 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project genius by opendaylight.

the class AlivenessMonitor method sendMonitorPacket.

private void sendMonitorPacket(final MonitoringInfo monitoringInfo) {
    // TODO: Handle interrupts
    final Long monitorId = monitoringInfo.getId();
    final String monitorKey = monitorIdKeyCache.getUnchecked(monitorId);
    if (monitorKey == null) {
        LOG.warn("No monitor Key associated with id {} to send the monitor packet", monitorId);
        return;
    } else {
        LOG.debug("Sending monitoring packet for key: {}", monitorKey);
    }
    final MonitorProfile profile;
    Optional<MonitorProfile> optProfile = getMonitorProfile(monitoringInfo.getProfileId());
    if (optProfile.isPresent()) {
        profile = optProfile.get();
    } else {
        LOG.warn("No monitor profile associated with id {}. " + "Could not send Monitor packet for monitor-id {}", monitoringInfo.getProfileId(), monitorId);
        return;
    }
    final Semaphore lock = lockMap.get(monitorKey);
    LOG.debug("Acquiring lock for monitor key : {} to send monitor packet", monitorKey);
    acquireLock(lock);
    final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
    ListenableFuture<Optional<MonitoringState>> readResult = tx.read(LogicalDatastoreType.OPERATIONAL, getMonitorStateId(monitorKey));
    ListenableFuture<Void> writeResult = Futures.transformAsync(readResult, optState -> {
        if (optState.isPresent()) {
            MonitoringState state = optState.get();
            // Increase the request count
            Long requestCount = state.getRequestCount() + 1;
            // Check with the monitor window
            LivenessState currentLivenessState = state.getState();
            // Increase the pending response count
            long responsePendingCount = state.getResponsePendingCount();
            if (responsePendingCount < profile.getMonitorWindow()) {
                responsePendingCount = responsePendingCount + 1;
            }
            // Check with the failure threshold
            if (responsePendingCount >= profile.getFailureThreshold()) {
                // Change the state to down and notify
                if (currentLivenessState != LivenessState.Down) {
                    LOG.debug("Response pending Count: {}, Failure threshold: {} for monitorId {}", responsePendingCount, profile.getFailureThreshold(), state.getMonitorId());
                    LOG.info("Sending notification for monitor Id : {} with State: {}", state.getMonitorId(), LivenessState.Down);
                    publishNotification(monitorId, LivenessState.Down);
                    currentLivenessState = LivenessState.Down;
                    // Reset requestCount when state changes
                    // from UP to DOWN
                    requestCount = INITIAL_COUNT;
                }
            }
            // Update the ODS with state
            MonitoringState updatedState = new MonitoringStateBuilder().setMonitorKey(state.getMonitorKey()).setRequestCount(requestCount).setResponsePendingCount(responsePendingCount).setState(currentLivenessState).build();
            tx.merge(LogicalDatastoreType.OPERATIONAL, getMonitorStateId(state.getMonitorKey()), updatedState);
            return tx.submit();
        } else {
            // Close the transaction
            tx.submit();
            String errorMsg = String.format("Monitoring State associated with id %d is not present to send packet out.", monitorId);
            return Futures.immediateFailedFuture(new RuntimeException(errorMsg));
        }
    }, callbackExecutorService);
    Futures.addCallback(writeResult, new FutureCallback<Void>() {

        @Override
        public void onSuccess(Void noarg) {
            // invoke packetout on protocol handler
            AlivenessProtocolHandler<?> handler = alivenessProtocolHandlerRegistry.getOpt(profile.getProtocolType());
            if (handler != null) {
                LOG.debug("Sending monitoring packet {}", monitoringInfo);
                handler.startMonitoringTask(monitoringInfo);
            }
            releaseLock(lock);
        }

        @Override
        public void onFailure(Throwable error) {
            LOG.warn("Updating monitoring state for key: {} failed. Monitoring packet is not sent", monitorKey, error);
            releaseLock(lock);
        }
    }, callbackExecutorService);
}
Also used : Optional(com.google.common.base.Optional) MonitoringStateBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringStateBuilder) MonitorProfile(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profiles.MonitorProfile) Semaphore(java.util.concurrent.Semaphore) AlivenessProtocolHandler(org.opendaylight.genius.alivenessmonitor.protocols.AlivenessProtocolHandler) MonitoringState(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringState) LivenessState(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.LivenessState) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)

Example 28 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project genius by opendaylight.

the class AlivenessMonitor method associateMonitorIdWithInterface.

private void associateMonitorIdWithInterface(final Long monitorId, final String interfaceName) {
    LOG.debug("associate monitor Id {} with interface {}", monitorId, interfaceName);
    final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
    ListenableFuture<Optional<InterfaceMonitorEntry>> readFuture = tx.read(LogicalDatastoreType.OPERATIONAL, getInterfaceMonitorMapId(interfaceName));
    ListenableFuture<Void> updateFuture = Futures.transformAsync(readFuture, optEntry -> {
        if (optEntry.isPresent()) {
            InterfaceMonitorEntry entry = optEntry.get();
            List<Long> monitorIds1 = entry.getMonitorIds();
            monitorIds1.add(monitorId);
            InterfaceMonitorEntry newEntry1 = new InterfaceMonitorEntryBuilder().setKey(new InterfaceMonitorEntryKey(interfaceName)).setMonitorIds(monitorIds1).build();
            tx.merge(LogicalDatastoreType.OPERATIONAL, getInterfaceMonitorMapId(interfaceName), newEntry1);
        } else {
            // Create new monitor entry
            LOG.debug("Adding new interface-monitor association for interface {} with id {}", interfaceName, monitorId);
            List<Long> monitorIds2 = new ArrayList<>();
            monitorIds2.add(monitorId);
            InterfaceMonitorEntry newEntry2 = new InterfaceMonitorEntryBuilder().setInterfaceName(interfaceName).setMonitorIds(monitorIds2).build();
            tx.put(LogicalDatastoreType.OPERATIONAL, getInterfaceMonitorMapId(interfaceName), newEntry2, CREATE_MISSING_PARENT);
        }
        return tx.submit();
    }, callbackExecutorService);
    Futures.addCallback(updateFuture, new FutureCallbackImpl(String.format("Association of monitorId %d with Interface %s", monitorId, interfaceName)), MoreExecutors.directExecutor());
}
Also used : Optional(com.google.common.base.Optional) InterfaceMonitorEntry(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntry) InterfaceMonitorEntryBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntryBuilder) ArrayList(java.util.ArrayList) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) InterfaceMonitorEntryKey(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntryKey)

Example 29 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project controller by opendaylight.

the class OpendaylightToaster method checkStatusAndMakeToast.

private void checkStatusAndMakeToast(final MakeToastInput input, final SettableFuture<RpcResult<Void>> futureResult, final int tries) {
    // Read the ToasterStatus and, if currently Up, try to write the status to Down.
    // If that succeeds, then we essentially have an exclusive lock and can proceed
    // to make toast.
    final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
    ListenableFuture<Optional<Toaster>> readFuture = tx.read(OPERATIONAL, TOASTER_IID);
    final ListenableFuture<Void> commitFuture = Futures.transformAsync(readFuture, toasterData -> {
        ToasterStatus toasterStatus = ToasterStatus.Up;
        if (toasterData.isPresent()) {
            toasterStatus = toasterData.get().getToasterStatus();
        }
        LOG.debug("Read toaster status: {}", toasterStatus);
        if (toasterStatus == ToasterStatus.Up) {
            if (outOfBread()) {
                LOG.debug("Toaster is out of bread");
                return Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("", makeToasterOutOfBreadError()));
            }
            LOG.debug("Setting Toaster status to Down");
            // We're not currently making toast - try to update the status to Down
            // to indicate we're going to make toast. This acts as a lock to prevent
            // concurrent toasting.
            tx.put(OPERATIONAL, TOASTER_IID, buildToaster(ToasterStatus.Down));
            return tx.submit();
        }
        LOG.debug("Oops - already making toast!");
        // TransactionStatus in the RpcResult as an error condition.
        return Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("", makeToasterInUseError()));
    });
    Futures.addCallback(commitFuture, new FutureCallback<Void>() {

        @Override
        public void onSuccess(final Void result) {
            // OK to make toast
            currentMakeToastTask.set(executor.submit(new MakeToastTask(input, futureResult)));
        }

        @Override
        public void onFailure(final Throwable ex) {
            if (ex instanceof OptimisticLockFailedException) {
                if (tries - 1 > 0) {
                    LOG.debug("Got OptimisticLockFailedException - trying again");
                    checkStatusAndMakeToast(input, futureResult, tries - 1);
                } else {
                    futureResult.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, ex.getMessage()).build());
                }
            } else if (ex instanceof TransactionCommitFailedException) {
                LOG.debug("Failed to commit Toaster status", ex);
                // Probably already making toast.
                futureResult.set(RpcResultBuilder.<Void>failed().withRpcErrors(((TransactionCommitFailedException) ex).getErrorList()).build());
            } else {
                LOG.debug("Unexpected error committing Toaster status", ex);
                futureResult.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, "Unexpected error committing Toaster status", ex).build());
            }
        }
    });
}
Also used : TransactionCommitFailedException(org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException) Optional(com.google.common.base.Optional) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) ToasterStatus(org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster.ToasterStatus) OptimisticLockFailedException(org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException)

Example 30 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project controller by opendaylight.

the class Bug1333DataChangeListenerTest method deleteItem.

public void deleteItem(final LogicalDatastoreType store, final InstanceIdentifier<?> path) {
    ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
    tx.delete(store, path);
    assertCommit(tx.submit());
}
Also used : ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)

Aggregations

ReadWriteTransaction (org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)67 Optional (com.google.common.base.Optional)21 TransactionCommitFailedException (org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException)17 Test (org.junit.Test)16 FlowCapableNode (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode)13 Node (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node)13 CountDownLatch (java.util.concurrent.CountDownLatch)11 Mockito.doReturn (org.mockito.Mockito.doReturn)11 Nodes (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes)11 InstanceIdentifier (org.opendaylight.yangtools.yang.binding.InstanceIdentifier)11 ReadFailedException (org.opendaylight.controller.md.sal.common.api.data.ReadFailedException)10 NodeId (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)9 DataTreeModification (org.opendaylight.controller.md.sal.binding.api.DataTreeModification)8 TestUtils.newInvNodeKey (org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey)8 NodeKey (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey)8 TestUtils.newLink (org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newLink)7 Link (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link)7 ArrayList (java.util.ArrayList)6 Flow (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow)6 NodeBuilder (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder)6