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;
  }
Exemple #11
0
  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);
    }
  }