Search in sources :

Example 11 with Subscription

use of java.util.concurrent.Flow.Subscription in project helidon by oracle.

the class BufferedEmittingPublisherTest method testHookOnRequested.

@Test
public void testHookOnRequested() {
    final AtomicLong requested = new AtomicLong();
    BufferedEmittingPublisher<Long> publisher = new BufferedEmittingPublisher<Long>() {
    };
    publisher.onRequest((n, demand) -> requested.set(n));
    TestSubscriber<Long> subscriber = new TestSubscriber<Long>() {

        @Override
        public void onSubscribe(Subscription subscription) {
            subscription.request(1);
        }
    };
    publisher.subscribe(subscriber);
    assertThat(requested.get(), is(equalTo(1L)));
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong) Subscription(java.util.concurrent.Flow.Subscription) Test(org.junit.jupiter.api.Test)

Example 12 with Subscription

use of java.util.concurrent.Flow.Subscription in project helidon by oracle.

the class MultiPartDecoderTest method testPartContentSubscriberThrottling.

@Test
public void testPartContentSubscriberThrottling() {
    String boundary = "boundary";
    final byte[] chunk1 = ("--" + boundary + "\n" + "Content-Id: part1\n" + "\n" + "body 1.aaaa\n").getBytes();
    final byte[] chunk2 = "body 1.bbbb\n".getBytes();
    final byte[] chunk3 = ("body 1.cccc\n" + "--" + boundary + "\n" + "Content-Id: part2\n" + "\n" + "This is the 2nd").getBytes();
    final byte[] chunk4 = ("body.\n" + "--" + boundary + "--").getBytes();
    final CountDownLatch latch = new CountDownLatch(3);
    Consumer<BodyPart> consumer = (part) -> {
        latch.countDown();
        if (latch.getCount() == 2) {
            assertThat(part.headers().values("Content-Id"), hasItems("part1"));
        }
        part.content().subscribe(new Subscriber<DataChunk>() {

            @Override
            public void onSubscribe(Subscription subscription) {
                subscription.request(1);
            }

            @Override
            public void onNext(DataChunk item) {
                latch.countDown();
            }

            @Override
            public void onError(Throwable throwable) {
            }

            @Override
            public void onComplete() {
            }
        });
    };
    BodyPartSubscriber testSubscriber = new BodyPartSubscriber(SUBSCRIBER_TYPE.ONE_BY_ONE, consumer);
    partsPublisher(boundary, List.of(chunk1, chunk2, chunk3, chunk4)).subscribe(testSubscriber);
    waitOnLatchNegative(latch, "the 2nd part should not be processed");
    assertThat(latch.getCount(), is(equalTo(1L)));
    try {
        testSubscriber.complete.orTimeout(200, TimeUnit.MILLISECONDS).join();
        throw new IllegalStateException("Not expecting to make progress, unless the part is consumed");
    } catch (CompletionException e) {
        Throwable error = e.getCause();
        // This is the expected outcome - the testSubcriber is not making progress
        assertThat(error.getClass(), is(equalTo(TimeoutException.class)));
    }
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) Assertions.fail(org.junit.jupiter.api.Assertions.fail) CoreMatchers.hasItems(org.hamcrest.CoreMatchers.hasItems) Subscription(java.util.concurrent.Flow.Subscription) DataChunk(io.helidon.common.http.DataChunk) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Publisher(java.util.concurrent.Flow.Publisher) Subscriber(java.util.concurrent.Flow.Subscriber) Matchers.equalTo(org.hamcrest.Matchers.equalTo) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Multi(io.helidon.common.reactive.Multi) CoreMatchers.nullValue(org.hamcrest.CoreMatchers.nullValue) CountDownLatch(java.util.concurrent.CountDownLatch) Subscriber(java.util.concurrent.Flow.Subscriber) CompletionException(java.util.concurrent.CompletionException) DataChunk(io.helidon.common.http.DataChunk) Subscription(java.util.concurrent.Flow.Subscription) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 13 with Subscription

use of java.util.concurrent.Flow.Subscription in project helidon by oracle.

the class ContextLifeCycleTest method testContextReactive.

@Test
void testContextReactive() {
    Handler handler = (req, res) -> {
        String cid = req.context().id();
        req.content().subscribe(new Subscriber<>() {

            @Override
            public void onSubscribe(Subscription subscription) {
                subscription.request(Long.MAX_VALUE);
            }

            @Override
            public void onNext(DataChunk item) {
                item.release();
                if (!cid.equals(contextId())) {
                    throw new IllegalStateException("Context invalid");
                }
            }

            @Override
            public void onError(Throwable throwable) {
                res.send(throwable);
            }

            @Override
            public void onComplete() {
                if (!cid.equals(contextId())) {
                    res.send(new IllegalStateException("Context invalid"));
                } else {
                    res.send();
                }
            }
        });
    };
    WebServer webServer = WebServer.builder(Routing.builder().post(handler)).build().start().await(10, TimeUnit.SECONDS);
    ResponseStatus responseStatus = WebClient.builder().baseUri("http://localhost:" + webServer.port()).build().post().submit("some-payload").map(WebClientResponse::status).onTerminate(webServer::shutdown).await(10, TimeUnit.SECONDS);
    assertThat(responseStatus.code(), is(200));
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) Subscription(java.util.concurrent.Flow.Subscription) DataChunk(io.helidon.common.http.DataChunk) Context(io.helidon.common.context.Context) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) Contexts(io.helidon.common.context.Contexts) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) Subscriber(java.util.concurrent.Flow.Subscriber) ResponseStatus(io.helidon.common.http.Http.ResponseStatus) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) WebClientResponse(io.helidon.webclient.WebClientResponse) Subscriber(java.util.concurrent.Flow.Subscriber) ResponseStatus(io.helidon.common.http.Http.ResponseStatus) DataChunk(io.helidon.common.http.DataChunk) Subscription(java.util.concurrent.Flow.Subscription) Test(org.junit.jupiter.api.Test)

Example 14 with Subscription

use of java.util.concurrent.Flow.Subscription in project helidon by oracle.

the class RequestContentTest method multiThreadingFilterAndReaderTest.

@SuppressWarnings("unchecked")
@Test
public void multiThreadingFilterAndReaderTest() throws Exception {
    CountDownLatch subscribedLatch = new CountDownLatch(1);
    SubmissionPublisher<DataChunk> publisher = new SubmissionPublisher<>(Runnable::run, 10);
    ForkJoinPool.commonPool().submit(() -> {
        try {
            if (!subscribedLatch.await(10, TimeUnit.SECONDS)) {
                fail("Subscriber didn't subscribe in timely manner!");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted!", e);
        }
        publisher.submit(DataChunk.create("first".getBytes()));
        publisher.submit(DataChunk.create("second".getBytes()));
        publisher.submit(DataChunk.create("third".getBytes()));
        publisher.close();
    });
    Request request = requestTestStub(Multi.create(publisher));
    request.content().registerFilter(originalPublisher -> subscriberDelegate -> originalPublisher.subscribe(new Subscriber<DataChunk>() {

        @Override
        public void onSubscribe(Subscription subscription) {
            subscriberDelegate.onSubscribe(subscription);
            subscribedLatch.countDown();
        }

        @Override
        public void onNext(DataChunk item) {
            // mapping the on next call only
            subscriberDelegate.onNext(DataChunk.create(requestChunkAsString(item).toUpperCase().getBytes()));
        }

        @Override
        public void onError(Throwable throwable) {
            subscriberDelegate.onError(throwable);
        }

        @Override
        public void onComplete() {
            subscriberDelegate.onComplete();
        }
    }));
    request.content().registerReader(Iterable.class, (publisher1, clazz) -> {
        fail("Iterable reader should have not been used!");
        throw new IllegalStateException("unreachable code");
    });
    request.content().registerReader(ArrayList.class, (publisher1, clazz) -> {
        fail("ArrayList reader should have not been used!");
        throw new IllegalStateException("unreachable code");
    });
    request.content().registerReader(List.class, (publisher1, clazz) -> {
        CompletableFuture<List> future = new CompletableFuture<>();
        List<String> list = new CopyOnWriteArrayList<>();
        publisher1.subscribe(new Subscriber<DataChunk>() {

            @Override
            public void onSubscribe(Subscription subscription) {
                subscription.request(Long.MAX_VALUE);
                subscribedLatch.countDown();
            }

            @Override
            public void onNext(DataChunk item) {
                list.add(TestUtils.requestChunkAsString(item));
            }

            @Override
            public void onError(Throwable throwable) {
                fail("Received an exception: " + throwable.getMessage());
            }

            @Override
            public void onComplete() {
                future.complete(list);
            }
        });
        return future;
    });
    List<String> result = (List<String>) request.content().as(List.class).toCompletableFuture().get(10, TimeUnit.SECONDS);
    assertThat(result, hasItems(is("FIRST"), is("SECOND"), is("THIRD")));
}
Also used : SubmissionPublisher(java.util.concurrent.SubmissionPublisher) TestUtils.requestChunkAsString(io.helidon.webserver.utils.TestUtils.requestChunkAsString) StringContains.containsString(org.hamcrest.core.StringContains.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) CompletableFuture(java.util.concurrent.CompletableFuture) Subscriber(java.util.concurrent.Flow.Subscriber) DataChunk(io.helidon.common.http.DataChunk) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Subscription(java.util.concurrent.Flow.Subscription) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Test(org.junit.jupiter.api.Test)

Example 15 with Subscription

use of java.util.concurrent.Flow.Subscription in project helidon by oracle.

the class NettyWebServerTest method main.

/**
 * Start the test and then run:
 * <pre><code>
 *     seq 1000 | head -c 1000 | curl -X PUT -Ssf http://localhost:8080 --data-binary @- http://localhost:8080 --data ahoj
 * </code></pre>
 * <p>
 *
 * @throws InterruptedException if the main thread is interrupted
 */
static void main(String[] args) throws InterruptedException {
    WebServer webServer = WebServer.builder().port(8080).host("localhost").routing(routing((breq, bres) -> {
        SubmissionPublisher<DataChunk> responsePublisher = new SubmissionPublisher<>(ForkJoinPool.commonPool(), 1024);
        responsePublisher.subscribe(bres);
        final AtomicReference<Subscription> subscription = new AtomicReference<>();
        // Read request and immediately write to response
        Multi.create(breq.bodyPublisher()).subscribe((DataChunk chunk) -> {
            DataChunk responseChunk = DataChunk.create(true, chunk::release, chunk.data());
            responsePublisher.submit(responseChunk);
            ForkJoinPool.commonPool().submit(() -> {
                try {
                    Thread.sleep(1);
                    subscription.get().request(ThreadLocalRandom.current().nextLong(1, 3));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new IllegalStateException(e);
                }
            });
        }, (Throwable ex) -> {
            LOGGER.log(Level.WARNING, "An error occurred during the flow consumption!", ex);
        }, responsePublisher::close, (Subscription s) -> {
            subscription.set(s);
            s.request(1);
            bres.writeStatusAndHeaders(Http.Status.CREATED_201, Collections.emptyMap());
        });
    })).build();
    webServer.start();
    Thread.currentThread().join();
}
Also used : SubmissionPublisher(java.util.concurrent.SubmissionPublisher) DataChunk(io.helidon.common.http.DataChunk) AtomicReference(java.util.concurrent.atomic.AtomicReference) Subscription(java.util.concurrent.Flow.Subscription)

Aggregations

Subscription (java.util.concurrent.Flow.Subscription)28 Test (org.junit.jupiter.api.Test)14 CountDownLatch (java.util.concurrent.CountDownLatch)10 AtomicReference (java.util.concurrent.atomic.AtomicReference)8 DataChunk (io.helidon.common.http.DataChunk)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 BinaryRow (org.apache.ignite.internal.schema.BinaryRow)5 Subscriber (java.util.concurrent.Flow.Subscriber)4 TestSubscription (io.servicetalk.concurrent.api.TestSubscription)3 ScalarValueSubscription (io.servicetalk.concurrent.internal.ScalarValueSubscription)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 AtomicLong (java.util.concurrent.atomic.AtomicLong)3 ReentrantLock (java.util.concurrent.locks.ReentrantLock)3 Test (org.testng.annotations.Test)3 IntegerGene (io.jenetics.IntegerGene)2 ByteBuffer (java.nio.ByteBuffer)2 List (java.util.List)2 Flow (java.util.concurrent.Flow)2 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)2