├── java-demo ├── build.sbt └── src │ └── main │ └── java │ ├── demo4 │ ├── Ex1.java │ └── Ex2.java │ ├── demo1 │ ├── Ex1.java │ ├── Ex2.java │ └── Ex3.java │ ├── demo5 │ ├── ErrorHandling1.java │ ├── ErrorHandling3.java │ └── ErrorHandling2.java │ ├── demo3 │ ├── Ex1.java │ └── Ex2.java │ └── demo2 │ └── GraphEx.java ├── project └── build.properties ├── scala-demo ├── build.sbt └── src │ └── main │ └── scala │ ├── demo4 │ ├── Ex1.scala │ └── Ex2.scala │ ├── demo1 │ ├── Ex1.scala │ ├── Ex2.scala │ └── Ex3.scala │ ├── demo5 │ ├── ErrorHandling1.scala │ ├── ErrorHandling3.scala │ └── ErrorHandling2.scala │ ├── demo3 │ ├── Ex1.scala │ └── Ex2.scala │ ├── demo2 │ └── GraphEx.scala │ └── extra │ └── CustomersExample.scala ├── scala-demo-seed ├── build.sbt └── src │ └── main │ └── scala │ ├── demo3 │ ├── Ex1.scala │ └── Ex2.scala │ ├── demo1 │ ├── Ex1.scala │ ├── Ex3.scala │ └── Ex2.scala │ ├── demo4 │ ├── Ex1.scala │ └── Ex2.scala │ ├── demo5 │ ├── ErrorHandling1.scala │ ├── ErrorHandling2.scala │ └── ErrorHandling3.scala │ ├── demo2 │ └── GraphEx.scala │ └── extra │ └── CustomersExample.scala ├── .gitignore └── LICENSE /java-demo/build.sbt: -------------------------------------------------------------------------------- 1 | name := """java-demo""" -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.8 2 | -------------------------------------------------------------------------------- /scala-demo/build.sbt: -------------------------------------------------------------------------------- 1 | name := """scala-demo""" -------------------------------------------------------------------------------- /scala-demo-seed/build.sbt: -------------------------------------------------------------------------------- 1 | name := """scala-demo-seed""" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | /**/.gitignore 5 | 6 | # sbt specific 7 | .cache 8 | .history 9 | .lib/ 10 | dist/* 11 | target/ 12 | lib_managed/ 13 | src_managed/ 14 | project/boot/ 15 | project/plugins/project/ 16 | 17 | # Eclipse 18 | .classpath 19 | .project 20 | .settings 21 | 22 | # Scala-IDE specific 23 | .scala_dependencies 24 | .worksheet 25 | -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo3/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo3 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | 10 | object Ex1 extends App { 11 | implicit val system = ActorSystem("demo3") 12 | implicit val materializer = ActorMaterializer() 13 | import system.dispatcher 14 | 15 | // Create a stream composing two sources 16 | 17 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo1/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex1 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a source with some integer and print them 19 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo1/Ex3.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex3 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a stream that folds it's elements 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo4/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo4 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex1 extends App { 14 | implicit val system = ActorSystem("demo4") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a slow stream and show CPUs usage 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo1/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex2 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a stream with a mapping stage (using a Flow) 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo5/ErrorHandling1.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling1 extends App { 12 | implicit val system = ActorSystem("demo5") 13 | implicit val materializer = ActorMaterializer() 14 | import system.dispatcher 15 | 16 | // Create a stream that will complete with a failure because of a division by zero 17 | 18 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo3/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo3 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import FlowGraph.Implicits._ 10 | import scala.concurrent.Future 11 | import scala.concurrent.Await 12 | 13 | object Ex2 extends App { 14 | implicit val system = ActorSystem("demo3") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a new fan-in junction that takes 3 Int inputs and outputs the max 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo4/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo4 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex1 extends App { 14 | implicit val system = ActorSystem("demo4") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a slow stream and show CPUs usage 19 | val source = Source(() => Iterator.from(1)) 20 | source.map { e => Thread.sleep(1000); e}.runForeach(println) 21 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo5/ErrorHandling2.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling2 extends App { 12 | 13 | implicit val system = ActorSystem("demo5") 14 | implicit val materializer = ActorMaterializer() 15 | import system.dispatcher 16 | 17 | // Create a materializer with a supervision strategy that Resume if an ArithmeticException occurs. 18 | // The superision strategy is applied to the whole stream. 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo5/ErrorHandling3.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling3 extends App { 12 | 13 | implicit val system = ActorSystem("demo5") 14 | implicit val mat = ActorMaterializer() 15 | import system.dispatcher 16 | 17 | // Create a materializer with a supervision strategy that Resume if an ArithmeticException occurs. 18 | // The supervision strategy is applied only to the relevant junction. 19 | 20 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo1/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex1 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a source with some integer and print them 19 | val source = Source(List(1,2,3)) 20 | val sink = Sink.foreach(println) 21 | val runnable: RunnableGraph[Unit] = source.to(sink) 22 | runnable.run() 23 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo4/Ex1.java: -------------------------------------------------------------------------------- 1 | package demo4; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.javadsl.Source; 8 | 9 | public class Ex1 { 10 | 11 | public static void main(String[] args) { 12 | ActorSystem system = ActorSystem.create("demo4"); 13 | ActorMaterializer materializer = ActorMaterializer.create(system); 14 | 15 | // Create a slow stream and show CPUs usage 16 | IntStream numbers = IntStream.iterate(1, x -> x + 1); 17 | Source source = Source.from(() -> numbers.iterator()); 18 | source.map(e -> { Thread.sleep(1000); return e; }).runForeach(x -> System.out.println(x), materializer); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo1/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex2 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a stream with a mapping stage (using a Flow) 19 | val source = Source(1 to 3) 20 | val flow = Flow[Int].map(_ + 10).filter(_ % 2 == 0) 21 | val sink = Sink.foreach(println) 22 | source.via(flow).runWith(sink) 23 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo1/Ex3.scala: -------------------------------------------------------------------------------- 1 | package demo1 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | object Ex3 extends App { 14 | implicit val system = ActorSystem("demo1") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a stream that folds it's elements 19 | val numbers = Source(1 to 10) 20 | val foldingSink = Sink.fold[Int, Int](0)(_ + _) 21 | val foldingResult = numbers.runWith(foldingSink) 22 | println(Await.result(foldingResult, Duration.Inf)) 23 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo2/GraphEx.scala: -------------------------------------------------------------------------------- 1 | package demo2 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | // Important for using the FLowGraph DSL! 14 | import FlowGraph.Implicits._ 15 | 16 | object GraphEx extends App { 17 | implicit val system = ActorSystem("demo2") 18 | implicit val materializer = ActorMaterializer() 19 | import system.dispatcher 20 | 21 | // create a stream for the following graph 22 | // f2 23 | // in -> f1 -> bcast / \ merge -> f3 -> out 24 | // \ f4 / 25 | 26 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/demo4/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo4 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | 10 | object Ex2 extends App { 11 | implicit val system = ActorSystem("demo4") 12 | implicit val materializer = ActorMaterializer() 13 | import system.dispatcher 14 | 15 | // Let's create a cycle 16 | // 17 | // source → merge → printer → bcast → sink.ignore 18 | // ↑ ↓ 19 | // ←←←←←←←←← 20 | 21 | // Show that it deadlocks 22 | // Then show how to fix it with an unfair PreferredMerge junction 23 | // Then show how to properly fix it by adding a buffering stage 24 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo5/ErrorHandling1.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling1 extends App { 12 | 13 | // Here is a stream that will complete with a failure because of a division by zero 14 | implicit val system = ActorSystem("demo5") 15 | import system.dispatcher 16 | implicit val materializer = ActorMaterializer() 17 | 18 | val source = Source(0 to 5).map(100 / _) 19 | val result = source.runWith(Sink.fold(0)(_ + _)) 20 | val res = Await.result(result, Duration.Inf) 21 | 22 | println(res) // this will print an ArithmeticException 23 | 24 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo1/Ex1.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.Arrays; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.javadsl.RunnableGraph; 8 | import akka.stream.javadsl.Sink; 9 | import akka.stream.javadsl.Source; 10 | import scala.concurrent.Future; 11 | import scala.runtime.BoxedUnit; 12 | 13 | public class Ex1 { 14 | public static void main(String[] args) { 15 | ActorSystem system = ActorSystem.create("demo1"); 16 | ActorMaterializer materializer = ActorMaterializer.create(system); 17 | 18 | // Create a source with some integer and print them 19 | Source source = Source.from(Arrays.asList(0,1,2,3)); 20 | Sink> sink = Sink.foreach(x -> System.out.println(x)); 21 | RunnableGraph runnable = source.to(sink); 22 | runnable.run(materializer); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo3/Ex1.scala: -------------------------------------------------------------------------------- 1 | package demo3 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph 9 | import akka.stream.scaladsl.FlowGraph.Implicits._ 10 | 11 | object Ex1 extends App { 12 | implicit val system = ActorSystem("demo3") 13 | implicit val materializer = ActorMaterializer() 14 | import system.dispatcher 15 | 16 | // Create a stream composing two sources 17 | val numbers = Source(List(1,2,3)) 18 | val strings = Source(List("a", "b", "c")) 19 | 20 | val composite = Source.fromGraph( 21 | FlowGraph.create() { implicit b => 22 | val zip = b.add(Zip[Int,String]()) 23 | numbers ~> zip.in0 24 | strings ~> zip.in1 25 | 26 | SourceShape(zip.out) 27 | } 28 | ) 29 | 30 | composite.runForeach(println) 31 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo5/ErrorHandling3.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling3 extends App { 12 | 13 | implicit val system = ActorSystem("demo5") 14 | import system.dispatcher 15 | 16 | val decider: Supervision.Decider = { 17 | case _: ArithmeticException => Supervision.Resume 18 | case _ => Supervision.Stop 19 | } 20 | 21 | implicit val mat = ActorMaterializer() 22 | val source = Source(0 to 5).map { 100 / _ }.withAttributes(ActorAttributes.supervisionStrategy(decider)) 23 | val result = source.runWith(Sink.fold(0)(_ + _)) 24 | 25 | val res = Await.result(result, Duration.Inf) 26 | println(res) // this will print 228 27 | 28 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo5/ErrorHandling2.scala: -------------------------------------------------------------------------------- 1 | package demo5 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import scala.concurrent.Await 10 | 11 | object ErrorHandling2 extends App { 12 | 13 | implicit val system = ActorSystem("demo5") 14 | import system.dispatcher 15 | 16 | val decider: Supervision.Decider = { 17 | case _: ArithmeticException => Supervision.Resume 18 | case _ => Supervision.Stop 19 | } 20 | 21 | // materializer with a custom supervision strategy 22 | implicit val mat = ActorMaterializer( 23 | ActorMaterializerSettings(system).withSupervisionStrategy(decider)) 24 | 25 | val source = Source(0 to 5).map(100 / _) 26 | val result = source.runWith(Sink.fold(0)(_ + _)) 27 | 28 | val res = Await.result(result, Duration.Inf) 29 | println(res) // this will print 228 30 | 31 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo1/Ex2.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.javadsl.Flow; 8 | import akka.stream.javadsl.RunnableGraph; 9 | import akka.stream.javadsl.Sink; 10 | import akka.stream.javadsl.Source; 11 | import scala.concurrent.Future; 12 | import scala.runtime.BoxedUnit; 13 | 14 | public class Ex2 { 15 | public static void main(String[] args) { 16 | ActorSystem system = ActorSystem.create("demo1"); 17 | ActorMaterializer materializer = ActorMaterializer.create(system); 18 | 19 | // Create a source with some integer and print them 20 | IntStream stream = IntStream.range(1, 4); 21 | Source source = Source.from(() -> stream.iterator()); 22 | Flow f = Flow. create().map(x -> x + 10).filter(x -> x % 2 == 0); 23 | Sink> sink = Sink.foreach(x -> System.out.println(x)); 24 | RunnableGraph runnable = source.via(f).to(sink); 25 | runnable.run(materializer); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java-demo/src/main/java/demo5/ErrorHandling1.java: -------------------------------------------------------------------------------- 1 | package demo5; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.javadsl.Sink; 8 | import akka.stream.javadsl.Source; 9 | import scala.concurrent.Await; 10 | import scala.concurrent.Future; 11 | import scala.concurrent.duration.Duration; 12 | 13 | public class ErrorHandling1 { 14 | public static void main(String[] args) throws Exception { 15 | ActorSystem system = ActorSystem.create("demo5"); 16 | ActorMaterializer materializer = ActorMaterializer.create(system); 17 | 18 | // // Here is a stream that will complete with a failure because of a division by zero 19 | IntStream stream = IntStream.range(0, 5); 20 | Source source = Source.from(() -> stream.iterator()).map(x -> 100 / x); 21 | Future result = source.runWith(Sink.fold(0, (x, y) -> x + y), materializer); 22 | Integer res = Await.result(result, Duration.Inf()); 23 | 24 | System.out.println(res); // this will print an ArithmeticException 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java-demo/src/main/java/demo1/Ex3.java: -------------------------------------------------------------------------------- 1 | package demo1; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.japi.function.Function2; 7 | import akka.stream.ActorMaterializer; 8 | import akka.stream.javadsl.Sink; 9 | import akka.stream.javadsl.Source; 10 | import scala.concurrent.Await; 11 | import scala.concurrent.Future; 12 | import scala.concurrent.duration.Duration; 13 | 14 | public class Ex3 { 15 | public static void main(String[] args) throws Exception { 16 | ActorSystem system = ActorSystem.create("demo1"); 17 | ActorMaterializer materializer = ActorMaterializer.create(system); 18 | 19 | // Create a source with some integer and print them 20 | IntStream stream = IntStream.range(1, 11); 21 | Source source = Source.from(() -> stream.iterator()); 22 | Integer zero = 0; 23 | Function2 f = (x, y) -> x + y; 24 | Sink> foldingSink = Sink.fold(zero, f); 25 | Future foldingResult = source.runWith(foldingSink, materializer); 26 | 27 | System.out.println(Await.result(foldingResult, Duration.Inf())); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo4/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo4 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | 10 | object Ex2 extends App { 11 | implicit val system = ActorSystem("demo4") 12 | implicit val materializer = ActorMaterializer() 13 | import system.dispatcher 14 | 15 | // Let's create a cycle 16 | // 17 | // source → merge → printer → bcast → sink.ignore 18 | // ↑ ↓ 19 | // ←←←←←←←←← 20 | val source = Source(() => Iterator.from(1)) 21 | val g = RunnableGraph.fromGraph( 22 | FlowGraph.create() { implicit b => 23 | val merge = b.add(Merge[Int](2)) 24 | val bcast = b.add(Broadcast[Int](2)) 25 | val printer = Flow[Int].map {e => println(e); e} 26 | source ~> merge ~> printer ~> bcast ~> Sink.ignore 27 | merge <~ bcast 28 | 29 | ClosedShape 30 | } 31 | ) 32 | g.run() 33 | 34 | // Show that it deadlocks 35 | // Then show how to fix it with an unfair PreferredMerge junction 36 | // Then show how to properly fix it by adding a buffering stage 37 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo3/Ex1.java: -------------------------------------------------------------------------------- 1 | package demo3; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.IntStream; 5 | 6 | import akka.actor.ActorSystem; 7 | import akka.japi.Pair; 8 | import akka.stream.ActorMaterializer; 9 | import akka.stream.FanInShape2; 10 | import akka.stream.SourceShape; 11 | import akka.stream.javadsl.FlowGraph; 12 | import akka.stream.javadsl.Source; 13 | import akka.stream.javadsl.Zip; 14 | 15 | public class Ex1 { 16 | public static void main(String[] args) throws Exception { 17 | ActorSystem system = ActorSystem.create("demo3"); 18 | ActorMaterializer materializer = ActorMaterializer.create(system); 19 | 20 | Source numbers = Source.from(() -> IntStream.range(1, 4).iterator()); 21 | Source chars = Source.from(Arrays.asList('a', 'b', 'c')); 22 | 23 | Source, ?> composite = Source.fromGraph(FlowGraph.create(b -> { 24 | FanInShape2> zip = b.add(Zip. create()); 25 | 26 | b.from(b.add(numbers)).toInlet(zip.in0()); 27 | b.from(b.add(chars)).toInlet(zip.in1()); 28 | return SourceShape.of(zip.out()); 29 | })); 30 | 31 | composite.runForeach(x -> System.out.println(x), materializer); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo2/GraphEx.scala: -------------------------------------------------------------------------------- 1 | package demo2 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | 8 | import scala.concurrent.Future 9 | import scala.concurrent.Await 10 | import scala.concurrent.duration.Duration 11 | import scala.concurrent.duration._ 12 | 13 | // Important for using the FLowGraph DSL! 14 | import FlowGraph.Implicits._ 15 | 16 | object GraphEx extends App { 17 | implicit val system = ActorSystem("demo2") 18 | implicit val materializer = ActorMaterializer() 19 | import system.dispatcher 20 | 21 | // create a stream for the following graph 22 | // f2 23 | // in -> f1 -> bcast / \ merge -> f3 -> out 24 | // \ f4 / 25 | val sink = Sink.foreach(println) 26 | val g = RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b => 27 | sink => 28 | val in = Source(List(1, 2, 3)) 29 | val bcast = b.add(Broadcast[Int](2)) 30 | val merge = b.add(Merge[Int](2)) 31 | 32 | val f1, f2, f3, f4 = Flow[Int].map(_ + 10) 33 | 34 | in ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> sink 35 | bcast ~> f4 ~> merge 36 | ClosedShape 37 | }) 38 | 39 | val res = g.run() 40 | Await.result(res, Duration.Inf) 41 | } -------------------------------------------------------------------------------- /scala-demo-seed/src/main/scala/extra/CustomersExample.scala: -------------------------------------------------------------------------------- 1 | // This is a sample code that was shamelessly stolen from 2 | // http://boldradius.com/blog-post/VS0NpTAAADAACs_E/introduction-to-akka-streams 3 | package extra 4 | 5 | import akka.actor.ActorSystem 6 | import akka.stream.ActorMaterializer 7 | import akka.stream.scaladsl.{Flow, Sink, Source} 8 | 9 | import scala.collection.immutable 10 | import scala.util.Random 11 | 12 | object InputCustomer { 13 | def random():InputCustomer = { 14 | InputCustomer(s"FirstName${Random.nextInt(1000)} LastName${Random.nextInt(1000)}") 15 | } 16 | } 17 | 18 | case class InputCustomer(name: String) 19 | case class OutputCustomer(firstName: String, lastName: String) 20 | 21 | object CustomersExample extends App { 22 | implicit val actorSystem = ActorSystem("extra") 23 | implicit val flowMaterializer = ActorMaterializer() 24 | import actorSystem.dispatcher 25 | 26 | // 1. create the customers to use as input 27 | // val inputCustomers = 28 | 29 | // 2. create a stage that maps InputCustomer into OutputCustomer 30 | // val normalize: Flow[InputCustomer, OutputCustomer, Unit] = 31 | 32 | // 3. create a sink that stores the normalized sustomers 33 | // val writeCustomers 34 | 35 | // 4. create the bluprint and run it, making sure that the actor system is shutted down 36 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo5/ErrorHandling3.java: -------------------------------------------------------------------------------- 1 | package demo5; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.japi.function.Function; 7 | import akka.stream.ActorAttributes; 8 | import akka.stream.ActorMaterializer; 9 | import akka.stream.Supervision; 10 | import akka.stream.javadsl.Sink; 11 | import akka.stream.javadsl.Source; 12 | import scala.concurrent.Await; 13 | import scala.concurrent.Future; 14 | import scala.concurrent.duration.Duration; 15 | 16 | public class ErrorHandling3 { 17 | public static void main(String[] args) throws Exception { 18 | ActorSystem system = ActorSystem.create("demo5"); 19 | ActorMaterializer materializer = ActorMaterializer.create(system); 20 | 21 | Function decider = e -> { 22 | if (e instanceof ArithmeticException) 23 | return Supervision.resume(); 24 | else 25 | return Supervision.stop(); 26 | }; 27 | 28 | IntStream stream = IntStream.range(0, 6); 29 | Source source = Source.from(() -> stream.iterator()).map(x -> 100 / x) 30 | .withAttributes(ActorAttributes.withSupervisionStrategy(decider)); 31 | Future result = source.runWith(Sink.fold(0, (x, y) -> x + y), materializer); 32 | Integer res = Await.result(result, Duration.Inf()); 33 | 34 | System.out.println(res); // this will print 228 35 | } 36 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/demo3/Ex2.scala: -------------------------------------------------------------------------------- 1 | package demo3 2 | 3 | import akka.actor.ActorSystem 4 | import akka.stream.ActorMaterializer 5 | import akka.stream._ 6 | import akka.stream.scaladsl._ 7 | import scala.concurrent.duration._ 8 | import akka.stream.scaladsl.FlowGraph.Implicits._ 9 | import FlowGraph.Implicits._ 10 | import scala.concurrent.Future 11 | import scala.concurrent.Await 12 | 13 | object Ex2 extends App { 14 | implicit val system = ActorSystem("demo3") 15 | implicit val materializer = ActorMaterializer() 16 | import system.dispatcher 17 | 18 | // Create a new fan-in junction that takes 3 Int inputs and outputs the max 19 | val maxOfThree = FlowGraph.create() { implicit b => 20 | val zip1 = b.add(ZipWith[Int, Int, Int](math.max)) 21 | val zip2 = b.add(ZipWith[Int, Int, Int](math.max)) 22 | 23 | zip1.out ~> zip2.in0 24 | 25 | UniformFanInShape(zip2.out, zip1.in0, zip1.in1, zip2.in1) 26 | } 27 | 28 | // and now let's create a stream using this new fan-in shape 29 | 30 | val sink = Sink.head[Int] 31 | val g = RunnableGraph.fromGraph( 32 | FlowGraph.create(sink) { implicit b => out => 33 | val s1 = Source.single(1) 34 | val s2 = Source.single(2) 35 | val s3 = Source.single(3) 36 | val pm3 = b.add(maxOfThree) 37 | 38 | s1 ~> pm3 39 | s2 ~> pm3 40 | s3 ~> pm3 41 | pm3 ~> out 42 | 43 | ClosedShape 44 | } 45 | ) 46 | 47 | val max = g.run() 48 | val res = Await.result(max, Duration.Inf) 49 | println(res) 50 | } -------------------------------------------------------------------------------- /scala-demo/src/main/scala/extra/CustomersExample.scala: -------------------------------------------------------------------------------- 1 | // This is a sample code that was shamelessly stolen from 2 | // http://boldradius.com/blog-post/VS0NpTAAADAACs_E/introduction-to-akka-streams 3 | package extra 4 | 5 | import akka.actor.ActorSystem 6 | import akka.stream.ActorMaterializer 7 | import akka.stream.scaladsl.{Flow, Sink, Source} 8 | 9 | import scala.collection.immutable 10 | import scala.util.Random 11 | 12 | object InputCustomer { 13 | def random():InputCustomer = { 14 | InputCustomer(s"FirstName${Random.nextInt(1000)} LastName${Random.nextInt(1000)}") 15 | } 16 | } 17 | case class InputCustomer(name: String) 18 | case class OutputCustomer(firstName: String, lastName: String) 19 | 20 | object CustomersExample extends App { 21 | implicit val actorSystem = ActorSystem() 22 | import actorSystem.dispatcher 23 | implicit val flowMaterializer = ActorMaterializer() 24 | 25 | val inputCustomers = Source((1 to 100).map(_ => InputCustomer.random())) 26 | 27 | val normalize = Flow[InputCustomer].mapConcat { input => 28 | input.name.split(" ").toList match { 29 | case firstName::lastName::Nil => immutable.Seq(OutputCustomer(firstName, lastName)) 30 | case _ => immutable.Seq[OutputCustomer]() 31 | } 32 | } 33 | 34 | val writeCustomers = Sink.foreach[OutputCustomer] { customer => 35 | println(customer) 36 | } 37 | 38 | inputCustomers.via(normalize).runWith(writeCustomers).andThen { 39 | case _ => 40 | actorSystem.shutdown() 41 | actorSystem.awaitTermination() 42 | } 43 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo5/ErrorHandling2.java: -------------------------------------------------------------------------------- 1 | package demo5; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.japi.function.Function; 7 | import akka.stream.ActorMaterializer; 8 | import akka.stream.ActorMaterializerSettings; 9 | import akka.stream.Supervision; 10 | import akka.stream.javadsl.Sink; 11 | import akka.stream.javadsl.Source; 12 | import scala.concurrent.Await; 13 | import scala.concurrent.Future; 14 | import scala.concurrent.duration.Duration; 15 | 16 | public class ErrorHandling2 { 17 | public static void main(String[] args) throws Exception { 18 | ActorSystem system = ActorSystem.create("demo5"); 19 | 20 | Function decider = e -> { 21 | if (e instanceof ArithmeticException) 22 | return Supervision.resume(); 23 | else 24 | return Supervision.stop(); 25 | }; 26 | 27 | ActorMaterializerSettings settings = ActorMaterializerSettings.create(system).withSupervisionStrategy( 28 | decider); 29 | // materializer with a custom supervision strategy 30 | ActorMaterializer materializer = ActorMaterializer.create(settings, system); 31 | 32 | IntStream stream = IntStream.range(0, 6); 33 | Source source = Source.from(() -> stream.iterator()).map(x -> 100 / x); 34 | Future result = source.runWith(Sink.fold(0, (x, y) -> x + y), materializer); 35 | Integer res = Await.result(result, Duration.Inf()); 36 | 37 | System.out.println(res); // this will print 228 38 | } 39 | } -------------------------------------------------------------------------------- /java-demo/src/main/java/demo4/Ex2.java: -------------------------------------------------------------------------------- 1 | package demo4; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.ClosedShape; 8 | import akka.stream.FlowShape; 9 | import akka.stream.Outlet; 10 | import akka.stream.SinkShape; 11 | import akka.stream.UniformFanInShape; 12 | import akka.stream.UniformFanOutShape; 13 | import akka.stream.javadsl.Broadcast; 14 | import akka.stream.javadsl.Flow; 15 | import akka.stream.javadsl.FlowGraph; 16 | import akka.stream.javadsl.Merge; 17 | import akka.stream.javadsl.RunnableGraph; 18 | import akka.stream.javadsl.Sink; 19 | import akka.stream.javadsl.Source; 20 | 21 | public class Ex2 { 22 | public static void main(String[] args) throws Exception { 23 | ActorSystem system = ActorSystem.create("demo2"); 24 | ActorMaterializer materializer = ActorMaterializer.create(system); 25 | 26 | // Let's create a cycle 27 | // 28 | // source → merge → printer → bcast → sink.ignore 29 | // ↑ ↓ 30 | // ←←←←←←←←← 31 | RunnableGraph runnable = RunnableGraph.fromGraph(FlowGraph.create(b -> { 32 | IntStream numbers = IntStream.iterate(1, x -> x + 1); 33 | Outlet source = b.add(Source.from(() -> numbers.iterator())).outlet(); 34 | UniformFanInShape merge = b.add(Merge.create(2)); 35 | UniformFanOutShape bcast = b.add(Broadcast.create(2)); 36 | FlowShape printer = b.add(Flow.of(Integer.class).map(x -> { 37 | System.out.println(x); 38 | return x; 39 | })); 40 | SinkShape sink = b.add(Sink.ignore()); 41 | 42 | b.from(source).viaFanIn(merge).via(printer).viaFanOut(bcast).to(sink); 43 | b.to(merge).fromFanOut(bcast); 44 | return ClosedShape.getInstance(); 45 | })); 46 | 47 | runnable.run(materializer); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java-demo/src/main/java/demo2/GraphEx.java: -------------------------------------------------------------------------------- 1 | package demo2; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | import akka.actor.ActorSystem; 6 | import akka.stream.ActorMaterializer; 7 | import akka.stream.ClosedShape; 8 | import akka.stream.FlowShape; 9 | import akka.stream.Outlet; 10 | import akka.stream.UniformFanInShape; 11 | import akka.stream.UniformFanOutShape; 12 | import akka.stream.javadsl.Broadcast; 13 | import akka.stream.javadsl.Flow; 14 | import akka.stream.javadsl.FlowGraph; 15 | import akka.stream.javadsl.Merge; 16 | import akka.stream.javadsl.RunnableGraph; 17 | import akka.stream.javadsl.Sink; 18 | import akka.stream.javadsl.Source; 19 | import scala.concurrent.Await; 20 | import scala.concurrent.Future; 21 | import scala.concurrent.duration.Duration; 22 | import scala.runtime.BoxedUnit; 23 | 24 | public class GraphEx { 25 | public static void main(String[] args) throws Exception { 26 | ActorSystem system = ActorSystem.create("demo2"); 27 | ActorMaterializer materializer = ActorMaterializer.create(system); 28 | 29 | // create a stream for the following graph 30 | // f2 31 | // in -> f1 -> bcast / \ merge -> f3 -> out 32 | // \ f4 / 33 | Sink> aSink = Sink. foreach(x -> System.out.println(x)); 34 | RunnableGraph> runnable = RunnableGraph.>fromGraph(FlowGraph.create(aSink, (builder, out) -> { 35 | IntStream stream = IntStream.range(1, 4); 36 | Outlet in = builder.add(Source.from(() -> stream.iterator())).outlet(); 37 | FlowShape f1 = builder.add(Flow. create().map(x -> x + 10)); 38 | FlowShape f2 = builder.add(Flow. create().map(x -> x + 10)); 39 | FlowShape f3 = builder.add(Flow. create().map(x -> x + 10)); 40 | FlowShape f4 = builder.add(Flow. create().map(x -> x + 10)); 41 | UniformFanOutShape bcast = builder.add(Broadcast.create(2)); 42 | UniformFanInShape merge = builder.add(Merge.create(2)); 43 | 44 | builder.from(in).via(f1).viaFanOut(bcast).via(f2).viaFanIn(merge).via(f3).to(out); 45 | builder.from(bcast).via(f4).toFanIn(merge); 46 | return ClosedShape.getInstance(); 47 | })); 48 | Future res = runnable.run(materializer); 49 | Await.result(res, Duration.Inf()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java-demo/src/main/java/demo3/Ex2.java: -------------------------------------------------------------------------------- 1 | package demo3; 2 | 3 | import akka.actor.ActorSystem; 4 | import akka.stream.ActorMaterializer; 5 | import akka.stream.ClosedShape; 6 | import akka.stream.FanInShape2; 7 | import akka.stream.Graph; 8 | import akka.stream.Inlet; 9 | import akka.stream.Outlet; 10 | import akka.stream.UniformFanInShape; 11 | import akka.stream.javadsl.FlowGraph; 12 | import akka.stream.javadsl.RunnableGraph; 13 | import akka.stream.javadsl.Sink; 14 | import akka.stream.javadsl.Source; 15 | import akka.stream.javadsl.ZipWith; 16 | import scala.concurrent.Await; 17 | import scala.concurrent.Future; 18 | import scala.concurrent.duration.Duration; 19 | 20 | public class Ex2 { 21 | public static void main(String[] args) throws Exception { 22 | ActorSystem system = ActorSystem.create("demo3"); 23 | ActorMaterializer materializer = ActorMaterializer.create(system); 24 | 25 | Graph, ?> zip = 26 | ZipWith.create((Integer left, Integer right) -> Math.max(left, right)); 27 | // Create a new fan-in junction that takes 3 Integer inputs and outputs the max 28 | Graph, ?> maxOfThree = 29 | FlowGraph.create( b -> { 30 | FanInShape2 zip1 = b.add(zip); 31 | FanInShape2 zip2 = b.add(zip); 32 | 33 | b.from(zip1.out()).toInlet(zip2.in0()); 34 | 35 | // return the shape, which has three inputs and one output 36 | return new UniformFanInShape(zip2.out(), 37 | new Inlet[] {zip1.in0(), zip1.in1(), zip2.in1()}); 38 | }); 39 | 40 | Sink> sink = Sink.head(); 41 | 42 | RunnableGraph> runnable = RunnableGraph.>fromGraph( 43 | FlowGraph.create(sink, (b, out) -> { 44 | Outlet s1 = b.add(Source.single(1)).outlet(); 45 | Outlet s2 = b.add(Source.single(2)).outlet(); 46 | Outlet s3 = b.add(Source.single(3)).outlet(); 47 | UniformFanInShape pm3 = b.add(maxOfThree); 48 | 49 | b.from(s1).toInlet(pm3.in(0)); 50 | b.from(s2).toInlet(pm3.in(1)); 51 | b.from(s3).toInlet(pm3.in(2)); 52 | b.from(pm3.out()).to(out); 53 | return ClosedShape.getInstance(); 54 | } 55 | )); 56 | 57 | Future max = runnable.run(materializer); 58 | Integer res = Await.result(max, Duration.Inf()); 59 | System.out.println(res); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | --------------------------------------------------------------------------------