Search in sources :

Example 31 with RestconfDocumentedException

use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.

the class RestconfImpl method subscribeToStream.

/**
 * Subscribes to some path in schema context (stream) to listen on changes
 * on this stream.
 *
 * <p>
 * Additional parameters for subscribing to stream are loaded via rpc input
 * parameters:
 * <ul>
 * <li>datastore - default CONFIGURATION (other values of
 * {@link LogicalDatastoreType} enum type)</li>
 * <li>scope - default BASE (other values of {@link Scope})</li>
 * </ul>
 */
@Override
public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
    boolean startTimeUsed = false;
    boolean stopTimeUsed = false;
    Instant start = Instant.now();
    Instant stop = null;
    boolean filterUsed = false;
    String filter = null;
    boolean leafNodesOnlyUsed = false;
    boolean leafNodesOnly = false;
    boolean skipNotificationDataUsed = false;
    boolean skipNotificationData = false;
    for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
        switch(entry.getKey()) {
            case "start-time":
                if (!startTimeUsed) {
                    startTimeUsed = true;
                    start = parseDateFromQueryParam(entry);
                } else {
                    throw new RestconfDocumentedException("Start-time parameter can be used only once.");
                }
                break;
            case "stop-time":
                if (!stopTimeUsed) {
                    stopTimeUsed = true;
                    stop = parseDateFromQueryParam(entry);
                } else {
                    throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
                }
                break;
            case "filter":
                if (!filterUsed) {
                    filterUsed = true;
                    filter = entry.getValue().iterator().next();
                } else {
                    throw new RestconfDocumentedException("Filter parameter can be used only once.");
                }
                break;
            case "odl-leaf-nodes-only":
                if (!leafNodesOnlyUsed) {
                    leafNodesOnlyUsed = true;
                    leafNodesOnly = Boolean.parseBoolean(entry.getValue().iterator().next());
                } else {
                    throw new RestconfDocumentedException("Odl-leaf-nodes-only parameter can be used only once.");
                }
                break;
            case "odl-skip-notification-data":
                if (!skipNotificationDataUsed) {
                    skipNotificationDataUsed = true;
                    skipNotificationData = Boolean.parseBoolean(entry.getValue().iterator().next());
                } else {
                    throw new RestconfDocumentedException("Odl-skip-notification-data parameter can be used only once.");
                }
                break;
            default:
                throw new RestconfDocumentedException("Bad parameter used with notifications: " + entry.getKey());
        }
    }
    if (!startTimeUsed && stopTimeUsed) {
        throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
    }
    URI response = null;
    if (identifier.contains(DATA_SUBSCR)) {
        response = dataSubs(identifier, uriInfo, start, stop, filter, leafNodesOnly, skipNotificationData);
    } else if (identifier.contains(NOTIFICATION_STREAM)) {
        response = notifStream(identifier, uriInfo, start, stop, filter);
    }
    if (response != null) {
        // prepare node with value of location
        final InstanceIdentifierContext<?> iid = prepareIIDSubsStreamOutput();
        final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> builder = ImmutableLeafNodeBuilder.create().withValue(response.toString());
        builder.withNodeIdentifier(NodeIdentifier.create(QName.create("subscribe:to:notification", "2016-10-28", "location")));
        // prepare new header with location
        return new NormalizedNodeContext(iid, builder.build(), ImmutableMap.of("Location", response));
    }
    final String msg = "Bad type of notification of sal-remote";
    LOG.warn(msg);
    throw new RestconfDocumentedException(msg);
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) Instant(java.time.Instant) URI(java.net.URI) NormalizedNodeContext(org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext) NodeIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier) LeafNode(org.opendaylight.yangtools.yang.data.api.schema.LeafNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 32 with RestconfDocumentedException

use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.

the class RestconfImpl method checkRpcResponse.

@SuppressWarnings("checkstyle:avoidHidingCauseException")
private static DOMRpcResult checkRpcResponse(final ListenableFuture<? extends DOMRpcResult> response) {
    if (response == null) {
        return null;
    }
    try {
        final DOMRpcResult retValue = response.get();
        if (retValue.getErrors().isEmpty()) {
            return retValue;
        }
        LOG.debug("RpcError message {}", retValue.getErrors());
        throw new RestconfDocumentedException("RpcError message", null, retValue.getErrors());
    } catch (final InterruptedException e) {
        final String errMsg = "The operation was interrupted while executing and did not complete.";
        LOG.debug("Rpc Interrupt - {}", errMsg, e);
        throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, e);
    } catch (final ExecutionException e) {
        LOG.debug("Execution RpcError: ", e);
        Throwable cause = e.getCause();
        if (cause == null) {
            throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.", e);
        }
        while (cause.getCause() != null) {
            cause = cause.getCause();
        }
        if (cause instanceof IllegalArgumentException) {
            throw new RestconfDocumentedException(cause.getMessage(), ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
        } else if (cause instanceof DOMRpcImplementationNotAvailableException) {
            throw new RestconfDocumentedException(cause.getMessage(), ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED);
        }
        throw new RestconfDocumentedException("The operation encountered an unexpected error while executing.", cause);
    } catch (final CancellationException e) {
        final String errMsg = "The operation was cancelled while executing.";
        LOG.debug("Cancel RpcExecution: {}", errMsg, e);
        throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION);
    }
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) DefaultDOMRpcResult(org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult) DOMRpcResult(org.opendaylight.mdsal.dom.api.DOMRpcResult) CancellationException(java.util.concurrent.CancellationException) DOMRpcImplementationNotAvailableException(org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException) ExecutionException(java.util.concurrent.ExecutionException)

Example 33 with RestconfDocumentedException

use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.

the class BrokerFacade method patchConfigurationDataWithinTransaction.

public PatchStatusContext patchConfigurationDataWithinTransaction(final PatchContext patchContext) throws Exception {
    final DOMMountPoint mountPoint = patchContext.getInstanceIdentifierContext().getMountPoint();
    // get new transaction and schema context on server or on mounted device
    final EffectiveModelContext schemaContext;
    final DOMDataTreeReadWriteTransaction patchTransaction;
    if (mountPoint == null) {
        schemaContext = patchContext.getInstanceIdentifierContext().getSchemaContext();
        patchTransaction = this.domDataBroker.newReadWriteTransaction();
    } else {
        schemaContext = modelContext(mountPoint);
        final Optional<DOMDataBroker> optional = mountPoint.getService(DOMDataBroker.class);
        if (optional.isPresent()) {
            patchTransaction = optional.get().newReadWriteTransaction();
        } else {
            // if mount point does not have broker it is not possible to continue and global error is reported
            LOG.error("Http Patch {} has failed - device {} does not support broker service", patchContext.getPatchId(), mountPoint.getIdentifier());
            return new PatchStatusContext(patchContext.getPatchId(), null, false, ImmutableList.of(new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "DOM data broker service isn't available for mount point " + mountPoint.getIdentifier())));
        }
    }
    final List<PatchStatusEntity> editCollection = new ArrayList<>();
    List<RestconfError> editErrors;
    boolean withoutError = true;
    for (final PatchEntity patchEntity : patchContext.getData()) {
        final PatchEditOperation operation = patchEntity.getOperation();
        switch(operation) {
            case CREATE:
                if (withoutError) {
                    try {
                        postDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode(), patchEntity.getNode(), schemaContext);
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
                    } catch (final RestconfDocumentedException e) {
                        LOG.error("Error call http Patch operation {} on target {}", operation, patchEntity.getTargetNode().toString());
                        editErrors = new ArrayList<>();
                        editErrors.addAll(e.getErrors());
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
                        withoutError = false;
                    }
                }
                break;
            case REPLACE:
                if (withoutError) {
                    try {
                        putDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode(), patchEntity.getNode(), schemaContext);
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
                    } catch (final RestconfDocumentedException e) {
                        LOG.error("Error call http Patch operation {} on target {}", operation, patchEntity.getTargetNode().toString());
                        editErrors = new ArrayList<>();
                        editErrors.addAll(e.getErrors());
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
                        withoutError = false;
                    }
                }
                break;
            case DELETE:
            case REMOVE:
                if (withoutError) {
                    try {
                        deleteDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode());
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
                    } catch (final RestconfDocumentedException e) {
                        LOG.error("Error call http Patch operation {} on target {}", operation, patchEntity.getTargetNode().toString());
                        editErrors = new ArrayList<>();
                        editErrors.addAll(e.getErrors());
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
                        withoutError = false;
                    }
                }
                break;
            case MERGE:
                if (withoutError) {
                    try {
                        mergeDataWithinTransaction(patchTransaction, CONFIGURATION, patchEntity.getTargetNode(), patchEntity.getNode(), schemaContext);
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), true, null));
                    } catch (final RestconfDocumentedException e) {
                        LOG.error("Error call http Patch operation {} on target {}", operation, patchEntity.getTargetNode().toString());
                        editErrors = new ArrayList<>();
                        editErrors.addAll(e.getErrors());
                        editCollection.add(new PatchStatusEntity(patchEntity.getEditId(), false, editErrors));
                        withoutError = false;
                    }
                }
                break;
            default:
                LOG.error("Unsupported http Patch operation {} on target {}", operation, patchEntity.getTargetNode().toString());
                break;
        }
    }
    // if errors then cancel transaction and return error status
    if (!withoutError) {
        patchTransaction.cancel();
        return new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection), false, null);
    }
    // if no errors commit transaction
    final CountDownLatch waiter = new CountDownLatch(1);
    final FluentFuture<? extends CommitInfo> future = patchTransaction.commit();
    final PatchStatusContextHelper status = new PatchStatusContextHelper();
    future.addCallback(new FutureCallback<CommitInfo>() {

        @Override
        public void onSuccess(final CommitInfo result) {
            status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection), true, null));
            waiter.countDown();
        }

        @Override
        public void onFailure(final Throwable throwable) {
            // if commit failed it is global error
            LOG.error("Http Patch {} transaction commit has failed", patchContext.getPatchId());
            status.setStatus(new PatchStatusContext(patchContext.getPatchId(), ImmutableList.copyOf(editCollection), false, ImmutableList.of(new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, throwable.getMessage()))));
            waiter.countDown();
        }
    }, MoreExecutors.directExecutor());
    waiter.await();
    return status.getStatus();
}
Also used : PatchEditOperation(org.opendaylight.restconf.common.patch.PatchEditOperation) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) PatchEntity(org.opendaylight.restconf.common.patch.PatchEntity) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) DOMDataTreeReadWriteTransaction(org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction) PatchStatusContext(org.opendaylight.restconf.common.patch.PatchStatusContext) PatchStatusEntity(org.opendaylight.restconf.common.patch.PatchStatusEntity) RestconfError(org.opendaylight.restconf.common.errors.RestconfError) CommitInfo(org.opendaylight.mdsal.common.api.CommitInfo) DOMDataBroker(org.opendaylight.mdsal.dom.api.DOMDataBroker) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext)

Example 34 with RestconfDocumentedException

use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.

the class NotificationListenerAdapter method writeBodyToString.

private static String writeBodyToString(final EffectiveModelContext schemaContext, final DOMNotification notification) {
    final Writer writer = new StringWriter();
    final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.createExclusiveWriter(JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext), notification.getType().asSchemaPath(), null, JsonWriterFactory.createJsonWriter(writer));
    final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
    try {
        nodeWriter.write(notification.getBody());
        nodeWriter.close();
    } catch (final IOException e) {
        throw new RestconfDocumentedException("Problem while writing body of notification to JSON. ", e);
    }
    return writer.toString();
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) StringWriter(java.io.StringWriter) NormalizedNodeWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter) JSONNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) IOException(java.io.IOException) JSONNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter) NormalizedNodeWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter) StringWriter(java.io.StringWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) Writer(java.io.Writer)

Example 35 with RestconfDocumentedException

use of org.opendaylight.restconf.common.errors.RestconfDocumentedException in project netconf by opendaylight.

the class JsonToNnTest method emptyDataReadTest.

@Test
public void emptyDataReadTest() throws Exception {
    final NormalizedNodeContext normalizedNodeContext = prepareNNC("/json-to-nn/empty-data.json", "array-with-null-yang:cont");
    assertNotNull(normalizedNodeContext);
    assertEquals("cont", normalizedNodeContext.getData().getIdentifier().getNodeType().getLocalName());
    final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext.getData());
    assertTrue(dataTree.contains("lflst1"));
    assertTrue(dataTree.contains("lflst2 45"));
    RestconfDocumentedException exception = null;
    mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
    final InputStream inputStream = this.getClass().getResourceAsStream("/json-to-nn/empty-data.json1");
    try {
        this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null, inputStream);
    } catch (final RestconfDocumentedException e) {
        exception = e;
    }
    assertNotNull(exception);
    assertEquals("Error parsing input: null", exception.getErrors().get(0).getErrorMessage());
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) InputStream(java.io.InputStream) NormalizedNodeContext(org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext) Test(org.junit.Test) AbstractBodyReaderTest(org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest)

Aggregations

RestconfDocumentedException (org.opendaylight.restconf.common.errors.RestconfDocumentedException)136 Test (org.junit.Test)65 InputStream (java.io.InputStream)30 DOMMountPoint (org.opendaylight.mdsal.dom.api.DOMMountPoint)20 RestconfError (org.opendaylight.restconf.common.errors.RestconfError)20 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)19 QName (org.opendaylight.yangtools.yang.common.QName)17 NormalizedNode (org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)17 DataSchemaNode (org.opendaylight.yangtools.yang.model.api.DataSchemaNode)16 ListSchemaNode (org.opendaylight.yangtools.yang.model.api.ListSchemaNode)14 List (java.util.List)13 EffectiveModelContext (org.opendaylight.yangtools.yang.model.api.EffectiveModelContext)13 ArrayList (java.util.ArrayList)12 ContainerNode (org.opendaylight.yangtools.yang.data.api.schema.ContainerNode)11 NodeIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier)9 LeafListSchemaNode (org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode)9 IOException (java.io.IOException)8 ExecutionException (java.util.concurrent.ExecutionException)8 NodeIdentifierWithPredicates (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates)8 MapEntryNode (org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)8