Repository: iluwatar/java-design-patterns
Issue: Pipeline pattern
Labels: epic: pattern

https://msdn.microsoft.com/en-us/library/ff963548.aspx


Issue comments:
Working on it

Ok @ghost-60 

@ghost-60 are you still working on this?
Sorry.... not yet

On Feb 12, 2017 05:02, "Ilkka Seppälä" <notifications@github.com> wrote:

> @ghost-60 <https://github.com/ghost-60> are you still working on this?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/iluwatar/java-design-patterns/issues/496#issuecomment-279183789>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AUIdn6FWVcnwQchUgMgDBSqwfm9wtyCjks5rbkT5gaJpZM4KF-qy>
> .
>

My question, do you still want to keep the issue or can someone else take it?
Someone else can take it. Sorry.

On Feb 13, 2017 20:41, "Ilkka Seppälä" <notifications@github.com> wrote:

> My question, do you still want to keep the issue or can someone else take
> it?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/iluwatar/java-design-patterns/issues/496#issuecomment-279418778>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AUIdn8sorgk2-Hk4nq3Xt1TndOtAXUFqks5rcHKEgaJpZM4KF-qy>
> .
>

It's ok @ghost-60. This issue is free for taking again.
can I take it? 
Sure @urielatzmon go ahead
@urielatzmon  are you still implementing this?
Hello. Can I take on this issue and make a PR? 
Ok @jjjimenez100 
If this is inactive, I'd love to take this up
Yes, it seems so. Please go ahead @havanagrawal 
The issue is free
Hi. I'll continue working on this one (for real now). Just forked the repository. Will have you pinged when the PR's up. 

Thanks!
@jjjimenez100 ok the second time's a charm, or how it goes :smirk: 

Pull request review comments:
We can leave this chapter if there are no aliases
We can link to https://java-design-patterns.com/principles/#single-responsibility-principle

Patch that resolved the issue:
diff --git a/pipeline/README.md b/pipeline/README.md
new file mode 100644
index 000000000000..e990affd62c7
--- /dev/null
+++ b/pipeline/README.md
@@ -0,0 +1,37 @@
+---
+layout: pattern
+title: Pipeline
+folder: pipeline
+permalink: /patterns/pipeline/
+categories: Behavioral
+tags:
+ - Java
+ - Functional
+ - Difficulty-Intermediate
+---
+
+## Intent
+Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be used by the next stages.
+
+## Applicability
+Use the Pipeline pattern when you want to
+
+* execute individual stages that yields a final value
+* add readability to complex sequence of operations by providing a fluent builder as an interface
+* improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle)
+
+## Typical Use Case
+
+* implement stages and execute them in an ordered manner
+
+## Real world examples
+
+* [java.util.Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
+* [Maven Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
+* [Functional Java](https://github.com/functionaljava/functionaljava)
+
+## Credits
+
+* [The Pipeline Pattern — for fun and profit](https://medium.com/@aaronweatherall/the-pipeline-pattern-for-fun-and-profit-9b5f43a98130)
+* [The Pipeline design pattern (in Java)](https://medium.com/@deepakbapat/the-pipeline-design-pattern-in-java-831d9ce2fe21)
+* [Pipelines | Microsoft Docs](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff963548(v=pandp.10))
\ No newline at end of file
diff --git a/pipeline/pom.xml b/pipeline/pom.xml
new file mode 100644
index 000000000000..7ad60d5620e4
--- /dev/null
+++ b/pipeline/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+    The MIT License
+    Copyright (c) 2014-2016 Ilkka Seppälä
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iluwatar</groupId>
+        <artifactId>java-design-patterns</artifactId>
+        <version>1.22.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>pipeline</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/App.java b/pipeline/src/main/java/com.iluwatar.pipeline/App.java
new file mode 100644
index 000000000000..7efa2ecca003
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/App.java
@@ -0,0 +1,66 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * The Pipeline pattern uses ordered stages to process a sequence of input values.
+ * Each implemented task is represented by a stage of the pipeline. You can think of
+ * pipelines as similar to assembly lines in a factory, where each item in the assembly
+ * line is constructed in stages. The partially assembled item is passed from one assembly
+ * stage to another. The outputs of the assembly line occur in the same order as that of the
+ * inputs.
+ *
+ * Classes used in this example are suffixed with "Handlers", and synonymously refers to the
+ * "stage".
+ */
+public class App {
+  /**
+   * Specify the initial input type for the first stage handler and the expected output type
+   * of the last stage handler as type parameters for Pipeline. Use the fluent builder by
+   * calling addHandler to add more stage handlers on the pipeline.
+   */
+  public static void main(String[] args) {
+    /*
+      Suppose we wanted to pass through a String to a series of filtering stages and convert it
+      as a char array on the last stage.
+
+      - Stage handler 1 (pipe): Removing the alphabets, accepts a String input and returns the
+      processed String output. This will be used by the next handler as its input.
+
+      - Stage handler 2 (pipe): Removing the digits, accepts a String input and returns the
+      processed String output. This shall also be used by the last handler we have.
+
+      - Stage handler 3 (pipe): Converting the String input to a char array handler. We would
+      be returning a different type in here since that is what's specified by the requirement.
+      This means that at any stages along the pipeline, the handler can return any type of data
+      as long as it fulfills the requirements for the next handler's input.
+
+      Suppose we wanted to add another handler after ConvertToCharArrayHandler. That handler
+      then is expected to receive an input of char[] array since that is the type being returned
+      by the previous handler, ConvertToCharArrayHandler.
+     */
+    new Pipeline<>(new RemoveAlphabetsHandler())
+        .addHandler(new RemoveDigitsHandler())
+        .addHandler(new ConvertToCharArrayHandler());
+  }
+}
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java
new file mode 100644
index 000000000000..b69241914980
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java
@@ -0,0 +1,45 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ * <p>
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * <p>
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * <p>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+
+/**
+ * Stage handler that converts an input String to its char[] array counterpart.
+ */
+class ConvertToCharArrayHandler implements Handler<String, char[]> {
+
+  private final Logger logger = LoggerFactory.getLogger(ConvertToCharArrayHandler.class);
+
+  @Override
+  public char[] process(String input) {
+    char[] characters = input.toCharArray();
+    logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+        ConvertToCharArrayHandler.class, input, String.class, Arrays.toString(characters), Character[].class));
+
+    return characters;
+  }
+}
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java b/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java
new file mode 100644
index 000000000000..7d2bc0db7f59
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java
@@ -0,0 +1,32 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * Forms a contract to all stage handlers to accept a certain type of input and return a processed output.
+ * @param <I> the input type of the handler
+ * @param <O> the processed output type of the handler
+ */
+interface Handler<I, O> {
+  O process(I input);
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java b/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java
new file mode 100644
index 000000000000..8e231bbc4d09
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java
@@ -0,0 +1,46 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * Main Pipeline class that initially sets the current handler. Processed output
+ * of the initial handler is then passed as the input to the next stage handlers.
+ * @param <I> the type of the input for the first stage handler
+ * @param <O> the final stage handler's output type
+ */
+class Pipeline<I, O> {
+
+  private final Handler<I, O> currentHandler;
+
+  Pipeline(Handler<I, O> currentHandler) {
+    this.currentHandler = currentHandler;
+  }
+
+  <K> Pipeline<I, K> addHandler(Handler<O, K> newHandler) {
+    return new Pipeline<>(input -> newHandler.process(currentHandler.process(input)));
+  }
+
+  O execute(I input) {
+    return currentHandler.process(input);
+  }
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java
new file mode 100644
index 000000000000..2085052742fa
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java
@@ -0,0 +1,54 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Stage handler that returns a new instance of String without the alphabet characters of the input string.
+ */
+class RemoveAlphabetsHandler implements Handler<String, String> {
+
+  private final Logger logger = LoggerFactory.getLogger(RemoveAlphabetsHandler.class);
+
+  @Override
+  public String process(String input) {
+    StringBuilder inputWithoutAlphabets = new StringBuilder();
+
+    for (int index = 0; index < input.length(); index++) {
+      char currentCharacter = input.charAt(index);
+      if (Character.isAlphabetic(currentCharacter)) {
+        continue;
+      }
+
+      inputWithoutAlphabets.append(currentCharacter);
+    }
+
+    String inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
+    logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+        RemoveAlphabetsHandler.class, input, String.class, inputWithoutAlphabetsStr, String.class));
+
+    return inputWithoutAlphabetsStr;
+  }
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java
new file mode 100644
index 000000000000..e0c0aa6a87b2
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java
@@ -0,0 +1,54 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Stage handler that returns a new instance of String without the digit characters of the input string.
+ */
+class RemoveDigitsHandler implements Handler<String, String> {
+
+  private final Logger logger = LoggerFactory.getLogger(RemoveDigitsHandler.class);
+
+  @Override
+  public String process(String input) {
+    StringBuilder inputWithoutDigits = new StringBuilder();
+
+    for (int index = 0; index < input.length(); index++) {
+      char currentCharacter = input.charAt(index);
+      if (Character.isDigit(currentCharacter)) {
+        continue;
+      }
+
+      inputWithoutDigits.append(currentCharacter);
+    }
+
+    String inputWithoutDigitsStr = inputWithoutDigits.toString();
+    logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+        RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class));
+
+    return inputWithoutDigitsStr;
+  }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f1a586eb8b34..325a2ff00025 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,7 @@
         <module>property</module>
         <module>intercepting-filter</module>
         <module>producer-consumer</module>
+        <module>pipeline</module>
         <module>poison-pill</module>
         <module>reader-writer-lock</module>
         <module>lazy-loading</module>


Test patch:
diff --git a/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java b/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java
new file mode 100644
index 000000000000..79524575c13c
--- /dev/null
+++ b/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java
@@ -0,0 +1,37 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ * <p>
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * <p>
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * <p>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Application Test
+ */
+public class AppTest {
+
+  @Test
+  public void test() {
+    String[] args = {};
+    App.main(args);
+  }
+}
diff --git a/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java b/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java
new file mode 100644
index 000000000000..1a2676e25d05
--- /dev/null
+++ b/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java
@@ -0,0 +1,45 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ * <p>
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * <p>
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * <p>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+/**
+ * Test for {@link Pipeline}
+ */
+public class PipelineTest {
+
+  @Test
+  public void testAddHandlersToPipeline() {
+    Pipeline<String, char[]> filters = new Pipeline<>(new RemoveAlphabetsHandler())
+        .addHandler(new RemoveDigitsHandler())
+        .addHandler(new ConvertToCharArrayHandler());
+
+    assertArrayEquals(
+        new char[] {'#', '!', '(', '&', '%', '#', '!'},
+        filters.execute("#H!E(L&L0O%THE3R#34E!")
+    );
+  }
+}