Search in sources :

Example 76 with RestconfDocumentedException

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

the class RestconfImpl method updateConfigurationData.

@Override
public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) {
    boolean insertUsed = false;
    boolean pointUsed = false;
    String insert = null;
    String point = null;
    for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
        switch(entry.getKey()) {
            case "insert":
                if (!insertUsed) {
                    insertUsed = true;
                    insert = entry.getValue().iterator().next();
                } else {
                    throw new RestconfDocumentedException("Insert parameter can be used only once.");
                }
                break;
            case "point":
                if (!pointUsed) {
                    pointUsed = true;
                    point = entry.getValue().iterator().next();
                } else {
                    throw new RestconfDocumentedException("Point parameter can be used only once.");
                }
                break;
            default:
                throw new RestconfDocumentedException("Bad parameter for post: " + entry.getKey());
        }
    }
    if (pointUsed && !insertUsed) {
        throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.");
    }
    if (pointUsed && (insert.equals("first") || insert.equals("last"))) {
        throw new RestconfDocumentedException("Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
    }
    requireNonNull(identifier);
    final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
    validateInput(iiWithData.getSchemaNode(), payload);
    validateTopLevelNodeName(payload, iiWithData.getInstanceIdentifier());
    validateListKeysEqualityInPayloadAndUri(payload);
    final DOMMountPoint mountPoint = iiWithData.getMountPoint();
    final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
    /*
         * There is a small window where another write transaction could be
         * updating the same data simultaneously and we get an
         * OptimisticLockFailedException. This error is likely transient and The
         * WriteTransaction#submit API docs state that a retry will likely
         * succeed. So we'll try again if that scenario occurs. If it fails a
         * third time then it probably will never succeed so we'll fail in that
         * case.
         *
         * By retrying we're attempting to hide the internal implementation of
         * the data store and how it handles concurrent updates from the
         * restconf client. The client has instructed us to put the data and we
         * should make every effort to do so without pushing optimistic lock
         * failures back to the client and forcing them to handle it via retry
         * (and having to document the behavior).
         */
    PutResult result = null;
    int tries = 2;
    while (true) {
        if (mountPoint != null) {
            result = broker.commitMountPointDataPut(mountPoint, normalizedII, payload.getData(), insert, point);
        } else {
            result = broker.commitConfigurationDataPut(controllerContext.getGlobalSchema(), normalizedII, payload.getData(), insert, point);
        }
        try {
            result.getFutureOfPutData().get();
        } catch (final InterruptedException e) {
            LOG.debug("Update failed for {}", identifier, e);
            throw new RestconfDocumentedException(e.getMessage(), e);
        } catch (final ExecutionException e) {
            final TransactionCommitFailedException failure = Throwables.getCauseAs(e, TransactionCommitFailedException.class);
            if (failure instanceof OptimisticLockFailedException) {
                if (--tries <= 0) {
                    LOG.debug("Got OptimisticLockFailedException on last try - failing {}", identifier);
                    throw new RestconfDocumentedException(e.getMessage(), e, failure.getErrorList());
                }
                LOG.debug("Got OptimisticLockFailedException - trying again {}", identifier);
                continue;
            }
            LOG.debug("Update failed for {}", identifier, e);
            throw RestconfDocumentedException.decodeAndThrow(e.getMessage(), failure);
        }
        return Response.status(result.getStatus()).build();
    }
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) ArrayList(java.util.ArrayList) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) OptimisticLockFailedException(org.opendaylight.mdsal.common.api.OptimisticLockFailedException)

Example 77 with RestconfDocumentedException

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

the class RestconfImpl method readConfigurationData.

@Override
public NormalizedNodeContext readConfigurationData(final String identifier, final UriInfo uriInfo) {
    boolean withDefaUsed = false;
    String withDefa = null;
    for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
        switch(entry.getKey()) {
            case "with-defaults":
                if (!withDefaUsed) {
                    withDefaUsed = true;
                    withDefa = entry.getValue().iterator().next();
                } else {
                    throw new RestconfDocumentedException("With-defaults parameter can be used only once.");
                }
                break;
            default:
                LOG.info("Unknown key : {}.", entry.getKey());
                break;
        }
    }
    // TODO: this flag is always ignored
    boolean tagged = false;
    if (withDefaUsed) {
        if ("report-all-tagged".equals(withDefa)) {
            tagged = true;
            withDefa = null;
        }
        if ("report-all".equals(withDefa)) {
            withDefa = null;
        }
    }
    final InstanceIdentifierContext<?> iiWithData = controllerContext.toInstanceIdentifier(identifier);
    final DOMMountPoint mountPoint = iiWithData.getMountPoint();
    NormalizedNode data = null;
    final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier();
    if (mountPoint != null) {
        data = broker.readConfigurationData(mountPoint, normalizedII, withDefa);
    } else {
        data = broker.readConfigurationData(normalizedII, withDefa);
    }
    if (data == null) {
        throw dataMissing(identifier);
    }
    return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseWriterParameters(uriInfo));
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) DOMMountPoint(org.opendaylight.mdsal.dom.api.DOMMountPoint) ArrayList(java.util.ArrayList) List(java.util.List) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) NormalizedNodeContext(org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext)

Example 78 with RestconfDocumentedException

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

the class XmlToPatchBodyReader method readValueNodes.

/**
 * Read value nodes.
 *
 * @param element Element of current edit operation
 * @param operation Name of current operation
 * @return List of value elements
 */
private static List<Element> readValueNodes(@NonNull final Element element, @NonNull final PatchEditOperation operation) {
    final Node valueNode = element.getElementsByTagName("value").item(0);
    if (operation.isWithValue() && valueNode == null) {
        throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
    }
    if (!operation.isWithValue() && valueNode != null) {
        throw new RestconfDocumentedException("Error parsing input", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
    }
    if (valueNode == null) {
        return null;
    }
    final List<Element> result = new ArrayList<>();
    final NodeList childNodes = valueNode.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); i++) {
        if (childNodes.item(i) instanceof Element) {
            result.add((Element) childNodes.item(i));
        }
    }
    return result;
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) ListSchemaNode(org.opendaylight.yangtools.yang.model.api.ListSchemaNode) ContainerSchemaNode(org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode) Node(org.w3c.dom.Node) SchemaNode(org.opendaylight.yangtools.yang.model.api.SchemaNode) DataSchemaNode(org.opendaylight.yangtools.yang.model.api.DataSchemaNode) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) ArrayList(java.util.ArrayList)

Example 79 with RestconfDocumentedException

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

the class RestconfDocumentedExceptionMapperTest method testToResponseWithAcceptHeader.

@Test
public void testToResponseWithAcceptHeader() throws Exception {
    stageMockEx(new RestconfDocumentedException("mock error"));
    final Response resp = target("/operational/foo").request().header("Accept", MediaType.APPLICATION_JSON).get();
    final InputStream stream = verifyResponse(resp, MediaType.APPLICATION_JSON, Status.INTERNAL_SERVER_ERROR);
    verifyJsonResponseBody(stream, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, null);
}
Also used : Response(javax.ws.rs.core.Response) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 80 with RestconfDocumentedException

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

the class RestconfDocumentedExceptionMapperTest method testToJsonResponseWithExceptionCause.

@Test
public void testToJsonResponseWithExceptionCause() throws Exception {
    final Exception cause = new Exception("mock exception cause");
    testJsonResponse(new RestconfDocumentedException("mock error", cause), Status.INTERNAL_SERVER_ERROR, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, "mock error", null, new SimpleErrorInfoVerifier(cause.getMessage()));
}
Also used : RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) SAXException(org.xml.sax.SAXException) IOException(java.io.IOException) RestconfDocumentedException(org.opendaylight.restconf.common.errors.RestconfDocumentedException) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

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