@Test public void demonstrateBroadcast() { final Sink<Author, CompletionStage<Done>> writeAuthors = Sink.ignore(); final Sink<Hashtag, CompletionStage<Done>> writeHashtags = Sink.ignore(); // #flow-graph-broadcast RunnableGraph.fromGraph( GraphDSL.create( b -> { final UniformFanOutShape<Tweet, Tweet> bcast = b.add(Broadcast.create(2)); final FlowShape<Tweet, Author> toAuthor = b.add(Flow.of(Tweet.class).map(t -> t.author)); final FlowShape<Tweet, Hashtag> toTags = b.add( Flow.of(Tweet.class) .mapConcat(t -> new ArrayList<Hashtag>(t.hashtags()))); final SinkShape<Author> authors = b.add(writeAuthors); final SinkShape<Hashtag> hashtags = b.add(writeHashtags); b.from(b.add(tweets)).viaFanOut(bcast).via(toAuthor).to(authors); b.from(bcast).via(toTags).to(hashtags); return ClosedShape.getInstance(); })) .run(mat); // #flow-graph-broadcast }
private void assertConnected(Activity activity) { Collection transitions = flow.getBegin().getLeavingTransitions(); assertTrue(transitions.contains(activity.getDefaultArrivingTransition())); transitions = flow.getEnd().getArrivingTransitions(); assertTrue(transitions.contains(activity.getDefaultLeavingTransition())); }
public static Flow buildLegacyFlow( final JobManager jobManager, final Map<String, Flow> alreadyBuiltFlows, final JobDescriptor rootDescriptor, final Map<String, JobDescriptor> allJobDescriptors) { // TODO MED: The jobManager isn't really the best Job factory. It should be revisited, but it // works for now. if (alreadyBuiltFlows.containsKey(rootDescriptor.getId())) { return alreadyBuiltFlows.get(rootDescriptor.getId()); } final Flow retVal; if (rootDescriptor.hasDependencies()) { Set<JobDescriptor> dependencies = rootDescriptor.getDependencies(); Flow[] depFlows = new Flow[dependencies.size()]; int index = 0; for (JobDescriptor jobDescriptor : dependencies) { depFlows[index] = buildLegacyFlow(jobManager, alreadyBuiltFlows, jobDescriptor, allJobDescriptors); ++index; } retVal = new MultipleDependencyFlow( new IndividualJobFlow(rootDescriptor.getId(), jobManager), depFlows); } else { retVal = new IndividualJobFlow(rootDescriptor.getId(), jobManager); } alreadyBuiltFlows.put(retVal.getName(), retVal); return retVal; }
@Test public void reusingComponents() throws Exception { final Source<Integer, NotUsed> nestedSource = Source.single(0) // An atomic source .map(i -> i + 1) // an atomic processing stage .named("nestedSource"); // wraps up the current Source and gives it a name final Flow<Integer, Integer, NotUsed> nestedFlow = Flow.of(Integer.class) .filter(i -> i != 0) // an atomic processing stage .map(i -> i - 2) // another atomic processing stage .named("nestedFlow"); // wraps up the Flow, and gives it a name final Sink<Integer, NotUsed> nestedSink = nestedFlow .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow .named("nestedSink"); // wrap it up // #reuse // Create a RunnableGraph from our components final RunnableGraph<NotUsed> runnableGraph = nestedSource.to(nestedSink); // Usage is uniform, no matter if modules are composite or atomic final RunnableGraph<NotUsed> runnableGraph2 = Source.single(0).to(Sink.fold(0, (acc, i) -> acc + i)); // #reuse }
private void handlePkt(byte[] data) throws NetUtilsException { try { // extract flow five tuple. FiveTuple ft = new FiveTuple(data); // if flow already opened then update. if (myFlowHash.containsKey(ft)) { Flow dt = myFlowHash.get(ft); dt.update(data, myStas.total); myFlowByOrder.add(dt); myPktToFlowMap.put(myStas.total, dt); } else { FiveTuple newft = new FiveTuple(data); Flow newfd = createFlowData(ft); newfd.update(data, myStas.total); myFlowHash.put(newft, newfd); myFlowDataList.add(newfd); myFlowByOrder.add(newfd); myPktToFlowMap.put(myStas.total, newfd); myFlowsNumByFt.put(newft, myFlowsNumByFt.size() + 1); } } // tmp solution for IP fragments catch (NetUtilsFragmentException ex) { myFrags.update(data, myStas.total); } }
public void testListners() { Flow flow = new Flow(); FlowListener listener = new FlowListener() { public void onStarting(Flow flow) {} public void onStopping(Flow flow) {} public void onCompleted(Flow flow) {} public boolean onThrowable(Flow flow, Throwable throwable) { return false; // To change body of implemented methods use File | Settings | File // Templates. } }; flow.addListener(listener); assertTrue("no listener found", flow.hasListeners()); flow.removeListener(listener); assertFalse("listener found", flow.hasListeners()); }
public void testStartStopRace() throws Exception { if (!new File(inputFileLower).exists()) fail("data file not found"); copyFromLocal(inputFileLower); Tap sourceLower = new Hfs(new TextLine(new Fields("offset", "line")), inputFileLower); Map sources = new HashMap(); sources.put("lower", sourceLower); Function splitter = new RegexSplitter(new Fields("num", "char"), " "); // using null pos so all fields are written Tap sink = new Hfs(new TextLine(), outputPath + "/startstop/", true); Pipe pipeLower = new Each(new Pipe("lower"), new Fields("line"), splitter); pipeLower = new GroupBy(pipeLower, new Fields("num")); Flow flow = new FlowConnector(getProperties()).connect(sources, sink, pipeLower); flow.start(); flow.stop(); // should not fail }
@Test public void testSendHtmlMail() { Map<String, Object> map = new HashMap<String, Object>(); Flow flow = new Flow(); flow.setPaticipants("wangyue10-zhanglihui-记文清qa-向海龙alb"); flow.setNotstandardreason("KA外部特殊政策"); map.put("flowid", flow.getId()); List<Flowtask> flowTask = new ArrayList<Flowtask>(); Flowtask task1 = new Flowtask(); task1.setErpCustomerName("wangyue10"); task1.setEndtime(new Date()); task1.setOperatorName("wangyue10"); task1.setFlowtaskstatusName("审核通过"); task1.setMsg("1"); flowTask.add(task1); Flowtask task2 = new Flowtask(); task2.setErpCustomerName("zhanglihui"); task2.setEndtime(new Date()); task2.setOperatorName("zhanglihui"); task2.setFlowtaskstatusName("审核通过"); task2.setMsg("2"); flowTask.add(task2); Flowtask task3 = new Flowtask(); task3.setErpCustomerName("记文清qa"); task3.setEndtime(new Date()); task3.setOperatorName("记文清qa"); task3.setFlowtaskstatusName("审核中"); task3.setMsg("3"); flowTask.add(task3); map.put("contractName", "新签"); Contractinapprove contract = new Contractinapprove(); contract.setContractid(105L); map.put("contractId", contract.getContractid()); Flowtask task = new Flowtask(); task.setErpCustomerName("zhanglihui"); map.put("prePerson", task.getErpCustomerName()); map.put("nextPerson", flowTask.get(flowTask.size() - 1).getErpCustomerName()); map.put("flow", flow); map.put("flowTask", flowTask); // 发起人信息 Useracct useracct = new Useracct(); useracct.setUsername("陈刚"); map.put("addUserName", useracct.getUsername()); StringBuilder sb = new StringBuilder("您的【"); sb.append("新签"); sb.append("】合同【"); sb.append(contract.getContractid()); sb.append("】已经通过【"); sb.append(task.getErpCustomerName()); sb.append("】审批,当前待【"); sb.append(flowTask.get(flowTask.size() - 1).getErpCustomerName()); sb.append("】审批"); String content = VelocityUtils.getInstance().parse("contract_approved_node_notice.vm", map); // MailHtmlUtils.sendHtmlMail("*****@*****.**", sb.toString(), content, // "1", "*****@*****.**"); }
@Test public void testFlowPartInfoCreation() throws Exception { Flow flow = Flows.createFlow(PACKET, 1); FlowPart part = flow.getPart("0.0"); FlowPartInfo info = part.getInfo(flow); assertEquals("CLEAN", info.getStatus()); assertEquals(0, info.getContributionCount()); flow.acknowledge("0.0", false); info = part.getInfo(flow); assertEquals(1, info.getContributionCount()); }
@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 }
public static void main(String[] args) throws IOException, NetUtilsException { // CaptureFileFlowAnalyzer ca = new CaptureFileFlowAnalyzer("c:\\zattoo.enc"); CaptureFileFlowAnalyzer ca = new CaptureFileFlowAnalyzer("c:\\client.enc"); System.out.println("Total Flows:" + ca.getNumberOfFlows()); for (Iterator ir = ca.iterator(); ir.hasNext(); ) { StringBuffer bf = new StringBuffer(); Flow next = (Flow) ir.next(); next.headerToReadableSting(bf); System.out.println(bf.toString()); } System.out.println("============" + ca.getNumberOfFlows()); }
@Test public void complexGraph() throws Exception { // #complex-graph RunnableGraph.fromGraph( GraphDSL.create( builder -> { final Outlet<Integer> A = builder.add(Source.single(0)).out(); final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2)); final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2)); final FlowShape<Integer, Integer> D = builder.add(Flow.of(Integer.class).map(i -> i + 1)); final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2)); final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2)); final Inlet<Integer> G = builder.add(Sink.<Integer>foreach(System.out::println)).in(); builder.from(F).toFanIn(C); builder.from(A).viaFanOut(B).viaFanIn(C).toFanIn(F); builder.from(B).via(D).viaFanOut(E).toFanIn(F); builder.from(E).toInlet(G); return ClosedShape.getInstance(); })); // #complex-graph // #complex-graph-alt RunnableGraph.fromGraph( GraphDSL.create( builder -> { final SourceShape<Integer> A = builder.add(Source.single(0)); final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2)); final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2)); final FlowShape<Integer, Integer> D = builder.add(Flow.of(Integer.class).map(i -> i + 1)); final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2)); final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2)); final SinkShape<Integer> G = builder.add(Sink.foreach(System.out::println)); builder.from(F.out()).toInlet(C.in(0)); builder.from(A).toInlet(B.in()); builder.from(B.out(0)).toInlet(C.in(1)); builder.from(C.out()).toInlet(F.in(0)); builder.from(B.out(1)).via(D).toInlet(E.in()); builder.from(E.out(0)).toInlet(F.in(1)); builder.from(E.out(1)).to(G); return ClosedShape.getInstance(); })); // #complex-graph-alt }
/* * jconsole only */ @Override public void _create(String flowName, String link, String attributes) throws XbowException { Map<FlowAttribute, String> attrs = new HashMap<FlowAttribute, String>(); for (String entry : attributes.split(",")) { attrs.put(FlowAttribute.fromString(entry.split("=")[0]), entry.split("=")[1]); } Map<FlowProperty, String> props = new HashMap<FlowProperty, String>(); props.put(FlowProperty.PRIORITY, "medium"); Flow flow = FlowToFlowInfoTranslator.toFlow(new FlowInfo(flowName, link, attrs, props, false)); flow.setFlowadm(flowadm); create(flow); }
@Test public void materializedValues() throws Exception { // #mat-combine-1 // Materializes to Promise<BoxedUnit> (red) final Source<Integer, CompletableFuture<Optional<Integer>>> source = Source.<Integer>maybe(); // Materializes to BoxedUnit (black) final Flow<Integer, Integer, NotUsed> flow1 = Flow.of(Integer.class).take(100); // Materializes to Promise<Option<>> (red) final Source<Integer, CompletableFuture<Optional<Integer>>> nestedSource = source.viaMat(flow1, Keep.left()).named("nestedSource"); // #mat-combine-1 // #mat-combine-2 // Materializes to BoxedUnit (orange) final Flow<Integer, ByteString, NotUsed> flow2 = Flow.of(Integer.class).map(i -> ByteString.fromString(i.toString())); // Materializes to Future<OutgoingConnection> (yellow) final Flow<ByteString, ByteString, CompletionStage<OutgoingConnection>> flow3 = Tcp.get(system).outgoingConnection("localhost", 8080); // Materializes to Future<OutgoingConnection> (yellow) final Flow<Integer, ByteString, CompletionStage<OutgoingConnection>> nestedFlow = flow2.viaMat(flow3, Keep.right()).named("nestedFlow"); // #mat-combine-2 // #mat-combine-3 // Materializes to Future<String> (green) final Sink<ByteString, CompletionStage<String>> sink = Sink.<String, ByteString>fold("", (acc, i) -> acc + i.utf8String()); // Materializes to Pair<Future<OutgoingConnection>, Future<String>> (blue) final Sink<Integer, Pair<CompletionStage<OutgoingConnection>, CompletionStage<String>>> nestedSink = nestedFlow.toMat(sink, Keep.both()); // #mat-combine-3 // #mat-combine-4b // Materializes to Future<MyClass> (purple) final RunnableGraph<CompletionStage<MyClass>> runnableGraph = nestedSource.toMat(nestedSink, Combiner::f); // #mat-combine-4b }
/** * Discovers flows present in the system and, if a publisher has been set, publishes each * discovered flow. * * @see FlowManagerMBean#discover() */ @Override public void discover() { if (publisher != null) { synchronized (publisher) { List<FlowInfo> flowsInfo = flowadm.getFlowsInfo(); logger.debug(flowsInfo.size() + " flow(s) discovered."); for (FlowInfo flowInfo : flowsInfo) { // Create new Flow object, initialize and register it. Flow flow = FlowToFlowInfoTranslator.toFlow(flowInfo); flow.setFlowadm(flowadm); publisher.publish(flow); } // Unpublish flows user deleted manually. Set<String> published = new HashSet<String>(); for (Object flow : publisher.getPublished()) { published.add(((Flow) flow).getName()); } Set<String> discovered = new HashSet<String>(); for (Object flowInfo : flowsInfo) { discovered.add(((FlowInfo) flowInfo).getName()); } published.removeAll(discovered); for (Object flowName : published) { try { publisher.unpublish((String) flowName); } catch (NotPublishedException e) { logger.fatal("Error while removing stale flows.", e); } } } } }
@Test public void testFlowPartGetLatestUpdate() throws Exception { Flow flow = Flows.createFlow(PACKET, 1); FlowPart part = flow.getPart("0.0"); part.setContributionTime(null); part.setFilterTime(null); assertNull(part.getLatestUpdate()); part.setContributionTime(dateHigh()); part.setFilterTime(null); assertEquals(dateHigh(), part.getLatestUpdate()); part.setContributionTime(null); part.setFilterTime(dateHigh()); assertEquals(dateHigh(), part.getLatestUpdate()); part.setContributionTime(dateHigh()); part.setFilterTime(dateLow()); assertEquals(dateHigh(), part.getLatestUpdate()); part.setContributionTime(dateLow()); part.setFilterTime(dateHigh()); assertEquals(dateHigh(), part.getLatestUpdate()); }
@Test public void demonstrateASimplerOneToManyStage() throws Exception { // tests: Graph<FlowShape<Integer, Integer>, NotUsed> duplicator = Flow.fromGraph(new Duplicator2<Integer>()); CompletionStage<Integer> result = Source.from(Arrays.asList(1, 2, 3)).via(duplicator).runFold(0, (n, sum) -> n + sum, mat); assertEquals(new Integer(12), result.toCompletableFuture().get(3, TimeUnit.SECONDS)); }
public void testLocalModeSink() throws Exception { Tap source = new Hfs(new TextLine(), "input/path"); Tap sink = new Lfs(new TextLine(), "output/path", true); Pipe pipe = new Pipe("test"); Map<Object, Object> props = getProperties(); Flow flow = new FlowConnector(props).connect(source, sink, pipe); List<FlowStep> steps = flow.getSteps(); assertEquals("wrong size", 1, steps.size()); FlowStep step = (FlowStep) steps.get(0); String tracker = step.getJobConf(MultiMapReducePlanner.getJobConf(props)).get("mapred.job.tracker"); boolean isLocal = tracker.equalsIgnoreCase("local"); assertTrue("is not local", isLocal); }
@Test public void attributes() throws Exception { // #attributes-inheritance final Source<Integer, NotUsed> nestedSource = Source.single(0).map(i -> i + 1).named("nestedSource"); // Wrap, no inputBuffer set final Flow<Integer, Integer, NotUsed> nestedFlow = Flow.of(Integer.class) .filter(i -> i != 0) .via( Flow.of(Integer.class) .map(i -> i - 2) .withAttributes(Attributes.inputBuffer(4, 4))) // override .named("nestedFlow"); // Wrap, no inputBuffer set final Sink<Integer, NotUsed> nestedSink = nestedFlow .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow .withAttributes( Attributes.name("nestedSink").and(Attributes.inputBuffer(3, 3))); // override // #attributes-inheritance }
@Test public void mustBeAbleToUseQueue() throws Exception { final Pair<SourceQueueWithComplete<String>, CompletionStage<List<String>>> x = Flow.of(String.class) .runWith(Source.queue(2, OverflowStrategy.fail()), Sink.seq(), materializer); final SourceQueueWithComplete<String> source = x.first(); final CompletionStage<List<String>> result = x.second(); source.offer("hello"); source.offer("world"); source.complete(); assertEquals( result.toCompletableFuture().get(3, TimeUnit.SECONDS), Arrays.asList("hello", "world")); }
public void testFailedSerialization() throws Exception { if (!new File(inputFileLower).exists()) fail("data file not found"); copyFromLocal(inputFileLower); Tap sourceLower = new Hfs(new TextLine(new Fields("offset", "line")), inputFileLower); Map sources = new HashMap(); sources.put("lower", sourceLower); Function splitter = new RegexSplitter(new Fields("num", "char"), " "); // using null pos so all fields are written Tap sink = new Hfs(new TextLine(), outputPath + "/badserialization/", true); Pipe pipeLower = new Each(new Pipe("lower"), new Fields("line"), splitter); pipeLower = new Each(pipeLower, new Fields("num"), new BadFilter()); pipeLower = new GroupBy(pipeLower, new Fields("num")); Flow flow = new FlowConnector(getProperties()).connect(sources, sink, pipeLower); // countFlow.writeDOT( "stopped.dot" ); LockingFlowListener listener = new LockingFlowListener(); flow.addListener(listener); try { flow.complete(); fail("did not throw serialization exception"); } catch (Exception exception) { // ignore } assertTrue("not marked failed", flow.getFlowStats().isFailed()); }
@Test public void demonstrateAManyToOneElementGraphStage() throws Exception { // tests: Graph<FlowShape<Integer, Integer>, NotUsed> evenFilter = Flow.fromGraph(new Filter<Integer>(n -> n % 2 == 0)); CompletionStage<Integer> result = Source.from(Arrays.asList(1, 2, 3, 4, 5, 6)) .via(evenFilter) .runFold(0, (elem, sum) -> sum + elem, mat); assertEquals(new Integer(12), result.toCompletableFuture().get(3, TimeUnit.SECONDS)); }
@Test public void nestedFlow() throws Exception { // #nested-flow final Source<Integer, NotUsed> nestedSource = Source.single(0) // An atomic source .map(i -> i + 1) // an atomic processing stage .named("nestedSource"); // wraps up the current Source and gives it a name final Flow<Integer, Integer, NotUsed> nestedFlow = Flow.of(Integer.class) .filter(i -> i != 0) // an atomic processing stage .map(i -> i - 2) // another atomic processing stage .named("nestedFlow"); // wraps up the Flow, and gives it a name final Sink<Integer, NotUsed> nestedSink = nestedFlow .to(Sink.fold(0, (acc, i) -> acc + i)) // wire an atomic sink to the nestedFlow .named("nestedSink"); // wrap it up // Create a RunnableGraph final RunnableGraph<NotUsed> runnableGraph = nestedSource.to(nestedSink); // #nested-flow }
@Test public void testSimpleClasspath() throws Exception { getPlatform().copyFromLocal(inputFileApache); Tap source = getPlatform().getTextFile(new Fields("offset", "line"), inputFileApache); Pipe pipe = new Pipe("test"); pipe = new Each(pipe, new Fields("line"), new TestFunction(), Fields.RESULTS); Tap sink = getPlatform().getTextFile(getOutputPath("classpath"), SinkMode.REPLACE); FlowDef flowDef = FlowDef.flowDef() .addSource("test", source) .addTailSink(pipe, sink) .addToClassPath(testClasspathJar); Flow flow = getPlatform().getFlowConnector().connect(flowDef); flow.complete(); validateLength(flow, 10); }
// #worker-pool public static <In, Out> Flow<In, Out, BoxedUnit> balancer( Flow<In, Out, BoxedUnit> worker, int workerCount) { return Flow.fromGraph( GraphDSL.create( b -> { boolean waitForAllDownstreams = true; final UniformFanOutShape<In, In> balance = b.add(Balance.<In>create(workerCount, waitForAllDownstreams)); final UniformFanInShape<Out, Out> merge = b.add(Merge.<Out>create(workerCount)); for (int i = 0; i < workerCount; i++) { b.from(balance.out(i)).via(b.add(worker)).toInlet(merge.in(i)); } return FlowShape.of(balance.in(), merge.out()); })); }
public void testHandledException() { state .getExceptionHandlerSet() .add( new FlowExecutionExceptionHandler() { public boolean canHandle(FlowExecutionException exception) { return true; } public void handle(FlowExecutionException exception, RequestControlContext context) { handled = true; } }); FlowExecutionException e = new FlowExecutionException(flow.getId(), state.getId(), "Whatev"); MockRequestControlContext context = new MockRequestControlContext(flow); assertTrue(state.handleException(e, context)); assertTrue(handled); }
public void testRemoveNode() { // remove first, middle and last activities flow.addNode(first); flow.addNode(second); flow.removeNode(first); assertDisconnected(first); flow.removeNode(second); assertDisconnected(second); assertEquals(0, flow.getBegin().getLeavingTransitions().size()); assertEquals(0, flow.getEnd().getArrivingTransitions().size()); }
@Test public void mustBeAbleToUseConflate() throws Exception { final JavaTestKit probe = new JavaTestKit(system); final List<String> input = Arrays.asList("A", "B", "C"); CompletionStage<String> future = Source.from(input) .conflateWithSeed(s -> s, (aggr, in) -> aggr + in) .runFold("", (aggr, in) -> aggr + in, materializer); String result = future.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals("ABC", result); final Flow<String, String, NotUsed> flow2 = Flow.of(String.class).conflate((a, b) -> a + b); CompletionStage<String> future2 = Source.from(input) .conflate((String a, String b) -> a + b) .runFold("", (a, b) -> a + b, materializer); String result2 = future2.toCompletableFuture().get(3, TimeUnit.SECONDS); assertEquals("ABC", result2); }
@Test public void demonstrateOneToOne() throws Exception { // tests: final Graph<FlowShape<String, Integer>, NotUsed> stringLength = Flow.fromGraph( new Map<String, Integer>( new Function<String, Integer>() { @Override public Integer apply(String str) { return str.length(); } })); CompletionStage<Integer> result = Source.from(Arrays.asList("one", "two", "three")) .via(stringLength) .runFold(0, (sum, n) -> sum + n, mat); assertEquals(new Integer(11), result.toCompletableFuture().get(3, TimeUnit.SECONDS)); }
@Test public void mustWorksForTwoStreams() throws Exception { final Flow<Integer, Integer, NotUsed> sharedThrottle = Flow.of(Integer.class) .throttle(1, FiniteDuration.create(1, TimeUnit.DAYS), 1, ThrottleMode.enforcing()); CompletionStage<List<Integer>> result1 = Source.single(1).via(sharedThrottle).via(sharedThrottle).runWith(Sink.seq(), materializer); // If there is accidental shared state then we would not be able to pass through the single // element assertEquals( result1.toCompletableFuture().get(3, TimeUnit.SECONDS), Collections.singletonList(1)); // It works with a new stream, too CompletionStage<List<Integer>> result2 = Source.single(1).via(sharedThrottle).via(sharedThrottle).runWith(Sink.seq(), materializer); assertEquals( result2.toCompletableFuture().get(3, TimeUnit.SECONDS), Collections.singletonList(1)); }