<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[My experience with Java, Groovy, Grails, Python and more.]]></title><description><![CDATA[My thoughts, meanderings, ideas about some awesome technologies that I get to dabble in!]]></description><link>https://javawithravi.com/</link><image><url>http://javawithravi.com/favicon.png</url><title>My experience with Java, Groovy, Grails, Python and more.</title><link>https://javawithravi.com/</link></image><generator>Ghost 2.1</generator><lastBuildDate>Thu, 26 Mar 2026 17:04:15 GMT</lastBuildDate><atom:link href="https://javawithravi.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Playing with Graal VM]]></title><description><![CDATA[<p>Recently I started playing with <a href="https://www.graalvm.org/">Graal VM.</a> What is Graal VM? To quote directly:</p><blockquote>
<p>GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Kotlin, Clojure, and LLVM-based languages such as C and C++.</p>
</blockquote>
<blockquote>
<p>GraalVM removes the isolation between programming</p></blockquote>]]></description><link>https://javawithravi.com/playing-with-graal-vm/</link><guid isPermaLink="false">5ce1f61000324e5f26aacaca</guid><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Thu, 13 Jun 2019 04:18:29 GMT</pubDate><content:encoded><![CDATA[<p>Recently I started playing with <a href="https://www.graalvm.org/">Graal VM.</a> What is Graal VM? To quote directly:</p><blockquote>
<p>GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Kotlin, Clojure, and LLVM-based languages such as C and C++.</p>
</blockquote>
<blockquote>
<p>GraalVM removes the isolation between programming languages and enables interoperability in a shared runtime.</p>
</blockquote>
<p>In lay man's terms, Graal VM allows languages JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Kotlin, Clojure to <em>talk to each other</em>, thus removing isolation between these languages.</p><p>But, as a Java/JVM platform developer, I am more interested in Graal VM's ability to ahead-of-time compile Java to run a Java application as a native application. </p><blockquote><strong>GraalVM Native Image</strong> allows you to ahead-of-time compile Java code to a standalone executable, called a <strong>native image</strong>. </blockquote><blockquote><code>native-image</code> is a utility that processes all the classes of your application and their dependencies, including those from the JDK. It statically analyses these classes to determine which classes and methods are reachable and used during application execution. Then it passes all this reachable code as the input to the GraalVM compiler which ahead-of-time compiles it to the native binary.</blockquote><p>The key benefits of AOT compiling Java application to a native binary are: </p><ol><li>Speed of startup and </li><li>Reduced memory footprint</li></ol><p>For example here's a micronaut application: <a href="https://github.com/RaviH/graal-micronaut">https://github.com/RaviH/graal-micronaut</a></p><p>When I try to run the jar, it takes about 1.3 secs to start:</p><pre><code> $ java -jar target/graal-micronaut-0.1.jar
 18:30:22.244 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 1320ms. Server Running: http://localhost:8080
</code></pre>
<p>But, when I create the native image, it starts in <strong>29 ms </strong>(vs 1.3 s) – 45 times faster boot time.</p><pre><code># rhasija ~/dev/projects/tmp/graal-micronaut on git:master x  C:130
$ native-image -jar target/graal-micronaut-0.1.jar
Build on Server(pid: 5608, port: 50229)
[graal-micronaut:5608]    classlist:   3,788.29 ms
[graal-micronaut:5608]        (cap):   1,547.58 ms
[graal-micronaut:5608]        setup:   2,041.59 ms
[graal-micronaut:5608]   (typeflow):  27,169.03 ms
[graal-micronaut:5608]    (objects):  32,584.30 ms
[graal-micronaut:5608]   (features):   1,562.28 ms
[graal-micronaut:5608]     analysis:  63,945.36 ms
[graal-micronaut:5608]     universe:   1,593.43 ms
[graal-micronaut:5608]      (parse):   4,368.97 ms
[graal-micronaut:5608]     (inline):   9,400.59 ms
[graal-micronaut:5608]    (compile):  36,820.75 ms
[graal-micronaut:5608]      compile:  53,848.37 ms
[graal-micronaut:5608]        image:   4,955.53 ms
[graal-micronaut:5608]        write:   1,971.52 ms
[graal-micronaut:5608]      [total]: 132,379.50 ms

# rhasija ~/dev/projects/tmp/graal-micronaut on git:master x
$ ./graal-micronaut
18:36:13.776 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 29ms. Server Running: http://localhost:8080
</code></pre><p>Also, the native image took 14M of memory (vs  387M Java based app) – roughly 3% of the memory taken by Java app. This is awesome.</p><p>Micronaut Java app:<br>
<code>13068 java 0.1 00:03.00 23 1 84 387M 0B 0B 13068 5096</code></p>
<p>Native image:<br>
<code>13136 graal-micron 0.0 00:00.03 3 1 33 14M 0B 0B 13136 5096</code></p>
<p>Below are the performance metrics for the endpoint:</p><p><strong>For Graal VM native binary:</strong></p>
<pre><code>$ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=========================================================] 100.00% 18s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      5308.20    1376.18    9776.58
  Latency       18.70ms    23.93ms   305.78ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    16.31MB/s%


$ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=============================================================================================] 100.00% 19s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      5164.61    1269.64   11265.72
  Latency       19.22ms    19.82ms   249.97ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    15.87MB/s%


$ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=============================================================================================] 100.00% 19s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      5041.83    1283.07   10297.43
  Latency       19.66ms    22.36ms   310.20ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    15.51MB/s%  

</code></pre>
<p>For Java application:</p>
<pre><code>$ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=============================================================================================] 100.00% 17s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      5629.80    1057.21   13696.04
  Latency       17.70ms     8.91ms   182.28ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    17.15MB/s%

  $ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=============================================================================================] 100.00% 14s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      7034.21     592.21   15347.18
  Latency       14.22ms     2.91ms    65.69ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    21.45MB/s%


  # rhasija ~/dev/projects/tmp/graal-micronaut on git:master x
$ bombardier -n 100000 -c 100 &quot;http://localhost:8080/simple&quot;
Bombarding http://localhost:8080/simple with 100000 request(s) using 100 connection(s)
 100000 / 100000 [=============================================================================================] 100.00% 14s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec      7060.21    2076.69   61322.98
  Latency       14.31ms     2.79ms    57.63ms
  HTTP codes:
    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    21.31MB/s%
</code></pre>
<p>The java application performed consistently better.</p>
<p><strong>Details</strong>:</p>
<pre><code>$ mvn -v
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T11:41:47-07:00)
Maven home: /Users/rhasija/.sdkman/candidates/maven/current
Java version: 1.8.0_202, vendor: Oracle Corporation, runtime: /Users/rhasija/.sdkman/candidates/java/1.0.0-rc-16-grl/jre
Default locale: en_US, platform encoding: UTF-8
OS name: &quot;mac os x&quot;, version: &quot;10.13.6&quot;, arch: &quot;x86_64&quot;, family: &quot;mac&quot;
</code></pre>
<p>To get more information on it I asked the GraalVM folks and Oleg Selajev got back with this information:</p>
<blockquote>
<p>native image does offer superior startup / memory overhead doesn't it? In general peak performance will benefit more from the powerful JIT compiler, so it's expected that running for a longer period of time or under a heavy load will perform better in the jvm mode.</p>
</blockquote>
<blockquote>
<p>also, if you use GraalVM Enterprise, you can provide <code>--pgo-instrument</code> to build an instrumented binary, and use a profile from that to build (with <code>--pgo</code>) a better performing native image.</p>
</blockquote>
<p>IMO:</p>
<p>I could be wrong but this is what I have learnt: GraalVM is awesome for quick start applications / lamdas that will do a job and be shutdown right after or for applications where performance is a non-issue. But for a long running applications that are supposed to be performant under load, java application (because of JIT compiler) are still better. This might change in future, but for now this seems to be the case.</p>
<p>Thoughts/feedback?</p>
]]></content:encoded></item><item><title><![CDATA[How to Micronaut with Kotlin and Java with Groovy tests]]></title><description><![CDATA[How to get an intermix of Kotlin and Java working together with Micronaut framework and Groovy / Spock as test code...]]></description><link>https://javawithravi.com/how-to-micronaut-with-kotlin-and-java-with-groovy-tests/</link><guid isPermaLink="false">5bd509d900324e5f26aaca87</guid><category><![CDATA[micronaut]]></category><category><![CDATA[kotlin]]></category><category><![CDATA[groovy]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Sun, 28 Oct 2018 07:15:22 GMT</pubDate><media:content url="https://javawithravi.com/content/images/2018/10/micronaut.png" medium="image"/><content:encoded><![CDATA[<img src="https://javawithravi.com/content/images/2018/10/micronaut.png" alt="How to Micronaut with Kotlin and Java with Groovy tests"><p>Recently, I came across <a href="http://micronaut.io">Micronaut</a> framework. It's a super light framework that fills the need for something in between <code>Spring Boot</code> and <code>Vert.x</code>.</p>
<p>I have been playing with it and wanted to see if I could get a simple project with micronaut framework, kotlin / java intermix for (main) source code and groovy/spock tests. Turns out it's not that difficult. I just had to fiddle with it a little bit to get it right. So to save you time, here it is:</p>
<p>My requirements were:<br>
. Source code in Kotlin and Java with circular dependency (just for fun)<br>
. Test code exclusively in Groovy<br>
. Maven based<br>
. Micronaut as the base framework wiring everything together.</p>
<p><code>mn create-app --features http-server --lang kotlin --build maven hello-world-example</code> provided a great starting point. Than it was a matter of adding <code>gmavenplus-plugin</code> and <code>maven-surefire-plugin</code>.</p>
<p>Here's the source code: <a href="https://github.com/RaviH/kotlin-java-groovy-micronaut">https://github.com/RaviH/kotlin-java-groovy-micronaut</a></p>
<p>If you would like to know more about how the plugins work with each other then read below. If not, feel free to dig around in the <a href="https://github.com/RaviH/kotlin-java-groovy-micronaut">code</a>.</p>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="generator" content="Asciidoctor 1.5.4">
  <title>Untitled</title>
  <link rel="stylesheet" href="https://asciidoclive.com/assets/asciidoctor.js/css/asciidoctor.css">
</head>

<body class="article">
  <div id="header">
  </div>
  <div id="content">
    <hr>
    <div class="olist arabic">
      <ol class="arabic">
        <li>
          <p>To make Kotlin, Java and Micronaut work together, you need <code>kotlin-maven-plugin</code>            and <code>maven-compiler-plugin</code> as shown below.</p>
        </li>
        <li>
          <p>Also, you need <code>gmavenplus-plugin</code> to compile groovy code.</p>
        </li>
        <li>
          <p>Finally, you need <code>maven-surefire-plugin</code> to execute test(s).</p>
        </li>
      </ol>
    </div>
    <hr>
    <div class="listingblock">
      <div class="title">pom.xml (<code>kotlin-maven-plugin</code> section responsible for kotlin, java
        and micronaut mix)</div>
      <div class="content">
        <pre class="highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
    &lt;groupId&gt;org.jetbrains.kotlin&lt;/groupId&gt;
    &lt;artifactId&gt;kotlin-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;${kotlinVersion}&lt;/version&gt;

    &lt;configuration&gt;
        &lt;compilerPlugins&gt;
            &lt;plugin&gt;all-open&lt;/plugin&gt;
        &lt;/compilerPlugins&gt;
        &lt;pluginOptions&gt;
            &lt;option&gt;all-open:annotation=io.micronaut.aop.Around&lt;/option&gt;
        &lt;/pluginOptions&gt;
    &lt;/configuration&gt;

    &lt;executions&gt;
        &lt;execution&gt;                                                     <b class="conum">(1)</b>
            &lt;id&gt;kapt&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;kapt&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;sourceDirs&gt;
                    &lt;sourceDir&gt;src/main/kotlin&lt;/sourceDir&gt;              <b class="conum">(2)</b>
                    &lt;sourceDir&gt;src/main/java&lt;/sourceDir&gt;                <b class="conum">(3)</b>
                &lt;/sourceDirs&gt;
                &lt;annotationProcessorPaths&gt;
                    &lt;annotationProcessorPath&gt;
                        &lt;groupId&gt;io.micronaut&lt;/groupId&gt;
                        &lt;artifactId&gt;micronaut-inject-java&lt;/artifactId&gt;
                        &lt;version&gt;${micronaut.version}&lt;/version&gt;
                    &lt;/annotationProcessorPath&gt;
                    &lt;annotationProcessorPath&gt;
                        &lt;groupId&gt;io.micronaut&lt;/groupId&gt;
                        &lt;artifactId&gt;micronaut-validation&lt;/artifactId&gt;
                        &lt;version&gt;${micronaut.version}&lt;/version&gt;
                    &lt;/annotationProcessorPath&gt;
                &lt;/annotationProcessorPaths&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;

        &lt;execution&gt;                                                     <b class="conum">(4)</b>
            &lt;id&gt;compile&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;compile&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;sourceDirs&gt;
                    &lt;sourceDir&gt;src/main/kotlin&lt;/sourceDir&gt;
                &lt;/sourceDirs&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;

        &lt;execution&gt;                                                     <b class="conum">(5)</b>
            &lt;id&gt;test-kapt&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;test-kapt&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;sourceDirs&gt;
                    &lt;sourceDir&gt;src/test/kotlin&lt;/sourceDir&gt;
                &lt;/sourceDirs&gt;
                &lt;annotationProcessorPaths&gt;
                    &lt;annotationProcessorPath&gt;
                        &lt;groupId&gt;io.micronaut&lt;/groupId&gt;
                        &lt;artifactId&gt;micronaut-inject-java&lt;/artifactId&gt;
                        &lt;version&gt;${micronaut.version}&lt;/version&gt;
                    &lt;/annotationProcessorPath&gt;
                    &lt;annotationProcessorPath&gt;
                        &lt;groupId&gt;io.micronaut&lt;/groupId&gt;
                        &lt;artifactId&gt;micronaut-validation&lt;/artifactId&gt;
                        &lt;version&gt;${micronaut.version}&lt;/version&gt;
                    &lt;/annotationProcessorPath&gt;
                &lt;/annotationProcessorPaths&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;

        &lt;execution&gt;
            &lt;id&gt;test-compile&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;test-compile&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;sourceDirs&gt;
                    &lt;sourceDir&gt;src/test/kotlin&lt;/sourceDir&gt;
                    &lt;sourceDir&gt;target/generated-sources/kapt/test&lt;/sourceDir&gt;
                &lt;/sourceDirs&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.jetbrains.kotlin&lt;/groupId&gt;
            &lt;artifactId&gt;kotlin-maven-allopen&lt;/artifactId&gt;
            &lt;version&gt;${kotlinVersion}&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/plugin&gt;

&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
    &lt;version&gt;3.7.0&lt;/version&gt;
    &lt;configuration&gt;
        &lt;proc&gt;none&lt;/proc&gt;
        &lt;source&gt;1.8&lt;/source&gt;
        &lt;target&gt;1.8&lt;/target&gt;
    &lt;/configuration&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;default-compile&lt;/id&gt;                                    <b class="conum">(6)</b>
            &lt;phase&gt;none&lt;/phase&gt;
        &lt;/execution&gt;
        &lt;execution&gt;
            &lt;id&gt;default-testCompile&lt;/id&gt;                                <b class="conum">(7)</b>
            &lt;phase&gt;none&lt;/phase&gt;
        &lt;/execution&gt;
        &lt;execution&gt;
            &lt;id&gt;java-compile&lt;/id&gt;
            &lt;phase&gt;compile&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;compile&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
        &lt;execution&gt;
            &lt;id&gt;java-test-compile&lt;/id&gt;
            &lt;phase&gt;test-compile&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;testCompile&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;</code></pre>
      </div>
    </div>
    <div class="colist arabic">
      <ol>
        <li>
          <p>Kapt compiler plugin provides support for annotation processors. <code>micronaut</code>            does it&#8217;s work at compile time. Hence, <code>kapt</code> plugin
            is necessary.</p>
        </li>
        <li>
          <p>Kotlin source location</p>
        </li>
        <li>
          <p>Java source location</p>
        </li>
        <li>
          <p>For compile goal provide <code>kotlin</code> source location</p>
        </li>
        <li>
          <p><code>test-kapt</code> is only necessary when writing tests in <code>kotlin</code>.</p>
        </li>
      </ol>
    </div>
    <hr>
    <div class="listingblock">
      <div class="title">pom.xml (<code>gmavenplus-plugin</code> section responsible for groovy test
        code compilation)</div>
      <div class="content">
        <pre class="highlight"><code class="language-xml" data-lang="xml">            &lt;plugin&gt;
                &lt;groupId&gt;org.codehaus.gmavenplus&lt;/groupId&gt;
                &lt;artifactId&gt;gmavenplus-plugin&lt;/artifactId&gt;
                &lt;version&gt;1.6.1&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;addTestSources&lt;/goal&gt;             <b class="conum">(1)</b>
                            &lt;goal&gt;compileTests&lt;/goal&gt;               <b class="conum">(2)</b>
                        &lt;/goals&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;</code></pre>
      </div>
    </div>
    <div class="colist arabic">
      <ol>
        <li>
          <p>Add test sources</p>
        </li>
        <li>
          <p>Compile tests.</p>
        </li>
      </ol>
    </div>
    <hr>
    <div class="listingblock">
      <div class="title">pom.xml (<code>maven-surefire-plugin</code> responsible for executing unit
        tests)</div>
      <div class="content">
        <pre class="highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.22.0&lt;/version&gt;
    &lt;configuration&gt;
        &lt;useFile&gt;false&lt;/useFile&gt;
        &lt;includes&gt;
            &lt;include&gt;**/*Spec.*&lt;/include&gt;                       <b class="conum">(1)</b>
            &lt;include&gt;**/*Test.*&lt;/include&gt;                       <b class="conum">(2)</b>
        &lt;/includes&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
      </div>
    </div>
    <div class="colist arabic">
      <ol>
        <li>
          <p>Execute any class that ends with <code>Spec</code> or</p>
        </li>
        <li>
          <p>Execute any class that ends with <code>Test</code></p>
        </li>
      </ol>
    </div>
  </div>
</body>

</html>]]></content:encoded></item><item><title><![CDATA[Performance comparison: Spring Boot +  Spring Data vs Micronaut + Gorm performance]]></title><description><![CDATA[Performance comparison between Spring Boot + Data vs Micronaut + Gorm starting with...]]></description><link>https://javawithravi.com/spring-data-jpa-vs-micronaut-gorm/</link><guid isPermaLink="false">5bcc0e1a00324e5f26aaca7a</guid><category><![CDATA[spring]]></category><category><![CDATA[micronaut]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Mon, 22 Oct 2018 13:26:12 GMT</pubDate><content:encoded><![CDATA[<p><strong>Update 10/23/2018 12:30 pm PDT</strong>:</p>
<p>With the latest release of <code>micronaut v1.0.0</code>, it matches <code>Spring</code> <strong>without</strong> any changes to <code>bombardier</code> i.e. it's keeping the connection alive by default now.</p>
<p>You can find the latest test output <a href="https://github.com/RaviH/spring-data-micronaut-gorm/blob/master/performance_run_output/bombardier-performance-results-micronaut-1.0-output.txt">here</a></p>
<p><strong>Summary:</strong></p>
<p><code>micronaut</code> with 1.0.0 release beats <code>Spring</code> in startup time and performs same or slightly better in run time with a very simplistic one database entity based test. I would expect <code>micronaut</code> to perform better with it's strategy of providing implementations at compile time vs Spring's run time. I will perform a test with more number of enitites and with GETs and PUTs and provide a link to that article here.</p>
<hr>
<p><strong>Update 10/23/2018 8:40 PDT</strong>:</p>
<p>With the <code>keep-alive</code> connection header while testing with <code>bombardier</code>, <code>micronaut</code> provides the same results as <code>Spring</code>. So the updated comparison table is:</p>
<table>
<thead>
<tr>
<th>Criteria</th>
<th style="text-align:center">Spring Data App</th>
<th style="text-align:right">Micronaut + GORM app</th>
<th style="text-align:right">Winner</th>
</tr>
</thead>
<tbody>
<tr>
<td>Start up time</td>
<td style="text-align:center">4 - 5 sec</td>
<td style="text-align:right">2.5 - 3.2 sec</td>
<td style="text-align:right">Micronaut</td>
</tr>
<tr>
<td>bombardier total time</td>
<td style="text-align:center">1  sec</td>
<td style="text-align:right">1 sec</td>
<td style="text-align:right">Equal</td>
</tr>
<tr>
<td>loadtest total time</td>
<td style="text-align:center">2.71 - 3.07 sec</td>
<td style="text-align:right">2.61 - 3.23 sec</td>
<td style="text-align:right">Undecided</td>
</tr>
<tr>
<td>ab total time</td>
<td style="text-align:center">14.51 - 21.94 sec</td>
<td style="text-align:right">12.28 - 19.16 sec</td>
<td style="text-align:right">Micronaut by slight margin</td>
</tr>
</tbody>
</table>
<p>You can find the result output for all of the run(s) here: <a href="https://github.com/RaviH/spring-data-micronaut-gorm/tree/master/performance_run_output">https://github.com/RaviH/spring-data-micronaut-gorm/tree/master/performance_run_output</a></p>
<p>If you are interested in latest run with bombardier with keep-alive that output is <a href="https://github.com/RaviH/spring-data-micronaut-gorm/blob/master/performance_run_output/bombardier-performance-results-micronaut-output-with-keep-alive.txt">here</a></p>
<p>All the result outputs are <a href="https://github.com/RaviH/spring-data-micronaut-gorm/tree/master/performance_run_output">here</a></p>
<hr>
<p><strong>Update 10/23/2018 7:38 PDT</strong>:</p>
<p>I have been working with <code>Micronaut</code>s team and they have quickly found the reason why  <code>bombardier</code> tests provide such different results. <code>bombardier</code> closes the connection after every request and hence the huge discrepancy in the result. To address this <code>Micronaut</code> <code>1.0.GA</code> would release with Http 1.1 default of keeping the connection open. I will be updating this article as soon as I can get hands on it. I will be updating the article pretty soon here with the results of provoding <code>Connection:keep-alive</code> header with <code>bombardier</code> on <code>Micronaut 1.0.0.RC3</code></p>
<hr>
<p>Recently, I came across <a href="http://micronaut.io/">Micronaut framework</a> and found it to be very interesting. It provides low memory footprint and fast bootup time. I have used Micronaut now for couple non-database backed applications and it starts up really fast and is performing really well. In my performance tests comparing Micronaut app to Spring app, Micronaut performed better (will be covered in a separate post).</p>
<p>The next step for me was to see if I could recommend Micronaut for database backed applications. Micronaut works with straight up hibernate and even provides GORM (a <code>Spring Data</code> alternative). I am already familiar with Spring Data so I am curious about GORM. I decided to give it a spin and see how it holds up compared to Spring Data app.</p>
<p>You can find my repository here: <code>https://github.com/RaviH/spring-data-micronaut-gorm</code></p>
<p><strong>Details about the test:</strong></p>
<p>a. This is a very basic application with a single domain object: <code>Person</code>.<br>
b. 3 records were inserted into an in-memory H2 database at startup time.<br>
c. Only <code>GET</code>s are tested<br>
d. I haven't tweaked any of the apps for better performance i.e. this is as out of the box as we can get.<br>
e. Spring Boot v2.0.6 is used Micronaut: 1.0.0.RC3 is used.<br>
f. OS: MacOS High Sierra, 16 GB RAM, 2.5 Ghz Intel Core I7<br>
g. <code>mvn</code> and <code>java</code> version:</p>
<pre><code>$ mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-03T12:39:06-07:00)
Maven home: /usr/local/Cellar/maven/3.5.0/libexec
Java version: 1.8.0_162, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: &quot;mac os x&quot;, version: &quot;10.13.6&quot;, arch: &quot;x86_64&quot;, family: &quot;mac&quot;
</code></pre>
<p>i. Used different tools (<a href="https://github.com/codesenberg/bombardier">bombardier</a>, <a href="https://httpd.apache.org/docs/2.4/programs/ab.html">ab</a>, <a href="https://www.npmjs.com/package/loadtest">loadtest</a> for performance tests since each one of them offers different results.</p>
<h4 id="results">Results</h4>
<p><strong>Tabular comparison</strong>: <code>Total time to complete requests = total time</code></p>
<table>
<thead>
<tr>
<th>Criteria</th>
<th style="text-align:center">Spring Data App</th>
<th style="text-align:right">Micronaut + GORM app</th>
<th style="text-align:right">Winner</th>
</tr>
</thead>
<tbody>
<tr>
<td>Start up time</td>
<td style="text-align:center">4 - 5 sec</td>
<td style="text-align:right">2.5 - 3.2 sec</td>
<td style="text-align:right">Micronaut</td>
</tr>
<tr>
<td>bombardier total time</td>
<td style="text-align:center">1  sec</td>
<td style="text-align:right">12 - 20 sec</td>
<td style="text-align:right">Spring by a big margin</td>
</tr>
<tr>
<td>loadtest total time</td>
<td style="text-align:center">2.71 - 3.07 sec</td>
<td style="text-align:right">2.61 - 3.23 sec</td>
<td style="text-align:right">Undecided</td>
</tr>
<tr>
<td>ab total time</td>
<td style="text-align:center">14.51 - 21.94 sec</td>
<td style="text-align:right">12.28 - 19.16 sec</td>
<td style="text-align:right">Micronaut by 2 slight margin</td>
</tr>
</tbody>
</table>
<p><strong>Summary</strong>:</p>
<ul>
<li>Micronaut has a much faster startup time than Spring.</li>
<li>With <code>bombardier</code>: Spring data app blows Micronaut app out of the water as far as throughput is concerned.</li>
<li>With <code>ab</code>: <code>micronaut</code> wins by a slight margin.</li>
<li>With <code>loadtest</code>: it's too small a difference to decide.</li>
</ul>
<p><strong>Next Steps</strong><br>
This is probably going to be an in progress article. I will add more information as I gain it.</p>
<p>a. Try a different load test tool.<br>
b. Try loading these applications on a container to take my machine out of the picture.<br>
c. Try a more real world scenario i.e. more entities and real relationships between them, <code>constraints</code> on domain classes.</p>
<p>Please feel free to share your thoughts/comments on the article. Try this out on your machine and feel free to share your results.</p>
<p>Just be nice ;-)</p>
<hr><p></p>]]></content:encoded></item><item><title><![CDATA[Multiple MySQL databases with one MySQL container]]></title><description><![CDATA[Multiple MySQL databases within one container using base mysql image.]]></description><link>https://javawithravi.com/multiple-mysql-databases-with-one-mysql-container/</link><guid isPermaLink="false">5ba88afb00324e5f26aaca5b</guid><category><![CDATA[mysql]]></category><category><![CDATA[docker]]></category><category><![CDATA[container]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Tue, 25 Sep 2018 23:44:17 GMT</pubDate><content:encoded><![CDATA[<p><mark>Problem statement:</mark></p>
<p>I want to create 2 databases inside one MySQL container and have the user of first database full access to 2nd database. With <a href="https://hub.docker.com/_/mysql/">official mysql image</a> one can easily create a database, and allow a user access to that database. But, creating a 2nd database is not easily provisioned.</p>
<hr><p><mark>Solution:</mark></p>
<p>Docker images work on the concept of layers. Each new command so to speak creates a new layer and here in lies our solution.</p>
<p>Simply create a SQL file with following commands:</p>
<pre data-line="2,4" class="language-sql line-numbers"><code>
# Create second_db database if it doesn't exist
CREATE DATABASE IF NOT EXISTS second_db;
# Grant all privilidges on second_db to org_user
GRANT ALL PRIVILEGES ON second_db.* TO 'org_user' identified by 'org_user_password';
</code>
</pre>
<p>Let's say you created a file called <code>create_second_db.sql</code> in your project folder (or wherever you really want it to be). Than you can mount this file into docker <code>/docker-entrypoint-initdb.d</code> folder. Files in this folder are loaded in alphabetical order at startup time under <code>root</code> user.</p>
<p>Below is the corresponding <em>Dockerfile</em> (that would mount the <code>create_second_db.sql</code> into the <code>/docker-entrypoint-initdb.d</code>) folder:</p>
<pre data-line="2,4" class="language-docker line-numbers"><code>
# Use base mysql image with tag 5.7
FROM mysql:5.7
# Copy our custom SQL file to /docker-entrypoint-initdb.d folder
COPY ./create_second_db.sql /docker-entrypoint-initdb.d/create_second_db.sql
</code>
</pre><p><strong>NOTE:</strong> You can mount as many SQL files as you would like into that folder.</p>
<p>Once you have created the image (via <code>docker build</code>), than when you start the container, that container would have 2 databases created.</p>
<p><mark>Build the image</mark></p>
<pre><code>docker build -t custom_mysql -f Dockerfile .&lt;/code&gt;
</code></pre>
<p><mark>Start the container:</mark></p>
<pre><code>docker run --name custom_mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-e MYSQL_USER=org_user \
-e MYSQL_PASSWORD=org_user_password \
-e MYSQL_DATABASE=first_db \
-d custom_mysql
</code></pre>
<p><mark>Result</mark>:</p>
<pre data-line="22,25" class="language-bash line-numbers"><code>
# rhasija ~/tmp/docker
$ docker exec -it 0fdbf85f6218 /bin/bash
root@0fdbf85f6218:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| first_db           |
| mysql              |
| performance_schema |
| second_db          |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql>
</code>
</pre><p>Notice <mark>first_db</mark> and <mark>second_db</mark> above.</p>
<p>Boom! Job done. Let's open champagne! ;-)</p>
<p>Comments / questions welcome!</p>
<p><a href="https://dzone.com/articles/multiple-mysql-databases-with-one-mysql-container">Link to this article published on DZone</a></p>
]]></content:encoded></item><item><title><![CDATA[Spring Generic Type Factory]]></title><description><![CDATA[How to create generic factory using Spring and it's ability to consider generics as a form of @Qualifier.]]></description><link>https://javawithravi.com/spring-generic-type-factory/</link><guid isPermaLink="false">5ba818a400324e5f26aaca58</guid><category><![CDATA[spring]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Mon, 24 Sep 2018 01:06:21 GMT</pubDate><media:content url="https://javawithravi.com/content/images/2018/09/spring4d.png" medium="image"/><content:encoded><![CDATA[<img src="https://javawithravi.com/content/images/2018/09/spring4d.png" alt="Spring Generic Type Factory"><p><strong>Problem statement</strong>:</p>
<p>I want to be able to create multiple objects of generic type without having to create each instance by hand and wire it in via <code>@Bean</code>.</p>
<p><strong>For example:</strong>  In the code below, I am trying to create <code>DefaultRedisClient</code> and <code>CacheReadService</code> for 2 different class types: <code>Person</code> and <code>Blog</code>. That's just an example. In reality, there could be 10's of classes/objects I would like to read from cache and for each one of those I am duplicating the code with slight modifications.</p>
<p>To create this block of code, again and again with only the <code>CacheKey</code> and <code>CacheValue</code> type changing along with couple other things seems <em>wrong</em>.</p>
<pre data-line="1,6,15,19,21,34" class="language-groovy line-numbers"><code>
@Configuration
public class RedisCacheReadServiceConfig  {

    @Bean
    public DefaultRedisClient< PersonCacheValue > personRedisClient(
            @Autowired @Lazy
            RedisTemplate< String, String > redisTemplate) {

        return new DefaultRedisClient<>(redisTemplate, PERSON.getName());
    }

    @Bean
    public CacheReadService< PersonCacheKey, PersonCacheValue > personCacheReadServiceRedisImpl(
            @Lazy @Autowired 
            DefaultRedisClient< PersonCacheValue > personRedisClient,
            @Lazy @Autowired 
            PersonCacheFallback personCacheFallback,
            @Lazy @Autowired 
            RedisClientFactory< PersonCacheValue > redisClientFactory) {

        return new DefaultCacheReadService<>(personRedisClient, PERSON, personCacheFallback);
    }

    @Bean
    public DefaultRedisClient< BlogCacheValue > blogRedisClient(
            @Autowired @Lazy 
            RedisTemplate< String, String > redisTemplate) {

        return new DefaultRedisClient<>(redisTemplate, BLOG.getName());
    }

    @Bean
    public CacheReadService< 
            BlogCacheKey,
            BlogCacheValue > blogCacheReadServiceRedisImpl(
            @Lazy @Autowired 
            DefaultRedisClient< BlogCacheValue > blogRedisClient,
            @Lazy @Autowired 
            BlogCacheFallback blogCacheFallback,
            @Lazy @Autowired 
            RedisClientFactory< BlogCacheValue > redisClientFactory) {

        return new DefaultCacheReadService<>(blogRedisClient, BLOG, blogCacheFallback);
    }
}
</code>
</pre><hr><p><strong>Solution</strong>:</p>
<p>Fact of the matter is that there's a better way. Since <code>Spring 4.0</code>, <mark>Spring will automatically consider generics as a form of <code>@Qualifier</code></mark>. And because of that we can have a factory pattern that uses generic types as <code>@Qualifier</code>. Please consider the example below:</p>
<pre data-line="7,19" class="language-groovy line-numbers"><code>/**
 * A factory that generates / provides DefaultRedisClient < V >
 * 
 * @param <v> CacheValue type
 */
@Service
public class RedisClientFactory< V extends CacheValue > {

    private final RedisTemplate< String, String > redisTemplate;

    @Autowired
    public RedisClientFactory(@Lazy RedisTemplate< String, String > redisTemplate) {

        this.redisTemplate = redisTemplate;
    }

    public DefaultRedisClient< V > getRedisClient(final String domainName) {

        return new DefaultRedisClient<>(redisTemplate, domainName);
    }
}
</v></code>
</pre><p>With the <code>RedisClientFactory</code> above, our main config becomes <em>simpler</em> because instead of creating <code>DefaultRedisClient</code> beans for different <code>CacheValue</code> types, we have delegated that work to <code>RedisClientFactory</code> and now can simply autowire <code>DefaultRedisClient&lt;V&gt;</code> by specifying the generic class type <code>V</code>. <mark>See line number 7 and 19 below</mark>. Spring is injecting a generic <code>RedisClientFactory</code> of the given type. Once we have that we can simply call the <code>getRedisClient</code> method to create the <code>RedisClient</code> we want.</p>
<pre data-line="7,9,15,19" class="language-groovy line-numbers"><code>@Configuration
public class RedisCacheReadServiceConfig  {

    @Bean
    public CacheReadService< PersonCacheKey, PersonCacheValue > personCacheReadServiceRedisImpl(
            @Lazy @Autowired 
            PersonCacheFallback personCacheFallback,
            @Lazy @Autowired 
            RedisClientFactory< PersonCacheValue > redisClientFactory) {

        return new DefaultCacheReadService<>(redisClientFactory.getRedisClient(PERSON.getName()), BLOG, personCacheFallback);
    }

    @Bean
    public CacheReadService < BlogCacheKey, BlogCacheValue > blogCacheReadServiceRedisImpl(
            @Lazy @Autowired 
            BlogCacheFallback blogCacheFallback,
            @Lazy @Autowired 
            RedisClientFactory< BlogCacheValue > redisClientFactory) {

        return new DefaultCacheReadService<>(redisClientFactory.getRedisClient(BLOG.getName()), BLOG, blogCacheFallback);
    }
}
</code>
</pre><hr><p>But, we can go one step further and create a factory class to create <code>CacheReadService</code> for different <code>CacheKey</code> and <code>CacheValue</code>. See below:</p>
<p>Line #:</p>
<p>9  : We are injecting generic <code>RedisClientFactory&lt;V&gt;</code><br>
19 : We use generic <code>RedisClientFactory&lt;V&gt;</code> to create a generic <code>DefaultRedisClient&lt;V&gt;</code><br>
20 : This is pretty straight forward creation of <code>CacheReadService&lt;K,V&gt;</code></p>
<pre data-line="9,19-20" class="language-groovy line-numbers"><code>
@Service
public class CacheReadServiceFactory< K extends CacheKey, V extends CacheValue > {

  private final RedisClientFactory<v> redisClientFactory;
  private final CacheFallback<k, v=""> cacheFallback;

  @Autowired
  public CacheReadServiceFactory(
    @Lazy RedisClientFactory< V > redisClientFactory,
    @Lazy final CacheFallback< K, V > cacheFallback) {

    this.redisClientFactory = redisClientFactory;
    this.cacheFallback = cacheFallback;
  }

  public CacheReadService< K, V > getCacheReadService(
    final CacheDomainType cacheDomainType) {

    final DefaultRedisClient< V > redisClient = redisClientFactory.getRedisClient(cacheDomainType.getName());
    return new DefaultCacheReadService<>(redisClient, cacheDomainType, cacheFallback);
  }
}
</k,></v></code>
</pre><p>Now, because of the <code>CacheReadServiceFactory</code> (above) our configuration class (below) becomes super simple because of <code>Spring</code> and being able to use generics for autowiring (since <code>Spring 4.x</code>).</p>
<p><mark>Final Solution:</mark></p>
<pre data-line="9-10,18-19" class="language-groovy line-numbers"><code>

/**
 * Final Config class
 */
@Configuration
public class RedisCacheReadServiceConfig {

  @Bean
  public personCacheReadService(
    @Lazy @Autowired 
    final CacheReadServiceFactory< PersonCacheKey, PersonCacheValue > cacheReadServiceFactory
  ) {

    return cacheReadServiceFactory.getCacheReadService(PERSON);
  }

  @Bean
  public blogCacheReadService(
    @Lazy @Autowired 
    final CacheReadServiceFactory< BlogCacheKey, BlogCacheValue > cacheReadServiceFactory
  ) {

    return cacheReadServiceFactory.getCacheReadService(BLOG);
  }
}
</code>
</pre><p>Question / comments welcome. <mark>Just be nice. ;-)</mark></p>
<p>Link to the article published on DZone: <a href="https://dzone.com/articles/spring-generic-factory-1">https://dzone.com/articles/spring-generic-factory-1</a></p>
<hr><p>References:</p>
<p>1: <a href="https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics">https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics</a></p>
]]></content:encoded></item><item><title><![CDATA[Wiremock and Response Transformer]]></title><description><![CDATA[Wiremock's ResponseTransformer and how to use it to modify responses plus how to hook it into your tests.]]></description><link>https://javawithravi.com/wiremock-and-response-transformer/</link><guid isPermaLink="false">5ba5e923f4d94807c6335505</guid><category><![CDATA[wiremock]]></category><category><![CDATA[responsetransformer]]></category><category><![CDATA[response transformer]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Tue, 31 Oct 2017 20:05:15 GMT</pubDate><content:encoded><![CDATA[<p>I wanted to test a scenario where:</p>
<ul>
<li>For the first <code>x</code> calls respond with <code>y</code></li>
<li>Then for <code>x+1</code> respond with <code>z</code></li>
</ul>
<p>Wiremock by itself doesn't provide a direct way to to stub different responses akin to Mockito's <code>thenReturn</code> or <code>Spock's</code> multiple stubs. Wiremock however provides a <code>ResponseTransformer</code>. I used Wiremock's <code>ResponseTransformer</code> to store state, and return <code>y</code> by default but return <code>z</code> on <code>x+1</code> try.</p>
<pre data-line="1,8,11-12,23,34,40" class="language-groovy line-numbers"><code>  static class SuccessfulAtLastTransformer extends ` {

        int count = 1

        SuccessfulAtLastTransformer() {}

        @Override
        ResponseDefinition transform(
                final Request request, final ResponseDefinition responseDefinition, final FileSource fileSource) {

            if (request.getUrl().contains("/customer/cust1234")) {
                if (count == 3) {
                    def responseJson = new JsonSlurper().parseText(responseDefinition.body)
                    // Set the customerId on the final try
                    responseJson.customerCar = "toyota"
                    def newRequestBody = JsonOutput.toJson(responseJson)
                    return new ResponseDefinitionBuilder()
                            .withStatus(200)
                            .withBody(newRequestBody)
                            .build()
                }

                return new ResponseDefinitionBuilder()
                        .withHeader("COUNT", count++ as String)
                        .withStatus(200)
                        .withBody(responseDefinition.body)
                        .build()
            }

            return responseDefinition
        }

        @Override
        boolean applyGlobally() {
            return false
        }

        @Override
        String name() {
            return "SuccessfulAtLastTransformer"
        }
    }
</code>
</pre>
<p>Line #1: extend <code>import com.github.tomakehurst.wiremock.extension.ResponseTransformer</code></p>
<p>Line #8: override the <code>transform</code> function.</p>
<p>Line #11: Check if this is the api you are interested in.</p>
<p>Line #12: Check if the count has reached a certain threshold and if so, then add <code>customerCar</code> property to response JSON</p>
<p>Line #23: Add <code>count</code> to the response header. That acts as our state storage. Once the count will reach <code>x</code> in this case 3, then change the response (line #13).</p>
<p>Line #34: Set apply globally false i.e. don't use this <code>ResponseTransformer</code> as an interceptor anywhere else but where I put it.</p>
<p>Line #40: Give your transformer a name.</p>
<p>Once you have defined a <code>ResponseTransformer</code> like above, you can then attach it to wiremock instance like so:</p>
<pre class="language-groovy line-numbers"><code>@Shared
def customerServiceMock = 
      wireMockConfig()
     .port(8090)
     .extensions(SuccessfulAtLastTransformer)
</code></pre>
<p>Done.</p>
<p>Please let me know if you have any questions or if there's a better way to do the same thing in wiremock via comments on this post.</p>
]]></content:encoded></item><item><title><![CDATA[Kotlin generic extension functions]]></title><description><![CDATA[How to implement generic extension function in Kotlin]]></description><link>https://javawithravi.com/kotlin-generic-extension-functions/</link><guid isPermaLink="false">5ba5e923f4d94807c6335504</guid><category><![CDATA[kotlin]]></category><category><![CDATA[generics]]></category><category><![CDATA[extension functions]]></category><category><![CDATA[extension function]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Fri, 29 Sep 2017 15:46:55 GMT</pubDate><content:encoded><![CDATA[<p>I have been educating myself in Kotlin recently. One of the most powerful feature that Kotlin provides is: <code>Extension Functions</code>. The simplest of example of a <em>Extension Function</em> that I can come up with is:</p>
<p><code>fun String.addOne() = this + &quot;1&quot;</code></p>
<p>And then:<br>
<code>println(&quot;Boba&quot;.addOne())</code> leads to an output of: <code>Boba1</code></p>
<p>So above we have added a new function to <code>String</code> class.</p>
<h6 id="genericextensionfunctions">Generic Extension Functions</h6>
<p>With the basic introduction out of the way, I wanted to write a Generic extension function. We use Netflix OSS at work and are constantly getting property values via code that looks like this:</p>
<p><code>DynamicPropertyFactory.getInstance().getStringProperty(&quot;SOME_CONFIG_PROP_NAME&quot;, &quot;I am a good default value&quot;).get()</code></p>
<p>Basically, above code allows us to fetch (dynamically) values of a property: <code>SOME_CONFIG_PROP_NAME</code> in this example, and provide default value <code>I am a good default value</code> in this case.</p>
<p>We have several variations of this, for example:</p>
<p><code>DynamicPropertyFactory.getInstance().getIntProperty</code><br>
<code>DynamicPropertyFactory.getInstance().getFloatProperty</code><br>
<code>DynamicPropertyFactory.getInstance().getDoubleProperty</code><br>
<code>DynamicPropertyFactory.getInstance().getLongProperty</code><br>
<code>DynamicPropertyFactory.getInstance().getBooleanProperty</code></p>
<p>So on and so forth. I wanted to have a generic extension function available on <code>String</code> class because property names are always <code>String</code> type. Here's the generic function:</p>
<pre class="language-kotlin line-numbers">
<code>
fun <t> String.getConfig(default: T): T {
    val dynamicPropertyFactory = DynamicPropertyFactory.getInstance()
    return when (default) {
        is String  -> dynamicPropertyFactory.getStringProperty(this, default).get()
        is Int     -> dynamicPropertyFactory.getIntProperty(this, default).get()
        is Float   -> dynamicPropertyFactory.getFloatProperty(this, default).get()
        is Double  -> dynamicPropertyFactory.getDoubleProperty(this, default).get()
        is Boolean -> dynamicPropertyFactory.getBooleanProperty(this, default).get()
        is Long    -> dynamicPropertyFactory.getLongProperty(this, default).get()
        else       -> default
    } as T
}
</t></code>
</pre>
<p>Kotlin would know based on the input param what &quot;type&quot; it is. And we can use that power to use the <code>when</code> expression along with <code>is</code> to check what type it is and call appropriate function based on the type of default value.</p>
<p>So now our code can become as simple as:</p>
<p><code>&quot;SOME_CONFIG_PROP_NAME&quot;.getConfig(&quot;I am a good default value&quot;)</code></p>
<p><code>&quot;CallExternalService&quot;.getConfig(false)</code></p>
<p>Boom. Done.</p>
]]></content:encoded></item><item><title><![CDATA[Groovy Unmarshalling Json to a specific Object]]></title><description><![CDATA[<p>If you have a simple POJO (Plain Old Java Object) or POGO (Plain Old Groovy Object), you can use Groovy's default Map based constructor to convert the JSON string to an Object type.</p>
<pre class="language-groovy line-numbers">
<code>
package com.example.groovy

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.transform.ToString

/**
 * Created</code></pre>]]></description><link>https://javawithravi.com/groovy-unmarshalling-json-to-a-specific-object/</link><guid isPermaLink="false">5ba5e923f4d94807c6335503</guid><category><![CDATA[groovy]]></category><category><![CDATA[json]]></category><category><![CDATA[marshalling]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Fri, 15 Jan 2016 22:20:34 GMT</pubDate><content:encoded><![CDATA[<p>If you have a simple POJO (Plain Old Java Object) or POGO (Plain Old Groovy Object), you can use Groovy's default Map based constructor to convert the JSON string to an Object type.</p>
<pre class="language-groovy line-numbers">
<code>
package com.example.groovy

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.transform.ToString

/**
 * Created by rhasija on 1/15/16.
 */
class JsonToObject {

    public static void main(String[] args) {
        // Person object
        def person = new Person(firstName: "John", lastName: "Doe")
        // Json String
        def personJSON = new JsonBuilder(person).toPrettyString()
        // Json String to Map
        def personMap = new JsonSlurper().parseText(personJSON)
        // using Map to convert to Person object type
        def newPerson = new Person(personMap)

        println(person)
        println(newPerson)

        assert newPerson.firstName.equals(person.firstName)
        assert newPerson.lastName.equals(person.lastName)
    }
}

@ToString
class Person {
    String firstName
    String lastName
}</code></pre>
<p>Please let me know if you found this helpful. Thanks!</p>
]]></content:encoded></item><item><title><![CDATA[SSH Tunnel to connect to Remote Mongodb]]></title><description><![CDATA[Using ssh tunnel to connect to a private network mongodb server. Use Robomongo then to connect to locahost:<port>]]></description><link>https://javawithravi.com/ssh-tunnel-to-remote-mongodb/</link><guid isPermaLink="false">5ba5e923f4d94807c6335500</guid><category><![CDATA[remote]]></category><category><![CDATA[mongodb]]></category><category><![CDATA[robomongo]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Thu, 14 Jan 2016 23:50:05 GMT</pubDate><content:encoded><![CDATA[<h6 id="problem">Problem:</h6>
<p>I love to use RoboMongo<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> as the Mongo DB Query tool. In my case the problem is that the MongoDb server is on a private network and the only way to get to the private server from my machine is via ssh. Which means logging into the box, using <code>mongo</code> command to connect to the database and then issue my queries. Of course manually typing in my queries on a command line isn't my favorite thing to do. Being able to use <code>RoboMongo</code> is a major productivity boost and I want to be able to use it to connect to remote DB.</p>
<h6 id="solution">Solution:</h6>
<p>Enter <em>SSH tunnel.</em></p>
<p>Issue the following command on your terminal (I am using Mac hence a UNIX based system):</p>
<blockquote>
<p><code>ssh -fN -i ~/.ssh/YourKeyFile.pem -L 6666:localhost:27017 userId@1.2.3.4</code></p>
</blockquote>
<p>The command above is setting up: traffic on your local machine's <code>6666</code> port to be forwarded to remote server's localhost:27017. The <code>userId</code> is the <code>userId</code> you use to login to remote box. And <code>1.2.3.4</code> is remote server's ip address. The <code>-i</code> parameter allows you to connect using a <code>.pem</code> file i.e. a password-less connection.</p>
<p>Please make sure not to use low port numbers (lower than 1024) as local machine's port, since you won’t be able to bind them without root privileges.</p>
<p>Once you have the SSH tunnel set you can connect via <code>RoboMongo</code> on <code>localhost:6666</code>.</p>
<p>Any traffic will be diverted to <code>1.2.3.4</code> then to <code>localhost:27017</code>.</p>
<p>Hope you found this useful. Please let me know if you have any questions/comments/feedback.</p>
<h6 id="references">References:</h6>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="http://www.litixsoft.de/english/connect-remote-db-using-ssh-mongo-management-studio-community-edition/">http://www.litixsoft.de/english/connect-remote-db-using-ssh-mongo-management-studio-community-edition/</a> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[REST API Integration Testing with Wiremock]]></title><description><![CDATA[Wiremock allows you to provide stubbed responses for any http/restful call. It's a pretty expansive and flexible library and allows you to mock external services for integration testing.]]></description><link>https://javawithravi.com/rest-api-integration-testing-with-wiremock/</link><guid isPermaLink="false">5ba5e923f4d94807c6335502</guid><category><![CDATA[junit]]></category><category><![CDATA[spock]]></category><category><![CDATA[wiremock]]></category><category><![CDATA[integration test]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Thu, 14 Jan 2016 23:12:22 GMT</pubDate><content:encoded><![CDATA[<p>Lets say you have a service (customer-service) that calls another service (account-service) over HTTP, gets the response from account-service, does some munging with the data and returns it back to the UI.</p>
<p>Now like a good developer, you are trying to test customer-service to verify that it is adhering to the requirements contract. How do you test the service such that it goes through the system flow, makes the necessary calls to account service and returns responses?</p>
<p>Assuming that the account-service is configured to be available at <code>http://localhost:8090</code>, we can configure Wiremock <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup> to intercept all calls going to localhost:8090 and return stubbed responses.</p>
<p>Here's a sample Integration Test:</p>
<pre class="language-groovy line-numbers"><code>    WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8090))
    WireMock wireMock = new WireMock("localhost", 8090)
    def baseUrl = 'http://localhost:8889/customerservice/v1/customerInfo'

    def setup() {
        wireMockServer.start()
    }

    def cleanup() {
        wireMockServer.stop()
    }

    def "get customer info"() {
        given:
        wireMock.register(get(urlPathEqualTo( "/accountservice/v1/account/account1234"))
                .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/json")
                .withBody(JSON_RESPONSE_DATA))
        )

        def http = new HTTPBuilder(baseUrl)
        def headers = ['Accept': 'application/json', 'Content-Type': 'application/json', 'X-FORWARDED-FOR': '1.2.3.4']
        def requestBody = '{"customerNumber":"cust1234","ZipCode":"12345"}'

        http.handler.failure = http.handler.success

        when:
        def response = http.post(contentType: ContentType.JSON, headers: headers, body: requestBody)

        then:
        wireMock.verifyThat(new RequestPatternBuilder(RequestMethod.GET, urlPathEqualTo("/accountservice/v1/account/account1234")))
        response
        !response.errors
    }
</code></pre>
<p>Line: 1-2 are setting up Wiremock server to respond to http requests to <code>http://localhost:8090</code> (account-service in this case)</p>
<p>Line 5: Starts the wiremock proxy server before each test.</p>
<p>Line 9: Stops the wiremock proxy server after each test.</p>
<p>Line 14: Stubs the wiremock for a GET call for path matching <code>/accountservice/v1/account/account1234</code></p>
<p>Line 15-19: Will return a 200 response with response body defined as a String in <code>JSON_RESPONSE_DATA</code></p>
<p>Line 29: Calls the actual service via HTTP Post based on the <code>baseUrl</code> defined on line 3 with <code>headers</code> and <code>request body</code> defined on line 22 and 24.</p>
<p>Line 32: Verifies that the wiremock call was actually called.</p>
<p>Line 34-35: Verify that there was a valid response and response had no error.</p>
<p><strong>Note:</strong><br>
The test code is written in Groovy and is using Spock<sup class="footnote-ref"><a href="#fn1" id="fnref1:2">[1:2]</a></sup> test framework but you can also use Java along with JUnit as the test framework.</p>
<p>To add the wiremock library to your code (via pom.xml)</p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;com.github.tomakehurst&lt;/groupId&gt;
    &lt;artifactId&gt;wiremock&lt;/artifactId&gt;
    &lt;version&gt;1.57&lt;/version&gt;

    &lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
            &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
        &lt;/exclusion&gt;
    &lt;/exclusions&gt;
&lt;/dependency&gt;   
</code></pre>
<hr>
<p><strong>In summary:</strong></p>
<p>You can mock any external http/RESTful service based on the host and port you expect it at. Just configure Wiremock server to listen to that host and port, and start the wiremock server. Wiremock then would intercept all the calls that are made to that host and port.</p>
<p><strong>Advantages:</strong></p>
<p>a. Mock external services based on the contracts they provide.<br>
b. Verify marshaling and un-marshaling of JSON/XML data to their respective objects.<br>
c. Test your service end-points as if they are being called via external HTTP calls and verify parameter naming and marshaling to request object.<br>
d. Verify contracts provided by your service (and other external services).</p>
<p>That's it. Thank you for reading. Please let me know if you have any thoughts/questions/feedback via comments below.</p>
<h6 id="references">References:</h6>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><a href="https://code.google.com/p/spock/wiki/SpockBasics">Spock Test Framework</a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a> <a href="#fnref1:2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Resolve PKIX path building failed]]></title><description><![CDATA[Resolution for ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification]]></description><link>https://javawithravi.com/resolve-pkix-path-building-failed/</link><guid isPermaLink="false">5ba5e923f4d94807c63354ff</guid><category><![CDATA[PKIX]]></category><category><![CDATA[PKIX path building failed]]></category><category><![CDATA[InstallCert]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Sun, 20 Dec 2015 22:45:12 GMT</pubDate><content:encoded><![CDATA[<h6 id="problem">Problem:</h6>
<p>I was trying to get spring-cloud-server started on my laptop and I was getting:</p>
<pre><code>Downloaded: http://repo.spring.io/libs-snapshot/org/codehaus/mojo/maven-metadata.xml (21 KB at 16.6 KB/sec)
[WARNING] Could not transfer metadata org.apache.maven.plugins/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[WARNING] Could not transfer metadata org.codehaus.mojo/maven-metadata.xml from/to central (https://repo.maven.apache.org/maven2): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
</code></pre>
<h6 id="cause">Cause:</h6>
<p>The issue is I don't have a valid certificate for <a href="http://repo.spring.io">http://repo.spring.io</a>.</p>
<h6 id="solution">Solution:</h6>
<p><strong>Step 1</strong>: Get the certificate from the location. In this case it is: <a href="http://repo.spring.io">http://repo.spring.io</a>.</p>
<p>Here's how:</p>
<p>I used Firefox to browse to the link. On the top left there is a lock icon. Click on it &gt; Click on the <em>right arrow</em> to get to information &gt; Click on <em>More Information</em> &gt; Click on View Certificate &gt; Click on Details &gt; Click on Export and save the certificate on your drive as a file say: Certificate.cer.</p>
<p>** It's important you chose <strong>X.509 Certificate (PEM)</strong> as the type.</p>
<p><strong>Step 2</strong>: Now that you have downloaded the certificate, you need to install the certificate on your machine.</p>
<p>On my machine I did this:</p>
<p><code>keytool -import -file ~/Downloads/Certificate.cer -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/jre/lib/security/cacerts -alias &lt;your_custom_alias_name&gt;</code></p>
<p>Of course the location of your java's cacerts might be different. To find out the location of <strong>cacerts</strong> directory, do:</p>
<p><code>echo $JAVA_HOME</code></p>
<p>In my case the output of <code>echo $JAVA_HOME</code> was: <code>/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home</code>. Then I just looked for cacerts directory in it and found it to be at: <code>jre/lib/security/cacerts</code></p>
<h6 id="note">Note:</h6>
<ul>
<li><code>-alias foo_bar</code> is important so that you don't override default alias which goes to <code>my_key</code>. Of course <code>foo_bar</code> is an example and <strong>not</strong> a good alias name. You should use a more descriptive alias name than <code>foo_bar</code> ;-)</li>
<li>If you dont't want to install a certificate you can also do below:</li>
</ul>
<p><code>export MAVEN_OPTS=&quot;$MAVEN_OPTS -Djavax.net.ssl.trustStore=/Users/rhasija/Downloads/Certificate.cer&quot;</code></p>
<p>This will solve the problem for maven but not necessarily for java.</p>
<h6 id="summary">Summary</h6>
<p>The problem was java was missing the certificate from a specific website, in my case, <a href="http://repo.spring.io">http://repo.spring.io</a>. So I got the certificate file using Step 1 and then imported the certificate in my machine's java cacerts using <code>keytool</code> as show in Step 2.</p>
<p>Hope you found this information helpful. Please let me know if you have any questions.</p>
<h6 id="references">References:</h6>
]]></content:encoded></item><item><title><![CDATA[Know your Mongo through Replica Set Oplog and System Profile]]></title><description><![CDATA[MongoDB provides Oplog and System Profile; two of many tools that are very easy to use and help you debug queries, operations; help you see what's going on in your MongoDB. ]]></description><link>https://javawithravi.com/know-your-mongo/</link><guid isPermaLink="false">5ba5e923f4d94807c63354f9</guid><category><![CDATA[Mongo]]></category><category><![CDATA[Troubleshoot]]></category><category><![CDATA[Log]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Thu, 05 Feb 2015 18:55:48 GMT</pubDate><content:encoded><![CDATA[<p>At work, recently we noticed that records in a Mongo collection did not have the latest data. Specifically, I was storing the status as <code>NEW -&gt; PROCESSING -&gt; OK</code>, and then expecting to see status of <strong>OK</strong>, since that was the latest update, but we were seeing <strong>PROCESSING</strong> instead of <strong>OK</strong>. We checked the logs of the Java application and it was sending <strong>NEW -&gt; PROCESSING -&gt; OK</strong>. So based on the application logs we new we should see <code>OK</code> status but we were seeing <code>PROCESSING</code>.</p>
<p>We wanted to see what Mongo was getting. There are a couple ways to do it:</p>
<h5 id="1mongooplog">1. Mongo Oplog</h5>
<p>To quote Mongo documentation on Oplog<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>:</p>
<blockquote>
<p>The oplog (operations log) is a special capped collection that keeps a rolling record of all operations that modify the data stored in your databases. MongoDB applies database operations on the primary and then records the operations on the primary’s oplog. The secondary members then copy and apply these operations in an asynchronous process. All replica set members contain a copy of the oplog, in the local.oplog.rs collection, which allows them to maintain the current state of the database.</p>
</blockquote>
<p>So here's how we can use it:</p>
<pre><code>use local
db.oplog.rs.find();
</code></pre>
<p>This will return you all the records in the op log collection of the format:</p>
<pre class="language-javascript line-numbers"><code>/* 0 */
{
    "ts" : Timestamp(1422739093, 110),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.480Z")
    }
}

/* 1 */
{
    "ts" : Timestamp(1422739093, 110),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicVideos",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man Video",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.480Z")
    }
}</code></pre>
<p>Notice: They are returning operations on different collections since we have not restricted the query to a particular collection.</p>
<p>Here's what the fields mean:</p>
<ul>
<li><strong>ts</strong>: the time this operation occurred.</li>
<li><strong>h</strong>: a unique ID for this operation. Each operation will have a different value in this field.</li>
<li><strong>op</strong>: the write operation that should be applied to the slave. n indicates a * no-op, this is just an informational message.</li>
<li><strong>ns</strong>: the database and collection affected by this operation. Since this is a no-op, this field is left blank.</li>
<li><strong>o</strong>: the actual document representing the op. Since this is a no-op, this field is pretty useless.</li>
</ul>
<p>If you want to check the recent operations on a particular collection you can:</p>
<pre><code>db.oplog.rs.find({ns: 'Comic.ComicBooks'}).sort({ ts : -1 });
</code></pre>
<p>In <code>Comic.ComicBooks</code>: <code>Comic</code> is the database name and <code>ComicBooks</code> is the collection name.</p>
<pre class="language-javascript line-numbers"><code>/* 0 */
{
    "ts" : Timestamp(1422739093, 110),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man",
        "status: "NEW",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.480Z")
    }
}

/* 1 */
{
    "ts" : Timestamp(1422739093, 110),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Superman",
        "status: "NEW",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.480Z")
    }
}</code></pre>
<p>If you want to query for a certain record you can get all the logs for it by:</p>
<p><code>db.oplog.rs.find({ns: 'Comic.ComicBooks', 'o._id': ObjectId(&quot;54d3977de4b0ad9775570661&quot;)}).sort({ ts : -1 });</code></p>
<p>Here we are querying for <code>ComicBooks</code> collection in <code>Comic</code> db, for <code>id</code>: 54d3977de4b0ad9775570661</p>
<p>And when I did so for the problem at hand I got the response below:</p>
<pre class="language-javascript line-numbers"><code>/* 0 */
{
    "ts" : Timestamp(1422739093, 110),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man",
        "status": "PROCESSING",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.480Z")
    }
}

/* 1 */
{
    "ts" : Timestamp(1422739093, 108),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man",
        "status": "OK",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.580Z")
    }
}

/* 2 */
{
    "ts" : Timestamp(1422738003, 107),
    "h" : NumberLong(-5537608931132355814),
    "op" : "u",
    "ns" : "Comic.ComicBooks",
    "o2" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01")
    },
    "o" : {
        "_id" : ObjectId("54caab29368a16b1f1a00c01"),
        "_class" : "com.rackspace.automation.support.mongo.AgentFile",
        "name" : "Spider Man",
        "status": "NEW",
        "lastUpdated" : ISODate("2015-01-31T21:18:13.180Z")
    }
}</code></pre>
<p>The query sorts the records in descending order of time. So Mongo saw: NEW -&gt;  OK -&gt; PROCESSING but if you notice the <code>lastUpdated</code> field you will notice that the Java application updated the object/entity in NEW -&gt; PROCESSING -&gt; OK sequence. So it seems like something is going wrong in Spring Data or MongoDB Java driver.</p>
<p>Another way to get research issues with operations is <code>System Profile</code>.</p>
<h5 id="2mongosystemprofile">2. Mongo System Profile</h5>
<p>MongoDb provides system profiling<sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup> that allows you to profile database queries, operations etc. This can help identify inefficient queries and operations.</p>
<p>You can run the profile command on a particular database:</p>
<pre><code>use Comic
db.setProfilingLevel(2)
// Perform whatever operation you want to debug
db.system.profile.find();
</code></pre>
<p>Sample output:<pre class="language-javascript line-numbers"><code>/* 0 */<br>
{<br>
&quot;ts&quot; : ISODate(&quot;2015-02-05T19:49:19.354Z&quot;),<br>
&quot;op&quot; : &quot;update&quot;,<br>
&quot;ns&quot; : &quot;Comic.ComicBooks&quot;,<br>
&quot;query&quot; : {<br>
&quot;_id&quot; : ObjectId(&quot;54d3ba5a836c6476930566de&quot;)<br>
},<br>
&quot;updateobj&quot; : {<br>
&quot;_id&quot; : ObjectId(&quot;54d3ba5a836c6476930566de&quot;),<br>
&quot;_class&quot; : &quot;com.foobar.ComicBook&quot;,<br>
&quot;name&quot; : &quot;Superman&quot;,<br>
&quot;synchronizationStatus&quot; : &quot;OK&quot;,<br>
&quot;lastUpdated&quot; : ISODate(&quot;2015-02-05T19:49:08.428Z&quot;)<br>
},<br>
&quot;millis&quot; : 0,<br>
&quot;client&quot; : &quot;10.14.15.16&quot;<br>
}</code></pre></p>
<p>This will return you all the queries, and operations occurring in Comic db. Here's what the fields mean:</p>
<ul>
<li><strong>ts</strong>: the time this operation occurred.</li>
<li><strong>op</strong>: the write operation that should be applied to the slave. n indicates a * ns: the database and collection affected by this operation. Since this is a no-op, this field is left blank.</li>
<li><strong>query</strong>: the query used to find the record.</li>
<li><strong>updateobj</strong>: the actual document representing the op. The contents of updateobj are prety self explanatory.</li>
<li><strong>millis</strong>: The time in milliseconds from the perspective of the mongod from the beginning of the operation to the end of the operation.</li>
<li><strong>client</strong>: The IP address or hostname of the client connection where the operation originates.</li>
</ul>
<p>There are other fields that are included which are outside the scope of this post. You can read more about them here<sup class="footnote-ref"><a href="#fn1" id="fnref1:2">[1:2]</a></sup>.</p>
<p>NOTE: Please know that <code>system.profile</code> is a capped collection. So you can lose records over time since oldest records are removed if collection is near it's max size. Please set the profiling level to <code>0</code> once you are done researching the issue in order to not slow down the database. Also, this will help save hard disk space.</p>
<p>If you would like to query about specific collection you can do so by:<br>
<code>db.system.profile.find({ns: 'Comic.ComicBooks'});</code></p>
<p>If you want to query about a certain document id in a collection you can do so by:<br>
<code>db.system.profile.find({ns: 'Comic.ComicBooks', 'updateobj._id': ObjectId(&quot;54d3ba5a836c6476930566de&quot;)})</code></p>
<p>Basically, you can query this collection as you would query any other collection in Mongo.</p>
<p>Now, I could not find the records I was looking for in <code>system.profile</code>. The possible reason for that (according to team DBA is that we do not have logging on), but once I turn logging on, I would update this post to share if I could find what I was looking for with this. Regardless, I think this is a very handy tool to research issues with queries.</p>
<p>Great! I hope that was helpful.</p>
<p>Please help me out with your feedback/question in the comments section of this blog post. <em>Muchas gracias.</em></p>
<hr>
<h6 id="references">References</h6>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Database profiler: <a href="http://docs.mongodb.org/manual/reference/database-profiler/">http://docs.mongodb.org/manual/reference/database-profiler/</a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a> <a href="#fnref1:2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Delete GIT tags from local and remote branch]]></title><description><![CDATA[<p><strong>Problem statement</strong>: Recently at work we have been playing around with the concept of automated builds and one build (master build) kicking off builds for multiple projects. The master build that kicked off multiple builds would kick off builds for <em>all</em> projects regardless of whether there were any code changes</p>]]></description><link>https://javawithravi.com/delete-git-tags-from-local-and-remote-branch/</link><guid isPermaLink="false">5ba5e923f4d94807c63354f8</guid><category><![CDATA[Python]]></category><category><![CDATA[Github]]></category><category><![CDATA[Git]]></category><category><![CDATA[Tags]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Mon, 02 Feb 2015 02:22:01 GMT</pubDate><content:encoded><![CDATA[<p><strong>Problem statement</strong>: Recently at work we have been playing around with the concept of automated builds and one build (master build) kicking off builds for multiple projects. The master build that kicked off multiple builds would kick off builds for <em>all</em> projects regardless of whether there were any code changes in that particular project or not. This caused more than a 100 builds with no real code change in them. The builds would also create tags. I wanted to clean up these tags since we were moving away from automated builds for this one project.</p>
<p><strong>Solution</strong>: Here's a simple python script to delete tags locally as well as from remote branch.</p>
<pre class="language-python line-numbers"><code>__author__ = 'ravi'
from subprocess import call
import logging as log
import os
 
os.chdir('/home/ravi/dev/projects/spiderman')
for i in range(115, 280):
    try:
        # Remove locally
        call(['git', 'tag', '-d', '1.0.{}'.format(i)])
    except Exception as ex:
        log.exception(ex)
        pass
    try:
        # Remove from master
        call(['git', 'push', 'origin', ':refs/tags/1.0.{}'.format(i)])
    except Exception as ex:
        log.exception(ex)
        pass</code></pre>
<p><strong>NOTE:</strong></p>
<ol>
<li>Line #6: Provide the path of the git repo.</li>
<li>Line #7: Change the format and numbers to the tag format and numbers you want to remove.</li>
<li>Please be careful!</li>
</ol>
<p>Pretty straightforward!</p>
<hr>
]]></content:encoded></item><item><title><![CDATA[Automating Github releases via Jenkins]]></title><description><![CDATA[<p>Recently at work we were discussing releasing internal python artifacts to Github. Github has the concept of releases<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p>
<blockquote>
<p>Releases are a workflow for shipping software to end users. Releases are first-class objects with changelogs and binary assets that present a full project history beyond Git artifacts. They're accessible from</p></blockquote>]]></description><link>https://javawithravi.com/automating-github-releases-via-jenkins/</link><guid isPermaLink="false">5ba5e923f4d94807c63354fb</guid><category><![CDATA[Python]]></category><category><![CDATA[Github]]></category><category><![CDATA[Jenkins]]></category><category><![CDATA[Git]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Thu, 22 Jan 2015 05:54:07 GMT</pubDate><content:encoded><![CDATA[<p>Recently at work we were discussing releasing internal python artifacts to Github. Github has the concept of releases<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p>
<blockquote>
<p>Releases are a workflow for shipping software to end users. Releases are first-class objects with changelogs and binary assets that present a full project history beyond Git artifacts. They're accessible from a repository's homepage.</p>
</blockquote>
<p>Thus anybody within the company who has access to the repository would be able to access the release artifact, view the release history and know what went into each release by looking at the release notes/comments. It's pretty nifty!</p>
<p>You can of course create each release manually, but we wanted to automate the releases via Jenkins! Now, Jenkins has Github Publisher plugin but it does not have the ability to perform releases. Not as of yet. But, Github provides an api<sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup> which is super easy to use. And it is pretty straightforward to create a simple Python script that would integrate with the API to create releases, upload artifacts etc.</p>
<p>So I came up with a simple python script that allows us to:<br>
a. Get all the releases for a given repo,<br>
b. Create a release,<br>
c. Delete a release given the release name,<br>
d. Download release artifacts given the release name,<br>
e. List artifacts for a release.</p>
<p>I have included the full code below:<br>
<code data-gist-id="110fae3d2b18b01ada9d"></code></p>
<p>You can use the script like so:<br>
<code>python github\_release\_management.py -c -t &lt;Github_Token&gt; -o &lt;Github Organization&gt; -r &lt;repo name&gt;</code></p>
<p>Creating a release is now a simple two step process:</p>
<pre class="language-bash line-numbers"><code>export BUILD_NUMBER=1
python github_release_management.py -c -t <github_token> -o Spiderman -r awesome-api</github_token></code></pre>
<h5 id="creatingthegithubtokenforjenkins">Creating the Github token for Jenkins:</h5>
<p>In order to create and upload releases you need access to your github. If you have 2FA (Two Factored Authentication) <em>ON</em> then you need to generate a token that would allow you to create/upload release artifacts. You can create a token by going to <strong>Account Settings -&gt; Application</strong> and generating a new token:</p>
<p><img src="https://javawithravi.com/content/images/2015/02/Selection_073.png" alt=""></p>
<p><em>Once you have created the token, copy it some place so you can easily access it for the next step.</em></p>
<h5 id="integratingwithjenkins">Integrating with Jenkins:</h5>
<p>The reason why I am using <code>BUILD_NUMBER</code> environment variable in the script above is because Jenkins automatically sets the <code>BUILD_NUMBER</code> variable for each build. So I can use that as part of the release number.</p>
<p>To setup Jenkins build to run the python script above you need to install the <code>Post Build Task</code><sup class="footnote-ref"><a href="#fn1" id="fnref1:2">[1:2]</a></sup> plugin. Once you have the plugin installed, you can then go to your actual build configuration and setup the <code>Post Build Action</code> like so:</p>
<p><img src="https://javawithravi.com/content/images/2015/02/Selection_071-1.png" alt=""></p>
<p>Notice the grayed out area after <code>-t-</code>, that's where you should put the token you generated above.</p>
<p>Save. And voila! You are done!</p>
<hr>
<p>Have you automated releases via Jenkins on GitHub? How did you do it?</p>
<p>Also, please feel free to comment below any questions/comments/ideas you might have? Your comments help me understand what I need to tweak on my blog so as to make the content more explanatory!</p>
<hr>
<h5 id="references">References:</h5>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Jenkins - Post Build Task plugin: <a href="https://wiki.jenkins-ci.org/display/JENKINS/Post+build+task">https://wiki.jenkins-ci.org/display/JENKINS/Post+build+task</a> <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a> <a href="#fnref1:2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[Upload and Download file from Mongo using Bottle and Flask]]></title><description><![CDATA[Bottle and Flask are popular microframeworks for Python. You can use them to upload and download files to Mongo GridFS like so...]]></description><link>https://javawithravi.com/upload-and-download-file-from-mongo-using-bottle-and-flask/</link><guid isPermaLink="false">5ba5e923f4d94807c63354fa</guid><category><![CDATA[flask]]></category><category><![CDATA[gridfs]]></category><category><![CDATA[python]]></category><category><![CDATA[bottle]]></category><category><![CDATA[mongo]]></category><dc:creator><![CDATA[Ravi Hasija]]></dc:creator><pubDate>Mon, 12 Jan 2015 04:51:41 GMT</pubDate><content:encoded><![CDATA[<p>If you have a requirement to save and serve files, then there are at least a couple options.</p>
<ol>
<li>Save the file onto the server and serve it from there.</li>
<li>Mongo[^n] provide GridFS[^n] store that allows you not only to store files but also metadata related to the file. For example: you can store author, tags, group etc right with the file. You can provide this functionality via option 1 too, but you would need to make your own tables and link the files to the metadata information. Besides replication of data is in built in Mongo.</li>
</ol>
<h5 id="bottle">Bottle</h5>
<p>You can upload and download mongo files using Bottle[^n] like so:</p>
<pre class="language-python line-numbers" data-line="12,15-17,29-31"><code>import json

from bottle import run, Bottle, request, response
from gridfs import GridFS
from pymongo import MongoClient

FILE_API = Bottle()
MONGO_CLIENT = MongoClient('mongodb://localhost:27017/')
DB = MONGO_CLIENT['TestDB']
GRID_FS = GridFS(DB)

@FILE_API.put('/upload/< file_name>')
def upload(file_name):
    response.content_type = 'application/json'
    with GRID_FS.new_file(filename=file_name) as fp:
        fp.write(request.body)
        file_id = fp._id
    # If the file is found in the database then the save
    # was successful else an error occurred while saving.
    if GRID_FS.find_one(file_id) is not None: 
        return json.dumps({'status': 'File saved successfully'})
    else:
        response.status = 500
        return json.dumps({'status': 'Error occurred while saving file.'})


@FILE_API.get('/download/< file_name>')
def index(file_name):
    grid_fs_file = GRID_FS.find_one({'filename': file_name})
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers["Content-Disposition"] = "attachment; filename={}".format(file_name)
    return grid_fs_file


run(app=FILE_API, host='localhost', port=8080)</code></pre>
<p>And here's the break down of the code:</p>
<h6 id="uploadmethod">Upload method:</h6>
<p>Line 12: Sets up <code>upload</code> method to recieve a <code>PUT</code> request for <code>/upload/&lt;file_name&gt;</code> url with file_name variable holding the value that user passed in.<br>
Line 15-17: Create a new GridFS file with name: <code>file_name</code> and get the content from <code>request.body</code>. <code>request.body</code> may be <code>StringIO</code> type or a <code>File</code> type because Python is smart enough to decipher the <code>body</code> type based on the content.</p>
<h6 id="downloadmethod">Download method:</h6>
<p>Line 29: Find the GridFS file.<br>
Line 30-31: Set the response <code>Content-Type</code> as <code>application-octet-stream</code> and <code>Content-Disposition</code> to <code>attachment; filename=&lt;file_name&gt;</code> so the client can download the file.<br>
Line 33: Return the <code>GridOut</code> object. Based on Bottle documentation (below), we can return an object which has <code>.read()</code> method available and Bottle understands that to be a <code>File</code> object. Bottle handles return of <code>File</code> object(s) such that they can be downloaded.</p>
<blockquote>
<p>File objects<br>
Everything that has a .read() method is treated as a file or file-like object and passed to the wsgi.file_wrapper callable defined by the WSGI server framework. Some WSGI server implementations can make use of optimized system calls (sendfile) to transmit files more efficiently. In other cases this just iterates over chunks that fit into memory.</p>
</blockquote>
<p>That is as simple as it gets as far as Bottle is concerned. Now on to implementing the same functionality in Flask.</p>
<hr>
<h5 id="flask">Flask</h5>
<p>You can upload/download files using Flask[^n] like so:</p>
<pre class="language-python line-numbers" data-line="14,17,28-31"><code>import json
from gridfs import GridFS
from pymongo import MongoClient
from flask import Flask, make_response
from flask import request

__author__ = 'ravihasija'

app = Flask(__name__)
mongo_client = MongoClient('mongodb://localhost:27017/')
db = mongo_client['TestDB']
grid_fs = GridFS(db)

@app.route('/upload/<file_name>', methods=['PUT'])
def upload(file_name):
    with grid_fs.new_file(filename=file_name) as fp:
        fp.write(request.data)
        file_id = fp._id

    if grid_fs.find_one(file_id) is not None:
        return json.dumps({'status': 'File saved successfully'}), 200
    else:
        return json.dumps({'status': 'Error occurred while saving file.'}), 500

@app.route('/download/<file_name>')
def index(file_name):
    grid_fs_file = grid_fs.find_one({'filename': file_name})
    response = make_response(grid_fs_file.read())
    response.headers['Content-Type'] = 'application/octet-stream'
    response.headers["Content-Disposition"] = "attachment; filename={}".format(file_name)
    return response

app.run(host="localhost", port=8081)</file_name></file_name></code></pre>
<p>You might notice that the <code>Flask</code> upload and download method(s) are very similar to Bottle's. It differs only in a few places listed below:</p>
<p>Line 14: Routing is configured differently in Flask. You mention the URL and the HTTP methods that apply for that URL.<br>
Line 17: Instead of <code>request.body</code> you use <code>request.data</code> to get the request content.<br>
Line 28-31: In Flask, if you want to add additional headers, one way to do so is to &quot;make the response&quot; with the file content and set up the appropriate headers. Finally, return the response object.</p>
<p>Questions? Thoughts? Please feel free to leave me a comment below. Thank you for your time.</p>
___
**Github repo**: https://github.com/RaviH/file-upload-download-mongo
___
#####References:
[^n]: MongoDB: http://www.mongodb.org/
[^n]: GridFS: http://docs.mongodb.org/manual/core/gridfs/
[^n]: Bottle: http://bottlepy.org/docs/dev/tutorial.html
[^n]: Flask: http://flask.pocoo.org/
[^n]: PyMongo GridFS doc http://api.mongodb.org/python/current/api/gridfs/index.html?highlight=gridfs#module-gridfs
[^n]: Get to know GridFS: http://architects.dzone.com/articles/get-know-gridfs-mongodb
___]]></content:encoded></item></channel></rss>