<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://ankitkatiyar91.github.io/bytefold-site/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ankitkatiyar91.github.io/bytefold-site/" rel="alternate" type="text/html" /><updated>2025-06-21T16:53:31+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/feed.xml</id><title type="html">Bytefold</title><subtitle>Thoughts and experiences of a Curious Mind!</subtitle><entry><title type="html">Superset on docker</title><link href="https://ankitkatiyar91.github.io/bytefold-site/running-superset-on-docker/" rel="alternate" type="text/html" title="Superset on docker" /><published>2022-07-23T19:26:25+00:00</published><updated>2022-07-23T19:26:25+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/running-superset-on-docker</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/running-superset-on-docker/"><![CDATA[<p>Apache Superset is great tool for data visualization which comes with many useful features. It’s built using python
flask and JS frameworks. You can deploy it for your use case in multiple ways. I will share with you how to deploy it on
docker and do the necessary steps to make it work for you.</p>

<p>Apache superset provids an official docker image available on
Dockerhub <a href="https://hub.docker.com/r/apache/superset">https://hub.docker.com/r/apache/superset</a> that
can be used to run superset but this image lacs few functionality which are critical to use it in production
environment.</p>

<h3 id="missing-components-from-official-apache-superset-docker-image">Missing components from official Apache Superset docker image:</h3>

<ul>
  <li>User Login</li>
  <li>Database Drivers</li>
  <li>Certificates and other dependencies</li>
</ul>

<h4 id="user-login">User Login</h4>

<p>Superset image form dockerhub does not provide any easily accessible way to configure Admin user for the app. It relies
on superset <code class="language-java highlighter-rouge"><span class="n">fab</span> <span class="n">create</span><span class="o">-</span><span class="n">admin</span></code> command to create admin user. We often do not have acess to perform these tasks manually
from a docker container (specially when running on a managed cloud service like AWS ECS).</p>

<h4 id="database-drivers">Database Drivers</h4>

<p>Apache Superset supports a wide range of databases for visualization. Official dockerhub image keeps it light by not
addd all the required drivers and letting you add them later. You can find driver for your need in the
list <a href="https://hub.docker.com/r/apache/superset">https://superset.apache.org/docs/databases/installing-database-drivers/</a>
here.</p>

<h4 id="certificates-and-other-dependencies">Certificates and other dependencies</h4>

<p>Superset supports wide range of databases and services to be integated with and lot of these services support using
custom SSL Certificates to be used for the communication. Apache Superset does not comes with intutive user interface to
add these certificates and other dependencies. It has added few features in recent version to add ROOT CA from UI still
sometimes it’s easier to have these dependencies baked in before you run it.</p>

<h3 id="additional-configuration-support">Additional Configuration Support</h3>

<p>Superset uses python file named <code class="language-java highlighter-rouge"><span class="n">superset_config</span><span class="o">.</span><span class="na">py</span></code> to customize a lot of superset functionality. You can set many
variables which are used in Superset for enabling/disabling features. Below are few examples of that are</p>

<h5 id="enabling-jinja-template">Enabling Jinja template</h5>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="n">FEATURE_FLAGS</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">"ENABLE_TEMPLATE_PROCESSING"</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div></div>

<h5 id="enabling-proxy-fix-for-ssl-support">Enabling Proxy Fix for SSL support</h5>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="n">ENABLE_PROXY_FIX</span> <span class="o">=</span> <span class="bp">True</span>
</code></pre></div></div>

<h3 id="creating-custom-docker-image">Creating Custom Docker Image</h3>

<p>Simplest solution to these problems is creating your own custom docker image. You can do it form Apache Superset
source <a href="https://hub.docker.com/r/apache/superset">https://github.com/apache/superset</a> or by extending official image.
You can add more functionalites by adding custom config files and unix scripts that can we run an entrypoint (start of
the docker container).</p>

<p><strong>superset-custom.sh</strong></p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="c">#!/bin/bash</span>

<span class="c"># create Admin user, you can read these values from env or anywhere else possible.</span>
<span class="nb">echo</span> <span class="s2">"Creating admin user </span><span class="k">${</span><span class="nv">ADMIN_USERNAME</span><span class="k">}</span><span class="s2"> email </span><span class="k">${</span><span class="nv">ADMIN_EMAIL</span><span class="k">}</span><span class="s2">"</span>
superset fab create-admin <span class="nt">--username</span> <span class="s2">"</span><span class="nv">$ADMIN_USERNAME</span><span class="s2">"</span> <span class="nt">--firstname</span> Superset <span class="nt">--lastname</span> Admin <span class="nt">--email</span> <span class="s2">"</span><span class="nv">$ADMIN_EMAIL</span><span class="s2">"</span> <span class="nt">--password</span> <span class="s2">"</span><span class="nv">$ADMIN_PASSWORD</span><span class="s2">"</span>

<span class="c"># Upgrading Supersetset metastore.</span>
<span class="nb">echo</span> <span class="s2">"Upgrading DB"</span>
superset db upgrade

<span class="nb">echo</span> <span class="s2">"Setup roles"</span>
superset superset init  <span class="c">#setup roles and permissions</span>

<span class="nb">echo</span> <span class="s2">"Starting server"</span>
/bin/sh <span class="nt">-c</span> /usr/bin/run-server.sh
</code></pre></div></div>

<p><strong>Dockerfile</strong></p>

<div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="c"># Define base image</span>
<span class="k">FROM</span><span class="s"> apache/superset:1.5.1</span>

<span class="c"># Switching to root to install the required packages</span>
<span class="k">USER</span><span class="s"> root</span>

<span class="c"># Intall required dependencies.</span>
<span class="c"># Example: installing the MySQL driver to connect to the metadata database</span>
<span class="c"># if you prefer Postgres, you may want to use `psycopg2-binary` instead</span>
<span class="k">RUN </span>pip <span class="nb">install </span>psycopg2

<span class="c"># Define additional environment variables to be used </span>
<span class="k">ENV</span><span class="s"> ADMIN_EMAIL admin@superset.com</span>

<span class="c"># Add custom superset_config.py file and shell files</span>
<span class="k">COPY</span><span class="s"> superset_config.py /app/</span>
<span class="k">ENV</span><span class="s"> SUPERSET_CONFIG_PATH /app/superset_config.py #define variable that is used by Superset to look for config python file.</span>

<span class="k">COPY</span><span class="s"> superset-init.sh /app/superset-custom.sh</span>
<span class="k">RUN </span><span class="nb">chmod</span> +x /app/superset-custom.sh

<span class="c"># Switching back to using the `superset` user</span>
<span class="k">USER</span><span class="s"> superset</span>
<span class="k">ENTRYPOINT</span><span class="s"> [ "/app/superset-custom.sh" ]</span>

</code></pre></div></div>

<p>You can add a lot more to your docker image and customize it for you purpose. I hope it will help you starting with your
Apache Superset Journey</p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Data Visualization" /><category term="Docker" /><category term="Apache Superset" /><category term="Data Visualization" /><summary type="html"><![CDATA[Apache Superset is great tool for data visualization which comes with many useful features. It’s built using python flask and JS frameworks. You can deploy it for your use case in multiple ways. I will share with you how to deploy it on docker and do the necessary steps to make it work for you.]]></summary></entry><entry><title type="html">Our journey of sharing GPU in Kubernetes</title><link href="https://ankitkatiyar91.github.io/bytefold-site/sharing-gpu-in-kubernetes/" rel="alternate" type="text/html" title="Our journey of sharing GPU in Kubernetes" /><published>2022-04-02T19:26:25+00:00</published><updated>2022-04-02T19:26:25+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/sharing-gpu-in-kubernetes</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/sharing-gpu-in-kubernetes/"><![CDATA[<p>GPU’s popularity has been increasing for last decade with increasing usage in ML and other AI applications. We have seen a lot of application using GPUs as key computation component for processing. We struck with one such use-case of <strong>ASR</strong>(Automated Speech Recognition) and <strong>TTS</strong>(Text to Speech).</p>

<h1 id="context">Context</h1>

<p>Team built an amazing service to provide ASR and TTS for indic languages. GPUs were considered to have better performance. Kubernetes chosen to keep things simple and scalable at various levels. Everything was smooth until we got to know that we have to share GPUs and kubernetes does not have native support for GPUs. K8s official documentation says</p>

<blockquote>
  <p>Kubernetes includes experimental support for managing AMD and NVIDIA GPUs (graphical processing units) across several nodes.</p>
</blockquote>

<p>Our services were using libraries like pytorch which were using NVIDIA’s CUDA for GPU computations.</p>

<h3 id="nvidia-cuda-compute-unified-device-architecture">Nvidia CUDA (Compute Unified Device Architecture)</h3>

<p>Provides abstraction and high level language support on a variety of Nvidia GPUs.</p>

<ul>
  <li>Native CUDA programming can be done in C or C++</li>
  <li>Use a wrapper library like python, Java</li>
</ul>

<p>More on it <a href="https://developer.nvidia.com/cuda-zone">CUDA documentation</a>.</p>

<h1 id="why-share-gpus">Why Share GPUs</h1>

<ul>
  <li>GPUs are expensive.</li>
  <li>Better utilization of GPU cycles and memory
    <ul>
      <li>One model instance may not consume it all.</li>
      <li>Availability of best fit GPUs for your workload.</li>
    </ul>
  </li>
</ul>

<p>We always want to get most value out of any resource that we use. Our benchmarking showed the scope to do more on one single GPU.</p>

<p><img src="/assets/images/gpu-sharing/gpu-memory-allocation.png#45" alt="GPU Memory Allocation" />
<img src="/assets/images/gpu-sharing/gpu-utilization.png#45" alt="GPU Memory Utilization" /></p>

<p>*Peeks in the graphs represent load. We did these runs to benchmark our ASR model service. Here, one ASR model was running on an Nvidia T4 GPU which has 16 GB memory. With our increase in load utilization increases but saturates at a level and did not increase with increase in load (load means increase in number of concurrent request).</p>

<p>These load runs made it clear that deploying one instance of the service (one model running in a service) per GPU wasn’t the best use of it. We can load more models on to one GPU and get better results. We also have to mindful of that fact that current generations of GPUs are not designed for parallel workloads. So benchmarking plays important role in understanding the impact.</p>

<h1 id="gpu-with-kubernetes">GPU with Kubernetes</h1>

<p>Kubernetes has no internal support for GPU resource scheduling and isolation. Instead, it is implemented by third-party through the device plugin and scheduler extension.</p>

<p>As per k8s documentation (https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus)</p>
<blockquote>
  <p>Kubernetes includes experimental support for managing AMD and NVIDIA GPUs across several nodes.
Containers (and Pods) do not share GPUs. There’s no overcommitting of GPUs.
Each container can request one or more GPUs. It is not possible to request a fraction of a GPU.</p>
</blockquote>

<p><strong>What you can do</strong></p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">resources</span><span class="pi">:</span>
        <span class="na">limits</span><span class="pi">:</span>
          <span class="na">nvidia.com/gpu</span><span class="pi">:</span> <span class="m">1</span> <span class="c1"># requesting 1 GPU, Your pod will see one GPU only.</span>
</code></pre></div></div>

<p>This will only take care of scheduling your workload to an available GPU. It will be able to restrict utilization, memory etc. which you would usually find with other resources like memory, CPU. This feature will restrict the GPU visibility to your pod, it will only see defined number of GPUs in your pod. No other workload will be allowed to schedule on that instance with those GPUs assigned.</p>

<p><img src="/assets/images/gpu-sharing/k8s-workload-1.png" alt="GPU Sharing k8s workload" /></p>

<p><strong>You cannot do this</strong></p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">resources</span><span class="pi">:</span>
        <span class="na">limits</span><span class="pi">:</span>
          <span class="na">nvidia.com/gpu</span><span class="pi">:</span> <span class="m">0.5</span> <span class="c1"># cannot request fractions.</span>
</code></pre></div></div>

<p><strong>Trick</strong></p>

<p>You can set <code class="language-java highlighter-rouge"><span class="n">nvidia</span><span class="o">.</span><span class="na">com</span><span class="o">/</span><span class="n">gpu</span></code> value to <code class="language-java highlighter-rouge"><span class="mi">0</span></code> and still workload will be able to see all the GPUs available on the instance. It will also not block the GPU on kubernetes to more workloads can be scheduled on that node.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">resources</span><span class="pi">:</span>
        <span class="na">limits</span><span class="pi">:</span>
          <span class="na">nvidia.com/gpu</span><span class="pi">:</span> <span class="m">0</span> <span class="c1"># This will work fine and will not block your GPU for other workloads.</span>
</code></pre></div></div>

<h1 id="ways-to-achieve-gpu-sharing-in-kubernetes">Ways to achieve GPU sharing in kubernetes</h1>

<p>There are multiple ways to share a GPU instance with multiple processes like we do with CPU.</p>

<ul>
  <li><a href="#hardware-level-partitioning">Hardware level partitioning like MIG</a></li>
  <li><a href="#virtual-GPUs">Virtual GPUs</a></li>
  <li><a href="#custom-implementations">Custom implementations</a></li>
</ul>

<h1 id="hardware-level-partitioning">Hardware level partitioning</h1>

<p>This was our first level of option. NVIDIA provides an option of creating <a href="https://www.nvidia.com/en-in/technologies/multi-instance-gpu/">MULTI-INSTANCE GPU</a> at hardware level. One single physical GPU can be mapped to machine as upto seven GPUs. This feature is limited to specific NVIDIA GPUs and need a cluster/machine level changes to support.</p>

<h1 id="virtual-gpus">Virtual GPUs</h1>

<p>This is similar to what we do we CPU but not as cool. AWS has created device plugin to support creation of VGPUs (Virtual GPU) <a href="https://github.com/awslabs/aws-virtual-gpu-device-plugin">https://github.com/awslabs/aws-virtual-gpu-device-plugin</a>.</p>

<ul>
  <li>We can allocate 10 virtual GPUs for each physical GPU.</li>
  <li>We can run more than one pod on a physical GPU.</li>
  <li>We can exploit multi-process service for better performance.</li>
</ul>

<blockquote>
  <p>If you have large GPUs, you can do MIG and on top of that use device plugin.</p>
</blockquote>

<p><img src="/assets/images/gpu-sharing/sharing-as-vgpu.png" alt="GPU Sharing with Virtual GPU" /></p>

<blockquote>
  <p>This will require you to replace your exiting GPU driver with AWS virtual GPU driver.</p>
</blockquote>

<p><strong>Limitations:</strong> Plugin does provide any constraints over resource consumption. Process has to put limits itself.</p>

<blockquote>
  <p>Even in EKS this does not come out of the box as of April-2022. You have to install it on your cluster.</p>
</blockquote>

<h1 id="custom-implementations">Custom implementations</h1>

<p>MIG and Virtual GPU both these options require you to provision your hardware or cluster with custom drivers. In case, you do not have access to such level only choice that remain with us is GPU Sharing without Kubernetes. This can be done in multiple ways.</p>

<ul>
  <li><a href="#writing-custom-code">Writing custom code</a></li>
  <li><a href="#using-cuda_visible_devices">Using <code class="language-java highlighter-rouge"><span class="no">CUDA_VISIBLE_DEVICES</span></code></a></li>
</ul>

<h2 id="writing-custom-code">Writing custom code</h2>

<p>In case you have multiple GPUs attached to one single machine. CUDA will by default load data to 0th device. You can change that by creating a device object and passing this device object at all the places. Another challenge is deciding which GPU to use.</p>

<p><strong>Challenges</strong></p>
<ul>
  <li>By default, CUDA uses 0th device.</li>
  <li>CUDA does not provide support to get memory usage of a GPU in any programmatic way.</li>
</ul>

<p><strong>Sample <code class="language-java highlighter-rouge"><span class="n">nvidia</span><span class="o">-</span><span class="n">smi</span></code> output</strong></p>

<p><img src="/assets/images/gpu-sharing/nvidia-smi.png" alt="nvidia-smi output" /></p>

<p><strong>Solution</strong></p>
<ul>
  <li>Change your code to load models and data on specific device.</li>
  <li>Parse output of nvidia-smi to see memory consumption of a GPU.</li>
</ul>

<p><strong>Tip for Python Users</strong> <a href="https://github.com/anderskm/gputil">GPUtil</a> is a package to select GPU based on your criteria.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="n">GPUtil</span><span class="p">.</span><span class="n">getAvailable</span><span class="p">(</span><span class="n">order</span><span class="o">=</span><span class="s">'memory'</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">maxLoad</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">maxMemory</span><span class="o">=</span><span class="mf">0.75</span><span class="p">,</span><span class="n">excludeID</span><span class="o">=</span><span class="n">excluded_gpus</span><span class="p">)</span>
</code></pre></div></div>

<p>Reference <a href="https://pytorch.org/docs/stable/cuda.html">CUDA python library</a></p>

<h2 id="using-cuda_visible_devices">Using <code class="language-java highlighter-rouge"><span class="no">CUDA_VISIBLE_DEVICES</span></code></h2>

<p>CUDA provides a range of environment variable which can be used to control the visibility of GPU devices at process level. <code class="language-java highlighter-rouge"><span class="no">CUDA_VISIBLE_DEVICES</span></code> is one such variable. When you are starting a process you can set an environment variable <code class="language-java highlighter-rouge"><span class="no">CUDA_VISIBLE_DEVICES</span></code> with one or list of GPU ids and that process will only see those GPUs as available devices. As this is done at process leve, k8s does not know about this hence you can run multiple workload on same GPU device with your judgement of memory and utilization.</p>

<p><strong>Expose 2nd GPU</strong></p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">CUDA_VISIBLE_DEVICES</span><span class="pi">:</span> <span class="s2">"</span><span class="s">1"</span>
</code></pre></div></div>
<p><img src="/assets/images/gpu-sharing/cuda_visible-1-gpu.png" alt="CUDA_VISIBLE_DEVICES 1" /></p>

<p><strong>Expose 2nd and 3rd GPU</strong></p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">CUDA_VISIBLE_DEVICES</span><span class="pi">:</span> <span class="s2">"</span><span class="s">1,2"</span>
</code></pre></div></div>
<p><img src="/assets/images/gpu-sharing/cuda_visible-1-2-gpu.png" alt="CUDA_VISIBLE_DEVICES 1,2" /></p>

<h1 id="summary">Summary</h1>

<p>GPU sharing is still an experimental feature in kubernetes. There are efforts going on to make it available. Till then, we have to live with workarounds like these to make it work. It requires a bit of planning upfront to know which workload will go where and what GPU instance will be used by them.</p>

<p><strong>References:</strong></p>

<p><a href="https://developer.nvidia.com/cuda-zone">CUDA Documentation</a></p>

<p><a href="https://github.com/awslabs/aws-virtual-gpu-device-plugin">AWS Virtual GPU Plugin</a></p>

<p><a href="https://www.nvidia.com/en-in/technologies/multi-instance-gpu/">NVIDIA  Multi-instance GPU</a></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="GPU Sharing" /><category term="GPU" /><category term="NVIDIA-GPU" /><category term="GPU-Sharing" /><summary type="html"><![CDATA[GPU’s popularity has been increasing for last decade with increasing usage in ML and other AI applications. We have seen a lot of application using GPUs as key computation component for processing. We struck with one such use-case of ASR(Automated Speech Recognition) and TTS(Text to Speech).]]></summary></entry><entry><title type="html">Load Balancing a grpc service on k8s</title><link href="https://ankitkatiyar91.github.io/bytefold-site/load-balancing-a-grpc-service-on-k8s/" rel="alternate" type="text/html" title="Load Balancing a grpc service on k8s" /><published>2022-02-05T19:26:25+00:00</published><updated>2022-02-05T19:26:25+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/load-balancing-a-grpc-service-on-k8s</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/load-balancing-a-grpc-service-on-k8s/"><![CDATA[<p>Load balancing a GRPC service on a Kubernetes environment could be a big challenge if you miss out on the fact that GRPC works on HTTP2 and HTTP2 does the magic of multiplexing and reuses the connection for multiple requests. While trying to scale a GRPC service found some interesting insights about how GRPC works with ClusterIP.</p>

<h2 id="scenario"><strong>Scenario</strong></h2>

<!-- wp:image {"id":638,"sizeSlug":"large","linkDestination":"none"} -->

<p><img src="/assets/images/2022/02/stage-1-1024x188.png" alt="" /></p>

<p>We created a GRPC service and deployed it on k8s using a ClusterIP service which was exposed using an Nginx server. We
did some load tests and figured out its vertical scale limits. so we decided to scale the number of pods on our service
to achieve better results. As the <a href="https://kubernetes.io/docs/concepts/services-networking/service/">k8s documentation</a>
mentions</p>

<blockquote>
  <p>By default, kube-proxy in userspace mode chooses a backend via a round-robin algorithm</p>
</blockquote>

<p>With this assumption we expected our horizontally scaled service to evenly distribute load across pods. When we did this
we were surprised to see that most of the load was still going to 1 pod. We increased the number of pods but the pattern
continues and the load is not evenly distributed.</p>

<h2 id="problem">Problem</h2>

<p>After spending hours on the internet and playing with various configurations, we found that GRPC needs HTTP2 and
ClusterIP was using HTTP2 which was doing multiplexing. Because of this multiplexing, it was reusing existing
connections and sending new requests to the same k8s Pod rather than creating a new connection to the second pod. This
phenomenon continues with more pods and a few pods that get most of the load.</p>

<p><img src="/assets/images/2022/02/stage-2-1-1024x389.png" alt="" /></p>

<p><em>Un-even Load Distribution</em></p>

<h2 id="solution">Solution</h2>

<p>As we figured out the problem is with the load balancing system and a solution was achieved in two steps:</p>

<ul>
  <li>Create a headless k8s service.</li>
  <li>Using a custom/external load balancer.</li>
</ul>

<p>Let’s look at both of these options in detail</p>

<h2 id="creating-headless-k8s-service">Creating headless k8s service</h2>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">headless-svc</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">clusterIP</span><span class="pi">:</span> <span class="s">None</span> <span class="c1"># &lt;= Don't forget!!</span>
  <span class="na">selector</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">web</span>
  <span class="na">ports</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
      <span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
      <span class="na">targetPort</span><span class="pi">:</span> <span class="m">8080</span>
</code></pre></div></div>

<p>A Kubernetes headless service is a ClusterIP service that doesn’t create a cluster IP for your service and exposes the
IPs of all the pods that are created. With this approach, you can get the IPs of all the pods that are available for
your App.</p>

<h2 id="using-customexternal-load-balancer">Using custom/external load balancer</h2>

<p>Once your headless service is available you can use any load balancer that has the capability to discover IPs from the
ClusterIP service and do the load balancing. For us, <a href="https://www.envoyproxy.io/">envoy</a> being part of our system came
to our rescue. We were using envoy to support REST clients on our GRPC service.</p>

<!-- wp:image {"id":642,"sizeSlug":"large","linkDestination":"none"} -->

<p><img src="/assets/images/2022/02/stage-3-1024x664.png" alt="" /></p>

<p><strong>Example Envoy Config</strong></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="na">clusters</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">headless-svc</span>
    <span class="na">type</span><span class="pi">:</span> <span class="s">STRICT_DNS</span>
    <span class="na">lb_policy</span><span class="pi">:</span> <span class="s">ROUND_ROBIN</span>
    <span class="na">connect_timeout</span><span class="pi">:</span> <span class="s">30s</span>
    <span class="na">dns_lookup_family</span><span class="pi">:</span> <span class="s">V4_ONLY</span>
    <span class="na">load_assignment</span><span class="pi">:</span>
      <span class="na">cluster_name</span><span class="pi">:</span> <span class="s">headless-svc</span>
      <span class="na">endpoints</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">lb_endpoints</span><span class="pi">:</span>
            <span class="pi">-</span> <span class="na">endpoint</span><span class="pi">:</span>
                <span class="na">address</span><span class="pi">:</span>
                  <span class="na">socket_address</span><span class="pi">:</span>
                    <span class="na">address</span><span class="pi">:</span> <span class="s">headless-svc</span>
                    <span class="na">port_value</span><span class="pi">:</span> <span class="m">80</span>
</code></pre></div></div>

<h2 id="summary">Summary</h2>

<p>Kubernetes provides a great abstraction to our deployments, and sometimes it can make debugging load balancing and other
internals of services very complex. HTTP2 brings some performance optimisation which can cause behaviours that are not
good for some loads. Having an external load balancer that brings more control and clarity can be a boon. Envoy is one
such proxy that can do a lot of powerful stuff with very little resources.</p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Miscellaneous" /><category term="http2 load balancing" /><category term="kubernates" /><summary type="html"><![CDATA[Load balancing a GRPC service on a Kubernetes environment could be a big challenge if you miss out on the fact that GRPC works on HTTP2 and HTTP2 does the magic of multiplexing and reuses the connection for multiple requests. While trying to scale a GRPC service found some interesting insights about how GRPC works with ClusterIP.]]></summary></entry><entry><title type="html">Enable/Disable profile specific spring security debug flag</title><link href="https://ankitkatiyar91.github.io/bytefold-site/enable-disable-profile-specific-spring-security-debug-flag/" rel="alternate" type="text/html" title="Enable/Disable profile specific spring security debug flag" /><published>2020-05-02T15:34:02+00:00</published><updated>2020-05-02T15:34:02+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/enable-disable-profile-specific-spring-security-debug-flag</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/enable-disable-profile-specific-spring-security-debug-flag/"><![CDATA[<p>Spring security comes with a handy feature to enable <em>debug</em>flag to see a nice debug log as shown below to see what is happening with your application.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="mi">2020</span><span class="o">-</span><span class="mo">04</span><span class="o">-</span><span class="mi">21</span> <span class="mi">21</span><span class="o">:</span><span class="mi">19</span><span class="o">:</span><span class="mf">16.829</span>  <span class="no">INFO</span> <span class="mi">12332</span> <span class="o">---</span>
<span class="o">[</span><span class="n">nio</span><span class="o">-</span><span class="mi">8080</span><span class="o">-</span><span class="n">exec</span><span class="o">-</span><span class="mi">5</span><span class="o">]</span> <span class="nc">Spring</span> <span class="nc">Security</span> <span class="nc">Debugger</span> <span class="o">:</span> <span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span><span class="err">\</span><span class="o">*</span> <span class="nc">Request</span> <span class="n">received</span> <span class="k">for</span> <span class="no">GET</span> <span class="err">'</span><span class="o">/</span><span class="n">images</span><span class="o">/</span><span class="n">favicon</span><span class="o">.</span><span class="na">ico</span><span class="err">'</span><span class="o">:</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">catalina</span><span class="o">.</span><span class="na">connector</span><span class="o">.</span><span class="na">RequestFacade</span><span class="err">@</span><span class="mi">20617566</span> <span class="nl">servletPath:</span><span class="o">/</span><span class="n">images</span><span class="o">/</span><span class="n">favicon</span><span class="o">.</span><span class="na">ico</span> <span class="nl">pathInfo:</span><span class="kc">null</span> <span class="nl">headers:</span> <span class="nl">host:</span> <span class="nl">localhost:</span><span class="mi">8080</span> <span class="nl">connection:</span> <span class="n">keep</span><span class="o">-</span><span class="n">alive</span> <span class="nl">pragma:</span> <span class="n">no</span><span class="o">-</span><span class="n">cache</span> <span class="n">cache</span><span class="o">-</span><span class="nl">control:</span> <span class="n">no</span><span class="o">-</span><span class="n">cache</span> <span class="n">user</span><span class="o">-</span><span class="nl">agent:</span> <span class="nc">Mozilla</span><span class="o">/</span><span class="mf">5.0</span> <span class="o">(</span><span class="nc">Windows</span> <span class="no">NT</span> <span class="mf">10.0</span><span class="o">;</span> <span class="nc">Win64</span><span class="o">;</span> <span class="n">x64</span><span class="o">)</span> <span class="nc">AppleWebKit</span><span class="o">/</span><span class="mf">537.36</span> <span class="o">(</span><span class="no">KHTML</span><span class="o">,</span> <span class="n">like</span> <span class="nc">Gecko</span><span class="o">)</span> <span class="nc">Chrome</span><span class="o">/</span><span class="mf">80.0</span><span class="o">.</span><span class="mf">3987.163</span> <span class="nc">Safari</span><span class="o">/</span><span class="mf">537.36</span> <span class="n">sec</span><span class="o">-</span><span class="n">fetch</span><span class="o">-</span><span class="nl">dest:</span> <span class="n">image</span> <span class="nl">accept:</span> <span class="n">image</span><span class="o">/</span><span class="n">webp</span><span class="o">,</span><span class="n">image</span><span class="o">/</span><span class="n">apng</span><span class="o">,</span><span class="n">image</span><span class="o">/</span><span class="err">\</span><span class="o">*,</span><span class="err">\</span><span class="o">*/</span><span class="err">\</span><span class="o">*;</span><span class="n">q</span><span class="o">=</span><span class="mf">0.8</span> <span class="n">sec</span><span class="o">-</span><span class="n">fetch</span><span class="o">-</span><span class="nl">site:</span> <span class="n">same</span><span class="o">-</span><span class="n">origin</span> <span class="n">sec</span><span class="o">-</span><span class="n">fetch</span><span class="o">-</span><span class="nl">mode:</span> <span class="n">no</span><span class="o">-</span><span class="n">cors</span> <span class="nl">referer:</span> <span class="nl">http:</span><span class="c1">//localhost:8080/ accept-encoding: gzip, deflate, br accept-language: en-US,en;q=0.9,hi;q=0.8 cookie: ext\_name=jaehkpjddfdgiiefcnhahapilbejohhj; JSESSIONID=B31522BDCCAA126406166C25DBE9DE96; sub\_pop=1587484276805 Security filter chain: [] empty (bypassed by security='none') \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*</span>
</code></pre></div></div>

<p>You can control this feature from your bean configuration code</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="nd">@Configuration</span>
<span class="nd">@EnableWebSecurity</span><span class="o">(</span><span class="n">debug</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">SecurityConfig</span> <span class="kd">extends</span> <span class="nc">WebSecurityConfigurerAdapter</span>
</code></pre></div></div>

<p>Still, you may want to control it from <em>application.properties</em> files for some profiles. Like I want to keep it on for dev only.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="n">org</span><span class="o">.</span><span class="na">springframework</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">config</span><span class="o">.</span><span class="na">annotation</span><span class="o">.</span><span class="na">web</span><span class="o">.</span><span class="na">builders</span><span class="o">.</span><span class="na">WebSecurity</span><span class="o">.</span><span class="na">debugEnabled</span><span class="o">=</span><span class="kc">true</span>
</code></pre></div></div>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Miscellaneous" /><category term="Spring Security Debugging" /><category term="Spring Security Logging" /><summary type="html"><![CDATA[Spring security comes with a handy feature to enable debugflag to see a nice debug log as shown below to see what is happening with your application.]]></summary></entry><entry><title type="html">Why not to fall for a new technology</title><link href="https://ankitkatiyar91.github.io/bytefold-site/why-not-to-fall-for-a-new-technology/" rel="alternate" type="text/html" title="Why not to fall for a new technology" /><published>2020-03-11T10:11:50+00:00</published><updated>2020-03-11T10:11:50+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/why-not-to-fall-for-a-new-technology</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/why-not-to-fall-for-a-new-technology/"><![CDATA[<p>Technology is changing at an exponential rate. Every day we welcome a new technology that claims to change the world. Solve day to day problems in an amazing way. We all feel tempted to use these, and sometimes end up in unexpected situations. Here I sum up few things I consider before using anything new.</p>

<h3 id="its-notmature">It’s not mature</h3>

<p>When it comes to new innovating technologies which challenge the existing paradigm, often start with something small. It takes a significant amount of development, reiterations and changes to make it compatible with existing infrastructure and platforms.</p>

<!-- wp:quote -->

<blockquote>
  <p><em>ORM (Object relational mapping) tools started a long time back. But it took years to reach a level where you can simply relay on ORM to do everything with the database. In initial year if you used ORM, you still had to use native SQL to do lot of work. Sometime simply the dialect or driver wasn’t available or compatible.</em></p>
</blockquote>

<!-- /wp:quote -->

<!-- wp:heading {"level":3} -->

<h3 id="not-suited-for-your-usecase">Not Suited for your use case</h3>

<p>We are in a world that changes at an exponential rate. Whenever we see something fancy, we just want to play with it, try it out. In this love, we just use it with our app and later realize that we are using a very small part of it.</p>

<!-- wp:quote -->

<blockquote>
  <p><em>Blockchain, one of the great technologies of our time. I have seen people using it for trivial use cases like</em> Content Management System_. Such a waste of technology, right?_</p>
</blockquote>

<!-- /wp:quote -->

<p>Real-life failure: I was working on a project where a portal framework was in use. It used to take a minimum of 4GB of RAM to run the container itself, not to consider hardware requirements for development. where you need to run IDE, Database and other tools. After a year of work, we found ourselves using only 5% of the features. The framework had great features but was not needed for us!</p>

<!-- wp:heading {"level":3} -->

<h3 id="not-adding-any-businessvalue">Not adding any business value</h3>

<p>Every business uses technology. You cannot imagine a business without technology. Still, there is one thing that distinguishes them</p>

<!-- wp:quote -->

<blockquote>
  <p><strong><em>Technology is core of your business.</em></strong> <em>(Examples: Software Development, Innovation and R&amp;D companies)</em><br />
<strong><em>Business using technology to support/improve business.</em></strong> <em>(Examples: Manufacturing, Business Consulting, Real estate etc.)</em></p>
</blockquote>

<!-- /wp:quote -->

<p>In these two categories, we can definitely say that the first ones whose core function is technology/IT innovation need to stay on the top and needs to do a lot of research and innovations. Like FB, Google, IT servicing companies, Companies developing tools for the market.</p>

<p>In other ones, the core function is not technology. Business value is derived from core functions, technology works as support. In these scenarios keeping the tools/applications up to date may sound like an ideal approach but doesn’t add much to business. Sometimes these upgrades even cost way more than value added.</p>

<!-- wp:quote -->

<blockquote>
  <p><em>Use it if its useful for you not because everyone else doing it</em></p>
</blockquote>

<!-- /wp:quote -->

<!-- wp:heading {"level":3} -->

<h3 id="people">People</h3>

<p>You need people to create and maintain a application. We all know rare techs face challenges finding right talent for it. Better not end-up in a situation, what recruitment industry call it <em>Resource Crunch.</em></p>

<p><em><strong>Learning from everyone else is great, don’t follow them!</strong></em></p>

<!-- wp:separator -->

<hr />
<!-- /wp:separator -->

<p><em>These are some thoughts from my experience. Hope it help you make a informed decision.</em></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Miscellaneous" /><category term="New Technologies" /><category term="Technology" /><category term="Updating to new framework" /><summary type="html"><![CDATA[Technology is changing at an exponential rate. Every day we welcome a new technology that claims to change the world. Solve day to day problems in an amazing way. We all feel tempted to use these, and sometimes end up in unexpected situations. Here I sum up few things I consider before using anything new.]]></summary></entry><entry><title type="html">Serializing an object with static property</title><link href="https://ankitkatiyar91.github.io/bytefold-site/serializing-an-object-with-static-property/" rel="alternate" type="text/html" title="Serializing an object with static property" /><published>2019-02-18T10:32:58+00:00</published><updated>2019-02-18T10:32:58+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/serializing-an-object-with-static-property</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/serializing-an-object-with-static-property/"><![CDATA[<p>Serialization is often used to convert the <g class="gr_ gr_4 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="4" data-gr-id="4">in memory</g> objects to stream and vice-versa. But <strong><em>static</em></strong> members are not part the object states so they are not serialized in this process.</p>

<p>You need to serialize an object that has some static properties. The answer is, you need to control the process of serialization and De-Serialization for those objects. To do this in java you need to implement the interface <strong><em>Externalizable.</em> </strong> This is similar to the Serializable interface but with more control over the process of the serialization.</p>

<p><em>java.io.Externalizable</em> interface provides two methods <em>writeExternal()</em> and <em>readExternal()</em>. These methods are invoked whenever an object is being serialized or De-serialized. Syntax of both are shown below.</p>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">ObjectOutput</span> <span class="n">out</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">;</span>
</code></pre></div></div>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">ObjectInput</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">ClassNotFoundException</span><span class="o">;</span>
</code></pre></div></div>

<p>For demonstration, I have created a class <em>ExternalizableEmployee</em> which has only two Strong fields, name and a static field company.</p>

<!-- wp:heading {"level":3} -->

<h3 id="approach">Approach</h3>

<p>As we know that serialization will not save a property marked as static. we can create a proxy object that has the same properties but none of them is marked as static. So when you save the proxy object it will save all the properties and vice-versa when reading. In this example, I created a static <em>Employee</em> class with the <em>ExternalizableEmployee</em> class. Within because we do not need this outside the scope of E_xternalizableEmployee_ class_._</p>

<!-- wp:heading {"level":3} -->

<h3 id="e_xternalizableemployee_class">E_xternalizableEmployee _class</h3>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">java.io.Externalizable</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.ObjectInput</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.ObjectOutput</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.Serializable</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExternalizableEmployee</span> <span class="kd">implements</span> <span class="nc">Externalizable</span> <span class="o">{</span>

	<span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
	<span class="kd">private</span> <span class="kd">static</span> <span class="nc">String</span> <span class="n">company</span><span class="o">;</span>

	<span class="c1">// Inner Proxy class for Serialization.</span>
	<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">Employee</span> <span class="kd">implements</span> <span class="nc">Serializable</span> <span class="o">{</span>
		<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">serialVersionUID</span> <span class="o">=</span> <span class="mi">610993458650534361L</span><span class="o">;</span>

		<span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
		<span class="nc">String</span> <span class="n">company</span><span class="o">;</span>

		<span class="kd">public</span> <span class="nf">Employee</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="nc">String</span> <span class="n">company</span><span class="o">)</span> <span class="o">{</span>
			<span class="kd">super</span><span class="o">();</span>
			<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
			<span class="k">this</span><span class="o">.</span><span class="na">company</span> <span class="o">=</span> <span class="n">company</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
			<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getCompany</span><span class="o">()</span> <span class="o">{</span>
			<span class="k">return</span> <span class="n">company</span><span class="o">;</span>
		<span class="o">}</span>

	<span class="o">}</span>

	<span class="nd">@Override</span>
	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">ObjectOutput</span> <span class="n">out</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
		<span class="cm">/*
		 * Write the object of proxy class Employee with the values of
		 * ExternalizableEmployee
		 */</span>
		<span class="nc">Employee</span> <span class="n">emp</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Employee</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">company</span><span class="o">);</span>
		<span class="n">out</span><span class="o">.</span><span class="na">writeObject</span><span class="o">(</span><span class="n">emp</span><span class="o">);</span>
	<span class="o">}</span>

	<span class="nd">@Override</span>
	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">ObjectInput</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span><span class="o">,</span> <span class="nc">ClassNotFoundException</span> <span class="o">{</span>
		<span class="cm">/* Read the proxy object and initialize ExternalizableEmployee */</span>
		<span class="nc">Employee</span> <span class="n">employee</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Employee</span><span class="o">)</span> <span class="n">in</span><span class="o">.</span><span class="na">readObject</span><span class="o">();</span>
		<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">employee</span><span class="o">.</span><span class="na">getName</span><span class="o">();</span>
		<span class="n">company</span> <span class="o">=</span> <span class="n">employee</span><span class="o">.</span><span class="na">getCompany</span><span class="o">();</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">getCompany</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="n">company</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">setCompany</span><span class="o">(</span><span class="nc">String</span> <span class="n">company</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">ExternalizableEmployee</span><span class="o">.</span><span class="na">company</span> <span class="o">=</span> <span class="n">company</span><span class="o">;</span>
	<span class="o">}</span>

<span class="o">}</span>
</code></pre></div></div>

<!-- wp:heading {"level":3} -->

<h3 id="write-externalizableemployee-object-to-file">Write <em>ExternalizableEmployee</em> object to File</h3>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">java.io.FileOutputStream</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.ObjectOutputStream</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">WriteExternalizableEmployeeTest</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">try</span> <span class="o">(</span><span class="nc">ObjectOutputStream</span> <span class="n">objectOutputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectOutputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileOutputStream</span><span class="o">(</span><span class="s">"employee.data"</span><span class="o">)))</span> <span class="o">{</span>
			<span class="c1">// create an object of ExternalizableEmployee</span>
			<span class="nc">ExternalizableEmployee</span> <span class="n">emp</span><span class="o">=</span><span class="k">new</span> <span class="nc">ExternalizableEmployee</span><span class="o">();</span>
			<span class="n">emp</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Test"</span><span class="o">);</span>
			<span class="nc">ExternalizableEmployee</span><span class="o">.</span><span class="na">setCompany</span><span class="o">(</span><span class="s">"ByteFold"</span><span class="o">);</span>
			
			<span class="c1">// write object to file</span>
			<span class="n">objectOutputStream</span><span class="o">.</span><span class="na">writeObject</span><span class="o">(</span><span class="n">emp</span><span class="o">);</span>
		<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
			<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
		<span class="o">}</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<!-- wp:heading {"level":3} -->

<h3 id="read-externalizableemployee-object">Read <em>ExternalizableEmployee</em> object</h3>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">java.io.FileInputStream</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.ObjectInputStream</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ReadExternalizableEmployeeTest</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">try</span> <span class="o">(</span><span class="nc">ObjectInputStream</span> <span class="n">objectOutputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectInputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">(</span><span class="s">"employee.data"</span><span class="o">)))</span> <span class="o">{</span>
			<span class="c1">// Read an object of ExternalizableEmployee</span>
			<span class="nc">ExternalizableEmployee</span> <span class="n">employee</span> <span class="o">=</span> <span class="o">(</span><span class="nc">ExternalizableEmployee</span><span class="o">)</span> <span class="n">objectOutputStream</span><span class="o">.</span><span class="na">readObject</span><span class="o">();</span>

			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">employee</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">employee</span><span class="o">.</span><span class="na">getCompany</span><span class="o">());</span>
		<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="o">|</span> <span class="nc">ClassNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
			<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
		<span class="o">}</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Find the complete code at <a href="https://github.com/ankitkatiyar91/java-practise/tree/master/learning/src/main/java/IO/serialization">GitHub</a></p>

<p>More about <a href="https://dzone.com/articles/serialization-amp-de-serialization-in-java">Serialization</a></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Java" /><category term="Serialization" /><summary type="html"><![CDATA[Serialization is often used to convert the in memory objects to stream and vice-versa. But static members are not part the object states so they are not serialized in this process.]]></summary></entry><entry><title type="html">Quickstart Apache Shiro with Spring</title><link href="https://ankitkatiyar91.github.io/bytefold-site/quickstart-apache-shiro-with-spring/" rel="alternate" type="text/html" title="Quickstart Apache Shiro with Spring" /><published>2019-02-06T11:06:09+00:00</published><updated>2019-02-06T11:06:09+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/quickstart-apache-shiro-with-spring</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/quickstart-apache-shiro-with-spring/"><![CDATA[<p>Apache Shiro is an Authentication Authorization framework with support for cryptography and session management. You can quickly create a layer of security around your application.</p>
<p></p>

<p>I used this framework with couple of project and now it's my first go for authentication and authorization mechanism around any application, even over Spring Security. A lot of may like Spring Security because it comes with your spring and lot of community support and documentations.</p>
<p></p>

<p>You need to create a realm that provides all the logic of Authenticating a User and Authorizing it for any access.  Below is a simple realm class. (Not doing any verification, just for demonstration)</p>
<p></p>

<p><strong>Shiro&nbsp;Dependency</strong></p>
<p></p>
<p><!-- wp:enlighter/codeblock {"language":"xml"} --></p>
<pre class="highlight" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;!-- shiro dependency --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.shiro&lt;/groupId&gt;
			&lt;artifactId&gt;shiro-all&lt;/artifactId&gt;
			&lt;version&gt;1.1.0&lt;/version&gt;
		&lt;/dependency&gt;</pre>

<p><strong>Realm</strong></p>
<p></p>
<p><!-- wp:enlighter/codeblock {"language":"java"} --></p>
<pre class="highlight" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class MyRealm extends AuthorizingRealm {

	public MyRealm() {
		super();
		setCredentialsMatcher(new CredentialsMatcher() {
			
			@Override
			public boolean doCredentialsMatch(AuthenticationToken arg0,
					AuthenticationInfo arg1) {
				System.out
						.println("MyRealm.MyRealm().new CredentialsMatcher() {...}.doCredentialsMatch()");
				return true;
			}
		});
		
	}
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		System.out.println("MyRealm.doGetAuthorizationInfo()");
		AuthorizationInfo info=new SimpleAuthorizationInfo();
		return info;
	}

	

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken arg0) throws AuthenticationException {
		System.out.println("MyRealm.doGetAuthenticationInfo()");
		UsernamePasswordToken token=(UsernamePasswordToken) arg0;
		
		AuthenticationInfo info=new SimpleAuthenticationInfo(1,token.getCredentials(), getName());
		return info;
	}

}</pre>

<p><strong>Spring Configuration for Shiro</strong></p>
<p></p>
<p><!-- wp:enlighter/codeblock {"language":"xml"} --></p>
<pre class="highlight" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;


&lt;!-- Define the realm you want to use to connect to your back-end security datasource: --&gt;
&lt;bean id="myRealm" class="com.realm.MyRealm"&gt;&lt;/bean&gt;

&lt;bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager"&gt;
    &lt;!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. --&gt;
    &lt;property name="realm" ref="myRealm"/&gt;
    &lt;property name="sessionManager.sessionListeners"&gt;
    	&lt;list&gt;
    	&lt;ref bean="mySessionListener" /&gt;
    	&lt;/list&gt;
    &lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/&gt;

&lt;!-- For simplest integration, so that all SecurityUtils.* methods work in all cases, --&gt;
&lt;!-- make the securityManager bean a static singleton.  DO NOT do this in web         --&gt;
&lt;!-- applications - see the 'Web Applications' section below instead.                 --&gt;
&lt;bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
    &lt;property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/&gt;
    &lt;property name="arguments" ref="securityManager"/&gt;
&lt;/bean&gt;

&lt;bean id="mySessionListener" class="com.listner.MySessionListener" &gt;&lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p><strong>Demo</strong></p>
<pre class="highlight" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">
public class ShiroTest {
	public static void main(String[] args) {
		AbstractApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
		context.registerShutdownHook();
		org.apache.shiro.subject.Subject subject=SecurityUtils.getSubject();
		AuthenticationToken token=new UsernamePasswordToken("username", "password");
		System.out.println("Login a user--");
 		subject.login(token);
 		System.out.println("User logged in---"); subject.logout(); System.out.println("User logged out"); 
    } 
}
</pre>

<p>A fully functional demo available on GitHub <a href="https://github.com/ankitkatiyar91/java-framework-examples/tree/master/spring-examples/SpringShiro">https://github.com/ankitkatiyar91/java-framework-examples/tree/master/spring-examples/SpringShiro</a></p>

<p>Check CMS application that usages Shiro for security <a href="https://github.com/ankitkatiyar91/cms-java">https://github.com/ankitkatiyar91/cms-java</a></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Java" /><category term="Apache Shiro" /><category term="Authentication" /><summary type="html"><![CDATA[Apache Shiro is an Authentication Authorization framework with support for cryptography and session management. You can quickly create a layer of security around your application. This is Quick Demo of the Apche Shiro with Spring framework in java.]]></summary></entry><entry><title type="html">Java SSH Tunnel with Dynamic Port Forwarding</title><link href="https://ankitkatiyar91.github.io/bytefold-site/java-ssh-tunnel-with-dynamic-port-forwarding/" rel="alternate" type="text/html" title="Java SSH Tunnel with Dynamic Port Forwarding" /><published>2019-01-28T08:06:54+00:00</published><updated>2019-01-28T08:06:54+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/java-ssh-tunnel-with-dynamic-port-forwarding</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/java-ssh-tunnel-with-dynamic-port-forwarding/"><![CDATA[<p>If you have ever worked with deployment teams, you have done SSH through some clients like putty to your server and check whether a particular service reachable from there or verify something else.</p>

<p>I stuck with a problem where my production team has blocked access to production URLs of individual nodes. Now I cannot check if a particular node in my cluster is working or not. After a lot of efforts, they gave us a <strong><em>bastion server</em> </strong> (a server machine that is allowed with special rights, <a href="https://en.wikipedia.org/wiki/Bastion_host">more</a>) that allows us access to these nodes.</p>

<p>Basically, my application URL is <em>www.myurl.com</em> that runs 10 nodes on 8080 port. Then I am allowed to access <em>www.myurl.com</em> URL over internet/VPN but not allowed to check individual nodes like <em>www.node1.myurl.com:8080</em> etc. Now I have to use the new bastion server and log in through SSH then use dynamic port forward on that server. After that use SOCKS proxy of my browser to access these URLs.</p>

<p>Although, I am able to access these URLs from my browser but what about my JAVA utility that was doing all the verification without me doing all the manual work? So juggled around couple of libraries to see if I can still use that utitily and do all this.</p>

<p>There are couple of libraries but I explored two of them</p>

<ul>
  <li>JSCH (Doesn’t support dynamic port forward as of now)</li>
  <li>Apache MINA</li>
</ul>

<!-- wp:heading {"level":3} -->

<h3 id="jsch-example">JSCH Example</h3>

<p><strong>Dependencies</strong></p>

<!-- wp:enlighter/codeblock {"language":"xml"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="o">&lt;</span><span class="n">dependency</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">groupId</span><span class="o">&gt;</span><span class="n">com</span><span class="o">.</span><span class="na">jcraft</span><span class="o">&lt;/</span><span class="n">groupId</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">artifactId</span><span class="o">&gt;</span><span class="n">jsch</span><span class="o">&lt;/</span><span class="n">artifactId</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">version</span><span class="o">&gt;</span><span class="mf">0.1</span><span class="o">.</span><span class="mi">55</span><span class="o">&lt;/</span><span class="n">version</span><span class="o">&gt;</span>
<span class="o">&lt;/</span><span class="n">dependency</span><span class="o">&gt;</span>
</code></pre></div></div>

<p><strong>Example</strong></p>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">java.io.BufferedReader</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.InputStreamReader</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">com.jcraft.jsch.JSch</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.jcraft.jsch.Session</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.jcraft.jsch.UserInfo</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">TunnelJSCH</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">TunnelJSCH</span> <span class="n">t</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TunnelJSCH</span><span class="o">();</span>
		<span class="k">try</span> <span class="o">{</span>
			<span class="n">t</span><span class="o">.</span><span class="na">go</span><span class="o">();</span>
		<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span>
			<span class="n">ex</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
		<span class="o">}</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="kt">void</span> <span class="nf">go</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
		<span class="nc">String</span> <span class="n">host</span> <span class="o">=</span> <span class="s">"bastion-server-host"</span><span class="o">;</span>
		<span class="nc">String</span> <span class="n">user</span> <span class="o">=</span> <span class="s">"user"</span><span class="o">;</span>
		<span class="nc">String</span> <span class="n">password</span> <span class="o">=</span> <span class="s">"password"</span><span class="o">;</span>
		<span class="kt">int</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">22</span><span class="o">;</span>

		<span class="kt">int</span> <span class="n">tunnelLocalPort</span> <span class="o">=</span> <span class="mi">8000</span><span class="o">;</span>
		<span class="nc">String</span> <span class="n">tunnelRemoteHost</span> <span class="o">=</span> <span class="s">"remote-host"</span><span class="o">;</span>
		<span class="kt">int</span> <span class="n">tunnelRemotePort</span> <span class="o">=</span> <span class="mi">9080</span><span class="o">;</span>

		<span class="nc">JSch</span> <span class="n">jsch</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSch</span><span class="o">();</span>
		<span class="nc">Session</span> <span class="n">session</span> <span class="o">=</span> <span class="n">jsch</span><span class="o">.</span><span class="na">getSession</span><span class="o">(</span><span class="n">user</span><span class="o">,</span> <span class="n">host</span><span class="o">,</span> <span class="n">port</span><span class="o">);</span>
		<span class="n">session</span><span class="o">.</span><span class="na">setPassword</span><span class="o">(</span><span class="n">password</span><span class="o">);</span>
		<span class="n">localUserInfo</span> <span class="n">lui</span> <span class="o">=</span> <span class="k">new</span> <span class="n">localUserInfo</span><span class="o">();</span>
		<span class="n">session</span><span class="o">.</span><span class="na">setUserInfo</span><span class="o">(</span><span class="n">lui</span><span class="o">);</span>
		<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Creating connection to server:"</span> <span class="o">+</span> <span class="n">host</span><span class="o">);</span>
		<span class="n">session</span><span class="o">.</span><span class="na">connect</span><span class="o">();</span>
		<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Connected to server, initializing Port forwarding "</span><span class="o">);</span>
		<span class="n">session</span><span class="o">.</span><span class="na">setPortForwardingL</span><span class="o">(</span><span class="n">tunnelLocalPort</span><span class="o">,</span> <span class="n">tunnelRemoteHost</span><span class="o">,</span> <span class="n">tunnelRemotePort</span><span class="o">);</span>
		
		<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Port forward successful forwarding: localhost:"</span> <span class="o">+</span> <span class="n">tunnelLocalPort</span> <span class="o">+</span> <span class="s">" -&gt; "</span>
				<span class="o">+</span> <span class="n">tunnelRemoteHost</span> <span class="o">+</span> <span class="s">":"</span> <span class="o">+</span> <span class="n">tunnelRemotePort</span><span class="o">);</span>

		<span class="k">try</span> <span class="o">{</span>

			<span class="no">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="s">"http://localhost:8000"</span><span class="o">);</span>
			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Reading data from URL: "</span> <span class="o">+</span> <span class="n">url</span><span class="o">);</span>
			<span class="nc">BufferedReader</span> <span class="n">in</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">url</span><span class="o">.</span><span class="na">openStream</span><span class="o">()));</span>
			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"================== Data From URL ==================\n"</span><span class="o">);</span>
			<span class="nc">String</span> <span class="n">inputLine</span><span class="o">;</span>
			<span class="k">while</span> <span class="o">((</span><span class="n">inputLine</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">inputLine</span><span class="o">);</span>
			<span class="n">in</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>

			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"================== Data From URL ==================\n"</span><span class="o">);</span>
		<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
			<span class="c1">// TODO Auto-generated catch block</span>
			<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
		<span class="o">}</span>

		<span class="k">if</span> <span class="o">(</span><span class="n">session</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">session</span><span class="o">.</span><span class="na">isConnected</span><span class="o">())</span> <span class="o">{</span>
			<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Closing SSH Connection"</span><span class="o">);</span>
			<span class="n">session</span><span class="o">.</span><span class="na">disconnect</span><span class="o">();</span>
		<span class="o">}</span>

	<span class="o">}</span>

	<span class="kd">class</span> <span class="nc">localUserInfo</span> <span class="kd">implements</span> <span class="nc">UserInfo</span> <span class="o">{</span>
		<span class="nc">String</span> <span class="n">passwd</span><span class="o">;</span>

		<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getPassword</span><span class="o">()</span> <span class="o">{</span>
			<span class="k">return</span> <span class="n">passwd</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">promptYesNo</span><span class="o">(</span><span class="nc">String</span> <span class="n">str</span><span class="o">)</span> <span class="o">{</span>
			<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getPassphrase</span><span class="o">()</span> <span class="o">{</span>
			<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">promptPassphrase</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
			<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">promptPassword</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
			<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
		<span class="o">}</span>

		<span class="kd">public</span> <span class="kt">void</span> <span class="nf">showMessage</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
		<span class="o">}</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<!-- wp:heading {"level":3} -->

<h3 id="apache-mina">Apache MINA</h3>

<p><strong>Dependencies</strong></p>

<!-- wp:enlighter/codeblock {"language":"xml"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="o">&lt;!--</span> <span class="nl">https:</span><span class="c1">//mvnrepository.com/artifact/org.apache.mina/mina-core --&gt;</span>
		<span class="o">&lt;</span><span class="n">dependency</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">groupId</span><span class="o">&gt;</span><span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">mina</span><span class="o">&lt;/</span><span class="n">groupId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">artifactId</span><span class="o">&gt;</span><span class="n">mina</span><span class="o">-</span><span class="n">core</span><span class="o">&lt;/</span><span class="n">artifactId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">version</span><span class="o">&gt;</span><span class="mf">3.0</span><span class="o">.</span><span class="mi">0</span><span class="o">-</span><span class="no">M2</span><span class="o">&lt;/</span><span class="n">version</span><span class="o">&gt;</span>
		<span class="o">&lt;/</span><span class="n">dependency</span><span class="o">&gt;</span>

		<span class="o">&lt;!--</span> <span class="nl">https:</span><span class="c1">//mvnrepository.com/artifact/org.apache.sshd/sshd-core --&gt;</span>
		<span class="o">&lt;</span><span class="n">dependency</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">groupId</span><span class="o">&gt;</span><span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">sshd</span><span class="o">&lt;/</span><span class="n">groupId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">artifactId</span><span class="o">&gt;</span><span class="n">sshd</span><span class="o">-</span><span class="n">core</span><span class="o">&lt;/</span><span class="n">artifactId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">version</span><span class="o">&gt;</span><span class="mf">2.1</span><span class="o">.</span><span class="mi">0</span><span class="o">&lt;/</span><span class="n">version</span><span class="o">&gt;</span>
		<span class="o">&lt;/</span><span class="n">dependency</span><span class="o">&gt;</span>

		<span class="o">&lt;</span><span class="n">dependency</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">groupId</span><span class="o">&gt;</span><span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">sshd</span><span class="o">&lt;/</span><span class="n">groupId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">artifactId</span><span class="o">&gt;</span><span class="n">sshd</span><span class="o">-</span><span class="n">putty</span><span class="o">&lt;/</span><span class="n">artifactId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">version</span><span class="o">&gt;</span><span class="mf">2.1</span><span class="o">.</span><span class="mi">0</span><span class="o">&lt;/</span><span class="n">version</span><span class="o">&gt;</span>
		<span class="o">&lt;/</span><span class="n">dependency</span><span class="o">&gt;</span>

		<span class="o">&lt;</span><span class="n">dependency</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">groupId</span><span class="o">&gt;</span><span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">sshd</span><span class="o">&lt;/</span><span class="n">groupId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">artifactId</span><span class="o">&gt;</span><span class="n">sshd</span><span class="o">-</span><span class="n">common</span><span class="o">&lt;/</span><span class="n">artifactId</span><span class="o">&gt;</span>
			<span class="o">&lt;</span><span class="n">version</span><span class="o">&gt;</span><span class="mf">2.1</span><span class="o">.</span><span class="mi">0</span><span class="o">&lt;/</span><span class="n">version</span><span class="o">&gt;</span>
		<span class="o">&lt;/</span><span class="n">dependency</span><span class="o">&gt;</span>
</code></pre></div></div>

<p><strong>Example</strong></p>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">java.io.BufferedReader</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.io.InputStreamReader</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.HttpURLConnection</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.InetSocketAddress</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.MalformedURLException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.Proxy</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.URISyntaxException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.nio.file.Paths</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.security.GeneralSecurityException</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.security.KeyPair</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Collection</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Collections</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">org.apache.sshd.client.SshClient</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.client.auth.hostbased.HostKeyIdentityProvider</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.client.session.ClientSession</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.NamedFactory</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.config.keys.loader.pem.PEMResourceParserUtils</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.config.keys.loader.putty.PuttyKeyUtils</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.forward.PortForwardingEventListener</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.session.Session</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.common.util.net.SshdSocketAddress</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.server.channel.PuttyRequestHandler</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.server.forward.AcceptAllForwardingFilter</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider</span><span class="o">;</span>

<span class="cm">/**
 * This class
 * 
 * @author Ankit Katiyar
 *
 */</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AmazonTest</span> <span class="o">{</span>

	<span class="kd">private</span> <span class="kd">static</span> <span class="nc">String</span> <span class="no">BASTION_SERVER_PASSWORD</span> <span class="o">=</span> <span class="s">"P@ssword1"</span><span class="o">;</span>
	<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">String</span> <span class="no">BASTION_SERVER_USER</span> <span class="o">=</span> <span class="s">"ec2-user"</span><span class="o">;</span>
	<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">String</span> <span class="no">BASTION_SEREVR_HOST</span> <span class="o">=</span> <span class="s">"ec2-18-191-207-91.us-east-2.compute.amazonaws.com"</span><span class="o">;</span>
	<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">String</span> <span class="no">URL_TO_ACCESS</span> <span class="o">=</span> <span class="s">"http://www.google.com"</span><span class="o">;</span>

	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>

		<span class="k">try</span> <span class="o">{</span>
			
			
			<span class="nc">Collection</span><span class="o">&lt;</span><span class="nc">KeyPair</span><span class="o">&gt;</span> <span class="n">keys</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
			<span class="c1">// OPtional loading keys from a PEM file</span>
			<span class="c1">//keys=PEMResourceParserUtils.getPEMResourceParserByAlgorithm("RSA").loadKeyPairs(ClassLoader.getSystemResource("local-ps-test.pem").toURI().toURL(), null);</span>
			
			<span class="c1">// Optional: Using Putty key for login </span>
			 <span class="n">keys</span><span class="o">=</span><span class="nc">PuttyKeyUtils</span><span class="o">.</span><span class="na">DEFAULT_INSTANCE</span><span class="o">.</span><span class="na">loadKeyPairs</span><span class="o">(</span><span class="nc">ClassLoader</span><span class="o">.</span><span class="na">getSystemResource</span><span class="o">(</span><span class="s">"local-ps-private-key.ppk"</span><span class="o">).</span><span class="na">toURI</span><span class="o">().</span><span class="na">toURL</span><span class="o">(),</span> <span class="kc">null</span><span class="o">);</span>
			 
			<span class="nc">SshClient</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">SshClient</span><span class="o">.</span><span class="na">setUpDefaultClient</span><span class="o">();</span>
			<span class="n">client</span><span class="o">.</span><span class="na">setForwardingFilter</span><span class="o">(</span><span class="nc">AcceptAllForwardingFilter</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">);</span>
			<span class="n">client</span><span class="o">.</span><span class="na">setServerKeyVerifier</span><span class="o">(</span><span class="nc">AcceptAllServerKeyVerifier</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">);</span>
			<span class="n">client</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>

			<span class="c1">// using the client for multiple sessions...</span>
			<span class="k">try</span> <span class="o">(</span><span class="nc">ClientSession</span> <span class="n">session</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">connect</span><span class="o">(</span><span class="no">BASTION_SERVER_USER</span><span class="o">,</span> <span class="no">BASTION_SEREVR_HOST</span><span class="o">,</span> <span class="mi">22</span><span class="o">).</span><span class="na">verify</span><span class="o">()</span>
					<span class="o">.</span><span class="na">getSession</span><span class="o">())</span> <span class="o">{</span>
				<span class="c1">// IF you use password to login provide here</span>
				<span class="c1">// session.addPasswordIdentity(BASTION_SERVER_PASSWORD); // for password-based</span>
				<span class="c1">// authentication</span>
				
				<span class="n">session</span><span class="o">.</span><span class="na">addPublicKeyIdentity</span><span class="o">(</span><span class="n">keys</span><span class="o">.</span><span class="na">iterator</span><span class="o">().</span><span class="na">next</span><span class="o">());</span>

				<span class="c1">// authentication</span>
				<span class="c1">// Note: can add BOTH password AND public key identities - depends on the</span>
				<span class="c1">// client/server security setup</span>

				<span class="n">session</span><span class="o">.</span><span class="na">auth</span><span class="o">().</span><span class="na">verify</span><span class="o">(</span><span class="mi">10000</span><span class="o">);</span>
				<span class="c1">// start using the session to run commands, do SCP/SFTP, create local/remote</span>
				<span class="c1">// port forwarding, etc...</span>

				<span class="n">session</span><span class="o">.</span><span class="na">addPortForwardingEventListener</span><span class="o">(</span><span class="k">new</span> <span class="nc">PortForwardingEventListener</span><span class="o">()</span> <span class="o">{</span>

					<span class="nd">@Override</span>
					<span class="kd">public</span> <span class="kt">void</span> <span class="nf">establishedDynamicTunnel</span><span class="o">(</span><span class="nc">Session</span> <span class="n">session</span><span class="o">,</span> <span class="nc">SshdSocketAddress</span> <span class="n">local</span><span class="o">,</span>
							<span class="nc">SshdSocketAddress</span> <span class="n">boundAddress</span><span class="o">,</span> <span class="nc">Throwable</span> <span class="n">reason</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
						<span class="c1">// TODO Auto-generated method stub</span>
						<span class="nc">PortForwardingEventListener</span><span class="o">.</span><span class="na">super</span><span class="o">.</span><span class="na">establishedDynamicTunnel</span><span class="o">(</span><span class="n">session</span><span class="o">,</span> <span class="n">local</span><span class="o">,</span> <span class="n">boundAddress</span><span class="o">,</span> <span class="n">reason</span><span class="o">);</span>

						<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Dynamic Forword Tunnel is Ready"</span><span class="o">);</span>
					<span class="o">}</span>
				<span class="o">});</span>

				<span class="nc">SshdSocketAddress</span> <span class="n">sshdSocketAddress</span> <span class="o">=</span> <span class="n">session</span>
						<span class="o">.</span><span class="na">startDynamicPortForwarding</span><span class="o">(</span><span class="k">new</span> <span class="nc">SshdSocketAddress</span><span class="o">(</span><span class="s">"localhost"</span><span class="o">,</span> <span class="mi">8000</span><span class="o">));</span>

				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Host: "</span> <span class="o">+</span> <span class="n">sshdSocketAddress</span><span class="o">.</span><span class="na">getHostName</span><span class="o">());</span>
				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Port: "</span> <span class="o">+</span> <span class="n">sshdSocketAddress</span><span class="o">.</span><span class="na">getPort</span><span class="o">());</span>

				<span class="c1">// Create a Proxy object to work with</span>
				<span class="nc">Proxy</span> <span class="n">proxy</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Proxy</span><span class="o">(</span><span class="nc">Proxy</span><span class="o">.</span><span class="na">Type</span><span class="o">.</span><span class="na">SOCKS</span><span class="o">,</span>
						<span class="k">new</span> <span class="nf">InetSocketAddress</span><span class="o">(</span><span class="n">sshdSocketAddress</span><span class="o">.</span><span class="na">getHostName</span><span class="o">(),</span> <span class="n">sshdSocketAddress</span><span class="o">.</span><span class="na">getPort</span><span class="o">()));</span>

				<span class="cm">/**
				 * Now you can use this proxy instance into any URL until this SSH session is active. 
				 */</span>
				
				<span class="c1">// TEST one URL</span>
				<span class="nc">HttpURLConnection</span> <span class="n">connection</span> <span class="o">=</span> <span class="o">(</span><span class="nc">HttpURLConnection</span><span class="o">)</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="no">URL_TO_ACCESS</span><span class="o">).</span><span class="na">openConnection</span><span class="o">(</span><span class="n">proxy</span><span class="o">);</span>

				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Proxy work:"</span> <span class="o">+</span> <span class="n">connection</span><span class="o">.</span><span class="na">getURL</span><span class="o">());</span>

				<span class="nc">BufferedReader</span> <span class="n">in</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">connection</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">()));</span>
				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"================== Data From URL ==================\n"</span><span class="o">);</span>
				<span class="nc">String</span> <span class="n">inputLine</span><span class="o">;</span>
				<span class="k">while</span> <span class="o">((</span><span class="n">inputLine</span> <span class="o">=</span> <span class="n">in</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
					<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">inputLine</span><span class="o">);</span>
				<span class="n">in</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>

				<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"================== Data From URL ==================\n"</span><span class="o">);</span>
			<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e1</span><span class="o">)</span> <span class="o">{</span>
				<span class="c1">// TODO Auto-generated catch block</span>
				<span class="n">e1</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
			<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
				<span class="c1">// TODO Auto-generated catch block</span>
				<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
			<span class="o">}</span>
		<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
			<span class="c1">// TODO Auto-generated catch block</span>
			<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
		<span class="o">}</span>

	<span class="o">}</span>

<span class="o">}</span>
</code></pre></div></div>

<p>View complete project at <a href="https://github.com/ankitkatiyar91/java-framework-examples/tree/master/java-tunneling">GitHub </a></p>

<p><a href="https://github.com/ankitkatiyar91/java-framework-examples/tree/master/java-tunneling">https://github.com/ankitkatiyar91/java-framework-examples/tree/master/java-tunneling</a></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Java" /><category term="Dynamic port forward in java" /><category term="Java Tunnel" /><summary type="html"><![CDATA[Create a putty like dynamic port forward in Java. Unable to access URL on you network? want to bypass them over a bastion server? A running demo using JSCH and Apache MINA to use port forwarding.]]></summary></entry><entry><title type="html">JVM Shutdown Hook</title><link href="https://ankitkatiyar91.github.io/bytefold-site/jvm-shutdown-hook/" rel="alternate" type="text/html" title="JVM Shutdown Hook" /><published>2019-01-26T16:25:05+00:00</published><updated>2019-01-26T16:25:05+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/jvm-shutdown-hook</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/jvm-shutdown-hook/"><![CDATA[<p>Recently I got a problem where I had to perform some task while the application is shutting down. I worked with <g class="gr_ gr_18 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace" id="18" data-gr-id="18">lot's</g> of problems where I have to write object unload tasks (_ <strong>finalize</strong> _ method). But this was something completely new to me.</p>

<p>After some googling I found that JAVA supports JVM shutdown hooks. These hooks are some threads that are executed when JVM is shutting down. Java’s Runtime class provide an <strong><em>addShutdownHook(Thread hook) </em></strong>method. This method will add this <strong><em>hook</em> </strong> thread to be executed when all the tasks are done and JVM this about to shutdown/close.</p>

<!-- wp:enlighter/codeblock {"language":"java"} -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">JVMShutdownHook</span>
<span class="o">{</span>

    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span>
    <span class="o">{</span>
        <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Main start... "</span><span class="o">);</span>
        <span class="nc">Runtime</span><span class="o">.</span><span class="na">getRuntime</span><span class="o">().</span><span class="na">addShutdownHook</span><span class="o">(</span><span class="k">new</span> <span class="nc">Thread</span><span class="o">()</span>
        <span class="o">{</span>
            <span class="nd">@Override</span>
            <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span>
            <span class="o">{</span>
                <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Finally shut down hook called"</span><span class="o">);</span>
            <span class="o">}</span>
        <span class="o">});</span>

        <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Main end.... "</span><span class="o">);</span>
    <span class="o">}</span>

<span class="o">}</span>
</code></pre></div></div>

<!-- wp:heading {"level":4} -->

<h4 id="output">Output</h4>

<!-- wp:code -->

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="nc">Main</span> <span class="n">start</span><span class="o">...</span> 
<span class="nc">Main</span> <span class="n">end</span><span class="o">....</span>   
<span class="nc">Finally</span> <span class="n">shut</span> <span class="n">down</span> <span class="n">hook</span> <span class="n">called</span>
</code></pre></div></div>

<!-- /wp:code -->

<p>You can see from the output that code inside hook is executed at the end. This way you can handle events, free resources or something else like updating some flags/logs/process file when you application is shutting down. We often need these while running some jobs on server.</p>

<!-- wp:separator -->

<hr />
<!-- /wp:separator -->

<!-- wp:paragraph {"align":"right"} -->

<p>A moment’s insight is sometimes worth a life’s experience.<br />
 –Oliver Wendell Holmes (1809-1894)</p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Java" /><category term="JVM Shutdown Hook" /><summary type="html"><![CDATA[JVM shutdown hook are like finalize methods for your JVM. It does the same job for JVM that finalize method does for the objects of a class.]]></summary></entry><entry><title type="html">Traversing an array without using length property</title><link href="https://ankitkatiyar91.github.io/bytefold-site/traversing-an-array-without-using-length-property/" rel="alternate" type="text/html" title="Traversing an array without using length property" /><published>2018-08-04T19:23:49+00:00</published><updated>2018-08-04T19:23:49+00:00</updated><id>https://ankitkatiyar91.github.io/bytefold-site/traversing-an-array-without-using-length-property</id><content type="html" xml:base="https://ankitkatiyar91.github.io/bytefold-site/traversing-an-array-without-using-length-property/"><![CDATA[<p>We often face an interview question when it is asked to search or traverse an array without knowing/using the length property. In Java, if you try to access the element that is outside the length of the array.</p>

<p>it will give you an exception as <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html"><strong>java.lang.ArrayIndexOutOfBoundsException</strong></a>.</p>

<p>Here I have one implementation of a binary search where I will not use the length property of the array.</p>

<h3 id="example">Example</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="syntax"><code><span class="kn">import</span> <span class="nn">static</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Math</span><span class="o">.</span><span class="na">pow</span><span class="o">;</span>

<span class="kd">public</span> <span class="kd">class</span> <span class="nc">BinarySearchWithoutLength</span> <span class="o">{</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Integer</span> <span class="nf">binarySearch</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Integer</span><span class="o">[]</span> <span class="n">elements</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">Integer</span> <span class="n">find</span><span class="o">)</span> <span class="o">{</span>
    <span class="cm">/*
     * Start looking for element at the 0th position and move in multiple of 2. like 2^0, 2^1, 2^2,
     * 2^3
     */</span>
    <span class="nc">Integer</span> <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
    <span class="nc">Integer</span> <span class="n">exp</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="c1">// initial exponent value will be 0</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">while</span> <span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="o">{</span>
        <span class="c1">// check if we found the element at 2^exp index</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">elements</span><span class="o">[</span><span class="n">index</span><span class="o">]</span> <span class="o">==</span> <span class="n">find</span><span class="o">)</span> <span class="o">{</span>
          <span class="k">return</span> <span class="n">index</span><span class="o">;</span>
        <span class="o">}</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">elements</span><span class="o">[</span><span class="n">index</span><span class="o">]</span> <span class="o">&lt;</span> <span class="n">find</span><span class="o">)</span> <span class="o">{</span>
          <span class="n">index</span> <span class="o">=</span> <span class="o">(</span><span class="kt">int</span><span class="o">)</span> <span class="n">pow</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">exp</span><span class="o">);</span>
          <span class="n">exp</span> <span class="o">+=</span> <span class="mi">1</span><span class="o">;</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
          <span class="k">break</span><span class="o">;</span>
        <span class="o">}</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">ArrayIndexOutOfBoundsException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="cm">/*
       * ignore this exception as we expect it to happen if we go beyond the size of the array
       * without finding element at position 2^exp
       */</span>
    <span class="o">}</span>
    <span class="kt">int</span> <span class="n">mid</span><span class="o">;</span> <span class="c1">// it will represent mid value where lookup will happen</span>
    <span class="kt">int</span> <span class="n">left</span> <span class="o">=</span> <span class="o">(</span><span class="n">index</span> <span class="o">/</span> <span class="mi">2</span><span class="o">)</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kt">int</span> <span class="n">right</span> <span class="o">=</span> <span class="n">index</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span>
    <span class="cm">/*
     * we will start our lookup from the middle of the array and then shift towards other half of
     * the array.
     */</span>
    <span class="k">while</span> <span class="o">(</span><span class="n">left</span> <span class="o">&lt;=</span> <span class="n">right</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">mid</span> <span class="o">=</span> <span class="o">((</span><span class="n">right</span> <span class="o">+</span> <span class="n">left</span><span class="o">)</span> <span class="o">/</span> <span class="mi">2</span><span class="o">);</span>
      <span class="k">try</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">elements</span><span class="o">[</span><span class="n">mid</span><span class="o">]</span> <span class="o">==</span> <span class="n">find</span><span class="o">)</span> <span class="o">{</span>
          <span class="cm">/*
           * As we have found one matching element. Stop
           */</span>
          <span class="k">return</span> <span class="n">mid</span><span class="o">;</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
          <span class="k">if</span> <span class="o">(</span><span class="n">elements</span><span class="o">[</span><span class="n">mid</span><span class="o">]</span> <span class="o">&gt;</span> <span class="n">find</span><span class="o">)</span> <span class="o">{</span>
            <span class="cm">/* whenever you find and element which is greater than the find */</span>
            <span class="n">right</span> <span class="o">=</span> <span class="n">mid</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span>
          <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="n">left</span> <span class="o">=</span> <span class="n">mid</span> <span class="o">+</span> <span class="mi">1</span><span class="o">;</span>
          <span class="o">}</span>
        <span class="o">}</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">ArrayIndexOutOfBoundsException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="cm">/*
         * we got this because we reached beyond the size, shift our right index to one place left
         * of the mid
         */</span>
        <span class="n">right</span> <span class="o">=</span> <span class="n">mid</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span>
      <span class="o">}</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="o">;</span>
  <span class="o">}</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="nc">Integer</span><span class="o">[]</span> <span class="n">sample_1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Integer</span><span class="o">[]</span> <span class="o">{-</span><span class="mi">3</span><span class="o">,</span> <span class="o">-</span><span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">7</span><span class="o">};</span>
    <span class="nc">Integer</span><span class="o">[]</span> <span class="n">sample_2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Integer</span><span class="o">[]</span> <span class="o">{-</span><span class="mi">3</span><span class="o">,</span> <span class="o">-</span><span class="mi">2</span><span class="o">,</span> <span class="o">-</span><span class="mi">1</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">6</span><span class="o">,</span> <span class="mi">7</span><span class="o">,</span> <span class="mi">8</span><span class="o">,</span> <span class="mi">9</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">12</span><span class="o">,</span> <span class="mi">13</span><span class="o">};</span>
    <span class="nc">Integer</span><span class="o">[]</span> <span class="n">sample_3</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Integer</span><span class="o">[]</span> <span class="o">{</span><span class="mi">1</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">6</span><span class="o">,</span> <span class="mi">7</span><span class="o">,</span> <span class="mi">8</span><span class="o">,</span> <span class="mi">9</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">12</span><span class="o">,</span> <span class="mi">13</span><span class="o">};</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Index of 4: "</span> <span class="o">+</span> <span class="n">binarySearch</span><span class="o">(</span><span class="n">sample_1</span><span class="o">,</span> <span class="mi">4</span><span class="o">));</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Index of 4: "</span> <span class="o">+</span> <span class="n">binarySearch</span><span class="o">(</span><span class="n">sample_2</span><span class="o">,</span> <span class="mi">4</span><span class="o">));</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Index of 4: "</span> <span class="o">+</span> <span class="n">binarySearch</span><span class="o">(</span><span class="n">sample_3</span><span class="o">,</span> <span class="mi">10</span><span class="o">));</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Index of 4: "</span> <span class="o">+</span> <span class="n">binarySearch</span><span class="o">(</span><span class="n">sample_3</span><span class="o">,</span> <span class="mi">0</span><span class="o">));</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p><a href="https://github.com/ankitkatiyar91/bytefold/blob/master/java/BinarySearchWithoutLength.java">Download from GitHub</a></p>]]></content><author><name>Ankit Katiyar</name><email>ankit@bytefold.com</email></author><category term="Java" /><category term="Miscellaneous" /><category term="Binary Search" /><category term="Java" /><summary type="html"><![CDATA[We often face an interview question when it is asked to search or traverse an array without knowing/using the length property. In Java, if you try to access the element that is outside the length of the array. it will give you an exception as java.lang.ArrayIndexOutOfBoundsException. Here I have one implementation of a binary search where I will not use the length property of the array. Example import static java.lang.Math.pow; public class BinarySearchWithoutLength { public static Integer binarySearch(final Integer[] elements, final Integer find) { /* * Start looking for element at the 0th position and move in multiple of 2. like 2^0, 2^1, 2^2, * 2^3 */ Integer index = 0; Integer exp = 0; // initial exponent value will be 0 try { while (true) { // check if we found the element at 2^exp index if (elements[index] == find) { return index; } if (elements[index] &lt; find) { index = (int) pow(2, exp); exp += 1; } else { break; } } } catch (ArrayIndexOutOfBoundsException e) { /* * ignore this exception as we expect it to happen if we go beyond the size of the array * without finding element at position 2^exp */ } int mid; // it will represent mid value where lookup will happen int left = (index / 2) + 1; int right = index - 1; /* * we will start our lookup from the middle of the array and then shift towards other half of * the array. */ while (left &lt;= right) { mid = ((right + left) / 2); try { if (elements[mid] == find) { /* * As we have found one matching element. Stop */ return mid; } else { if (elements[mid] &gt; find) { /* whenever you find and element which is greater than the find */ right = mid - 1; } else { left = mid + 1; } } } catch (ArrayIndexOutOfBoundsException e) { /* * we got this because we reached beyond the size, shift our right index to one place left * of the mid */ right = mid - 1; } } return -1; } public static void main(String[] args) { Integer[] sample_1 = new Integer[] {-3, -2, 3, 4, 7}; Integer[] sample_2 = new Integer[] {-3, -2, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; Integer[] sample_3 = new Integer[] {1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; System.out.println("Index of 4: " + binarySearch(sample_1, 4)); System.out.println("Index of 4: " + binarySearch(sample_2, 4)); System.out.println("Index of 4: " + binarySearch(sample_3, 10)); System.out.println("Index of 4: " + binarySearch(sample_3, 0)); } } Download from GitHub]]></summary></entry></feed>