private void postDataWithinTransaction( final DOMDataReadWriteTransaction rWTransaction, final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) { // FIXME: This is doing correct post for container and list children // not sure if this will work for choice case if (payload instanceof MapNode) { LOG.trace( "POST {} within Restconf PATCH: {} with payload {}", datastore.name(), path, payload); final NormalizedNode<?, ?> emptySubtree = ImmutableNodes.fromInstanceId(schemaContext, path); rWTransaction.merge( datastore, YangInstanceIdentifier.create(emptySubtree.getIdentifier()), emptySubtree); ensureParentsByMerge(datastore, path, rWTransaction, schemaContext); for (final MapEntryNode child : ((MapNode) payload).getValue()) { final YangInstanceIdentifier childPath = path.node(child.getIdentifier()); checkItemDoesNotExists(rWTransaction, datastore, childPath); rWTransaction.put(datastore, childPath, child); } } else { checkItemDoesNotExists(rWTransaction, datastore, path); ensureParentsByMerge(datastore, path, rWTransaction, schemaContext); rWTransaction.put(datastore, path, payload); } }
@Override public synchronized void close() throws Exception { for (DOMDataReadWriteTransaction rwt : allOpenReadWriteTransactions) { rwt.cancel(); } allOpenReadWriteTransactions.clear(); }
private CheckedFuture<Void, TransactionCommitFailedException> putDataViaTransaction( final DOMDataReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) { LOG.trace("Put {} via Restconf: {} with payload {}", datastore.name(), path, payload); ensureParentsByMerge(datastore, path, writeTransaction, schemaContext); writeTransaction.put(datastore, path, payload); return writeTransaction.submit(); }
public synchronized boolean commitTransaction() throws DocumentedException { if (!getCandidateTransaction().isPresent()) { throw new DocumentedException( NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting, ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); } CheckedFuture<Void, TransactionCommitFailedException> future = candidateTransaction.submit(); try { future.checkedGet(); } catch (TransactionCommitFailedException e) { LOG.debug("Transaction {} failed on", candidateTransaction, e); throw new DocumentedException( "Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting, ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); } allOpenReadWriteTransactions.remove(candidateTransaction); candidateTransaction = null; return true; }
private void ensureParentsByMerge( final LogicalDatastoreType store, final YangInstanceIdentifier normalizedPath, final DOMDataReadWriteTransaction rwTx, final SchemaContext schemaContext) { final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>(); YangInstanceIdentifier rootNormalizedPath = null; final Iterator<PathArgument> it = normalizedPath.getPathArguments().iterator(); while (it.hasNext()) { final PathArgument pathArgument = it.next(); if (rootNormalizedPath == null) { rootNormalizedPath = YangInstanceIdentifier.create(pathArgument); } // Skip last element, its not a parent if (it.hasNext()) { normalizedPathWithoutChildArgs.add(pathArgument); } } // No parent structure involved, no need to ensure parents if (normalizedPathWithoutChildArgs.isEmpty()) { return; } Preconditions.checkArgument(rootNormalizedPath != null, "Empty path received"); final NormalizedNode<?, ?> parentStructure = ImmutableNodes.fromInstanceId( schemaContext, YangInstanceIdentifier.create(normalizedPathWithoutChildArgs)); rwTx.merge(store, rootNormalizedPath, parentStructure); }
public synchronized void abortRunningTransaction(DOMDataReadWriteTransaction tx) { LOG.debug("Aborting current running Transaction"); Preconditions.checkState( runningTransaction != null, NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); tx.cancel(); allOpenReadWriteTransactions.remove(tx); }
public synchronized void abortTransaction() { LOG.debug("Aborting current candidateTransaction"); Optional<DOMDataReadWriteTransaction> otx = getCandidateTransaction(); Preconditions.checkState( otx.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); candidateTransaction.cancel(); allOpenReadWriteTransactions.remove(candidateTransaction); candidateTransaction = null; }
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); } }
private void putDataWithinTransaction( final DOMDataReadWriteTransaction writeTransaction, final LogicalDatastoreType datastore, final YangInstanceIdentifier path, final NormalizedNode<?, ?> payload, final SchemaContext schemaContext) { LOG.trace("Put {} within Restconf PATCH: {} with payload {}", datastore.name(), path, payload); ensureParentsByMerge(datastore, path, writeTransaction, schemaContext); writeTransaction.put(datastore, path, payload); }
public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws DocumentedException { allOpenReadWriteTransactions.remove(tx); CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit(); try { future.checkedGet(); } catch (TransactionCommitFailedException e) { LOG.debug("Transaction {} failed on", tx, e); throw new DocumentedException( "Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting, ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); } return true; }
public PATCHStatusContext patchConfigurationDataWithinTransaction( final PATCHContext context, final SchemaContext globalSchema) { final DOMDataReadWriteTransaction patchTransaction = domDataBroker.newReadWriteTransaction(); List<PATCHStatusEntity> editCollection = new ArrayList<>(); List<RestconfError> editErrors; List<RestconfError> globalErrors = null; int errorCounter = 0; for (PATCHEntity patchEntity : context.getData()) { final PATCHEditOperation operation = PATCHEditOperation.valueOf(patchEntity.getOperation().toUpperCase()); switch (operation) { case CREATE: if (errorCounter == 0) { try { postDataWithinTransaction( patchTransaction, CONFIGURATION, patchEntity.getTargetNode(), patchEntity.getNode(), globalSchema); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null)); } catch (RestconfDocumentedException e) { editErrors = new ArrayList<>(); editErrors.addAll(e.getErrors()); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), false, editErrors)); errorCounter++; } } break; case REPLACE: if (errorCounter == 0) { try { putDataWithinTransaction( patchTransaction, CONFIGURATION, patchEntity.getTargetNode(), patchEntity.getNode(), globalSchema); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null)); } catch (RestconfDocumentedException e) { editErrors = new ArrayList<>(); editErrors.addAll(e.getErrors()); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), false, editErrors)); errorCounter++; } } break; case DELETE: if (errorCounter == 0) { try { deleteDataWithinTransaction( patchTransaction, CONFIGURATION, patchEntity.getTargetNode()); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null)); } catch (RestconfDocumentedException e) { editErrors = new ArrayList<>(); editErrors.addAll(e.getErrors()); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), false, editErrors)); errorCounter++; } } break; case REMOVE: if (errorCounter == 0) { try { deleteDataWithinTransaction( patchTransaction, CONFIGURATION, patchEntity.getTargetNode()); editCollection.add(new PATCHStatusEntity(patchEntity.getEditId(), true, null)); } catch (RestconfDocumentedException e) { LOG.error( "Error removing {} by {} operation", patchEntity.getTargetNode().toString(), patchEntity.getEditId(), e); } } break; } } // TODO: make sure possible global errors are filled up correctly and decide transaction // submission based on that // globalErrors = new ArrayList<>(); if (errorCounter == 0) { final CheckedFuture<Void, TransactionCommitFailedException> submit = patchTransaction.submit(); return new PATCHStatusContext( context.getPatchId(), ImmutableList.copyOf(editCollection), true, globalErrors); } else { patchTransaction.cancel(); return new PATCHStatusContext( context.getPatchId(), ImmutableList.copyOf(editCollection), false, globalErrors); } }