Search in sources :

Example 6 with RestconfError

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

the class RestconfDocumentedExceptionMapper method getResponseStatusCode.

/**
 * Deriving of the status code from the thrown exception. At the first step, status code is tried to be read using
 * {@link RestconfDocumentedException#getStatus()}. If it is {@code null}, status code will be derived from status
 * codes appended to error entries (the first that will be found). If there are not any error entries,
 * {@link RestconfDocumentedExceptionMapper#DEFAULT_STATUS_CODE} will be used.
 *
 * @param exception Thrown exception.
 * @return Derived status code.
 */
private static Status getResponseStatusCode(final RestconfDocumentedException exception) {
    final Status status = exception.getStatus();
    if (status != null) {
        // status code that is specified directly as field in exception has the precedence over error entries
        return status;
    }
    final List<RestconfError> errors = exception.getErrors();
    if (errors.isEmpty()) {
        // server error
        return DEFAULT_STATUS_CODE;
    }
    final Set<Status> allStatusCodesOfErrorEntries = errors.stream().map(restconfError -> ErrorTags.statusOf(restconfError.getErrorTag())).collect(Collectors.toCollection(LinkedHashSet::new));
    // entries, we should create WARN message
    if (allStatusCodesOfErrorEntries.size() > 1) {
        LOG.warn("An unexpected error occurred during translation of exception {} to response: " + "Different status codes have been found in appended error entries: {}. The first error " + "entry status code is chosen for response.", exception, allStatusCodesOfErrorEntries);
    }
    return allStatusCodesOfErrorEntries.iterator().next();
}
Also used : Status(javax.ws.rs.core.Response.Status) SchemaPath(org.opendaylight.yangtools.yang.model.api.SchemaPath) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Provider(javax.ws.rs.ext.Provider) NodeIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier) ExceptionMapper(javax.ws.rs.ext.ExceptionMapper) LoggerFactory(org.slf4j.LoggerFactory) XMLNamespace(org.opendaylight.yangtools.yang.common.XMLNamespace) MediaType(javax.ws.rs.core.MediaType) NormalizedNodeWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter) SchemaContextHandler(org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler) OutputStreamWriter(java.io.OutputStreamWriter) ImmutableContainerNodeBuilder(org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder) Status(javax.ws.rs.core.Response.Status) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) LinkedHashSet(java.util.LinkedHashSet) Context(javax.ws.rs.core.Context) Logger(org.slf4j.Logger) DataContainerNodeBuilder(org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder) Error(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.errors.errors.Error) ImmutableUnkeyedListNodeBuilder(org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder) Set(java.util.Set) UnkeyedListEntryNode(org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode) IOException(java.io.IOException) ImmutableUnkeyedListEntryNodeBuilder(org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder) Collectors(java.util.stream.Collectors) RestconfError(org.opendaylight.restconf.common.errors.RestconfError) StandardCharsets(java.nio.charset.StandardCharsets) Errors(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.errors.Errors) QName(org.opendaylight.yangtools.yang.common.QName) Preconditions.checkState(com.google.common.base.Preconditions.checkState) ErrorTags(org.opendaylight.restconf.common.ErrorTags) MediaTypes(org.opendaylight.restconf.nb.rfc8040.MediaTypes) org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.$YangModuleInfoImpl.qnameOf(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.$YangModuleInfoImpl.qnameOf) List(java.util.List) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) ImmutableNodes(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) RestconfError(org.opendaylight.restconf.common.errors.RestconfError)

Example 7 with RestconfError

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

the class JsonPatchStatusBodyWriter method reportErrors.

private static void reportErrors(final List<RestconfError> errors, final JsonWriter jsonWriter) throws IOException {
    jsonWriter.name("errors");
    jsonWriter.beginObject();
    jsonWriter.name("error");
    jsonWriter.beginArray();
    for (final RestconfError restconfError : errors) {
        jsonWriter.beginObject();
        jsonWriter.name("error-type").value(restconfError.getErrorType().elementBody());
        jsonWriter.name("error-tag").value(restconfError.getErrorTag().elementBody());
        // optional node
        if (restconfError.getErrorPath() != null) {
            jsonWriter.name("error-path").value(restconfError.getErrorPath().toString());
        }
        // optional node
        if (restconfError.getErrorMessage() != null) {
            jsonWriter.name("error-message").value(restconfError.getErrorMessage());
        }
        // optional node
        if (restconfError.getErrorInfo() != null) {
            jsonWriter.name("error-info").value(restconfError.getErrorInfo());
        }
        jsonWriter.endObject();
    }
    jsonWriter.endArray();
    jsonWriter.endObject();
}
Also used : RestconfError(org.opendaylight.restconf.common.errors.RestconfError)

Example 8 with RestconfError

use of org.opendaylight.restconf.common.errors.RestconfError 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 9 with RestconfError

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

the class PatchJsonBodyWriter method reportErrors.

private static void reportErrors(final List<RestconfError> errors, final JsonWriter jsonWriter) throws IOException {
    jsonWriter.name("errors");
    jsonWriter.beginObject();
    jsonWriter.name("error");
    jsonWriter.beginArray();
    for (final RestconfError restconfError : errors) {
        jsonWriter.beginObject();
        jsonWriter.name("error-type").value(restconfError.getErrorType().elementBody());
        jsonWriter.name("error-tag").value(restconfError.getErrorTag().elementBody());
        // optional node
        if (restconfError.getErrorPath() != null) {
            jsonWriter.name("error-path").value(restconfError.getErrorPath().toString());
        }
        // optional node
        if (restconfError.getErrorMessage() != null) {
            jsonWriter.name("error-message").value(restconfError.getErrorMessage());
        }
        // optional node
        if (restconfError.getErrorInfo() != null) {
            jsonWriter.name("error-info").value(restconfError.getErrorInfo());
        }
        jsonWriter.endObject();
    }
    jsonWriter.endArray();
    jsonWriter.endObject();
}
Also used : RestconfError(org.opendaylight.restconf.common.errors.RestconfError)

Example 10 with RestconfError

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

the class PatchXmlBodyWriter method reportErrors.

private static void reportErrors(final List<RestconfError> errors, final XMLStreamWriter writer) throws XMLStreamException {
    writer.writeStartElement("errors");
    for (final RestconfError restconfError : errors) {
        writer.writeStartElement("error-type");
        writer.writeCharacters(restconfError.getErrorType().elementBody());
        writer.writeEndElement();
        writer.writeStartElement("error-tag");
        writer.writeCharacters(restconfError.getErrorTag().elementBody());
        writer.writeEndElement();
        // optional node
        if (restconfError.getErrorPath() != null) {
            writer.writeStartElement("error-path");
            writer.writeCharacters(restconfError.getErrorPath().toString());
            writer.writeEndElement();
        }
        // optional node
        if (restconfError.getErrorMessage() != null) {
            writer.writeStartElement("error-message");
            writer.writeCharacters(restconfError.getErrorMessage());
            writer.writeEndElement();
        }
        // optional node
        if (restconfError.getErrorInfo() != null) {
            writer.writeStartElement("error-info");
            writer.writeCharacters(restconfError.getErrorInfo());
            writer.writeEndElement();
        }
    }
    writer.writeEndElement();
}
Also used : RestconfError(org.opendaylight.restconf.common.errors.RestconfError)

Aggregations

RestconfError (org.opendaylight.restconf.common.errors.RestconfError)30 RestconfDocumentedException (org.opendaylight.restconf.common.errors.RestconfDocumentedException)19 Test (org.junit.Test)16 InputStream (java.io.InputStream)6 JerseyTest (org.glassfish.jersey.test.JerseyTest)4 ErrorTag (org.opendaylight.yangtools.yang.common.ErrorTag)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Response (javax.ws.rs.core.Response)3 ErrorType (org.opendaylight.yangtools.yang.common.ErrorType)3 MediaType (javax.ws.rs.core.MediaType)2 Status (javax.ws.rs.core.Response.Status)2 Ignore (org.junit.Ignore)2 PatchEntity (org.opendaylight.restconf.common.patch.PatchEntity)2 PatchStatusContext (org.opendaylight.restconf.common.patch.PatchStatusContext)2 PatchStatusEntity (org.opendaylight.restconf.common.patch.PatchStatusEntity)2 RpcError (org.opendaylight.yangtools.yang.common.RpcError)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1