diff options
Diffstat (limited to 'netconf/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BatchedExistenceCheck.java')
-rw-r--r-- | netconf/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BatchedExistenceCheck.java | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/netconf/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BatchedExistenceCheck.java b/netconf/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BatchedExistenceCheck.java new file mode 100644 index 0000000..4efc6a8 --- /dev/null +++ b/netconf/restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BatchedExistenceCheck.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017 Pantheon Technologies, s.r.o. 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.netconf.sal.restconf.impl; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.SettableFuture; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Collection; +import java.util.Map.Entry; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.common.api.ReadFailedException; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadOperations; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +final class BatchedExistenceCheck { + private static final AtomicIntegerFieldUpdater<BatchedExistenceCheck> UPDATER = + AtomicIntegerFieldUpdater.newUpdater(BatchedExistenceCheck.class, "outstanding"); + + private final SettableFuture<Entry<YangInstanceIdentifier, ReadFailedException>> future = SettableFuture.create(); + + @SuppressWarnings("unused") + private volatile int outstanding; + + private BatchedExistenceCheck(final int total) { + this.outstanding = total; + } + + static BatchedExistenceCheck start(final DOMDataTreeReadOperations readTx, + final LogicalDatastoreType datastore, final YangInstanceIdentifier parentPath, + final Collection<? extends NormalizedNode> children) { + final BatchedExistenceCheck ret = new BatchedExistenceCheck(children.size()); + for (NormalizedNode child : children) { + final YangInstanceIdentifier path = parentPath.node(child.getIdentifier()); + readTx.exists(datastore, path).addCallback(new FutureCallback<Boolean>() { + @Override + public void onSuccess(final Boolean result) { + ret.complete(path, result); + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE") + public void onFailure(final Throwable throwable) { + final Exception e; + if (throwable instanceof Exception) { + e = (Exception) throwable; + } else { + e = new ExecutionException(throwable); + } + + ret.complete(path, ReadFailedException.MAPPER.apply(e)); + } + }, MoreExecutors.directExecutor()); + } + + return ret; + } + + Entry<YangInstanceIdentifier, ReadFailedException> getFailure() throws InterruptedException { + try { + return future.get(); + } catch (ExecutionException e) { + // This should never happen + throw new IllegalStateException(e); + } + } + + private void complete(final YangInstanceIdentifier childPath, final boolean present) { + final int count = UPDATER.decrementAndGet(this); + if (present) { + future.set(new SimpleImmutableEntry<>(childPath, null)); + } else if (count == 0) { + future.set(null); + } + } + + private void complete(final YangInstanceIdentifier childPath, final ReadFailedException cause) { + UPDATER.decrementAndGet(this); + future.set(new SimpleImmutableEntry<>(childPath, cause)); + } +} |