@Test public void mustWorkFromFuture() throws Exception { final Iterable<String> input = Arrays.asList("A", "B", "C"); CompletionStage<String> future1 = Source.from(input).runWith(Sink.<String>head(), materializer); CompletionStage<String> future2 = Source.fromCompletionStage(future1).runWith(Sink.<String>head(), materializer); String result = future2.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals("A", result); }
@Test public void mustBeAbleToUseFlatMapMerge() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final Iterable<Integer> input1 = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); final Iterable<Integer> input2 = Arrays.asList(10, 11, 12, 13, 14, 15, 16, 17, 18, 19); final Iterable<Integer> input3 = Arrays.asList(20, 21, 22, 23, 24, 25, 26, 27, 28, 29); final Iterable<Integer> input4 = Arrays.asList(30, 31, 32, 33, 34, 35, 36, 37, 38, 39); final List<Source<Integer, NotUsed>> mainInputs = new ArrayList<Source<Integer, NotUsed>>(); mainInputs.add(Source.from(input1)); mainInputs.add(Source.from(input2)); mainInputs.add(Source.from(input3)); mainInputs.add(Source.from(input4)); CompletionStage<List<Integer>> future = Source.from(mainInputs) .flatMapMerge(3, ConstantFun.<Source<Integer, NotUsed>>javaIdentityFunction()) .grouped(60) .runWith(Sink.<List<Integer>>head(), materializer); List<Integer> result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); final Set<Integer> set = new HashSet<Integer>(); for (Integer i : result) { set.add(i); } final Set<Integer> expected = new HashSet<Integer>(); for (int i = 0; i < 40; ++i) { expected.add(i); } assertEquals(expected, set); }
@Test public void mustRepeat() throws Exception { final CompletionStage<List<Integer>> f = Source.repeat(42).grouped(10000).runWith(Sink.<List<Integer>>head(), materializer); final List<Integer> result = f.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(result.size(), 10000); for (Integer i : result) assertEquals(i, (Integer) 42); }
@Test public void mustBeAbleToUseToFuture() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final Iterable<String> input = Arrays.asList("A", "B", "C"); CompletionStage<String> future = Source.from(input).runWith(Sink.<String>head(), materializer); String result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals("A", result); }
@Test public void mustWorkFromRange() throws Exception { CompletionStage<List<Integer>> f = Source.range(0, 10).grouped(20).runWith(Sink.<List<Integer>>head(), materializer); final List<Integer> result = f.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(11, result.size()); Integer counter = 0; for (Integer i : result) assertEquals(i, counter++); }
@Test public void mustBeAbleToUseThrottle() throws Exception { Integer result = Source.from(Arrays.asList(0, 1, 2)) .throttle(10, FiniteDuration.create(1, TimeUnit.SECONDS), 10, ThrottleMode.shaping()) .throttle(10, FiniteDuration.create(1, TimeUnit.SECONDS), 10, ThrottleMode.enforcing()) .runWith(Sink.head(), materializer) .toCompletableFuture() .get(3, TimeUnit.SECONDS); assertEquals((Object) 0, result); }
@Test public void partialGraph() throws Exception { // #partial-graph final Graph<FlowShape<Integer, Integer>, NotUsed> partial = GraphDSL.create( builder -> { final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2)); final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2)); final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2)); final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2)); builder.from(F.out()).toInlet(C.in(0)); builder.from(B).viaFanIn(C).toFanIn(F); builder .from(B) .via(builder.add(Flow.of(Integer.class).map(i -> i + 1))) .viaFanOut(E) .toFanIn(F); return new FlowShape<Integer, Integer>(B.in(), E.out(1)); }); // #partial-graph // #partial-use Source.single(0).via(partial).to(Sink.ignore()); // #partial-use // #partial-flow-dsl // Convert the partial graph of FlowShape to a Flow to get // access to the fluid DSL (for example to be able to call .filter()) final Flow<Integer, Integer, NotUsed> flow = Flow.fromGraph(partial); // Simple way to create a graph backed Source final Source<Integer, NotUsed> source = Source.fromGraph( GraphDSL.create( builder -> { final UniformFanInShape<Integer, Integer> merge = builder.add(Merge.create(2)); builder.from(builder.add(Source.single(0))).toFanIn(merge); builder.from(builder.add(Source.from(Arrays.asList(2, 3, 4)))).toFanIn(merge); // Exposing exactly one output port return new SourceShape<Integer>(merge.out()); })); // Building a Sink with a nested Flow, using the fluid DSL final Sink<Integer, NotUsed> sink = Flow.of(Integer.class).map(i -> i * 2).drop(10).named("nestedFlow").to(Sink.head()); // Putting all together final RunnableGraph<NotUsed> closed = source.via(flow.filter(i -> i > 1)).to(sink); // #partial-flow-dsl }
@Test public void mustBeAbleToUseBuffer() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final List<String> input = Arrays.asList("A", "B", "C"); final CompletionStage<List<String>> future = Source.from(input) .buffer(2, OverflowStrategy.backpressure()) .grouped(4) .runWith(Sink.<List<String>>head(), materializer); List<String> result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(input, result); }
@Test public void mustBeAbleToUseIdleTimeout() throws Throwable { try { try { Source.maybe() .idleTimeout(Duration.create(1, "second")) .runWith(Sink.head(), materializer) .toCompletableFuture() .get(3, TimeUnit.SECONDS); fail("A TimeoutException was expected"); } catch (ExecutionException e) { throw e.getCause(); } } catch (TimeoutException e) { // expected } }
@Test public void mustBeAbleToUsePrefixAndTail() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final Iterable<Integer> input = Arrays.asList(1, 2, 3, 4, 5, 6); CompletionStage<Pair<List<Integer>, Source<Integer, NotUsed>>> future = Source.from(input) .prefixAndTail(3) .runWith(Sink.<Pair<List<Integer>, Source<Integer, NotUsed>>>head(), materializer); Pair<List<Integer>, Source<Integer, NotUsed>> result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(Arrays.asList(1, 2, 3), result.first()); CompletionStage<List<Integer>> tailFuture = result.second().limit(4).runWith(Sink.<Integer>seq(), materializer); List<Integer> tailResult = tailFuture.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(Arrays.asList(4, 5, 6), tailResult); }
@Test public void mustBeAbleToUseIdleInject() throws Exception { Integer result = Source.maybe() .keepAlive( Duration.create(1, "second"), new Creator<Integer>() { public Integer create() { return 0; } }) .takeWithin(Duration.create(1500, "milliseconds")) .runWith(Sink.<Integer>head(), materializer) .toCompletableFuture() .get(3, TimeUnit.SECONDS); assertEquals((Object) 0, result); }
@Test public void mustBeAbleToUseConcatAllWithSources() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final Iterable<Integer> input1 = Arrays.asList(1, 2, 3); final Iterable<Integer> input2 = Arrays.asList(4, 5); final List<Source<Integer, NotUsed>> mainInputs = new ArrayList<Source<Integer, NotUsed>>(); mainInputs.add(Source.from(input1)); mainInputs.add(Source.from(input2)); CompletionStage<List<Integer>> future = Source.from(mainInputs) .<Integer, NotUsed>flatMapConcat( ConstantFun.<Source<Integer, NotUsed>>javaIdentityFunction()) .grouped(6) .runWith(Sink.<List<Integer>>head(), materializer); List<Integer> result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals(Arrays.asList(1, 2, 3, 4, 5), result); }
@Test public void mustBeAbleToUseOnCompleteError() { final JavaTestKit probe = new JavaTestKit(system); final Iterable<String> input = Arrays.asList("A", "B", "C"); Source.from(input) .<String>map( in -> { throw new RuntimeException("simulated err"); }) .runWith(Sink.<String>head(), materializer) .whenComplete( (s, ex) -> { if (ex == null) { probe.getRef().tell("done", ActorRef.noSender()); } else { probe.getRef().tell(ex.getMessage(), ActorRef.noSender()); } }); probe.expectMsgEquals("simulated err"); }
@Test public void mustBeAbleToUseSplitAfter() throws Exception { final Iterable<String> input = Arrays.asList("A", "B", "C", ".", "D", ".", "E", "F"); final Source<List<String>, NotUsed> source = Source.from(input) .splitAfter( new Predicate<String>() { public boolean test(String elem) { return elem.equals("."); } }) .grouped(10) .concatSubstreams(); final CompletionStage<List<List<String>>> future = source.grouped(10).runWith(Sink.<List<List<String>>>head(), materializer); final List<List<String>> result = future.toCompletableFuture().get(1, TimeUnit.SECONDS); assertEquals( Arrays.asList( Arrays.asList("A", "B", "C", "."), Arrays.asList("D", "."), Arrays.asList("E", "F")), result); }
@SuppressWarnings("unchecked") @Test public void mustBeAbleToUseGroupBy() throws Exception { final Iterable<String> input = Arrays.asList("Aaa", "Abb", "Bcc", "Cdd", "Cee"); final Source<List<String>, NotUsed> source = Source.from(input) .groupBy( 3, new Function<String, String>() { public String apply(String elem) { return elem.substring(0, 1); } }) .grouped(10) .mergeSubstreams(); final CompletionStage<List<List<String>>> future = source.grouped(10).runWith(Sink.<List<List<String>>>head(), materializer); final Object[] result = future.toCompletableFuture().get(1, TimeUnit.SECONDS).toArray(); Arrays.sort( result, (Comparator<Object>) (Object) new Comparator<List<String>>() { @Override public int compare(List<String> o1, List<String> o2) { return o1.get(0).charAt(0) - o2.get(0).charAt(0); } }); assertArrayEquals( new Object[] { Arrays.asList("Aaa", "Abb"), Arrays.asList("Bcc"), Arrays.asList("Cdd", "Cee") }, result); }
public static void main(String[] args) { Outlet<Integer> outlet = null; Outlet<Integer> outlet1 = null; Outlet<Integer> outlet2 = null; Inlet<Integer> inlet = null; Inlet<Integer> inlet1 = null; Inlet<Integer> inlet2 = null; Flow<Integer, Integer, BoxedUnit> flow = Flow.of(Integer.class); Flow<Integer, Integer, BoxedUnit> flow1 = Flow.of(Integer.class); Flow<Integer, Integer, BoxedUnit> flow2 = Flow.of(Integer.class); Promise<Option<Integer>> promise = null; { Graph<SourceShape<Integer>, BoxedUnit> graphSource = null; Graph<SinkShape<Integer>, BoxedUnit> graphSink = null; Graph<FlowShape<Integer, Integer>, BoxedUnit> graphFlow = null; // #flow-wrap Source<Integer, BoxedUnit> source = Source.fromGraph(graphSource); Sink<Integer, BoxedUnit> sink = Sink.fromGraph(graphSink); Flow<Integer, Integer, BoxedUnit> aflow = Flow.fromGraph(graphFlow); Flow.fromSinkAndSource(Sink.<Integer>head(), Source.single(0)); Flow.fromSinkAndSourceMat(Sink.<Integer>head(), Source.single(0), Keep.left()); // #flow-wrap Graph<BidiShape<Integer, Integer, Integer, Integer>, BoxedUnit> bidiGraph = null; // #bidi-wrap BidiFlow<Integer, Integer, Integer, Integer, BoxedUnit> bidiFlow = BidiFlow.fromGraph(bidiGraph); BidiFlow.fromFlows(flow1, flow2); BidiFlow.fromFlowsMat(flow1, flow2, Keep.both()); // #bidi-wrap } { // #graph-create GraphDSL.create( builder -> { // ... return ClosedShape.getInstance(); }); GraphDSL.create( builder -> { // ... return new FlowShape<>(inlet, outlet); }); // #graph-create } { // #graph-create-2 GraphDSL.create( builder -> { // ... return SourceShape.of(outlet); }); GraphDSL.create( builder -> { // ... return SinkShape.of(inlet); }); GraphDSL.create( builder -> { // ... return FlowShape.of(inlet, outlet); }); GraphDSL.create( builder -> { // ... return BidiShape.of(inlet1, outlet1, inlet2, outlet2); }); // #graph-create-2 } { // #graph-builder GraphDSL.create( builder -> { builder.from(outlet).toInlet(inlet); builder.from(outlet).via(builder.add(flow)).toInlet(inlet); builder.from(builder.add(Source.single(0))).to(builder.add(Sink.head())); // ... return ClosedShape.getInstance(); }); // #graph-builder } // #source-creators Source<Integer, Promise<Option<Integer>>> src = Source.<Integer>maybe(); // Complete the promise with an empty option to emulate the old lazyEmpty promise.trySuccess(scala.Option.empty()); final Source<String, Cancellable> ticks = Source.tick( FiniteDuration.create(0, TimeUnit.MILLISECONDS), FiniteDuration.create(200, TimeUnit.MILLISECONDS), "tick"); final Source<Integer, BoxedUnit> pubSource = Source.fromPublisher(TestPublisher.<Integer>manualProbe(true, sys)); final Source<Integer, BoxedUnit> futSource = Source.fromFuture(Futures.successful(42)); final Source<Integer, Subscriber<Integer>> subSource = Source.<Integer>asSubscriber(); // #source-creators // #sink-creators final Sink<Integer, BoxedUnit> subSink = Sink.fromSubscriber(TestSubscriber.<Integer>manualProbe(sys)); // #sink-creators // #sink-as-publisher final Sink<Integer, Publisher<Integer>> pubSink = Sink.<Integer>asPublisher(false); final Sink<Integer, Publisher<Integer>> pubSinkFanout = Sink.<Integer>asPublisher(true); // #sink-as-publisher // #empty-flow Flow<Integer, Integer, BoxedUnit> emptyFlow = Flow.<Integer>create(); // or Flow<Integer, Integer, BoxedUnit> emptyFlow2 = Flow.of(Integer.class); // #empty-flow // #flatMapConcat Flow.<Source<Integer, BoxedUnit>>create() .<Integer, BoxedUnit>flatMapConcat( new Function<Source<Integer, BoxedUnit>, Source<Integer, BoxedUnit>>() { @Override public Source<Integer, BoxedUnit> apply(Source<Integer, BoxedUnit> param) throws Exception { return param; } }); // #flatMapConcat Uri uri = null; // #raw-query final akka.japi.Option<String> theRawQueryString = uri.rawQueryString(); // #raw-query // #query-param final akka.japi.Option<String> aQueryParam = uri.query().get("a"); // #query-param // #file-source-sink final Source<ByteString, Future<Long>> fileSrc = FileIO.fromFile(new File(".")); final Source<ByteString, Future<Long>> otherFileSrc = FileIO.fromFile(new File("."), 1024); final Sink<ByteString, Future<Long>> fileSink = FileIO.toFile(new File(".")); // #file-source-sink // #input-output-stream-source-sink final Source<ByteString, Future<java.lang.Long>> inputStreamSrc = StreamConverters.fromInputStream( new Creator<InputStream>() { public InputStream create() { return new SomeInputStream(); } }); final Source<ByteString, Future<java.lang.Long>> otherInputStreamSrc = StreamConverters.fromInputStream( new Creator<InputStream>() { public InputStream create() { return new SomeInputStream(); } }, 1024); final Sink<ByteString, Future<java.lang.Long>> outputStreamSink = StreamConverters.fromOutputStream( new Creator<OutputStream>() { public OutputStream create() { return new SomeOutputStream(); } }); // #input-output-stream-source-sink // #output-input-stream-source-sink final FiniteDuration timeout = FiniteDuration.Zero(); final Source<ByteString, OutputStream> outputStreamSrc = StreamConverters.asOutputStream(); final Source<ByteString, OutputStream> otherOutputStreamSrc = StreamConverters.asOutputStream(timeout); final Sink<ByteString, InputStream> someInputStreamSink = StreamConverters.asInputStream(); final Sink<ByteString, InputStream> someOtherInputStreamSink = StreamConverters.asInputStream(timeout); // #output-input-stream-source-sink }