Search in sources :

Example 21 with TransportCallbackAdapter

use of com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter in project rest.li by linkedin.

the class RestLiIntTestServer method createServer.

public static HttpServer createServer(final Engine engine, int port, boolean useAsyncServletApi, int asyncTimeOut, List<? extends Filter> filters, final FilterChain filterChain, final boolean forceUseRestServer) {
    RestLiConfig config = new RestLiConfig();
    config.addResourcePackageNames(RESOURCE_PACKAGE_NAMES);
    config.setServerNodeUri(URI.create("http://localhost:" + port));
    config.setDocumentationRequestHandler(new DefaultDocumentationRequestHandler());
    config.addDebugRequestHandlers(new ParseqTraceDebugRequestHandler());
    config.setFilters(filters);
    GroupMembershipMgr membershipMgr = new HashGroupMembershipMgr();
    GroupMgr groupMgr = new HashMapGroupMgr(membershipMgr);
    GroupsRestApplication app = new GroupsRestApplication(groupMgr, membershipMgr);
    SimpleBeanProvider beanProvider = new SimpleBeanProvider();
    beanProvider.add("GroupsRestApplication", app);
    //using InjectMockResourceFactory to keep examples spring-free
    ResourceFactory factory = new InjectMockResourceFactory(beanProvider);
    //Todo this will have to change further to accomodate streaming tests - this is temporary
    final TransportDispatcher dispatcher;
    if (forceUseRestServer) {
        dispatcher = new DelegatingTransportDispatcher(new RestLiServer(config, factory, engine));
    } else {
        final StreamRequestHandler streamRequestHandler = new RestLiServer(config, factory, engine);
        dispatcher = new TransportDispatcher() {

            @Override
            public void handleRestRequest(RestRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<RestResponse> callback) {
                throw new UnsupportedOperationException("This server only accepts streaming");
            }

            @Override
            public void handleStreamRequest(StreamRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<StreamResponse> callback) {
                try {
                    streamRequestHandler.handleRequest(req, requestContext, new TransportCallbackAdapter<>(callback));
                } catch (Exception e) {
                    final Exception ex = RestException.forError(RestStatus.INTERNAL_SERVER_ERROR, e);
                    callback.onResponse(TransportResponseImpl.<StreamResponse>error(ex));
                }
            }
        };
    }
    return new HttpServerFactory(filterChain).createServer(port, HttpServerFactory.DEFAULT_CONTEXT_PATH, HttpServerFactory.DEFAULT_THREAD_POOL_SIZE, dispatcher, useAsyncServletApi ? HttpJettyServer.ServletType.ASYNC_EVENT : HttpJettyServer.ServletType.RAP, asyncTimeOut, !forceUseRestServer);
}
Also used : HttpServerFactory(com.linkedin.r2.transport.http.server.HttpServerFactory) TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.server.TransportCallbackAdapter) DelegatingTransportDispatcher(com.linkedin.restli.server.DelegatingTransportDispatcher) DefaultDocumentationRequestHandler(com.linkedin.restli.docgen.DefaultDocumentationRequestHandler) DelegatingTransportDispatcher(com.linkedin.restli.server.DelegatingTransportDispatcher) TransportDispatcher(com.linkedin.r2.transport.common.bridge.server.TransportDispatcher) ParseqTraceDebugRequestHandler(com.linkedin.restli.server.ParseqTraceDebugRequestHandler) HashGroupMembershipMgr(com.linkedin.restli.examples.groups.server.impl.HashGroupMembershipMgr) GroupMembershipMgr(com.linkedin.restli.examples.groups.server.api.GroupMembershipMgr) HashMapGroupMgr(com.linkedin.restli.examples.groups.server.impl.HashMapGroupMgr) GroupsRestApplication(com.linkedin.restli.examples.groups.server.rest.impl.GroupsRestApplication) RequestContext(com.linkedin.r2.message.RequestContext) RestLiServer(com.linkedin.restli.server.RestLiServer) SimpleBeanProvider(com.linkedin.restli.server.mock.SimpleBeanProvider) RestResponse(com.linkedin.r2.message.rest.RestResponse) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) InjectMockResourceFactory(com.linkedin.restli.server.mock.InjectMockResourceFactory) ResourceFactory(com.linkedin.restli.server.resources.ResourceFactory) RestException(com.linkedin.r2.message.rest.RestException) IOException(java.io.IOException) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) HashMapGroupMgr(com.linkedin.restli.examples.groups.server.impl.HashMapGroupMgr) GroupMgr(com.linkedin.restli.examples.groups.server.api.GroupMgr) StreamRequestHandler(com.linkedin.r2.transport.common.StreamRequestHandler) RestRequest(com.linkedin.r2.message.rest.RestRequest) InjectMockResourceFactory(com.linkedin.restli.server.mock.InjectMockResourceFactory) HashGroupMembershipMgr(com.linkedin.restli.examples.groups.server.impl.HashGroupMembershipMgr) RestLiConfig(com.linkedin.restli.server.RestLiConfig)

Example 22 with TransportCallbackAdapter

use of com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter in project rest.li by linkedin.

the class TestHttpNettyClient method testFailBackoff.

@Test
public void testFailBackoff() throws Exception {
    final int WARM_UP = 10;
    final int N = 5;
    final int MAX_RATE_LIMITING_PERIOD = 500;
    final CountDownLatch warmUpLatch = new CountDownLatch(WARM_UP);
    final CountDownLatch latch = new CountDownLatch(N);
    final AtomicReference<Boolean> isShutdown = new AtomicReference<>(false);
    AsyncPool<Channel> testPool = new AsyncPoolImpl<>("test pool", new AsyncPool.Lifecycle<Channel>() {

        @Override
        public void create(Callback<Channel> callback) {
            if (warmUpLatch.getCount() > 0) {
                warmUpLatch.countDown();
            } else {
                latch.countDown();
            }
            callback.onError(new Throwable("Oops..."));
        }

        @Override
        public boolean validateGet(Channel obj) {
            return false;
        }

        @Override
        public boolean validatePut(Channel obj) {
            return false;
        }

        @Override
        public void destroy(Channel obj, boolean error, Callback<Channel> callback) {
        }

        @Override
        public PoolStats.LifecycleStats getStats() {
            return null;
        }
    }, 200, 30000, _scheduler, Integer.MAX_VALUE, AsyncPoolImpl.Strategy.MRU, 0, new ExponentialBackOffRateLimiter(0, MAX_RATE_LIMITING_PERIOD, Math.max(10, MAX_RATE_LIMITING_PERIOD / 32), _scheduler));
    HttpNettyClient client = new HttpNettyClient(address -> testPool, _scheduler, 500, 500, 1024 * 1024 * 2);
    final RestRequest r = new RestRequestBuilder(URI.create("http://localhost:8080/")).setMethod("GET").build();
    final ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(() -> {
        while (!isShutdown.get()) {
            try {
                FutureCallback<RestResponse> callback = new FutureCallback<>();
                client.restRequest(r, new RequestContext(), new HashMap<>(), new TransportCallbackAdapter<RestResponse>(callback));
                callback.get();
            } catch (Exception e) {
            // ignore
            }
        }
    });
    // First ensure a bunch fail to get the rate limiting going
    warmUpLatch.await(120, TimeUnit.SECONDS);
    // Now we should be rate limited
    long start = System.currentTimeMillis();
    System.err.println("Starting at " + start);
    long lowTolerance = N * MAX_RATE_LIMITING_PERIOD * 4 / 5;
    long highTolerance = N * MAX_RATE_LIMITING_PERIOD * 5 / 4;
    Assert.assertTrue(latch.await(highTolerance, TimeUnit.MILLISECONDS), "Should have finished within " + highTolerance + "ms");
    long elapsed = System.currentTimeMillis() - start;
    Assert.assertTrue(elapsed > lowTolerance, "Should have finished after " + lowTolerance + "ms (took " + elapsed + ")");
    // shutdown everything
    isShutdown.set(true);
    executor.shutdown();
}
Also used : RequestContext(com.linkedin.r2.message.RequestContext) FutureCallback(com.linkedin.common.callback.FutureCallback) RestResponse(com.linkedin.r2.message.rest.RestResponse) Channel(io.netty.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) EncoderException(io.netty.handler.codec.EncoderException) TimeoutException(java.util.concurrent.TimeoutException) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ExecutionException(java.util.concurrent.ExecutionException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) RestRequest(com.linkedin.r2.message.rest.RestRequest) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Test(org.testng.annotations.Test)

Example 23 with TransportCallbackAdapter

use of com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter in project rest.li by linkedin.

the class TestHttpNettyStreamClient method testRestRequests.

@Test(dataProvider = "requestResponseParameters", expectedExceptions = UnsupportedOperationException.class)
public void testRestRequests(AbstractNettyStreamClient client, String method, int requestSize, int responseSize, boolean isFullRequest) throws Exception {
    Server server = new HttpServerBuilder().responseSize(responseSize).build();
    try {
        server.start();
        for (int i = 0; i < REQUEST_COUNT; i++) {
            RestRequest request = new RestRequestBuilder(new URI(URL)).setMethod(method).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).setEntity(ByteString.copy(new byte[requestSize])).build();
            RequestContext context = new RequestContext();
            context.putLocalAttr(R2Constants.IS_FULL_REQUEST, isFullRequest);
            client.restRequest(request, context, new HashMap<>(), new TransportCallbackAdapter<>(new Callback<RestResponse>() {

                @Override
                public void onSuccess(RestResponse response) {
                }

                @Override
                public void onError(Throwable e) {
                }
            }));
        }
    } finally {
        server.stop();
    }
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) Server(org.eclipse.jetty.server.Server) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) URI(java.net.URI) Test(org.testng.annotations.Test)

Example 24 with TransportCallbackAdapter

use of com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter in project rest.li by linkedin.

the class TestHttpNettyStreamClient method testCancelStreamRequests.

@Test(dataProvider = "requestResponseParameters", groups = TestGroupNames.TESTNG_GROUP_KNOWN_ISSUE)
public void testCancelStreamRequests(AbstractNettyStreamClient client, String method, int requestSize, int responseSize, boolean isFullRequest) throws Exception {
    AtomicInteger succeeded = new AtomicInteger(0);
    AtomicInteger failed = new AtomicInteger(0);
    Server server = new HttpServerBuilder().responseSize(responseSize).build();
    try {
        server.start();
        CountDownLatch latch = new CountDownLatch(REQUEST_COUNT);
        for (int i = 0; i < REQUEST_COUNT; i++) {
            StreamRequest request = new StreamRequestBuilder(new URI(URL)).setMethod(method).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[requestSize]))));
            RequestContext context = new RequestContext();
            context.putLocalAttr(R2Constants.IS_FULL_REQUEST, isFullRequest);
            client.streamRequest(request, context, new HashMap<>(), new TransportCallbackAdapter<>(new Callback<StreamResponse>() {

                @Override
                public void onSuccess(StreamResponse response) {
                    response.getEntityStream().setReader(new Reader() {

                        @Override
                        public void onDataAvailable(ByteString data) {
                        }

                        @Override
                        public void onDone() {
                            failed.incrementAndGet();
                            latch.countDown();
                        }

                        @Override
                        public void onError(Throwable e) {
                            failed.incrementAndGet();
                            latch.countDown();
                        }

                        @Override
                        public void onInit(ReadHandle rh) {
                            rh.cancel();
                            succeeded.incrementAndGet();
                            latch.countDown();
                        }
                    });
                }

                @Override
                public void onError(Throwable e) {
                    failed.incrementAndGet();
                    latch.countDown();
                }
            }));
        }
        if (!latch.await(30, TimeUnit.SECONDS)) {
            Assert.fail("Timeout waiting for responses. " + succeeded + " requests succeeded and " + failed + " requests failed out of total " + REQUEST_COUNT + " requests");
        }
        Assert.assertEquals(latch.getCount(), 0);
        Assert.assertEquals(failed.get(), 0);
        Assert.assertEquals(succeeded.get(), REQUEST_COUNT);
        FutureCallback<None> shutdownCallback = new FutureCallback<>();
        client.shutdown(shutdownCallback);
        shutdownCallback.get(30, TimeUnit.SECONDS);
    } finally {
        server.stop();
    }
}
Also used : Server(org.eclipse.jetty.server.Server) ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Reader(com.linkedin.r2.message.stream.entitystream.Reader) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) ReadHandle(com.linkedin.r2.message.stream.entitystream.ReadHandle) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RequestContext(com.linkedin.r2.message.RequestContext) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 25 with TransportCallbackAdapter

use of com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter in project rest.li by linkedin.

the class TestHttpNettyStreamClient method testRequestContextAttributes.

@Test(dataProvider = "remoteClientAddressClients")
public void testRequestContextAttributes(AbstractNettyStreamClient client) throws InterruptedException, IOException, TimeoutException {
    RestRequest r = new RestRequestBuilder(URI.create("http://localhost")).build();
    FutureCallback<StreamResponse> cb = new FutureCallback<>();
    TransportCallback<StreamResponse> callback = new TransportCallbackAdapter<>(cb);
    RequestContext requestContext = new RequestContext();
    client.streamRequest(Messages.toStreamRequest(r), requestContext, new HashMap<>(), callback);
    final String actualRemoteAddress = (String) requestContext.getLocalAttr(R2Constants.REMOTE_SERVER_ADDR);
    final HttpProtocolVersion actualProtocolVersion = (HttpProtocolVersion) requestContext.getLocalAttr(R2Constants.HTTP_PROTOCOL_VERSION);
    Assert.assertTrue("127.0.0.1".equals(actualRemoteAddress) || "0:0:0:0:0:0:0:1".equals(actualRemoteAddress), "Actual remote client address is not expected. " + "The local attribute field must be IP address in string type" + actualRemoteAddress);
    if (client instanceof HttpNettyStreamClient) {
        Assert.assertEquals(actualProtocolVersion, HttpProtocolVersion.HTTP_1_1);
    } else if (client instanceof Http2NettyStreamClient) {
        Assert.assertEquals(actualProtocolVersion, HttpProtocolVersion.HTTP_2);
    } else {
        Assert.fail("Unexpected client instance type");
    }
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) HttpProtocolVersion(com.linkedin.r2.transport.http.common.HttpProtocolVersion) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) AsciiString(io.netty.util.AsciiString) ByteString(com.linkedin.data.ByteString) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Aggregations

RequestContext (com.linkedin.r2.message.RequestContext)34 FutureCallback (com.linkedin.common.callback.FutureCallback)30 RestRequest (com.linkedin.r2.message.rest.RestRequest)30 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)27 Test (org.testng.annotations.Test)26 RestResponse (com.linkedin.r2.message.rest.RestResponse)23 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)22 TransportCallbackAdapter (com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter)22 ExecutionException (java.util.concurrent.ExecutionException)21 RemoteInvocationException (com.linkedin.r2.RemoteInvocationException)15 URI (java.net.URI)15 ByteString (com.linkedin.data.ByteString)14 TimeoutException (java.util.concurrent.TimeoutException)13 AsciiString (io.netty.util.AsciiString)10 None (com.linkedin.common.util.None)8 HashMap (java.util.HashMap)7 RestException (com.linkedin.r2.message.rest.RestException)6 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)6 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)6 Server (org.eclipse.jetty.server.Server)6