From d42eb31028645a23df3d1e53e10a8ee3a6b434cd Mon Sep 17 00:00:00 2001
From: Korbinian <korbinian@remeeting.com>
Date: Tue, 27 Jun 2023 01:01:17 +0200
Subject: [PATCH] updated assignment to cnjdb from chucknorris.io

---
 README.md                                     |  4 +-
 assets/images/GeneratorSpec.svg               | 41 +---------
 assets/images/StreamFlow.svg                  | 24 +-----
 assets/uml/generator-spec.plantuml            |  4 +-
 assets/uml/stream-flow.plantuml               |  3 +-
 build.gradle                                  |  2 +
 src/main/java/ohm/softa/a12/App.java          | 10 +--
 .../java/ohm/softa/a12/cnjdb/CNJDBApi.java    | 35 +++++++++
 .../ohm/softa/a12/cnjdb/CNJDBService.java     | 31 ++++++++
 .../a12/{icndb => cnjdb}/JokeGenerator.java   | 12 ++-
 .../suppliers/AllJokesSupplier.java           | 13 ++--
 .../suppliers/RandomJokeSupplier.java         | 13 ++--
 .../java/ohm/softa/a12/icndb/ICNDBApi.java    | 49 ------------
 .../ohm/softa/a12/icndb/ICNDBService.java     | 78 -------------------
 .../java/ohm/softa/a12/model/JokeDto.java     | 47 +++--------
 .../ohm/softa/a12/model/ResponseWrapper.java  | 72 -----------------
 .../java/ohm/softa/a12/icndb/ICNDBTests.java  | 51 ++++--------
 .../softa/a12/icndb/JokesGeneratorTests.java  |  5 +-
 18 files changed, 121 insertions(+), 373 deletions(-)
 create mode 100644 src/main/java/ohm/softa/a12/cnjdb/CNJDBApi.java
 create mode 100644 src/main/java/ohm/softa/a12/cnjdb/CNJDBService.java
 rename src/main/java/ohm/softa/a12/{icndb => cnjdb}/JokeGenerator.java (63%)
 rename src/main/java/ohm/softa/a12/{icndb => cnjdb}/suppliers/AllJokesSupplier.java (76%)
 rename src/main/java/ohm/softa/a12/{icndb => cnjdb}/suppliers/RandomJokeSupplier.java (60%)
 delete mode 100644 src/main/java/ohm/softa/a12/icndb/ICNDBApi.java
 delete mode 100644 src/main/java/ohm/softa/a12/icndb/ICNDBService.java
 delete mode 100644 src/main/java/ohm/softa/a12/model/ResponseWrapper.java

diff --git a/README.md b/README.md
index 663e2e7..c3a063e 100644
--- a/README.md
+++ b/README.md
@@ -25,8 +25,8 @@ _Remark: the given test suite is incomplete but will succeed after the checkout.
 
 _Note 1:_ the class structure is already there (including the empty unit tests).
 
-_Note 2:_ the whole logic around the **ICNDB** is already implemented including the `ICNDBService` singleton!
-There is no way to implement asynchronous generators so you will have to use the `ICNDBService` also in a synchronous way.
+_Note 2:_ the whole logic around the **CNJDB** is already implemented including the `CNJDBService` service (which manages an API singleton)!
+There is no way to implement asynchronous generators so you will have to use the `CNJDBApi` also in a synchronous way.
 
 ## Generators
 
diff --git a/assets/images/GeneratorSpec.svg b/assets/images/GeneratorSpec.svg
index f935427..1d04d59 100644
--- a/assets/images/GeneratorSpec.svg
+++ b/assets/images/GeneratorSpec.svg
@@ -1,40 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="334px" preserveAspectRatio="none" style="width:812px;height:334px;" version="1.1" viewBox="0 0 812 334" width="812px" zoomAndPan="magnify"><defs><filter height="300%" id="f1lp1nfqy0adly" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><!--cluster java.util.function--><polygon fill="#FFFFFF" filter="url(#f1lp1nfqy0adly)" points="433,16,559,16,566,38.4883,569,38.4883,569,113,433,113,433,16" style="stroke: #000000; stroke-width: 1.5;"/><line style="stroke: #000000; stroke-width: 1.5;" x1="433" x2="566" y1="38.4883" y2="38.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="120" x="437" y="31.5352">java.util.function</text><!--cluster ohm.softa.a12.icndb--><polygon fill="#FFFFFF" filter="url(#f1lp1nfqy0adly)" points="14,121,163,121,170,143.4883,790,143.4883,790,322,14,322,14,121" style="stroke: #000000; stroke-width: 1.5;"/><line style="stroke: #000000; stroke-width: 1.5;" x1="14" x2="170" y1="143.4883" y2="143.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="143" x="18" y="136.5352">ohm.softa.a12.icndb</text><!--cluster suppliers--><polygon fill="#FFFFFF" filter="url(#f1lp1nfqy0adly)" points="614,148,687,148,694,170.4883,782,170.4883,782,314,614,314,614,148" style="stroke: #000000; stroke-width: 1.5;"/><line style="stroke: #000000; stroke-width: 1.5;" x1="614" x2="694" y1="170.4883" y2="170.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="67" x="618" y="163.5352">suppliers</text><!--class Supplier--><rect fill="#FEFECE" filter="url(#f1lp1nfqy0adly)" height="60.9551" id="Supplier" style="stroke: #A80036; stroke-width: 1.5;" width="91" x="455" y="43.5"/><ellipse cx="470" cy="59.5" fill="#B4A7E5" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M466.4277,55.7651 L466.4277,53.6069 L473.8071,53.6069 L473.8071,55.7651 L471.3418,55.7651 L471.3418,63.8418 L473.8071,63.8418 L473.8071,66 L466.4277,66 L466.4277,63.8418 L468.8931,63.8418 L468.8931,55.7651 Z "/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="47" x="484" y="64.0352">Supplier</text><rect fill="#FFFFFF" height="16.1328" style="stroke: #000000; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" width="10" x="539" y="40.5"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="8" x="540" y="53.1016">T</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="456" x2="545" y1="75.5" y2="75.5"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="456" x2="545" y1="83.5" y2="83.5"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="38" x="461" y="98.1348">T get();</text><!--class JokeGenerator--><rect fill="#FEFECE" filter="url(#f1lp1nfqy0adly)" height="73.9102" id="JokeGenerator" style="stroke: #A80036; stroke-width: 1.5;" width="358" x="22" y="197"/><ellipse cx="155.25" cy="213" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M157.7231,219.1431 Q157.1421,219.4419 156.5029,219.5913 Q155.8638,219.7407 155.1582,219.7407 Q152.6514,219.7407 151.3315,218.0889 Q150.0117,216.437 150.0117,213.3159 Q150.0117,210.1865 151.3315,208.5347 Q152.6514,206.8828 155.1582,206.8828 Q155.8638,206.8828 156.5112,207.0322 Q157.1587,207.1816 157.7231,207.4805 L157.7231,210.2031 Q157.0923,209.6221 156.4988,209.3523 Q155.9053,209.0825 155.2744,209.0825 Q153.9297,209.0825 153.2449,210.1492 Q152.5601,211.2158 152.5601,213.3159 Q152.5601,215.4077 153.2449,216.4744 Q153.9297,217.541 155.2744,217.541 Q155.9053,217.541 156.4988,217.2712 Q157.0923,217.0015 157.7231,216.4204 Z "/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="83" x="175.75" y="217.5352">JokeGenerator</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="23" x2="379" y1="229" y2="229"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="23" x2="379" y1="237" y2="237"/><ellipse cx="33" cy="248.9775" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="332" x="42" y="251.6348">randomJokesStream(): Stream&lt;ResponseWrapper&lt;JokeDto&gt;&gt;</text><ellipse cx="33" cy="261.9326" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="290" x="42" y="264.5898">jokesStream(): Stream&lt;ResponseWrapper&lt;JokeDto&gt;&gt;</text><!--class AllJokesSupplier--><rect fill="#FEFECE" filter="url(#f1lp1nfqy0adly)" height="48" id="AllJokesSupplier" style="stroke: #A80036; stroke-width: 1.5;" width="124" x="636" y="175"/><ellipse cx="651" cy="191" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M653.4731,197.1431 Q652.8921,197.4419 652.2529,197.5913 Q651.6138,197.7407 650.9082,197.7407 Q648.4014,197.7407 647.0815,196.0889 Q645.7617,194.437 645.7617,191.3159 Q645.7617,188.1865 647.0815,186.5347 Q648.4014,184.8828 650.9082,184.8828 Q651.6138,184.8828 652.2612,185.0322 Q652.9087,185.1816 653.4731,185.4805 L653.4731,188.2031 Q652.8423,187.6221 652.2488,187.3523 Q651.6553,187.0825 651.0244,187.0825 Q649.6797,187.0825 648.9949,188.1492 Q648.3101,189.2158 648.3101,191.3159 Q648.3101,193.4077 648.9949,194.4744 Q649.6797,195.541 651.0244,195.541 Q651.6553,195.541 652.2488,195.2712 Q652.8423,195.0015 653.4731,194.4204 Z "/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="92" x="665" y="195.5352">AllJokesSupplier</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="637" x2="759" y1="207" y2="207"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="637" x2="759" y1="215" y2="215"/><!--class RandomJokeSupplier--><rect fill="#FEFECE" filter="url(#f1lp1nfqy0adly)" height="48" id="RandomJokeSupplier" style="stroke: #A80036; stroke-width: 1.5;" width="152" x="622" y="258"/><ellipse cx="637" cy="274" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;"/><path d="M639.4731,280.1431 Q638.8921,280.4419 638.2529,280.5913 Q637.6138,280.7407 636.9082,280.7407 Q634.4014,280.7407 633.0815,279.0889 Q631.7617,277.437 631.7617,274.3159 Q631.7617,271.1865 633.0815,269.5347 Q634.4014,267.8828 636.9082,267.8828 Q637.6138,267.8828 638.2612,268.0322 Q638.9087,268.1816 639.4731,268.4805 L639.4731,271.2031 Q638.8423,270.6221 638.2488,270.3523 Q637.6553,270.0825 637.0244,270.0825 Q635.6797,270.0825 634.9949,271.1492 Q634.3101,272.2158 634.3101,274.3159 Q634.3101,276.4077 634.9949,277.4744 Q635.6797,278.541 637.0244,278.541 Q637.6553,278.541 638.2488,278.2712 Q638.8423,278.0015 639.4731,277.4204 Z "/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="120" x="651" y="278.5352">RandomJokeSupplier</text><line style="stroke: #A80036; stroke-width: 1.5;" x1="623" x2="773" y1="290" y2="290"/><line style="stroke: #A80036; stroke-width: 1.5;" x1="623" x2="773" y1="298" y2="298"/><!--link Supplier to AllJokesSupplier--><path d="M564.6238,101.1015 C573.9933,105.7268 583.3804,110.7471 592,116 C620.5412,133.3935 650.2714,157.2534 670.9566,174.9283 " fill="none" id="Supplier-AllJokesSupplier" style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 7.0,7.0;"/><polygon fill="none" points="561.3861,107.3145,546.2574,92.478,567.3362,94.6419,561.3861,107.3145" style="stroke: #A80036; stroke-width: 1.0;"/><!--link Supplier to RandomJokeSupplier--><path d="M562.5288,106.6396 C564.8141,108.666 566.9849,110.7862 569,113 C585.7377,131.3881 583.4103,140.6657 592,164 C604.1477,196.9997 591.4957,212.9796 614,240 C619.8433,247.016 627.1497,252.9722 634.9995,257.9966 " fill="none" id="Supplier-RandomJokeSupplier" style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 7.0,7.0;"/><polygon fill="none" points="558.1745,112.1262,546.2241,94.6279,566.4782,100.8547,558.1745,112.1262" style="stroke: #A80036; stroke-width: 1.0;"/><!--link JokeGenerator to AllJokesSupplier--><path d="M380.0773,221.3889 C469.5086,215.0909 571.9823,207.8745 635.8566,203.3763 " fill="none" id="JokeGenerator-AllJokesSupplier" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="29" x="486" y="205.5684">uses</text><!--link JokeGenerator to RandomJokeSupplier--><path d="M380.0773,251.2952 C463.2498,259.3279 557.7031,268.4502 621.8965,274.65 " fill="none" id="JokeGenerator-RandomJokeSupplier" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="29" x="486" y="253.5684">uses</text><!--
-@startuml GeneratorSpec
-left to right direction
-package java.util.function {
-    interface Supplier<T> {
-        T get();
-    }
-}
-
-package ohm.softa.a12.icndb {
-    class JokeGenerator {
-        +randomJokesStream(): Stream<ResponseWrapper<JokeDto>>
-        +jokesStream(): Stream<ResponseWrapper<JokeDto>>
-    }
-
-    package suppliers {
-        class AllJokesSupplier implements Supplier {
-        }
-
-        class RandomJokeSupplier implements Supplier {
-        }
-    }
-
-    JokeGenerator - - AllJokesSupplier : "uses"
-    JokeGenerator - - RandomJokeSupplier : "uses"
-}
-
-@enduml
-
-PlantUML version 1.2019.03(Sun Mar 10 12:04:44 CET 2019)
-(GPL source distribution)
-Java Runtime: OpenJDK Runtime Environment
-JVM: OpenJDK 64-Bit Server VM
-Java Version: 12.0.1+12
-Operating System: Mac OS X
-OS Version: 10.14.5
-Default Encoding: UTF-8
-Language: en
-Country: GB
---></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="824px" preserveAspectRatio="none" style="width:784px;height:824px;background:#FFFFFF;" version="1.1" viewBox="0 0 784 824" width="784px" zoomAndPan="magnify"><defs/><g><!--cluster java--><g id="cluster_java"><path d="M134.5,568 L164.5,568 A3.75,3.75 0 0 1 167,570.5 L174,590.4883 L358.5,590.4883 A2.5,2.5 0 0 1 361,592.9883 L361,814.5 A2.5,2.5 0 0 1 358.5,817 L134.5,817 A2.5,2.5 0 0 1 132,814.5 L132,570.5 A2.5,2.5 0 0 1 134.5,568 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="132" x2="174" y1="590.4883" y2="590.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="29" x="136" y="583.5352">java</text></g><!--cluster util--><g id="cluster_util"><path d="M158.5,611 L184.5,611 A3.75,3.75 0 0 1 187,613.5 L194,633.4883 L334.5,633.4883 A2.5,2.5 0 0 1 337,635.9883 L337,790.5 A2.5,2.5 0 0 1 334.5,793 L158.5,793 A2.5,2.5 0 0 1 156,790.5 L156,613.5 A2.5,2.5 0 0 1 158.5,611 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="156" x2="194" y1="633.4883" y2="633.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="25" x="160" y="626.5352">util</text></g><!--cluster function--><g id="cluster_function"><path d="M182.5,654 L243.5,654 A3.75,3.75 0 0 1 246,656.5 L253,676.4883 L310.5,676.4883 A2.5,2.5 0 0 1 313,678.9883 L313,766.5 A2.5,2.5 0 0 1 310.5,769 L182.5,769 A2.5,2.5 0 0 1 180,766.5 L180,656.5 A2.5,2.5 0 0 1 182.5,654 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="180" x2="253" y1="676.4883" y2="676.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="60" x="184" y="669.5352">function</text></g><!--cluster ohm--><g id="cluster_ohm"><path d="M8.5,6 L41.5,6 A3.75,3.75 0 0 1 44,8.5 L51,28.4883 L774.5,28.4883 A2.5,2.5 0 0 1 777,30.9883 L777,541.5 A2.5,2.5 0 0 1 774.5,544 L8.5,544 A2.5,2.5 0 0 1 6,541.5 L6,8.5 A2.5,2.5 0 0 1 8.5,6 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="6" x2="51" y1="28.4883" y2="28.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="32" x="10" y="21.5352">ohm</text></g><!--cluster softa--><g id="cluster_softa"><path d="M32.5,49 L70.5,49 A3.75,3.75 0 0 1 73,51.5 L80,71.4883 L750.5,71.4883 A2.5,2.5 0 0 1 753,73.9883 L753,517.5 A2.5,2.5 0 0 1 750.5,520 L32.5,520 A2.5,2.5 0 0 1 30,517.5 L30,51.5 A2.5,2.5 0 0 1 32.5,49 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="30" x2="80" y1="71.4883" y2="71.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="37" x="34" y="64.5352">softa</text></g><!--cluster a12--><g id="cluster_a12"><path d="M56.5,92 L83.5,92 A3.75,3.75 0 0 1 86,94.5 L93,114.4883 L726.5,114.4883 A2.5,2.5 0 0 1 729,116.9883 L729,493.5 A2.5,2.5 0 0 1 726.5,496 L56.5,496 A2.5,2.5 0 0 1 54,493.5 L54,94.5 A2.5,2.5 0 0 1 56.5,92 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="54" x2="93" y1="114.4883" y2="114.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="26" x="58" y="107.5352">a12</text></g><!--cluster icndb--><g id="cluster_icndb"><path d="M80.5,135 L120.5,135 A3.75,3.75 0 0 1 123,137.5 L130,157.4883 L702.5,157.4883 A2.5,2.5 0 0 1 705,159.9883 L705,469.5 A2.5,2.5 0 0 1 702.5,472 L80.5,472 A2.5,2.5 0 0 1 78,469.5 L78,137.5 A2.5,2.5 0 0 1 80.5,135 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="78" x2="130" y1="157.4883" y2="157.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="39" x="82" y="150.5352">icndb</text></g><!--cluster suppliers--><g id="cluster_suppliers"><path d="M188.5,178 L256.5,178 A3.75,3.75 0 0 1 259,180.5 L266,200.4883 L678.5,200.4883 A2.5,2.5 0 0 1 681,202.9883 L681,357.5 A2.5,2.5 0 0 1 678.5,360 L188.5,360 A2.5,2.5 0 0 1 186,357.5 L186,180.5 A2.5,2.5 0 0 1 188.5,178 " fill="none" style="stroke:#000000;stroke-width:1.5;"/><line style="stroke:#000000;stroke-width:1.5;" x1="186" x2="266" y1="200.4883" y2="200.4883"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="67" x="190" y="193.5352">suppliers</text></g><!--class Supplier--><g id="elem_Supplier"><rect codeLine="3" fill="#F1F1F1" height="64.4883" id="Supplier" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="101" x="196" y="688.76"/><ellipse cx="211" cy="704.76" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M207.4277,701.0251 L207.4277,698.8669 L214.8071,698.8669 L214.8071,701.0251 L212.3418,701.0251 L212.3418,709.1018 L214.8071,709.1018 L214.8071,711.26 L207.4277,711.26 L207.4277,709.1018 L209.8931,709.1018 L209.8931,701.0251 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="57" x="225" y="710.051">Supplier</text><rect fill="#FFFFFF" height="16.1328" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" width="10" x="290" y="685.76"/><text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacing" textLength="8" x="291" y="698.3616">T</text><line style="stroke:#181818;stroke-width:0.5;" x1="197" x2="296" y1="720.76" y2="720.76"/><line style="stroke:#181818;stroke-width:0.5;" x1="197" x2="296" y1="728.76" y2="728.76"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="49" x="202" y="746.2952">T get();</text></g><!--class JokeGenerator--><g id="elem_JokeGenerator"><rect codeLine="9" fill="#F1F1F1" height="80.9766" id="JokeGenerator" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="305" x="94" y="375.51"/><ellipse cx="193.25" cy="391.51" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M195.7231,397.6531 Q195.1421,397.9519 194.5029,398.1013 Q193.8638,398.2507 193.1582,398.2507 Q190.6514,398.2507 189.3315,396.5989 Q188.0117,394.947 188.0117,391.8259 Q188.0117,388.6965 189.3315,387.0447 Q190.6514,385.3928 193.1582,385.3928 Q193.8638,385.3928 194.5112,385.5422 Q195.1587,385.6916 195.7231,385.9905 L195.7231,388.7131 Q195.0923,388.1321 194.4988,387.8623 Q193.9053,387.5925 193.2744,387.5925 Q191.9297,387.5925 191.2449,388.6592 Q190.5601,389.7258 190.5601,391.8259 Q190.5601,393.9177 191.2449,394.9844 Q191.9297,396.051 193.2744,396.051 Q193.9053,396.051 194.4988,395.7812 Q195.0923,395.5115 195.7231,394.9304 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="98" x="213.75" y="396.801">JokeGenerator</text><line style="stroke:#181818;stroke-width:0.5;" x1="95" x2="398" y1="407.51" y2="407.51"/><line style="stroke:#181818;stroke-width:0.5;" x1="95" x2="398" y1="415.51" y2="415.51"/><ellipse cx="105" cy="429.2541" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="279" x="114" y="433.0452">randomJokesStream(): Stream&lt;JokeDto&gt;</text><ellipse cx="105" cy="445.7424" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="241" x="114" y="449.5334">allJokesStream(): Stream&lt;JokeDto&gt;</text></g><!--class AllJokesSupplier--><g id="elem_AllJokesSupplier"><rect codeLine="15" fill="#F1F1F1" height="48" id="AllJokesSupplier" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="143" x="506" y="296"/><ellipse cx="521" cy="312" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M523.4731,318.1431 Q522.8921,318.4419 522.2529,318.5913 Q521.6138,318.7407 520.9082,318.7407 Q518.4014,318.7407 517.0815,317.0889 Q515.7617,315.437 515.7617,312.3159 Q515.7617,309.1865 517.0815,307.5347 Q518.4014,305.8828 520.9082,305.8828 Q521.6138,305.8828 522.2612,306.0322 Q522.9087,306.1816 523.4731,306.4805 L523.4731,309.2031 Q522.8423,308.6221 522.2488,308.3523 Q521.6553,308.0825 521.0244,308.0825 Q519.6797,308.0825 518.9949,309.1492 Q518.3101,310.2158 518.3101,312.3159 Q518.3101,314.4077 518.9949,315.4744 Q519.6797,316.541 521.0244,316.541 Q521.6553,316.541 522.2488,316.2712 Q522.8423,316.0015 523.4731,315.4204 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="111" x="535" y="317.291">AllJokesSupplier</text><line style="stroke:#181818;stroke-width:0.5;" x1="507" x2="648" y1="328" y2="328"/><line style="stroke:#181818;stroke-width:0.5;" x1="507" x2="648" y1="336" y2="336"/></g><!--class Supplier--><g id="elem_Supplier"><rect fill="#F1F1F1" height="48" id="Supplier" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="89" x="202" y="254"/><ellipse cx="217" cy="270" fill="#B4A7E5" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M213.4277,266.2651 L213.4277,264.1069 L220.8071,264.1069 L220.8071,266.2651 L218.3418,266.2651 L218.3418,274.3418 L220.8071,274.3418 L220.8071,276.5 L213.4277,276.5 L213.4277,274.3418 L215.8931,274.3418 L215.8931,266.2651 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="57" x="231" y="275.291">Supplier</text><line style="stroke:#181818;stroke-width:0.5;" x1="203" x2="290" y1="286" y2="286"/><line style="stroke:#181818;stroke-width:0.5;" x1="203" x2="290" y1="294" y2="294"/></g><!--class RandomJokeSupplier--><g id="elem_RandomJokeSupplier"><rect codeLine="18" fill="#F1F1F1" height="48" id="RandomJokeSupplier" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="175" x="490" y="213"/><ellipse cx="505" cy="229" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M507.4731,235.1431 Q506.8921,235.4419 506.2529,235.5913 Q505.6138,235.7407 504.9082,235.7407 Q502.4014,235.7407 501.0815,234.0889 Q499.7617,232.437 499.7617,229.3159 Q499.7617,226.1865 501.0815,224.5347 Q502.4014,222.8828 504.9082,222.8828 Q505.6138,222.8828 506.2612,223.0322 Q506.9087,223.1816 507.4731,223.4805 L507.4731,226.2031 Q506.8423,225.6221 506.2488,225.3523 Q505.6553,225.0825 505.0244,225.0825 Q503.6797,225.0825 502.9949,226.1492 Q502.3101,227.2158 502.3101,229.3159 Q502.3101,231.4077 502.9949,232.4744 Q503.6797,233.541 505.0244,233.541 Q505.6553,233.541 506.2488,233.2712 Q506.8423,233.0015 507.4731,232.4204 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="143" x="519" y="234.291">RandomJokeSupplier</text><line style="stroke:#181818;stroke-width:0.5;" x1="491" x2="664" y1="245" y2="245"/><line style="stroke:#181818;stroke-width:0.5;" x1="491" x2="664" y1="253" y2="253"/></g><!--reverse link Supplier to AllJokesSupplier--><g id="link_Supplier_AllJokesSupplier"><path d="M311.98,286.23 C367.77,293.35 448.28,303.63 505.81,310.98 " fill="none" id="Supplier-backto-AllJokesSupplier" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="311.14,293.05,292.19,283.58,312.91,279.17,311.14,293.05" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Supplier to RandomJokeSupplier--><g id="link_Supplier_RandomJokeSupplier"><path d="M311.92,269.97 C362.66,263.65 433.91,254.77 489.69,247.82 " fill="none" id="Supplier-backto-RandomJokeSupplier" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="none" points="312.9,277.03,292.19,272.56,311.17,263.14,312.9,277.03" style="stroke:#181818;stroke-width:1.0;"/></g><!--link JokeGenerator to AllJokesSupplier--><g id="link_JokeGenerator_AllJokesSupplier"><path codeLine="22" d="M399.38,407.14 C420.08,403.55 440.79,398.64 460,392 C491.46,381.12 523.35,360.61 545.79,344.25 " fill="none" id="JokeGenerator-AllJokesSupplier" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="29" x="430" y="388.5684">uses</text></g><!--link JokeGenerator to RandomJokeSupplier--><g id="link_JokeGenerator_RandomJokeSupplier"><path codeLine="23" d="M370.53,375.14 C380.39,370.49 390,365.44 399,360 C445.59,331.83 444.7,308.2 490,278 C498.99,272.01 508.99,266.42 518.91,261.41 " fill="none" id="JokeGenerator-RandomJokeSupplier" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="29" x="430" y="300.5684">uses</text></g><!--SRC=[ZL3DYW8n3BxtAO8dPR6WHrS4GH3skFe2sKvchFPdQ39UPDvz7QtZBEl1N5ho_UHB79K24Y7PwY1Gs4H6R0ogHdF2Yk28PzIDMAVB9jmWk2YubWr2gKH3i6lgsbbAo_qgOrtjeI8PJpvlZLQrghUC1wyvbe8QPtDjJIX-iiuuP8QlUA8j1KeeCGqSFnA68leEvfqaGZ-UBE3-MtRTZSJLautElK6zvkgUHpREk_1WxZtL-c6N6M1zxSXJ4EulC11btwV-km__jiF0v-zDfjF_SHOmQfXuz9h-OdelQDKl]--></g></svg>
\ No newline at end of file
diff --git a/assets/images/StreamFlow.svg b/assets/images/StreamFlow.svg
index 1c27b52..5ee4aaf 100644
--- a/assets/images/StreamFlow.svg
+++ b/assets/images/StreamFlow.svg
@@ -1,23 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="469px" preserveAspectRatio="none" style="width:355px;height:469px;" version="1.1" viewBox="0 0 355 469" width="355px" zoomAndPan="magnify"><defs><filter height="300%" id="f9zskfbuzy97j" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><ellipse cx="175" cy="18" fill="#000000" filter="url(#f9zskfbuzy97j)" rx="10" ry="10" style="stroke: none; stroke-width: 1.0;"/><rect fill="#FEFECE" filter="url(#f9zskfbuzy97j)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="176" x="87" y="68"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="156" x="97" y="89.1387">Filter for non null objects</text><rect fill="#FEFECE" filter="url(#f9zskfbuzy97j)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="222" x="64" y="142"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="202" x="74" y="163.1387">Skip as many values as required</text><rect fill="#FEFECE" filter="url(#f9zskfbuzy97j)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="338" x="6" y="216"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="318" x="16" y="237.1387">Limit the stream to the required count of elements</text><rect fill="#FEFECE" filter="url(#f9zskfbuzy97j)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="309" x="20.5" y="290"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="289" x="30.5" y="311.1387">use `map` to unwrap the `ResponseWrapper`</text><rect fill="#FEFECE" filter="url(#f9zskfbuzy97j)" height="33.9688" rx="12.5" ry="12.5" style="stroke: #A80036; stroke-width: 1.5;" width="206" x="72" y="364"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="186" x="82" y="385.1387">Print the jokes to the STDOUT</text><ellipse cx="175" cy="448" fill="none" filter="url(#f9zskfbuzy97j)" rx="10" ry="10" style="stroke: #000000; stroke-width: 1.0;"/><ellipse cx="175.5" cy="448.5" fill="#000000" rx="6" ry="6" style="stroke: none; stroke-width: 1.0;"/><!--link start to Filter for non null objects--><path d="M175,28.1759 C175,37.3186 175,51.0626 175,62.7436 " fill="none" id="start-Filter for non null objects" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,67.9414,179,58.9414,175,62.9414,171,58.9414,175,67.9414" style="stroke: #A80036; stroke-width: 1.0;"/><!--link Filter for non null objects to Skip as many values as required--><path d="M175,102.1631 C175,112.4368 175,125.6075 175,136.6831 " fill="none" id="Filter for non null objects-Skip as many values as required" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,141.93,179,132.93,175,136.93,171,132.93,175,141.93" style="stroke: #A80036; stroke-width: 1.0;"/><!--link Skip as many values as required to Limit the stream to the required count of elements--><path d="M175,176.1631 C175,186.4368 175,199.6075 175,210.6831 " fill="none" id="Skip as many values as required-Limit the stream to the required count of elements" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,215.93,179,206.93,175,210.93,171,206.93,175,215.93" style="stroke: #A80036; stroke-width: 1.0;"/><!--link Limit the stream to the required count of elements to use `map` to unwrap the `ResponseWrapper`--><path d="M175,250.1631 C175,260.4368 175,273.6075 175,284.6831 " fill="none" id="Limit the stream to the required count of elements-use `map` to unwrap the `ResponseWrapper`" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,289.93,179,280.93,175,284.93,171,280.93,175,289.93" style="stroke: #A80036; stroke-width: 1.0;"/><!--link use `map` to unwrap the `ResponseWrapper` to Print the jokes to the STDOUT--><path d="M175,324.1631 C175,334.4368 175,347.6075 175,358.6831 " fill="none" id="use `map` to unwrap the `ResponseWrapper`-Print the jokes to the STDOUT" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,363.93,179,354.93,175,358.93,171,354.93,175,363.93" style="stroke: #A80036; stroke-width: 1.0;"/><!--link Print the jokes to the STDOUT to end--><path d="M175,398.2542 C175,408.9518 175,422.5657 175,432.8464 " fill="none" id="Print the jokes to the STDOUT-end" style="stroke: #A80036; stroke-width: 1.0;"/><polygon fill="#A80036" points="175,437.8855,179,428.8855,175,432.8855,171,428.8855,175,437.8855" style="stroke: #A80036; stroke-width: 1.0;"/><!--
-@startuml StreamFlow
-
-(*) - -> "Filter for non null objects"
-- -> "Skip as many values as required"
-- -> "Limit the stream to the required count of elements"
-- -> "use `map` to unwrap the `ResponseWrapper`"
-- -> "Print the jokes to the STDOUT"
-- -> (*)
-
-@enduml
-
-PlantUML version 1.2017.20(Mon Dec 11 17:57:05 CET 2017)
-(GPL source distribution)
-Java Runtime: OpenJDK Runtime Environment
-JVM: OpenJDK 64-Bit Server VM
-Java Version: 1.8.0_144-b01
-Operating System: Linux
-OS Version: 4.14.8-1-ARCH
-Default Encoding: UTF-8
-Language: en
-Country: US
---></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="388px" preserveAspectRatio="none" style="width:323px;height:388px;background:#FFFFFF;" version="1.1" viewBox="0 0 323 388" width="323px" zoomAndPan="magnify"><defs/><g><ellipse cx="162" cy="16" fill="#222222" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><rect fill="#F1F1F1" height="34.1328" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="163" x="80.5" y="66"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="143" x="90.5" y="87.6016">Filter for non null objects</text><rect fill="#F1F1F1" height="34.1328" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="207" x="58.5" y="140.13"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="187" x="68.5" y="161.7316">Skip as many values as required</text><rect fill="#F1F1F1" height="34.1328" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="310" x="7" y="214.26"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="290" x="17" y="235.8616">Limit the stream to the required count of elements</text><rect fill="#F1F1F1" height="34.1328" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="192" x="66" y="288.4"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="172" x="76" y="310.0016">Print the jokes to the STDOUT</text><ellipse cx="162" cy="372.53" fill="none" rx="10" ry="10" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="162.5" cy="373.03" fill="#222222" rx="6" ry="6" style="stroke:none;stroke-width:1.0;"/><!--link start to Filter for non null objects--><g id="link_start_Filter for non null objects"><path d="M162,26.32 C162,35.06 162,48.46 162,59.93 " fill="none" id="start-to-Filter for non null objects" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162,64.72,166,55.72,162,59.72,158,55.72,162,64.72" style="stroke:#181818;stroke-width:1.0;"/></g><!--link Filter for non null objects to Skip as many values as required--><g id="link_Filter for non null objects_Skip as many values as required"><path d="M162,100.43 C162,110.32 162,123.06 162,133.87 " fill="none" id="Filter for non null objects-to-Skip as many values as required" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162,138.64,166,129.64,162,133.64,158,129.64,162,138.64" style="stroke:#181818;stroke-width:1.0;"/></g><!--link Skip as many values as required to Limit the stream to the required count of elements--><g id="link_Skip as many values as required_Limit the stream to the required count of elements"><path d="M162,174.57 C162,184.46 162,197.2 162,208 " fill="none" id="Skip as many values as required-to-Limit the stream to the required count of elements" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162,212.78,166,203.78,162,207.78,158,203.78,162,212.78" style="stroke:#181818;stroke-width:1.0;"/></g><!--link Limit the stream to the required count of elements to Print the jokes to the STDOUT--><g id="link_Limit the stream to the required count of elements_Print the jokes to the STDOUT"><path d="M162,248.7 C162,258.59 162,271.33 162,282.14 " fill="none" id="Limit the stream to the required count of elements-to-Print the jokes to the STDOUT" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162,286.91,166,277.91,162,281.91,158,277.91,162,286.91" style="stroke:#181818;stroke-width:1.0;"/></g><!--link Print the jokes to the STDOUT to end--><g id="link_Print the jokes to the STDOUT_end"><path d="M162,322.88 C162,333.23 162,346.5 162,356.56 " fill="none" id="Print the jokes to the STDOUT-to-end" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162,361.35,166,352.35,162,356.35,158,352.35,162,361.35" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[FOn13e8m44NtdEB75P1m1LV6bOacu04g3h7GpkXqQkBjLK2NBtdlbNM5fjbYi_V1I368WeN1EGJ8PQJUqgQOZNRoTxY4wFY5fmkPqXUL7jahNLVhuACts8sGJCb5cCpqqz1BPeCCe42H-By_gUSb76NwhDUkxNR7SxSuPLqLRm00]--></g></svg>
\ No newline at end of file
diff --git a/assets/uml/generator-spec.plantuml b/assets/uml/generator-spec.plantuml
index edd3fe2..c0d1794 100644
--- a/assets/uml/generator-spec.plantuml
+++ b/assets/uml/generator-spec.plantuml
@@ -8,8 +8,8 @@ package java.util.function {
 
 package ohm.softa.a12.icndb {
     class JokeGenerator {
-        +randomJokesStream(): Stream<ResponseWrapper<JokeDto>>
-        +jokesStream(): Stream<ResponseWrapper<JokeDto>>
+        +randomJokesStream(): Stream<JokeDto>
+        +allJokesStream(): Stream<JokeDto>
     }
 
     package suppliers {
diff --git a/assets/uml/stream-flow.plantuml b/assets/uml/stream-flow.plantuml
index 8fc99ff..3cfb32c 100644
--- a/assets/uml/stream-flow.plantuml
+++ b/assets/uml/stream-flow.plantuml
@@ -3,8 +3,7 @@
 (*) --> "Filter for non null objects"
 --> "Skip as many values as required"
 --> "Limit the stream to the required count of elements"
---> "use `map` to unwrap the `ResponseWrapper`"
 --> "Print the jokes to the STDOUT"
 --> (*)
 
-@enduml
\ No newline at end of file
+@enduml
diff --git a/build.gradle b/build.gradle
index a2a8c70..a8c943f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,7 @@
 plugins {
 	id 'java'
 	id 'application'
+	id "io.freefair.lombok" version "6.0.0-m2"
 	id "com.github.ben-manes.versions" version "0.20.0"
 }
 
@@ -24,6 +25,7 @@ dependencies {
 	implementation("com.squareup.retrofit2:retrofit:$retrofit2_version")
 	implementation("com.squareup.retrofit2:converter-gson:$retrofit2_version")
 	implementation("com.squareup.retrofit2:adapter-java8:$retrofit2_version")
+	implementation 'org.projectlombok:lombok:1.18.26'
 
 	/* JUnit 5 */
 	testCompile("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
diff --git a/src/main/java/ohm/softa/a12/App.java b/src/main/java/ohm/softa/a12/App.java
index 4c8c3de..cf47f7c 100644
--- a/src/main/java/ohm/softa/a12/App.java
+++ b/src/main/java/ohm/softa/a12/App.java
@@ -1,8 +1,7 @@
 package ohm.softa.a12;
 
-import ohm.softa.a12.icndb.JokeGenerator;
+import ohm.softa.a12.cnjdb.JokeGenerator;
 import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
 
 import java.util.Scanner;
 import java.util.stream.Stream;
@@ -29,12 +28,11 @@ public abstract class App {
             jokeCount = readInt("How many jokes do you want?");
             skipCount = readInt("How many jokes do you want to skip");
 
-            Stream<ResponseWrapper<JokeDto>> jokesSource = readJokeSource();
+            Stream<JokeDto> jokesSource = readJokeSource();
 
             /* TODO consume the `jokesSource`
              * filter it for non null objects
              * use `skip` and `limit` to retrieve the required elements
-             * use `map` to unwrap the ResponseWrapper value
              * and print the jokes to the STDOUT */
 
             System.out.println("If you want to quit press [Q] otherwise press [C] to continue.");
@@ -70,7 +68,7 @@ public abstract class App {
      *
      * @return stream of JokeDtos wrapped in ResponseWrapper objects
      */
-    private static Stream<ResponseWrapper<JokeDto>> readJokeSource() {
+    private static Stream<JokeDto> readJokeSource() {
         System.out.println("Which joke source do you want to use?");
         System.out.println("1) Random jokes");
         System.out.println("2) Linear by id");
@@ -82,7 +80,7 @@ public abstract class App {
                     case 1:
                         return jokeGenerator.randomJokesStream();
                     default:
-                        return jokeGenerator.jokesStream();
+                        return jokeGenerator.allJokesStream();
                 }
             } catch (Exception e) {
                 System.out.println("No valid selection");
diff --git a/src/main/java/ohm/softa/a12/cnjdb/CNJDBApi.java b/src/main/java/ohm/softa/a12/cnjdb/CNJDBApi.java
new file mode 100644
index 0000000..3de6290
--- /dev/null
+++ b/src/main/java/ohm/softa/a12/cnjdb/CNJDBApi.java
@@ -0,0 +1,35 @@
+package ohm.softa.a12.cnjdb;
+
+import ohm.softa.a12.model.JokeDto;
+import retrofit2.http.GET;
+import retrofit2.http.Path;
+import retrofit2.http.Query;
+
+import java.util.concurrent.CompletableFuture;
+
+public interface CNJDBApi {
+    /**
+     * Fetch a random joke
+     */
+    @GET("/jokes/random")
+    CompletableFuture<JokeDto> getRandomJoke();
+
+    /**
+     * Fetch a random joke for the given category
+     */
+    @GET("/jokes/random")
+    CompletableFuture<JokeDto> getRandomJokeByCategory(@Query("category") String category);
+
+	/**
+	 * Get a list of random jokes matching the search query
+	 */
+	@GET("/jokes/random")
+	CompletableFuture<JokeDto[]> getJokesByQuery(@Query("category") String query);
+
+    /**
+     * Fetch the joke corresponding to the given id string
+     */
+    @GET("/jokes/{id}")
+    CompletableFuture<JokeDto> getJoke(@Path("id") String id);
+
+}
diff --git a/src/main/java/ohm/softa/a12/cnjdb/CNJDBService.java b/src/main/java/ohm/softa/a12/cnjdb/CNJDBService.java
new file mode 100644
index 0000000..780f259
--- /dev/null
+++ b/src/main/java/ohm/softa/a12/cnjdb/CNJDBService.java
@@ -0,0 +1,31 @@
+package ohm.softa.a12.cnjdb;
+
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+/**
+ * CNJDB service encapsulating the API instance as singleton
+ */
+public final class CNJDBService {
+
+    private final CNJDBApi api;
+
+    /**
+     * Access the singleton instance
+     */
+    public CNJDBApi getInstance() {
+        return api;
+    }
+
+    public CNJDBService() {
+        /* Initialize Retrofit */
+        var retrofit = new Retrofit.Builder()
+                .baseUrl("https://api.chucknorris.io")
+                .addConverterFactory(GsonConverterFactory.create())
+                /* CallAdapterFactory required to wrap calls in CompletableFutures */
+                //.addCallAdapterFactory(Java8CallAdapterFactory.create())
+                .build();
+
+        api = retrofit.create(CNJDBApi.class);
+    }
+}
diff --git a/src/main/java/ohm/softa/a12/icndb/JokeGenerator.java b/src/main/java/ohm/softa/a12/cnjdb/JokeGenerator.java
similarity index 63%
rename from src/main/java/ohm/softa/a12/icndb/JokeGenerator.java
rename to src/main/java/ohm/softa/a12/cnjdb/JokeGenerator.java
index f216d74..01c5000 100644
--- a/src/main/java/ohm/softa/a12/icndb/JokeGenerator.java
+++ b/src/main/java/ohm/softa/a12/cnjdb/JokeGenerator.java
@@ -1,14 +1,12 @@
-package ohm.softa.a12.icndb;
+package ohm.softa.a12.cnjdb;
 
 import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
 import org.apache.commons.lang3.NotImplementedException;
 
 import java.util.stream.Stream;
 
 /**
  * Generator instance to provide streams of jokes
- * @author Peter Kurfer
  */
 
 public final class JokeGenerator {
@@ -17,7 +15,7 @@ public final class JokeGenerator {
      * Generator for random jokes
      * @return stream of random jokes wrapped in ResponseWrapper objects
      */
-    public Stream<ResponseWrapper<JokeDto>> randomJokesStream() {
+    public Stream<JokeDto> randomJokesStream() {
         /* TODO create new Stream of random jokes */
         throw new NotImplementedException("Method `randomJokeStream()` is not implemented");
     }
@@ -26,8 +24,8 @@ public final class JokeGenerator {
      * Generator for jokes ordered by their id
      * @return stream of jokes wrapped in ResponseWrapper objects
      */
-    public Stream<ResponseWrapper<JokeDto>> jokesStream() {
-        /* TODO create a new Stream of all jokes */
-        throw new NotImplementedException("Method `jokesStream()` is not implemented");
+    public Stream<JokeDto> allJokesStream() {
+        /* TODO create a new Stream of all jokes, ie. retrieve random jokes until collision */
+        throw new NotImplementedException("Method `allJokesStream()` is not implemented");
     }
 }
diff --git a/src/main/java/ohm/softa/a12/icndb/suppliers/AllJokesSupplier.java b/src/main/java/ohm/softa/a12/cnjdb/suppliers/AllJokesSupplier.java
similarity index 76%
rename from src/main/java/ohm/softa/a12/icndb/suppliers/AllJokesSupplier.java
rename to src/main/java/ohm/softa/a12/cnjdb/suppliers/AllJokesSupplier.java
index d6ab302..3e962aa 100644
--- a/src/main/java/ohm/softa/a12/icndb/suppliers/AllJokesSupplier.java
+++ b/src/main/java/ohm/softa/a12/cnjdb/suppliers/AllJokesSupplier.java
@@ -1,9 +1,8 @@
-package ohm.softa.a12.icndb.suppliers;
+package ohm.softa.a12.cnjdb.suppliers;
 
-import ohm.softa.a12.icndb.ICNDBApi;
-import ohm.softa.a12.icndb.ICNDBService;
+import ohm.softa.a12.cnjdb.CNJDBApi;
+import ohm.softa.a12.cnjdb.CNJDBService;
 import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
 import org.apache.commons.lang3.NotImplementedException;
 
 /**
@@ -14,15 +13,15 @@ import org.apache.commons.lang3.NotImplementedException;
 public final class AllJokesSupplier {
 
     /* ICNDB API proxy to retrieve jokes */
-    private final ICNDBApi icndbApi;
+    private final CNJDBApi icndbApi;
 
     public AllJokesSupplier() {
-        icndbApi = ICNDBService.getInstance();
+        icndbApi = new CNJDBService().getInstance();
         /* TODO fetch the total count of jokes the API is aware of
          * to determine when all jokes are iterated and the counters have to be reset */
     }
 
-    public ResponseWrapper<JokeDto> get() {
+    public JokeDto get() {
         /* TODO retrieve the next joke
          * note that there might be IDs that are not present in the database
          * you have to catch an exception and continue if no joke was retrieved to an ID
diff --git a/src/main/java/ohm/softa/a12/icndb/suppliers/RandomJokeSupplier.java b/src/main/java/ohm/softa/a12/cnjdb/suppliers/RandomJokeSupplier.java
similarity index 60%
rename from src/main/java/ohm/softa/a12/icndb/suppliers/RandomJokeSupplier.java
rename to src/main/java/ohm/softa/a12/cnjdb/suppliers/RandomJokeSupplier.java
index f1ea9b5..234d810 100644
--- a/src/main/java/ohm/softa/a12/icndb/suppliers/RandomJokeSupplier.java
+++ b/src/main/java/ohm/softa/a12/cnjdb/suppliers/RandomJokeSupplier.java
@@ -1,9 +1,8 @@
-package ohm.softa.a12.icndb.suppliers;
+package ohm.softa.a12.cnjdb.suppliers;
 
-import ohm.softa.a12.icndb.ICNDBApi;
-import ohm.softa.a12.icndb.ICNDBService;
+import ohm.softa.a12.cnjdb.CNJDBApi;
+import ohm.softa.a12.cnjdb.CNJDBService;
 import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
 import org.apache.commons.lang3.NotImplementedException;
 
 /**
@@ -13,13 +12,13 @@ import org.apache.commons.lang3.NotImplementedException;
 public final class RandomJokeSupplier {
 
     /* ICNDB API proxy to retrieve jokes */
-    private final ICNDBApi icndbApi;
+    private final CNJDBApi icndbApi;
 
     public RandomJokeSupplier() {
-        icndbApi = ICNDBService.getInstance();
+        icndbApi = new CNJDBService().getInstance();
     }
 
-    public ResponseWrapper<JokeDto> get() {
+    public JokeDto get() {
         /* TODO fetch a random joke synchronously
          * if an exception occurs return null */
         throw new NotImplementedException("Method `get()` is not implemented");
diff --git a/src/main/java/ohm/softa/a12/icndb/ICNDBApi.java b/src/main/java/ohm/softa/a12/icndb/ICNDBApi.java
deleted file mode 100644
index aaf257f..0000000
--- a/src/main/java/ohm/softa/a12/icndb/ICNDBApi.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package ohm.softa.a12.icndb;
-
-import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
-import retrofit2.http.GET;
-import retrofit2.http.Path;
-import retrofit2.http.Query;
-
-import java.util.concurrent.CompletableFuture;
-
-/**
- * @author Peter Kurfer
- * Created on 12/28/17.
- */
-public interface ICNDBApi {
-
-    /**
-     * Fetch the count of jokes the API is aware of
-     * @return count wrapped in a ResponseWrapper object
-     */
-    @GET("/jokes/count")
-    CompletableFuture<ResponseWrapper<Integer>> getJokeCount();
-
-    /**
-     * Fetch a random joke
-     * @return JokeDto wrapped in a ResponseWrapper object
-     */
-    @GET("/jokes/random")
-    CompletableFuture<ResponseWrapper<JokeDto>> getRandomJoke();
-
-    /**
-     * Fetch a random joke
-     * replaces 'Chuck' and 'Norris' by the provided values
-     * @param firstName name to replace 'Chuck'
-     * @param lastName name to replace 'Norris'
-     * @return JokeDto wrapped in a ResponseWrapper object
-     */
-    @GET("/jokes/random")
-    CompletableFuture<ResponseWrapper<JokeDto>> getRandomJoke(@Query("firstName") String firstName, @Query("lastName") String lastName);
-
-    /**
-     * Fetch the joke corresponding to the given id
-     * @param id id of the joke to fetch
-     * @return JokeDto wrapped in a ResponseWrapper object
-     */
-    @GET("/jokes/{id}")
-    CompletableFuture<ResponseWrapper<JokeDto>> getJoke(@Path("id") int id);
-
-}
diff --git a/src/main/java/ohm/softa/a12/icndb/ICNDBService.java b/src/main/java/ohm/softa/a12/icndb/ICNDBService.java
deleted file mode 100644
index 81d0ecf..0000000
--- a/src/main/java/ohm/softa/a12/icndb/ICNDBService.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package ohm.softa.a12.icndb;
-
-import ohm.softa.a12.model.JokeDto;
-import ohm.softa.a12.model.ResponseWrapper;
-import retrofit2.Retrofit;
-import retrofit2.adapter.java8.Java8CallAdapterFactory;
-import retrofit2.converter.gson.GsonConverterFactory;
-
-import java.util.concurrent.CompletableFuture;
-
-/**
- * ICNDB singleton service
- * acts as proxy to an underlying Retrofit proxy object
- * @author Peter Kurfer
- */
-public final class ICNDBService implements ICNDBApi {
-
-    /**
-     * Singleton instance
-     */
-    private static final ICNDBService instance = new ICNDBService();
-
-    /**
-     * Retrofit proxy
-     */
-    private final ICNDBApi icndbApi;
-
-    /**
-     * Access the singleton instance
-     */
-    public static ICNDBService getInstance() {
-        return instance;
-    }
-
-    private ICNDBService() {
-        /* Initialize Retrofit */
-        var retrofit = new Retrofit.Builder()
-                .baseUrl("http://api.icndb.com")
-                .addConverterFactory(GsonConverterFactory.create())
-                /* CallAdapterFactory required to wrap calls in CompletableFutures */
-                .addCallAdapterFactory(Java8CallAdapterFactory.create())
-                .build();
-
-        icndbApi = retrofit.create(ICNDBApi.class);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    @Override
-    public CompletableFuture<ResponseWrapper<Integer>> getJokeCount() {
-        return icndbApi.getJokeCount();
-    }
-
-    /**
-     * @inheritDoc
-     */
-    @Override
-    public CompletableFuture<ResponseWrapper<JokeDto>> getRandomJoke() {
-        return icndbApi.getRandomJoke();
-    }
-
-    /**
-     * @inheritDoc
-     */
-    @Override
-    public CompletableFuture<ResponseWrapper<JokeDto>> getRandomJoke(String firstName, String lastName) {
-        return icndbApi.getRandomJoke(firstName, lastName);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    @Override
-    public CompletableFuture<ResponseWrapper<JokeDto>> getJoke(int id) {
-        return icndbApi.getJoke(id);
-    }
-}
diff --git a/src/main/java/ohm/softa/a12/model/JokeDto.java b/src/main/java/ohm/softa/a12/model/JokeDto.java
index f0b16da..2300d5e 100644
--- a/src/main/java/ohm/softa/a12/model/JokeDto.java
+++ b/src/main/java/ohm/softa/a12/model/JokeDto.java
@@ -1,27 +1,25 @@
 package ohm.softa.a12.model;
 
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
+import com.google.gson.annotations.SerializedName;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * Data transfer object (DTO) for ICNDB jokes
- * @author Peter Kurfer
+ * Data transfer object (DTO) for chucknorris.io
  */
 public class JokeDto {
 
     /**
      * ID of the joke
      */
-    private int id;
+    private String id;
 
     /**
      * joke content
      */
-    private String joke;
+	private String value;
 
     /**
      * Categories of the joke
@@ -32,26 +30,13 @@ public class JokeDto {
         categories = new ArrayList<>();
     }
 
-    public int getId() {
+    public String getId() {
         return id;
     }
 
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public String getJoke() {
-        return joke;
-    }
-
-    public void setJoke(String joke) {
-        this.joke = joke;
-    }
-
-    public List<String> getCategories() {
-        return categories;
-    }
+	public String getValue() { return value; }
 
+	public List<String> getCategories() { return categories; }
     public void setCategories(List<String> categories) {
         if(categories == null) return;
         this.categories = categories;
@@ -60,32 +45,20 @@ public class JokeDto {
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-
         if (!(o instanceof JokeDto)) return false;
-
-        var joke1 = (JokeDto) o;
-
-        return new EqualsBuilder()
-                .append(getId(), joke1.getId())
-                .append(getJoke(), joke1.getJoke())
-                .append(getCategories(), joke1.getCategories())
-                .isEquals();
+        return this.id.equals(((JokeDto) o).id);
     }
 
     @Override
     public int hashCode() {
-        return new HashCodeBuilder(17, 37)
-                .append(getId())
-                .append(getJoke())
-                .append(getCategories())
-                .toHashCode();
+        return id.hashCode();
     }
 
     @Override
     public String toString() {
         return new ToStringBuilder(this)
                 .append("id", id)
-                .append("joke", joke)
+                .append("value", value)
                 .append("categories", categories)
                 .toString();
     }
diff --git a/src/main/java/ohm/softa/a12/model/ResponseWrapper.java b/src/main/java/ohm/softa/a12/model/ResponseWrapper.java
deleted file mode 100644
index edb43a1..0000000
--- a/src/main/java/ohm/softa/a12/model/ResponseWrapper.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package ohm.softa.a12.model;
-
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-/**
- * Wrapper object for ICNDB API results
- * Results of the API always contain a value and a success indicator
- * to handle this wrapping this class models the same structure to ease the deserialization
- * @author Peter Kurfer
- */
-public class ResponseWrapper<T> {
-
-    /**
-     * success indicator: error or success
-     */
-    private String type;
-
-    /**
-     * actual received value
-     */
-    private T value;
-
-    public ResponseWrapper() {
-        /* set default to error
-         * to avoid calls to the value when there is no value */
-        type = "error";
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public T getValue() {
-        return value;
-    }
-
-    public void setValue(T value) {
-        this.value = value;
-    }
-
-    public boolean isSuccessfull() {
-        return type != null && type.equals("success");
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-
-        if (!(o instanceof ResponseWrapper)) return false;
-
-        var that = (ResponseWrapper<?>) o;
-
-        return new EqualsBuilder()
-                .append(getType(), that.getType())
-                .append(getValue(), that.getValue())
-                .isEquals();
-    }
-
-    @Override
-    public int hashCode() {
-        return new HashCodeBuilder(17, 37)
-                .append(getType())
-                .append(getValue())
-                .toHashCode();
-    }
-
-}
diff --git a/src/test/java/ohm/softa/a12/icndb/ICNDBTests.java b/src/test/java/ohm/softa/a12/icndb/ICNDBTests.java
index b0ef582..fd2119f 100644
--- a/src/test/java/ohm/softa/a12/icndb/ICNDBTests.java
+++ b/src/test/java/ohm/softa/a12/icndb/ICNDBTests.java
@@ -1,45 +1,41 @@
 package ohm.softa.a12.icndb;
 
+import ohm.softa.a12.cnjdb.CNJDBApi;
+import ohm.softa.a12.cnjdb.CNJDBService;
 import org.junit.jupiter.api.Test;
 
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.concurrent.ExecutionException;
 import java.util.logging.Logger;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-/**
- * @author Peter Kurfer
- */
-
 public class ICNDBTests {
 	private static final Logger logger = Logger.getLogger(ICNDBTests.class.getName());
 	private static final int REQUEST_COUNT = 100;
 
-	private ICNDBApi icndbApi;
+	private CNJDBApi icndbApi;
 
 	public ICNDBTests() {
-		this.icndbApi = ICNDBService.getInstance();
+		this.icndbApi = new CNJDBService().getInstance();
 	}
 
 	@Test
 	void testCollision() throws ExecutionException, InterruptedException {
-		var jokeNumbers = new HashSet<>();
+		var ids = new HashSet<>();
 		var requests = 0;
 		var collision = false;
 
 		while (requests++ < REQUEST_COUNT) {
-			var jokeCall = icndbApi.getRandomJoke();
-			var joke = jokeCall.get().getValue();
+			var joke = icndbApi.getRandomJoke().get();
 
-			if (jokeNumbers.contains(joke.getId())) {
+			if (ids.contains(joke.getId())) {
 				logger.info(String.format("Collision at joke %s", joke.getId()));
 				collision = true;
 				break;
 			}
 
-			jokeNumbers.add(joke.getId());
+			ids.add(joke.getId());
 			logger.info(joke.toString());
 		}
 
@@ -47,36 +43,17 @@ public class ICNDBTests {
 	}
 
 	@Test
-	void testGetRandomJokeWithChangedName() throws ExecutionException, InterruptedException {
-		var j = icndbApi.getRandomJoke("Bruce", "Wayne").get().getValue();
+	void testGetRandomJokeByCategory() throws ExecutionException, InterruptedException {
+		var j = icndbApi.getRandomJokeByCategory("food").get();
 		assertNotNull(j);
-		assertFalse(j.getJoke().contains("Chuck"));
-		assertFalse(j.getJoke().contains("Norris"));
+		assertTrue(j.getCategories().contains("food"));
 		logger.info(j.toString());
 	}
 
 	@Test
 	void testGetJokeById() throws ExecutionException, InterruptedException {
-
-		var randomIds = new ArrayList<Integer>(10);
-
-		for (var i = 0; i < 10; i++) {
-			randomIds.add(icndbApi.getRandomJoke().get().getValue().getId());
-		}
-
-		for (var id : randomIds) {
-			var j = icndbApi.getJoke(id).get().getValue();
-			assertNotNull(j);
-			assertTrue(randomIds.contains(j.getId()));
-			logger.info(j.toString());
-		}
-	}
-
-	@Test
-	void testGetJokeCount() throws ExecutionException, InterruptedException {
-		var jokeCount = icndbApi.getJokeCount().get().getValue();
-
-		assertNotEquals(0, jokeCount);
+		var j = icndbApi.getJoke("S5uiluahRM26CTWRZNXfwg").get();
+		assertNotNull(j);
+		logger.info(j.toString());
 	}
-
 }
diff --git a/src/test/java/ohm/softa/a12/icndb/JokesGeneratorTests.java b/src/test/java/ohm/softa/a12/icndb/JokesGeneratorTests.java
index 27c0956..8db6c9a 100644
--- a/src/test/java/ohm/softa/a12/icndb/JokesGeneratorTests.java
+++ b/src/test/java/ohm/softa/a12/icndb/JokesGeneratorTests.java
@@ -1,11 +1,8 @@
 package ohm.softa.a12.icndb;
 
+import ohm.softa.a12.cnjdb.JokeGenerator;
 import org.junit.jupiter.api.Test;
 
-/**
- * @author Peter Kurfer
- * Created on 12/28/17.
- */
 class JokesGeneratorTests {
 
     private JokeGenerator jokeGenerator = new JokeGenerator();
-- 
GitLab