Search in sources :

Example 16 with RestChannel

use of org.opensearch.rest.RestChannel in project OpenSearch by opensearch-project.

the class AbstractHttpServerTransport method handleIncomingRequest.

private void handleIncomingRequest(final HttpRequest httpRequest, final HttpChannel httpChannel, final Exception exception) {
    if (exception == null) {
        HttpResponse earlyResponse = corsHandler.handleInbound(httpRequest);
        if (earlyResponse != null) {
            httpChannel.sendResponse(earlyResponse, earlyResponseListener(httpRequest, httpChannel));
            httpRequest.release();
            return;
        }
    }
    Exception badRequestCause = exception;
    /*
         * We want to create a REST request from the incoming request from Netty. However, creating this request could fail if there
         * are incorrectly encoded parameters, or the Content-Type header is invalid. If one of these specific failures occurs, we
         * attempt to create a REST request again without the input that caused the exception (e.g., we remove the Content-Type header,
         * or skip decoding the parameters). Once we have a request in hand, we then dispatch the request as a bad request with the
         * underlying exception that caused us to treat the request as bad.
         */
    final RestRequest restRequest;
    {
        RestRequest innerRestRequest;
        try {
            innerRestRequest = RestRequest.request(xContentRegistry, httpRequest, httpChannel);
        } catch (final RestRequest.ContentTypeHeaderException e) {
            badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e);
            innerRestRequest = requestWithoutContentTypeHeader(httpRequest, httpChannel, badRequestCause);
        } catch (final RestRequest.BadParameterException e) {
            badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e);
            innerRestRequest = RestRequest.requestWithoutParameters(xContentRegistry, httpRequest, httpChannel);
        }
        restRequest = innerRestRequest;
    }
    final HttpTracer trace = tracer.maybeTraceRequest(restRequest, exception);
    /*
         * We now want to create a channel used to send the response on. However, creating this channel can fail if there are invalid
         * parameter values for any of the filter_path, human, or pretty parameters. We detect these specific failures via an
         * IllegalArgumentException from the channel constructor and then attempt to create a new channel that bypasses parsing of these
         * parameter values.
         */
    final RestChannel channel;
    {
        RestChannel innerChannel;
        ThreadContext threadContext = threadPool.getThreadContext();
        try {
            innerChannel = new DefaultRestChannel(httpChannel, httpRequest, restRequest, bigArrays, handlingSettings, threadContext, corsHandler, trace);
        } catch (final IllegalArgumentException e) {
            badRequestCause = ExceptionsHelper.useOrSuppress(badRequestCause, e);
            final RestRequest innerRequest = RestRequest.requestWithoutParameters(xContentRegistry, httpRequest, httpChannel);
            innerChannel = new DefaultRestChannel(httpChannel, httpRequest, innerRequest, bigArrays, handlingSettings, threadContext, corsHandler, trace);
        }
        channel = innerChannel;
    }
    dispatchRequest(restRequest, channel, badRequestCause);
}
Also used : RestRequest(org.opensearch.rest.RestRequest) ThreadContext(org.opensearch.common.util.concurrent.ThreadContext) RestChannel(org.opensearch.rest.RestChannel) CancelledKeyException(java.nio.channels.CancelledKeyException) IOException(java.io.IOException) BindTransportException(org.opensearch.transport.BindTransportException)

Example 17 with RestChannel

use of org.opensearch.rest.RestChannel in project OpenSearch by opensearch-project.

the class AbstractHttpServerTransportTests method testTracerLog.

@TestLogging(value = "org.opensearch.http.HttpTracer:trace", reason = "to ensure we log REST requests on TRACE level")
public void testTracerLog() throws Exception {
    final String includeSettings;
    final String excludeSettings;
    if (randomBoolean()) {
        includeSettings = randomBoolean() ? "*" : "";
    } else {
        includeSettings = "/internal/test";
    }
    excludeSettings = "/internal/testNotSeen";
    final ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
    try (AbstractHttpServerTransport transport = new AbstractHttpServerTransport(Settings.EMPTY, networkService, bigArrays, threadPool, xContentRegistry(), new HttpServerTransport.Dispatcher() {

        @Override
        public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) {
            channel.sendResponse(emptyResponse(RestStatus.OK));
        }

        @Override
        public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, Throwable cause) {
            channel.sendResponse(emptyResponse(RestStatus.BAD_REQUEST));
        }
    }, clusterSettings) {

        @Override
        protected HttpServerChannel bind(InetSocketAddress hostAddress) {
            return null;
        }

        @Override
        protected void doStart() {
        }

        @Override
        protected void stopInternal() {
        }

        @Override
        public HttpStats stats() {
            return null;
        }
    }) {
        clusterSettings.applySettings(Settings.builder().put(HttpTransportSettings.SETTING_HTTP_TRACE_LOG_INCLUDE.getKey(), includeSettings).put(HttpTransportSettings.SETTING_HTTP_TRACE_LOG_EXCLUDE.getKey(), excludeSettings).build());
        final String traceLoggerName = "org.opensearch.http.HttpTracer";
        try (MockLogAppender appender = MockLogAppender.createForLoggers(LogManager.getLogger(traceLoggerName))) {
            final String opaqueId = UUIDs.randomBase64UUID(random());
            appender.addExpectation(new MockLogAppender.PatternSeenEventExpectation("received request", traceLoggerName, Level.TRACE, "\\[\\d+\\]\\[" + opaqueId + "\\]\\[OPTIONS\\]\\[/internal/test\\] received request from \\[.*"));
            final boolean badRequest = randomBoolean();
            appender.addExpectation(new MockLogAppender.PatternSeenEventExpectation("sent response", traceLoggerName, Level.TRACE, "\\[\\d+\\]\\[" + opaqueId + "\\]\\[" + (badRequest ? "BAD_REQUEST" : "OK") + "\\]\\[null\\]\\[0\\] sent response to \\[.*"));
            appender.addExpectation(new MockLogAppender.UnseenEventExpectation("received other request", traceLoggerName, Level.TRACE, "\\[\\d+\\]\\[" + opaqueId + "\\]\\[OPTIONS\\]\\[/internal/testNotSeen\\] received request from \\[.*"));
            final Exception inboundException;
            if (badRequest) {
                inboundException = new RuntimeException();
            } else {
                inboundException = null;
            }
            final FakeRestRequest fakeRestRequest = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY).withMethod(RestRequest.Method.OPTIONS).withPath("/internal/test").withHeaders(Collections.singletonMap(Task.X_OPAQUE_ID, Collections.singletonList(opaqueId))).withInboundException(inboundException).build();
            transport.incomingRequest(fakeRestRequest.getHttpRequest(), fakeRestRequest.getHttpChannel());
            final Exception inboundExceptionExcludedPath;
            if (randomBoolean()) {
                inboundExceptionExcludedPath = new RuntimeException();
            } else {
                inboundExceptionExcludedPath = null;
            }
            final FakeRestRequest fakeRestRequestExcludedPath = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY).withMethod(RestRequest.Method.OPTIONS).withPath("/internal/testNotSeen").withHeaders(Collections.singletonMap(Task.X_OPAQUE_ID, Collections.singletonList(opaqueId))).withInboundException(inboundExceptionExcludedPath).build();
            transport.incomingRequest(fakeRestRequestExcludedPath.getHttpRequest(), fakeRestRequestExcludedPath.getHttpChannel());
            appender.assertAllExpectationsMatched();
        }
    }
}
Also used : ClusterSettings(org.opensearch.common.settings.ClusterSettings) MockLogAppender(org.opensearch.test.MockLogAppender) InetSocketAddress(java.net.InetSocketAddress) ThreadContext(org.opensearch.common.util.concurrent.ThreadContext) RestChannel(org.opensearch.rest.RestChannel) Matchers.containsString(org.hamcrest.Matchers.containsString) FakeRestRequest(org.opensearch.test.rest.FakeRestRequest) UnknownHostException(java.net.UnknownHostException) FakeRestRequest(org.opensearch.test.rest.FakeRestRequest) RestRequest(org.opensearch.rest.RestRequest) TestLogging(org.opensearch.test.junit.annotations.TestLogging)

Aggregations

RestChannel (org.opensearch.rest.RestChannel)17 RestRequest (org.opensearch.rest.RestRequest)17 ThreadContext (org.opensearch.common.util.concurrent.ThreadContext)15 ClusterSettings (org.opensearch.common.settings.ClusterSettings)12 FakeRestRequest (org.opensearch.test.rest.FakeRestRequest)12 TransportAddress (org.opensearch.common.transport.TransportAddress)11 HttpServerTransport (org.opensearch.http.HttpServerTransport)11 NullDispatcher (org.opensearch.http.NullDispatcher)10 FullHttpResponse (io.netty.handler.codec.http.FullHttpResponse)9 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)8 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)8 Matchers.containsString (org.hamcrest.Matchers.containsString)8 Settings (org.opensearch.common.settings.Settings)8 HttpTransportSettings (org.opensearch.http.HttpTransportSettings)7 BytesRestResponse (org.opensearch.rest.BytesRestResponse)7 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)6 IOException (java.io.IOException)6 SharedGroupFactory (org.opensearch.transport.SharedGroupFactory)6 NioGroupFactory (org.opensearch.transport.nio.NioGroupFactory)5 OpenSearchException (org.opensearch.OpenSearchException)3