@Override public synchronized void close() throws Exception { for (DOMDataReadWriteTransaction rwt : allOpenReadWriteTransactions) { rwt.cancel(); } allOpenReadWriteTransactions.clear(); }
@Override public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) { delegate().merge(store, path, data); }
private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction( final DOMDataBroker domDataBroker, final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) { DOMDataReadWriteTransaction transaction = domDataBroker.newReadWriteTransaction(); LOG.trace("Put " + datastore.name() + " via Restconf: {} with payload {}", path, payload); if (!ensureParentsByMerge(datastore, path, transaction, schemaContext)) { transaction.cancel(); transaction = domDataBroker.newReadWriteTransaction(); } transaction.put(datastore, path, payload); return transaction.submit(); }
private void checkItemDoesNotExists(final DOMDataReadWriteTransaction rWTransaction,final LogicalDatastoreType store, final YangInstanceIdentifier path) { final ListenableFuture<Boolean> futureDatastoreData = rWTransaction.exists(store, path); try { if (futureDatastoreData.get()) { final String errMsg = "Post Configuration via Restconf was not executed because data already exists"; LOG.trace(errMsg + ":{}", path); rWTransaction.cancel(); throw new RestconfDocumentedException("Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS); } } catch (InterruptedException | ExecutionException e) { LOG.warn("It wasn't possible to get data loaded from datastore at path " + path, e); } }
final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path); try { transaction.merge(datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree); } catch (RuntimeException e) { transaction.cancel(); transaction = domDataBroker.newReadWriteTransaction(); LOG.debug("Empty subtree merge failed", e); transaction.cancel(); transaction = domDataBroker.newReadWriteTransaction(); final YangInstanceIdentifier childPath = path.node(child.getIdentifier()); checkItemDoesNotExists(transaction, datastore, childPath); transaction.put(datastore, childPath, child); transaction.cancel(); transaction = domDataBroker.newReadWriteTransaction(); transaction.put(datastore, path, payload); return transaction.submit();
return; case MERGE: rwtx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); break; case CREATE: try { final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet(); if (readResult.isPresent()) { throw new NetconfDocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error); rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); } catch (ReadFailedException e) { LOG.warn("Read from datastore failed when trying to read data for create operation", change, e); rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); break; case DELETE: try { final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet(); if (!readResult.isPresent()) { throw new NetconfDocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error); rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())); } catch (ReadFailedException e) { LOG.warn("Read from datastore failed when trying to read data for delete operation", change, e); rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())); break; default:
/** * Process a ready transaction. The caller needs to ensure that * each transaction is seen only once by this method. * * @param tx Transaction which needs processing. */ @GuardedBy("this") private void processTransaction(@Nonnull final PingPongTransaction tx) { if (failed) { LOG.debug("Cancelling transaction {}", tx); tx.getTransaction().cancel(); return; } LOG.debug("Submitting transaction {}", tx); if (!INFLIGHT_UPDATER.compareAndSet(this, null, tx)) { LOG.warn("Submitting transaction {} while {} is still running", tx, inflightTx); } Futures.addCallback(tx.getTransaction().submit(), new FutureCallback<Void>() { @Override public void onSuccess(final Void result) { transactionSuccessful(tx, result); } @Override public void onFailure(final Throwable t) { transactionFailed(tx, t); } }); }
@Override public CheckedFuture<Void, TransactionCommitFailedException> submit() { return delegate().submit(); }
@Override public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) { return delegate().read(store, path); }
@Override protected final void ensureParentsByMerge(final LogicalDatastoreType store, final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalizedPath, final InstanceIdentifier<?> path) { List<PathArgument> currentArguments = new ArrayList<>(); DataNormalizationOperation<?> currentOp = getCodec().getDataNormalizer().getRootOperation(); Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator(); while (iterator.hasNext()) { PathArgument currentArg = iterator.next(); try { currentOp = currentOp.getChild(currentArg); } catch (DataNormalizationException e) { throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e); } currentArguments.add(currentArg); org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier currentPath = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create( currentArguments); final Boolean exists; try { exists = getDelegate().exists(store, currentPath).checkedGet(); } catch (ReadFailedException e) { LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e); throw new IllegalStateException("Failed to read pre-existing data", e); } if (!exists && iterator.hasNext()) { getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg)); } } }
@Override public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) { return tx.getTransaction().exists(store, path); }
@Override public Object getIdentifier() { return delegate().getIdentifier(); }
@Override public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) { delegate().put(store, path, data); }
@Override public void delete(LogicalDatastoreType logicalDatastoreType, YangInstanceIdentifier yangInstanceIdentifier) { if (AuthzServiceImpl.isAuthorized(logicalDatastoreType, yangInstanceIdentifier, ActionType.Delete)) { domDataReadWriteTransaction.delete(logicalDatastoreType, yangInstanceIdentifier); } }
@Override public FluentFuture<? extends CommitInfo> commit() { return delegate().commit(); } }
return; case MERGE: rwtx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); break; case CREATE: try { final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet(); if (readResult.isPresent()) { throw new DocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error); rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); } catch (ReadFailedException e) { LOG.warn("Read from datastore failed when trying to read data for create operation", change, e); rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot()); break; case DELETE: try { final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet(); if (!readResult.isPresent()) { throw new DocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error); rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())); } catch (ReadFailedException e) { LOG.warn("Read from datastore failed when trying to read data for delete operation", change, e); rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())); break; default:
public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws NetconfDocumentedException { allOpenReadWriteTransactions.remove(tx); CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit(); try { future.checkedGet(); } catch (TransactionCommitFailedException e) { LOG.debug("Transaction {} failed on", tx, e); throw new NetconfDocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting, ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); } return true; }
@Override public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) { return tx.getTransaction().read(store, path); }
@Override public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) { return delegate().exists(store, path); }
@Override public Object getIdentifier() { if (AuthzServiceImpl.isAuthorized(ActionType.GetIdentifier)) { return domDataReadWriteTransaction.getIdentifier(); } return null; } }