<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-3906796692834764817</atom:id><lastBuildDate>Tue, 12 May 2026 06:23:31 +0000</lastBuildDate><category>How To</category><category>Social Media</category><category>Google</category><category>Wallpapers</category><category>Facebook</category><category>android</category><category>Mobile</category><category>Ethical Hacking</category><category>DevOps</category><category>NGINX</category><category>Top Tech News</category><category>Programming</category><category>Scala</category><category>Google Plus</category><category>Parallel Programming</category><category>Tech Junkie</category><category>iphone 5</category><category>tor</category><category>AWS</category><category>Blogging</category><category>Clojure</category><category>Cryptocurrency</category><category>Fun Stuff</category><category>Linux</category><category>SSL</category><category>email</category><category>free</category><category>gmail</category><category>iphone</category><category>music</category><category>social good</category><category>way2sms</category><category>wep</category><category>wireless network</category><category>Akka</category><category>Akka Streams</category><category>Play Framework</category><category>Reactive Streams</category><category>Scala Cats</category><category>Scala Cats Effect</category><category>Slick</category><category>app</category><category>apps</category><category>aws lambda</category><category>bitcoins</category><category>blogger</category><category>browser</category><category>chrome</category><category>darknet</category><category>deep web</category><category>opera</category><category>privacy</category><category>recharge</category><category>remove</category><category>service</category><category>ubuntu</category><category>160by2</category><category>AWS S3</category><category>Alpakka</category><category>Amazon Web Services</category><category>Apache</category><category>Apache Curator</category><category>Blockchain</category><category>Cracking</category><category>Friend</category><category>IP Filtering</category><category>Java</category><category>Load Balancing</category><category>Map</category><category>Microsoft</category><category>Microsoft SQL Server</category><category>News Feeds</category><category>PFX</category><category>Play Store</category><category>PostgreSQL</category><category>Reactive Programming</category><category>Remote Profiling</category><category>Reverse Proxy Server</category><category>SMS</category><category>SQL</category><category>SSH</category><category>Softwares</category><category>Streaming</category><category>Tor Network</category><category>WIFI</category><category>Zookeeper</category><category>adfree</category><category>anonymous</category><category>apple</category><category>babylon</category><category>cloud computing</category><category>cloud storage</category><category>computing</category><category>core</category><category>csvtojson</category><category>dolphin</category><category>download</category><category>drive</category><category>dual</category><category>extended</category><category>fake</category><category>firefox</category><category>games</category><category>greenify</category><category>grooveshark</category><category>hidden wiki</category><category>hilary duff</category><category>ice cream sandwich</category><category>image search</category><category>internet</category><category>ios</category><category>ipad</category><category>iphone 4S</category><category>jq</category><category>key lime pie</category><category>keyboard</category><category>malware</category><category>maps</category><category>market</category><category>nodejs</category><category>notifications</category><category>offline</category><category>online</category><category>picasa</category><category>pictures</category><category>play</category><category>popular</category><category>reverse image search</category><category>root</category><category>safari</category><category>search</category><category>shortcuts</category><category>slideshow</category><category>smiley</category><category>status</category><category>subscribe</category><category>time stamp</category><category>timeline</category><category>toolbar</category><category>tweaks</category><category>ucbrowser</category><category>update</category><category>viral</category><category>wallet</category><category>website</category><category>wordpress</category><category>wpa</category><title>UberTechBlog</title><description></description><link>http://www.ubertechblog.com/</link><managingEditor>noreply@blogger.com (Sidharth Khattri)</managingEditor><generator>Blogger</generator><openSearch:totalResults>112</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-7136015757797336336</guid><pubDate>Sun, 07 Feb 2021 23:43:00 +0000</pubDate><atom:updated>2021-02-08T05:13:46.486+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">AWS</category><category domain="http://www.blogger.com/atom/ns#">aws lambda</category><category domain="http://www.blogger.com/atom/ns#">csvtojson</category><category domain="http://www.blogger.com/atom/ns#">nodejs</category><title>Create Node.js and csvtojson Lambda Layer for AWS Lambda Custom Runtime</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisx8vX4w1F2rosZ911JpryYhKDfHsjL7ZrSLU6yu77MgrrEDuhILV7nYRcr4A8kBhi-e9UBYYs6fgJ9EDAlTU2myPow9OfJUhtNCAhlK3JmimmzWg5yaOtPoF0CacbCOlXP9oQxgcQO2c/s768/AWS-Lambda-and-Node.js-12_-Support-and-Benchmark.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;515&quot; data-original-width=&quot;768&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisx8vX4w1F2rosZ911JpryYhKDfHsjL7ZrSLU6yu77MgrrEDuhILV7nYRcr4A8kBhi-e9UBYYs6fgJ9EDAlTU2myPow9OfJUhtNCAhlK3JmimmzWg5yaOtPoF0CacbCOlXP9oQxgcQO2c/w379-h255/AWS-Lambda-and-Node.js-12_-Support-and-Benchmark.png&quot; width=&quot;379&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;This post will cover how to use Node.js and&amp;nbsp;&lt;a href=&quot;https://www.npmjs.com/package/csvtojson&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;csvtojson&lt;/a&gt;&amp;nbsp;in AWS Lambda Custom Runtime which can be useful for use cases wherein CSV to JSON conversion is required as a part of a Lambda function in a serverless architecture.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Have a quick look at &lt;a href=&quot;https://www.ubertechblog.com/2021/01/using-jq-in-aws-lambda-custom-runtime-via-aws-lambda-layer.html&quot; target=&quot;_blank&quot;&gt;Using JQ in AWS Lambda Custom Runtime via AWS Lambda Layer&lt;/a&gt; for a quick reference to understanding how AWS Lambda Custom Runtime is bootstrapped and how AWS Layers works.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Creating Node.js Lambda Layer&lt;/h3&gt;&lt;p&gt;Setup for Node.js for AWS Lambda Custom Runtime is actually quite easy, all that is needed is&amp;nbsp;&lt;a href=&quot;https://www.npmjs.com/package/aws-lambda-custom-node-runtime&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;aws-lambda-custom-node-runtime&lt;/a&gt;&amp;nbsp;(v1.0.2). Install NPM if not already done, and run the following command:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;aws-lambda-custom-node-runtime 11.3.0&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The above command will generate a directory named&amp;nbsp;&lt;i&gt;node-v11.3.0-linux-x64&lt;/i&gt;&amp;nbsp;(at the path where the command is run) with all the necessary files required to run Node.js.&lt;/p&gt;&lt;p&gt;Now zip the entire&amp;nbsp;&lt;i&gt;node-v11.3.0-linux-x64&lt;/i&gt;&amp;nbsp;directory using the following command&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;zip -r node-v11.3.0-linux-x64.zip node-v11.3.0-linux-x64&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The zip archive, i.e&amp;nbsp;&lt;i&gt;node-v11.3.0-linux-x64.zip&lt;/i&gt;, is our Node.js Lambda layer.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Creating CSVTOJSON Lambda Layer&lt;/h3&gt;&lt;p&gt;To create a CSVTOJSON bundle, run the following command&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-fd3f7a5c-7fff-7854-7299-4444c4fddce4&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;npm install csvtojson --save&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This will create a &lt;i&gt;node_modules&lt;/i&gt; directory at the path at which the command is executed. Now, similar to what was done for building the Node.js layer, run the following command to build the CSVTOJSON Lambda Layer&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;zip -r node_dependencies.zip node_modules&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The&amp;nbsp;node_dependencies.zip is now our CSVTOJSON Lambda layer.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Separating Lambda layers as Node.js layer and node dependencies layer helps because doing so allows the layers to be reused across multiple Lambda functions. Doing this, the Node.js Lambda layer can be reused across multiple Lambda functions and each Lambda function can have its own set of node dependencies. But it all boils down to how AWS Lambdas are used in your serverless architecture and there might be differences in best practices.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Using Node.js and CSVTOJSON Lambda Layers&lt;/h3&gt;&lt;p&gt;Now, the built Lambda Layers can be uploaded to the AWS Lambda Layers section, and a test-run in the following way can be done to verify whether they are working fine:&lt;/p&gt;&lt;p&gt;(Visit&amp;nbsp;&lt;a href=&quot;https://www.ubertechblog.com/2021/01/using-jq-in-aws-lambda-custom-runtime-via-aws-lambda-layer.html&quot; target=&quot;_blank&quot;&gt;Using JQ in AWS Lambda Custom Runtime via AWS Lambda Layer&lt;/a&gt;&amp;nbsp;for more details on what the function handler)&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-size: 11pt; white-space: pre-wrap;&quot;&gt;function handler () {
    EVENT_DATA=$1
    
    cd /opt
    &lt;/span&gt;&lt;span style=&quot;font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;./node-v11.3.0-linux-x64/bin/node --version
    ./node-v11.3.0-linux-x64/bin/node node_modules/csvtojson/bin/csvtojson version&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; white-space: pre-wrap;&quot;&gt;
}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;When the above handler is triggered, the Node and CSVTOJSON versions can be expected in the success output.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2021/02/create-nodejs-and-csvtojson-lambda-layer-for-aws-lambda-custom-runtime.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisx8vX4w1F2rosZ911JpryYhKDfHsjL7ZrSLU6yu77MgrrEDuhILV7nYRcr4A8kBhi-e9UBYYs6fgJ9EDAlTU2myPow9OfJUhtNCAhlK3JmimmzWg5yaOtPoF0CacbCOlXP9oQxgcQO2c/s72-w379-h255-c/AWS-Lambda-and-Node.js-12_-Support-and-Benchmark.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-2184036838845333414</guid><pubDate>Sat, 30 Jan 2021 23:25:00 +0000</pubDate><atom:updated>2021-01-31T04:55:32.123+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">AWS</category><category domain="http://www.blogger.com/atom/ns#">aws lambda</category><category domain="http://www.blogger.com/atom/ns#">jq</category><category domain="http://www.blogger.com/atom/ns#">Linux</category><title>Using JQ in AWS Lambda Custom Runtime via AWS Lambda Layer</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNRAc-IkYgjZ3JFsxaL9ak-EfnYntRcLgr9sMHW9bvSX_VP3GZN4SUvH_w5xXa2h0h-sRxhS5mTQ5LtK63u-XA9WAnyjleiPsOyor2a2rAN7erhjbi3S_QMhzamjWRS1ZWXUDJkauUf40/s2048/lambda.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1343&quot; data-original-width=&quot;2048&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNRAc-IkYgjZ3JFsxaL9ak-EfnYntRcLgr9sMHW9bvSX_VP3GZN4SUvH_w5xXa2h0h-sRxhS5mTQ5LtK63u-XA9WAnyjleiPsOyor2a2rAN7erhjbi3S_QMhzamjWRS1ZWXUDJkauUf40/w381-h250/lambda.png&quot; width=&quot;381&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;For a situation wherein there&#39;s a need to use &lt;a href=&quot;https://stedolan.github.io/jq/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;JQ&lt;/a&gt;&amp;nbsp;on AWS Lambda custom runtime, an AWS Lambda layer can be created and used for your AWS Lambda function. This blog post explains how the aforementioned can be achieved but is not just limited to creating a layer for JQ, the instructions can be similarly used for building AWS Lambda layer for any Linux distribution.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;For quick reference&lt;/h3&gt;&lt;p&gt;&lt;i&gt;&lt;u&gt;AWS Lambda:&lt;/u&gt;&lt;/i&gt; is a serverless compute service that allows running code without provisioning or managing servers. It&#39;s a powerful tool backing for potentially implementing the serverless architecture.&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;u&gt;JQ:&lt;/u&gt;&lt;/i&gt; it&#39;s is like &lt;i&gt;sed&lt;/i&gt; for JSON data and is a fast and flexible CLI JSON processor tool written in&amp;nbsp;portable C.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Steps to follow&lt;/h3&gt;&lt;p&gt;The entire process of building an AWS Lambda layer can be broken down as follows:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Get the required distribution files&lt;/li&gt;&lt;li&gt;Build a zip archive of the required files&amp;nbsp;&lt;/li&gt;&lt;li&gt;Create a layer on AWS Lambda&lt;/li&gt;&lt;li&gt;Use created AWS Lambda layer for your Lambda function&lt;/li&gt;&lt;/ul&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Get required distribution files&lt;/h4&gt;&lt;div&gt;Since AWS Lambda custom runtime is based on Amazon Linux AMI, let&#39;s first get the JQ files specific to Amazon Linux AMI. For this, create a new Amazon Linux EC2 instance (or use an&amp;nbsp;&lt;a href=&quot;https://hub.docker.com/_/amazonlinux/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Amazon Linux Docker image&lt;/a&gt;).&amp;nbsp;&lt;/div&gt;&lt;p&gt;Install JQ and locate the required files (installed on Amazon Linux EC2 instance) once the installation is completed.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Installing JQ&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;sudo yum install jq&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;At the time of writing this post, for JQ version 1.5, the required files can be found at the following location:&amp;nbsp;&lt;/div&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-align: left; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;# executable
/usr/bin/jq

# dependencies
/usr/lib64/libjq.so
/usr/lib64/libjq.so.1.0.4
/usr/lib64/libonig.so.2
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Build a zip archive with required files&lt;/h4&gt;&lt;p&gt;Build a jq.zip archive containing all these required files so that JQ is functional when used inside the AWS Lambda function. The&amp;nbsp;&lt;i&gt;jq&lt;/i&gt; executable file should be at the root of the zip file and dependencies should be inside the &lt;i&gt;lib&lt;/i&gt; directory in the zip file. The reason being, when AWS Lambda layers are unpacked by AWS, the custom runtime dependency path of the Lambda function should be /opt and /opt/lib. To simplify it, /opt is where the executables should go, and /opt/lib is where the required dependencies should go.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfNqWxoZAQQiKYOOnxg3US-AtLpWQqU9HqwMEwLDG16CtFWxzdk01L1_i8zX7P-cuB3Zw4UpEa7H1mMxtRe33_nILLt0xSV4GytSD1HYmqtiGrncbnPwSZkpBaIEfg4AQzeyWQM8unsLs/s688/Screenshot+from+2021-01-30+14-57-34.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;688&quot; height=&quot;105&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfNqWxoZAQQiKYOOnxg3US-AtLpWQqU9HqwMEwLDG16CtFWxzdk01L1_i8zX7P-cuB3Zw4UpEa7H1mMxtRe33_nILLt0xSV4GytSD1HYmqtiGrncbnPwSZkpBaIEfg4AQzeyWQM8unsLs/w503-h105/Screenshot+from+2021-01-30+14-57-34.png&quot; width=&quot;503&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Create a layer of AWS Lambda&lt;/h4&gt;&lt;p&gt;Now let&#39;s create a JQ layer on AWS Lambda so that it can be used by the AWS LAmbda function. It can be directly created via AWS Console or use the following command to create it using the AWS CLI:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;aws lambda publish-layer-version --layer-name jq --zip-file /PATH_TO_FILE/jq.zip&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Use created AWS Lambda layer for your Lambda function&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdqp80DTAiUjr-tu62arhiD_dQhNSL-gOi0JsD2umc9jPgfkunrj2pd5UnkqSAEfHQSTzoB0HVBJme0bCWjVyW8aGhexNVI67rCJdPbOyDKIH9j7nsvyIjTzlsafcwgQbnC3QYuDftMVA/s138/Screenshot+from+2021-01-30+15-10-53.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;58&quot; data-original-width=&quot;138&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdqp80DTAiUjr-tu62arhiD_dQhNSL-gOi0JsD2umc9jPgfkunrj2pd5UnkqSAEfHQSTzoB0HVBJme0bCWjVyW8aGhexNVI67rCJdPbOyDKIH9j7nsvyIjTzlsafcwgQbnC3QYuDftMVA/s0/Screenshot+from+2021-01-30+15-10-53.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Once the &lt;i&gt;jq&lt;/i&gt; layer is ready to use from the above step, create an AWS Lambda function with custom runtime using AWS console. After creating a Lambda function with custom runtime, AWS automatically creates a &lt;i&gt;bootstrap&lt;/i&gt; and &lt;i&gt;hello.sh&lt;/i&gt; files whose content (at the time of writing this post) is as follows:&lt;p&gt;&lt;/p&gt;&lt;p&gt;bootstrap:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;&lt;span style=&quot;font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;#!/bin/sh
set -euo pipefail

echo &quot;##  Environment variables:&quot;
env

# Handler format: &amp;lt;script_name&amp;gt;.&amp;lt;bash_function_name&amp;gt;
#
# The script file &amp;lt;script_name&amp;gt;.sh  must be located at the root of your
# function&#39;s deployment package, alongside this bootstrap executable.
source $(dirname &quot;$0&quot;)/&quot;$(echo $_HANDLER | cut -d. -f1).sh&quot;

while true
do
    # Request the next event from the Lambda runtime
    HEADERS=&quot;$(mktemp)&quot;
    EVENT_DATA=$(curl -v -sS -LD &quot;$HEADERS&quot; -X GET &quot;http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next&quot;)
    INVOCATION_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id &quot;$HEADERS&quot; | tr -d &#39;[:space:]&#39; | cut -d: -f2)

    # Execute the handler function from the script
    RESPONSE=$($(echo &quot;$_HANDLER&quot; | cut -d. -f2) &quot;$EVENT_DATA&quot;)

    # Send the response to Lambda runtime
    curl -v -sS -X POST &quot;http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$INVOCATION_ID/response&quot; -d &quot;$RESPONSE&quot;
done&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;div&gt;hello.sh&lt;/div&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;&lt;span style=&quot;font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;function handler () {
    EVENT_DATA=$1

    RESPONSE=&quot;{\&quot;statusCode\&quot;: 200, \&quot;body\&quot;: \&quot;Hello from Lambda!\&quot;}&quot;
    echo $RESPONSE
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Update the hello.sh function so at it prints the &lt;i&gt;jq&lt;/i&gt; version to test if the &lt;i&gt;jq&lt;/i&gt; layer is working properly.&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;function handler () {
    EVENT_DATA=$1
    
    cd /opt
    ./jq --version   
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now run a quick test on the hello.sh Lambda function and it should print the &lt;i&gt;jq&lt;/i&gt; version of the AWS Lambda layer as follows:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span id=&quot;docs-internal-guid-a1a77125-7fff-9d88-bad9-97689748fd1f&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;jq-1.5&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Follow a similar process to create an AWS Lambda layer for any distribution.&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2021/01/using-jq-in-aws-lambda-custom-runtime-via-aws-lambda-layer.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNRAc-IkYgjZ3JFsxaL9ak-EfnYntRcLgr9sMHW9bvSX_VP3GZN4SUvH_w5xXa2h0h-sRxhS5mTQ5LtK63u-XA9WAnyjleiPsOyor2a2rAN7erhjbi3S_QMhzamjWRS1ZWXUDJkauUf40/s72-w381-h250-c/lambda.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-3048143551176074578</guid><pubDate>Sun, 17 Jan 2021 05:26:00 +0000</pubDate><atom:updated>2021-01-18T08:48:06.301+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Scala</category><category domain="http://www.blogger.com/atom/ns#">Scala Cats</category><category domain="http://www.blogger.com/atom/ns#">Scala Cats Effect</category><title>Tagless Final in Scala for Beginners</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji-J_zkNu4NBN0cqk1xVY5fVdpp2xwF0R7dxoBMifnptxxs8zsPBrEtusXO9m_i7fqqZ-IWS6p7DMXbRbzG5eqzAs6uI1-6AfjcYZlcsTQE2CrQc9I4EL3UcfQsFeOHPoq2umQ4R4rb1s/s700/1_QFgSZTYpRbyxfti-ouAbtA.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;258&quot; data-original-width=&quot;700&quot; height=&quot;125&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji-J_zkNu4NBN0cqk1xVY5fVdpp2xwF0R7dxoBMifnptxxs8zsPBrEtusXO9m_i7fqqZ-IWS6p7DMXbRbzG5eqzAs6uI1-6AfjcYZlcsTQE2CrQc9I4EL3UcfQsFeOHPoq2umQ4R4rb1s/w340-h125/1_QFgSZTYpRbyxfti-ouAbtA.png&quot; width=&quot;340&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;This post is an effort to explain what is tagless-final in Scala and if one has bumped into strange-looking F[_] notations and wondered what it is, where, and how it is used, then this post will also try to answer those questions. There&#39;s nothing new to learn for a seasoned functional programmer, but this would give a head start for anyone beginning on the journey. Let&#39;s walk through it step-by-step.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What&#39;s a type constructor?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Simply put, something that constructs types can be considered as a type constructor. For example, List can be considered as a type constructor because it has the ability to construct types based on what type argument is passed to its constructor.&amp;nbsp;&lt;br /&gt;As per the type theory, List would be both a type (denoted by *) and type-constructor (denoted by * -&amp;gt; *)&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;val list: List.type = List
val intList: List[Int] = list[Int]()&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;In the above code snippet, Int is passed to the variable list (which is of type List) as an argument, i.e Int is the type argument to List type list.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What are higher-kinded types?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;A higher-kinded type can be considered as something that abstracts over the type constructor. As a continuation of the above example of List, abstraction over the type constructor can be done with the help of using the F[_] notation, for example:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;trait Test[F[_]]
val test = new Test[List] {}
val test = new Test[Option] {}
val test = new Test[Vector] {}
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;In the above code snippet, trait Test provides the ability to abstracts over the type constructor with the help of F[_] notation, and hence it is possible to pass List type constructor to it. And for that matter, it is also possible to pass other type constructors as well, for example, Option, Vector, etc. In this code snippet, Test now becomes a higher-kinded type.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What&#39;s an Effect in functional programming?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Do not confuse &lt;i&gt;Effect&lt;/i&gt; with a side-effect! A side-effect can be one of the &lt;i&gt;Effect&lt;/i&gt; but it is not the only &lt;i&gt;Effect&lt;/i&gt;. An &lt;i&gt;Effect&lt;/i&gt; can be considered as something that can happen within a Wrapper. For example, consider the Wrapper to be an Either. Now, anything that happens inside an Either&amp;nbsp;can be considered as an &lt;i&gt;Effect,&lt;/i&gt; as shown below:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;def work[A, B](value: A)(fn: A =&amp;gt; B): Either[Throwable, B] =
  try Right(fn(value))
  catch {
    case ex: Exception =&amp;gt; Left(ex)
  }

work(&quot;1&quot;)(_.toInt) // Right(1)
work(&quot;T&quot;)(_.toInt) // Left(NumberFormatException)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The method &lt;i&gt;work&lt;/i&gt; is considered as an &lt;i&gt;Effectful&lt;/i&gt; method as instead of returning just the value B, it is returning Either[Throwable, B] so the caller of the method will know what to expect from the method&#39;s return type. A method can be considered as &lt;i&gt;Effectful&lt;/i&gt; if it returns F[B] instead of B and F in the above example is Either.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What&#39;s a type class?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;A type class can be considered as a class that defines a common behavior that can be associated with some types (data types). A common behavior could be anything, for example, an Adder type class that defines behaviors for the addition of data types like Int, Double, Float, etc.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;trait Adder[A] {
  def add(value1: A, value2: A): A
}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Additionally, a type class should also be lawful in the sense that it should follow certain algebraic laws, in the case of the Adder type class above, it should follow the laws of associativity which is tantamount to it being a Semigroup.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What&#39;s ad-hoc polymorphism with respect to a type class?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The behavior of adding two numeric values specific to a data type can be achieved by method overloading in a normal OOPs setting, for example:&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;case class Age(v: Int)

def add(value1: Int, value2: Int): Int = value1 + value2
def add(value1: Double, value2: Double): Double = value1 + value2
def add(value1: Age, value2: Age): Age = Age(value1.v + value2.v)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;But this would result in some code duplication and a more generic way to write this would be using the method definition as seen from the Adder type class example above:&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;def add(value1: A, value2: A): A&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But how would add know what is the way to add two values, the values could be Int or they could very well be Age data type. A way to do it is by using the type classes, their instances tied to specific data types, and injecting datatype specific instances to the method using implicits in Scala, giving ad-hoc polymorphism capabilities.&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;case class Age(v: Int)

trait Adder[A] {
  def add(value1: A, value2: A): A
}

object Adder {
  def apply[A: Adder]: Adder[A]              = implicitly[Adder[A]]
  def add[A: Adder](value1: A, value2: A): A = Adder[A].add(value1, value2)
}

object AdderInstances {
  implicit val intAdder: Adder[Int] = (value1, value2) =&amp;gt; value1 + value2
  implicit val ageAdder: Adder[Age] = (value1, value2) =&amp;gt; Age(Adder[Int].add(value1.v, value2.v))
}

import AdderInstances._
Adder.add(25, 25) // 50
Adder.add(Age(25), Age(25)) // Age(50)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;What&#39;s tagless-final?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Let&#39;s look at a dumbed-down representation of a Stock Market with capabilities to buy and sell financial instruments.&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;font-size: 15px;&quot;&gt;import cats.Monad
import cats.effect.IO
import cats.implicits._
import scala.language.higherKinds

sealed trait OrderType
case object Buy  extends OrderType
case object Sell extends OrderType

sealed trait FinancialInstrument {
  val id: String
  val quantity: Int
  val price: Float
  val orderType: OrderType
}

case class FutureDerivativeInstrument(id: String, quantity: Int, price: Float, orderType: OrderType) extends FinancialInstrument
case class OptionDerivativeInstrument(id: String, quantity: Int, price: Float, orderType: OrderType) extends FinancialInstrument
case class EquityCashInstrument(id: String, quantity: Int, price: Float, orderType: OrderType)       extends FinancialInstrument

trait StockMarket[F[_]] {
  def buyInstrument(instrument: FinancialInstrument): F[FinancialInstrument]
  def sellInstrument(instrument: FinancialInstrument): F[FinancialInstrument]
}

object StockMarketInstances {
  implicit val instrument: StockMarket[IO] = new StockMarket[IO] {
    override def buyInstrument(instrument: FinancialInstrument): IO[FinancialInstrument]  = IO(instrument)
    override def sellInstrument(instrument: FinancialInstrument): IO[FinancialInstrument] = IO(instrument)
  }
}

object StockMarket {
  def apply[F[_]: StockMarket]: StockMarket[F] = implicitly[StockMarket[F]]

  def executeBuyOrder[F[_]: StockMarket](instrument: FinancialInstrument): F[FinancialInstrument]  = StockMarket[F].buyInstrument(instrument)
  def executeSellOrder[F[_]: StockMarket](instrument: FinancialInstrument): F[FinancialInstrument] = StockMarket[F].sellInstrument(instrument)
}

def placeOrder[F[_]: StockMarket: Monad](orders: Vector[FinancialInstrument]): F[Vector[FinancialInstrument]] = {
  orders.pure[F].flatMap { instruments =&amp;gt;
    instruments.traverse { instrument =&amp;gt;
      instrument.orderType match {
        case Buy  =&amp;gt; StockMarket[F].buyInstrument(instrument)
        case Sell =&amp;gt; StockMarket[F].sellInstrument(instrument)
      }
    } 
  }
}

import StockMarketInstances._
placeOrder[IO](Vector(OptionDerivativeInstrument(&quot;SA-121&quot;, 50, 100, Buy), FutureDerivativeInstrument(&quot;DS-991&quot;, 50, 100, Sell))).unsafeRunSync()&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Here, StockMarket is a tagless-final type class that describes the capabilities of generic type F[_]. The core concept of tagless-final is declaring dependencies for which Scala&#39;s implicits are used.&lt;/p&gt;&lt;p&gt;Tagless-final pattern enables:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Capability to abstract over the higher-kinded type providing means to use any of the available &lt;i&gt;Effect&lt;/i&gt; types in place of F, like Cats Effect IO, or Task, or Monix. That is, it enables&amp;nbsp;&lt;i&gt;Effect&lt;/i&gt; type indirection.&lt;/li&gt;&lt;li&gt;Ability to reason about the implementation of the polymorphic function (in the example above, the placeOrder function) by looking at the implicits required in order to be able to successfully use it. From placeOrder signature, it can be seen the function needs or uses an instance of StockMarket and Applicative to implement its functionality. That is, it enables &lt;i&gt;Effect&lt;/i&gt; parametric reasoning.&lt;/li&gt;&lt;li&gt;The inclination to use the principle of least power by declaring only those type classes as implicit parameters that are needed for the placeOrder function implementation.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;As an end note, it is only by following a disciplined approach as noted above the tagless-final would be useful but is not something that comes automatically just by using it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2021/01/tagless-final-in-scala.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji-J_zkNu4NBN0cqk1xVY5fVdpp2xwF0R7dxoBMifnptxxs8zsPBrEtusXO9m_i7fqqZ-IWS6p7DMXbRbzG5eqzAs6uI1-6AfjcYZlcsTQE2CrQc9I4EL3UcfQsFeOHPoq2umQ4R4rb1s/s72-w340-h125-c/1_QFgSZTYpRbyxfti-ouAbtA.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-8435589391773418591</guid><pubDate>Sat, 16 Jan 2021 06:45:00 +0000</pubDate><atom:updated>2021-01-17T11:27:15.687+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Scala</category><category domain="http://www.blogger.com/atom/ns#">Scala Cats</category><category domain="http://www.blogger.com/atom/ns#">Scala Cats Effect</category><title>Background processing with Scala Cats Effect</title><description>&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbbLxHVNH2RetZp66FF053F7p2dZsD1iMeeTYilUeZXWCLxVkqGj0mxRRQpunSuAl4NnlCHQelYE1EPFAM0T32iMywVX6WBOL4Uy8XQb3kTsWecbiA9GaOhfnW0Pe4hQNruhlst5JWdw/s574/cats-logo.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;574&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbbLxHVNH2RetZp66FF053F7p2dZsD1iMeeTYilUeZXWCLxVkqGj0mxRRQpunSuAl4NnlCHQelYE1EPFAM0T32iMywVX6WBOL4Uy8XQb3kTsWecbiA9GaOhfnW0Pe4hQNruhlst5JWdw/s320/cats-logo.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Running any tasks with Scala Future in the background can be done using the following:&lt;/div&gt;&lt;p&gt;Snippet 1&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;  import scala.concurrent.duration._
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.{Await, Future}

  val future1 = Future { Thread.sleep(4000); println(&quot;Work 1 Completed&quot;) }
  val future2 = Future { Thread.sleep(1000); println(&quot;Work 2 Completed&quot;) }

  val future3 =
    for {
      _ &amp;lt;- future1
      _ &amp;lt;- future2
    } yield ()

  Await.result(future3, Duration.Inf)&lt;/pre&gt;&lt;p&gt;And if one has been working with Scala Future it&#39;d be obvious that as soon as lines with variables future1 and future2 are executed the body inside the Future starts executing immediately, i.e the body of the Future is eagerly evaluated by submitting it for execution on a different Java Thread using the Implicit ExecutionContext available in the scope via the import. Now with the help of the for-comprehension, which is nothing but a combination of flatMap, the Futures are composed together to yield a Unit. And finally, Awaiting on future3 gets the result when both future1 and future2 are completed successfully (here Await is just used for demonstration purposes).&lt;/p&gt;&lt;p&gt;But if the above code snippet is changed a bit to the following:&lt;/p&gt;&lt;p&gt;Snippet 2&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;  val future =
    for {
      _ &amp;lt;- Future { Thread.sleep(4000); println(&quot;Work 1 Completed&quot;) }
      _ &amp;lt;- Future { Thread.sleep(1000); println(&quot;Work 2 Completed&quot;) }
    } yield ()

  Await.result(future, Duration.Inf)&lt;/pre&gt;&lt;p&gt;both Futures will be executed sequentially because the second Future is not initialized/executed until the first Future is completed, i.e the above for-comprehension is the same as the following:&lt;/p&gt;&lt;p&gt;Snippet 3&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;  Future {
    Thread.sleep(4000); println(&quot;Work 1 Completed&quot;)
  }.flatMap { _ =&amp;gt;
      Future {
        Thread.sleep(1000); println(&quot;Work 2 Completed&quot;)
      }
    }&lt;/pre&gt;&lt;p&gt;Similar results can be achieved using Cats Effect IO with the added benefit of referential transparency (note that the Scala Future is not referentially transparent).&lt;/p&gt;&lt;p&gt;Cats Effect version similar&amp;nbsp;to Snippet 2 will look something like the following:&lt;/p&gt;&lt;p&gt;Snippet 4&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;import cats.effect.{ExitCode, IO, IOApp}
import scala.concurrent.duration._

object Test extends IOApp {

  def work[A](work: A, time: FiniteDuration): IO[Unit] =
    IO.sleep(time) *&amp;gt; IO(work)
      .flatMap(completedWork =&amp;gt; IO(println(s&quot;Done work: $completedWork&quot;)))

  val program: IO[Unit] =
    for {
      _ &amp;lt;- work(&quot;work 1&quot;, 4.second)
      _ &amp;lt;- work(&quot;work 2&quot;, 1.second)
    } yield ()

  override def run(args: List[String]): IO[ExitCode] =
    program *&amp;gt; IO.never
}&lt;/pre&gt;&lt;p&gt;In the above case, the second IO (inside for-comprehension) is not evaluated until the first IO is completed, i.e the IOs are run sequentially and the order in which the print line statements will be executed is &quot;Done work: work 1&quot; and then &quot;Done work: work 2&quot;.&lt;/p&gt;&lt;p&gt;The Cats Effect version similar to Snippet 1 will look something like the following:&lt;/p&gt;&lt;p&gt;Snippet 5&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;val program1 = work(&quot;work 1&quot;, 4.second).start
val program2 = work(&quot;work 2&quot;, 1.second).start

val program: IO[Unit] =
  for {
    _ &amp;lt;- program1
    _ &amp;lt;- program2
    _ &amp;lt;- IO(println(&quot;for-comprehension done!&quot;))
  } yield ()&lt;/pre&gt;&lt;p&gt;wherein the order in which the print line statements will be executed is &quot;for-comprehension done!&quot; then &quot;Done work: work 2&quot; and then &quot;Done work: work 1&quot;. Here, the start method uses ContextShift instead of Scala&#39;s ExecutionContext directly.&lt;/p&gt;&lt;p&gt;start returns a Fiber which can be canceled, and the following code snippet will cancel the Fiber returned by program1 as soon as the program2 is evaluated.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Snippet 6&lt;/p&gt;&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;  val program1 = work(&quot;work 1&quot;, 4.second).start
  val program2 = work(&quot;work 2&quot;, 1.second).start

  val program: IO[Unit] =
    for {
      fiber1 &amp;lt;- program1
      _      &amp;lt;- program2
      _      &amp;lt;- fiber1.cancel
      _      &amp;lt;- IO(println(&quot;for-comprehension done!&quot;))
    } yield ()&lt;/pre&gt;&lt;p&gt;and in this case, the following will be the probable output on the console: &quot;for-comprehension done!&quot; then &quot;Done work: work 2&quot; and &quot;Done work: work 1&quot; won&#39;t be printed. &quot;Probable&quot; because the by the time program1 gets a chance to complete, fiber1.cancel line will be executed that&#39;ll cancel the execution of program1.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2021/01/background-processing-with-scala-cats.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbbLxHVNH2RetZp66FF053F7p2dZsD1iMeeTYilUeZXWCLxVkqGj0mxRRQpunSuAl4NnlCHQelYE1EPFAM0T32iMywVX6WBOL4Uy8XQb3kTsWecbiA9GaOhfnW0Pe4hQNruhlst5JWdw/s72-c/cats-logo.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-4155557348049445797</guid><pubDate>Sun, 17 Mar 2019 08:40:00 +0000</pubDate><atom:updated>2021-01-17T14:17:51.069+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitcoins</category><category domain="http://www.blogger.com/atom/ns#">Cryptocurrency</category><title>Can Crypto Replace National Currencies?</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2fsKN7NjgalKhGQVchtdjwyqs4dFSisLgVrWzgDxGuOflQoXjejga0eObOnyR9t23ZeT5enR2sZ5IC-XL9NyuSzZ_lPL-f99WNOJarQqvp2G89FOzh1PCROSOYTwhyphenhyphenOi9Yq-Z-Q4rBMk/s1207/cryptocurrency-banner.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;403&quot; data-original-width=&quot;1207&quot; height=&quot;178&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2fsKN7NjgalKhGQVchtdjwyqs4dFSisLgVrWzgDxGuOflQoXjejga0eObOnyR9t23ZeT5enR2sZ5IC-XL9NyuSzZ_lPL-f99WNOJarQqvp2G89FOzh1PCROSOYTwhyphenhyphenOi9Yq-Z-Q4rBMk/w533-h178/cryptocurrency-banner.jpg&quot; width=&quot;533&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Bitcoin has gained incredible momentum and adoption recently as the most popular and largest cryptocurrency. While many people think of Bitcoin as a speculative investment with the crazy returns, the real value driver behind Bitcoin is its status as a digital currency and store of value.&lt;br /&gt;
&lt;br /&gt;
There are many people that believe Bitcoin as a digital currency represents a viable alternative currency to national fiat currencies. Futurists claim that cryptocurrency is going to disrupt 25% of national currencies by 2030 and threaten the central banking system.&lt;br /&gt;
&lt;br /&gt;
But how realistic are these claims? Do cryptocurrencies have the potential to disrupt our system current currency and banking system?&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
WHY DOES CRYPTOCURRENCY THREATEN NATIONAL CURRENCIES?&lt;/h2&gt;
Cryptocurrencies are built on a decentralized technology called blockchain. The blockchain is a permanent secure ledger of records, transactions, and other data. In the traditional use case, the blockchain’s credibility is constantly maintained and verified by the network of users on the blockchain. This peer-to-peer network allows the system to function and thrive outside of a central point of control.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
So when this technology is applied to create a token, it can represent a unit of value and thus a currency.&lt;br /&gt;
&lt;br /&gt;
National currencies have gone through trends over the decades. Back in the 1900s, currencies, like the U.S. Dollar was backed by actual gold and had real value behind them. Today, national currencies are primarily fiat paper currencies backed by the trustworthiness of the government.&lt;br /&gt;
&lt;br /&gt;
Banking systems are set up maintain national currencies by creating a safe place to store money, a reliable place to borrow money, and a liquidity provider for the currency markets. However, banking systems have become so centralized, that many people are desperate for an alternative.&lt;br /&gt;
&lt;br /&gt;
The cryptocurrency market has gained massive adoption due to the decentralized nature and market equality it brings. There is still a lot of support for fiat currencies, but cryptocurrencies provide a secure digital way for people to store and trade money.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
WHAT DO PROPONENTS SAY ABOUT CRYPTOCURRENCY&lt;/h2&gt;
Proponents of cryptocurrencies note that they won’t be like traditional currencies. Where the US Dollar is tied to the economic activities of the United States, Bitcoin is independent of any government or jurisdiction (and thus, there is little cryptocurrency regulation). The cryptocurrency price is not tied to traditional economic activity. They also have the ability to limit the token or money supply to prevent governments from tampering with the currency by creating inflation.&lt;br /&gt;
&lt;br /&gt;
Cryptocurrency influencers and those trading cryptocurrencies also think the values and prices will continue to be volatile. Especially after the recent large downturn in January and February, long-time cryptocurrency traders pointed to the consistent trends of massive dips along the way the past few years. Traditional investments like stocks and bonds go through cycles, cryptocurrencies are doing the same and will likely see more volatility.&lt;br /&gt;
&lt;br /&gt;
Cryptocurrency also has the potential to change commerce as more and more retail is done online. Doing e-commerce transactions using digital currency makes sense for most people using Bitcoin and other cryptocurrencies to buy and sell online.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
HOW DO GOVERNMENTS DEFINE CRYPTOCURRENCY?&lt;/h2&gt;
&lt;br /&gt;
One key issue with cryptocurrencies at the moment is that government agencies, especially in the U.S., can’t come to a consensus and agree on what cryptocurrency is and how to define it. Each agency is defining cryptocurrencies to fit under their jurisdiction so they have the authority to regulate it.&lt;br /&gt;
&lt;br /&gt;
The U.S. Securities and Exchange Commission (SEC), which regulates the nation’s securities and stocks, classifies cryptocurrencies as a security. They view each coin as a security representing ownership interest in the blockchain company. It’s true that some tokens are ownership shares, but most cryptocurrencies are not intended to replace stocks or shares of a company.&lt;br /&gt;
&lt;br /&gt;
The Internal Revenue Service (IRS), which is the federal tax authority in the US, defines cryptocurrency as a property, rather than being an actual currency. This means that in the eyes of the IRS, any time a cryptocurrency is traded is a taxable event. Traders are obligated to pay taxes on any gains from any cryptocurrency trades. This raised eyes when people were expecting to use cryptocurrencies to pay for their cup of coffee. No one pays taxes on their currency gains in the US Dollar when they make a purchase, why would it apply to a digital currency?&lt;br /&gt;
&lt;br /&gt;
The IRS recently responded by saying that cryptocurrency transactions under $600 are not taxable. However, investors and traders are still up in arms over having to track each transaction for tax purposes. Many are purporting that cryptocurrencies are then similar to real estate property when traded and should be exempt for like-kind purchases under a 1031 exchange.&lt;br /&gt;
&lt;br /&gt;
The US Commodity Futures Trading Commission (CFTC) sees it a little differently and classifies cryptocurrency as a commodity, placing it under their authority. In response, two large platforms allowing futures trading have created and marketed Bitcoin futures. Cboe and CME both released Bitcoin futures trading in December 2017 when Bitcoin was spiking. People started trading Bitcoin like a commodity and betting on future prices of the cryptocurrency, pushing the coin’s price up towards an all-time high of $20,000 at its peak.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
PROS &amp;amp; CONS OF CRYPTO AS CURRENCY&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Advantages&lt;/h3&gt;
&lt;br /&gt;
One huge advantage of using digital currencies like Bitcoin as a store of value and medium of exchange is that they cannot be manipulated the same way fiat currency can. Central banks are notorious for printing paper money and diluting and inflating the nation’s money supply. This has happened in the US, where the dollar has lost 96% of its value since 1913 when the Federal Reserve took over the banking system.&lt;br /&gt;
&lt;br /&gt;
The US isn’t the only nation that falls into this predicament. Venezuela is famous for inflating away their nation’s currency and hurting its own citizens who believe in the monetary system. Just Google Venezuelan currency and you get headlines like the following, “Death Spiral: 4000% Inflation in Venezuela.” These are the primary problems when you have a central point of authority, and they are the key issues that cryptocurrency like Bitcoin is trying to solve.&lt;br /&gt;
&lt;br /&gt;
To continue with the Venezuela use case, the president is issuing a national cryptocurrency called the Petro that will be maintained on the blockchain and backed by the country’s chief export, oil. The government expects to leverage the cryptocurrency as a way to get around US sanctions and access international financing. This approach is interesting because it represents a move back toward physically-backed currency. Where paper money used to be commonly backed by gold, cryptocurrency is proving that you can back the currency with certain items of value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
Disadvantages&lt;/h3&gt;
&lt;br /&gt;
While there are some great potential benefits, there are also areas of concern when considering cryptocurrencies as actual currency. To start, as cryptocurrencies start to take market share so to speak, traditional currencies will naturally lose value and people holding would essentially have worthless paper in their hands.&lt;br /&gt;
&lt;br /&gt;
There is also an infrastructure gap for widespread use of cryptocurrency. Existing financial institutions are scrambling to get their arms around the idea of cryptocurrencies and build their own networks and exchanges in order to keep up with the pace. E-commerce retailers were starting to line up to accept crypto payments like Bitcoin. But with the recent volatility, many have realized the possible dangers in accepting crypto payments at the moment.&lt;br /&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;
FINAL THOUGHTS&lt;/h2&gt;
Regardless of how we individually feel about the aspect of Bitcoin and other cryptocurrencies replacing the national currency and banking system, the trend is in place and we have to learn how to take advantage. Governments and financial institutions quickly realized the potential impact to their established business practices and activities, and have been trying to get ahead of the game ever since.&lt;br /&gt;
&lt;br /&gt;
Whether the cryptocurrency wallet takes over in the next 10 years is unknown. But it’s important, especially for investors and trader, to keep abreast on the changing dynamic landscape. Governments, businesses, and individuals all have their own opinions about the cryptocurrency market, and it should continue to be a rollercoaster ride from here on out… so strap in!&lt;br /&gt;
&lt;br /&gt;
This article was first published on &lt;a href=&quot;https://www.mintdice.com/&quot; target=&quot;_blank&quot;&gt;mintdice&lt;/a&gt;.&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2019/03/can-crypto-replace-national-currencies.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2fsKN7NjgalKhGQVchtdjwyqs4dFSisLgVrWzgDxGuOflQoXjejga0eObOnyR9t23ZeT5enR2sZ5IC-XL9NyuSzZ_lPL-f99WNOJarQqvp2G89FOzh1PCROSOYTwhyphenhyphenOi9Yq-Z-Q4rBMk/s72-w533-h178-c/cryptocurrency-banner.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-8118718099848336616</guid><pubDate>Mon, 14 May 2018 17:20:00 +0000</pubDate><atom:updated>2018-05-14T23:14:02.470+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Blockchain</category><category domain="http://www.blogger.com/atom/ns#">Cryptocurrency</category><title>Why Blockchain Technology is the Answer to the World’s Banking System Woes</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
The banking system is inefficient in its current state as it requires the use of multiple third-party verifications and transferring services in order to complete a transaction.&amp;nbsp; Blockchain can alleviate the need for these organizations and provide the world with a viable solution to the inherent problems facing the banking community.&amp;nbsp; Blockchain is transforming the way in which we conduct business globally by offering us the ability to perform transactions securely in a peer-to-peer manner without the need of any middleman.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0TT9udGxthyphenhyphen7FXfEJIyVOKhqSNfL80Kn0Ks85Jh-2GQetLOTgD-svmhoQqgQE6yGqWERrmQDrjniH7q9WwW1m4KY4AQTSQRRzuSpGtfKllWuY_yW0qkexWFznzLRlZwti16OIu2jkVJM/s1600/blockchain.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1387&quot; data-original-width=&quot;1600&quot; height=&quot;554&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0TT9udGxthyphenhyphen7FXfEJIyVOKhqSNfL80Kn0Ks85Jh-2GQetLOTgD-svmhoQqgQE6yGqWERrmQDrjniH7q9WwW1m4KY4AQTSQRRzuSpGtfKllWuY_yW0qkexWFznzLRlZwti16OIu2jkVJM/s640/blockchain.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The current state of the global banking system is shabby at best.&amp;nbsp; We’ve already witnessed multiple government bailouts to date and it is exactly this type of pompous behavior that spawned the birth of cryptocurrencies nine years prior.&amp;nbsp; Satoshi, the unknown creator of Bitcoin, was even kind enough to let us know that this was his motivation by leaving a reference to the bailout headlines from the London Times embedded in BTC’s genesis block – The Times 03/Jan/2009 Chancellor on brink of the second bailout for banks.&lt;br /&gt;
&lt;br /&gt;
&lt;script async=&quot;&quot; src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt; &lt;!-- below post --&gt;
&lt;br /&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-3287823016154190&quot; data-ad-format=&quot;auto&quot; data-ad-slot=&quot;8995282414&quot; style=&quot;display: block;&quot;&gt;&lt;/ins&gt;&lt;script&gt;
(adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt; &lt;span style=&quot;font-size: large;&quot;&gt;A Brief History of How Banks Came About&lt;/span&gt;&lt;br /&gt;
To understand the advantages that blockchain has over the current banking system, you need to understand the history of banking.&amp;nbsp; Banks evolved out of the need to securely store gold.&amp;nbsp; The first “banker” was nothing more than a gold depository for wealthy people.&lt;br /&gt;
&lt;br /&gt;
Individuals would drop off their gold and the banker would then issue them a receipt that could be used to purchase items around town.&amp;nbsp; &amp;nbsp;Eventually, the banker realized that the people never all came for their gold at the same time and so he decided to start lending out other people’s gold at a slight mark up or interest rate.&lt;br /&gt;
&lt;br /&gt;
The people eventually became suspicious of the banker’s quickly expanding wealth and one night the banker was cornered by a furious crowd who accused him of spending their gold.&amp;nbsp; &amp;nbsp;They forced the banker to take them to his vault and show them that he had everyone’s gold.&amp;nbsp; He gladly obliged as he not only had all of their gold but he now had the interest he made in profit as well.&lt;br /&gt;
&lt;br /&gt;
After realizing what the banker had done, the wealthy individuals demanded in on the action.&amp;nbsp; This is why banks now have to pay you a small interest on your holdings as well.&amp;nbsp; Not much has changed since then in regards to the purpose of banks;&amp;nbsp; It’s still a third-party organization looking to make a profit off of holding your funds.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;A New Day&lt;/span&gt;&lt;br /&gt;
Today, none of these steps are necessary thanks to blockchain technology.&amp;nbsp; Technology has advanced and it is time for our banking systems to do the same.&amp;nbsp; The world cannot continue to bail out fraudulent bankers or run on a fiat-based financial system.&amp;nbsp; Let’s take a moment to see how blockchain technology could eliminate much of these banking problems in the coming years.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Peer-to-Peer&lt;/span&gt;&lt;br /&gt;
The words &lt;a href=&quot;https://en.wikipedia.org/wiki/Peer-to-peer&quot; rel=&quot;nofollow&quot;&gt;peer-to-peer&lt;/a&gt; has no use in the current central banking system that relies on a combination of verifications and monitoring platforms to ensure your funds are sent.&amp;nbsp; Every time you swipe your debit card there are around thirty separate third-party organizations that must coordinate to complete your transaction.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpeoFHKg5L4i2FrbCjJrE-7XUJzqcP4q1bq5pQ85W-2WtGDbUvkpphKi_YZKlLAj9yMKliP2Nd485hrqbJAuB1j2cgsPT1jCFFUee0NAxvVZqtbZW1N-3tkdDQOnc28tE-OdtC-slRE4M/s1600/per%253Dto%253Dpeer.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;450&quot; data-original-width=&quot;810&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpeoFHKg5L4i2FrbCjJrE-7XUJzqcP4q1bq5pQ85W-2WtGDbUvkpphKi_YZKlLAj9yMKliP2Nd485hrqbJAuB1j2cgsPT1jCFFUee0NAxvVZqtbZW1N-3tkdDQOnc28tE-OdtC-slRE4M/s640/per%253Dto%253Dpeer.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Your bank must first check your balance, verify that it is you actually spending the funds, notify the account where the funds are going to ensure it is correct, interact with the merchant processing firms involved, interact with VISA or MC, and the list goes on.&amp;nbsp; This is why you can spend your debit card funds quickly but any refunds can take a week or longer to be processed.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Transparency&lt;/span&gt;&lt;br /&gt;
Cryptocurrencies eliminate this need for third-party verification.&amp;nbsp; The &lt;a href=&quot;https://coincentral.com/whats-in-a-block-anyway/&quot;&gt;transparent&lt;/a&gt; nature of blockchain technology makes it perfectly suited for financial services.&amp;nbsp; An individual can check any wallet on the blockchain to ensure funds are present and once they are sent, they go directly to the other individual involved in the transaction.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Send Any Amount Instantly&lt;/span&gt;&lt;br /&gt;
Have you ever tried to send a large amount of money internationally?&amp;nbsp; It is a nightmare that can take days to complete depending on the amount you decide to send.&amp;nbsp; During this layover, your funds are inaccessible to both you and the other party involved in the transaction.&amp;nbsp; It is common to wait over a week for a large transaction to complete.&lt;br /&gt;
&lt;br /&gt;
Blockchain technology eliminates the need to wait and regardless of the amount of crypto you are sending, the transfer time is the same.&amp;nbsp; This is a huge advantage that crypto has over the current banking system.&lt;br /&gt;
&lt;br /&gt;
Imagine that you are a large international company that must send millions of dollars in capital internationally.&amp;nbsp; Blockchain technology would allow you to accomplish this task with unmatched simplicity.&amp;nbsp; There would be no additional delays and the funds would be more secure than any other form of money transference currently available.&amp;nbsp; You also avoid any losses from converting your funds between countries.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Record Keeping&lt;/span&gt;&lt;br /&gt;
Records stored on a blockchain are immutable and easily traceable.&amp;nbsp; Nobody can hack this data and it is easy to search for a single transaction.&amp;nbsp; Integrating a blockchain-based system would allow banks to quickly handle common issues such as identity theft or disputed transactions.&amp;nbsp; &amp;nbsp; &amp;nbsp;Some banks are starting to explore this option and it can be expected that many more will follow suit in the coming months as the technology continues to see adoption.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Bye-Bye Credit Bureaus&lt;/span&gt;&lt;br /&gt;
The transparent nature of the blockchain eliminates the need for credit bureaus.&amp;nbsp; A blockchain-based system would allow for anyone to quickly see their financial history and thereby prove their ability to repay a debt.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrUHfTpE1dsr7BQsdU0hEOZPI5QH5GA3X9ey3Jczku52Yf-pDsKGN_uPQYJISeB1pcaaEbGl2n8PU512Hljoa6yGq5TbD_SuDTiTh6O0nLYPicMZ9t7yzfsBQnQILf9N7rlba5IxLtpiQ/s1600/credit-agency.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;398&quot; data-original-width=&quot;600&quot; height=&quot;424&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrUHfTpE1dsr7BQsdU0hEOZPI5QH5GA3X9ey3Jczku52Yf-pDsKGN_uPQYJISeB1pcaaEbGl2n8PU512Hljoa6yGq5TbD_SuDTiTh6O0nLYPicMZ9t7yzfsBQnQILf9N7rlba5IxLtpiQ/s640/credit-agency.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Currently, credit companies are only obligated to provide you with a single credit report yearly for free.&amp;nbsp; These are billion dollar organizations that thrive off of a technology that is no longer needed.&amp;nbsp; Significant time and capital could be realized by eliminating these wasteful institutions from the banking system.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Increased Security&lt;/span&gt;&lt;br /&gt;
Blockchain technology is light years ahead of the current banking system in terms of security.&amp;nbsp; The redundant nature of the protocol ensures that your funds are safe and allows you the ability to store your funds personally.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;A Blockchain Future&lt;/span&gt;&lt;br /&gt;
The advantages of blockchain technology are &lt;a href=&quot;https://coincentral.com/how-blockchain-can-eradicate-poverty-in-third-world-countries/&quot;&gt;unmistakable&lt;/a&gt; and for the first time in history, a global decentralized economy is a reality.&amp;nbsp; This is exactly why the central banking system has been so vocal on their opposition towards cryptocurrencies such as Bitcoin.&amp;nbsp; You can expect to see this aggressive rhetoric continue as the banking system continues to go through their identity crisis but in the end, its just math and efficiency will always win out.&lt;br /&gt;
&lt;br /&gt;
This &lt;a href=&quot;https://coincentral.com/why-blockchain-technology-is-the-answer-to-the-worlds-banking-system-woes/&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; by David Hamilton was originally published at CoinCentral.com.&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/why-blockchain-technology-is-answer-to-banking-woes.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0TT9udGxthyphenhyphen7FXfEJIyVOKhqSNfL80Kn0Ks85Jh-2GQetLOTgD-svmhoQqgQE6yGqWERrmQDrjniH7q9WwW1m4KY4AQTSQRRzuSpGtfKllWuY_yW0qkexWFznzLRlZwti16OIu2jkVJM/s72-c/blockchain.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-7831098638537137841</guid><pubDate>Fri, 04 May 2018 16:49:00 +0000</pubDate><atom:updated>2018-05-04T22:31:27.546+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Cryptocurrency</category><category domain="http://www.blogger.com/atom/ns#">tor</category><category domain="http://www.blogger.com/atom/ns#">Tor Network</category><title>In-depth Look at Verge Cryptocurrency &amp; Platform</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Verge is a privacy-focused cryptocurrency that aims to keep transactions anonymous and untraceable while allowing for high throughput and fast confirmation times.&lt;br /&gt;
&lt;br /&gt;
The project is entirely open source and community led. There is no company or foundation behind Verge. In fact, the core team signed Verge’s &lt;a href=&quot;https://vergecurrency.com/assets/Verge-Anonymity-Centric-CryptoCurrency.pdf&quot; target=&quot;_blank&quot;&gt;black paper&lt;/a&gt; with only their usernames. The community is committed to privacy, anonymity, and decentralization.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizP4EmJb6fGJ3hE9Nb5przmO3ekrPEvasFtyvMhME0v4yLTS33dl31eZcahPiDYh1h1AN54Rw1vrwPOS02V9nqIrtU_T_ArgqpYHhi_OuBDLcf70aFSW2LuTnyWEImyvhEciK_UZdJjlw/s1600/verge.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;603&quot; data-original-width=&quot;600&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizP4EmJb6fGJ3hE9Nb5przmO3ekrPEvasFtyvMhME0v4yLTS33dl31eZcahPiDYh1h1AN54Rw1vrwPOS02V9nqIrtU_T_ArgqpYHhi_OuBDLcf70aFSW2LuTnyWEImyvhEciK_UZdJjlw/s640/verge.png&quot; width=&quot;636&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
The coin originally began as DogeCoinDark in 2014. In February 2016, wanting to distance themselves from both the Doge meme and the “dark” connotation, DogeCoinDark rebranded to Verge. Over the past two years, the project has set a trajectory toward legitimacy for mass market adoption.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
Verge is entering the crowded the &lt;a href=&quot;https://coincentral.com/top-privacy-cryptocurrency-race/&quot; target=&quot;_blank&quot;&gt;race to be the top privacy coin&lt;/a&gt;. In this article, we’ll take a look at what privacy measures Verge implements. We’ll also do a deep dive on the technology behind Verge and whether this is a project with potential to rise to the top.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Making User Connections Anonymous&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
Verge attacks the issue of privacy from the vantage of how a user connects to the network.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
The internet we all recognize is fairly straightforward. To send information between computers, you use an Internet Service Provider (ISP) or other middleman to facilitate the message. When you send a message, your ISP can see your unique identifier on the internet – your IP address. Your ISP also needs to know the IP address of the destination computer, so it can route the message.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
This is okay for normal internet traffic, but it’s not anonymous. Over time, an ISP learns a lot about the IP addresses you’re contacting. They also know where you’re sending messages from. In many cases, signing up with your ISP associates your identity with your IP address, causing multiple anonymity and privacy issues. Verge uses two approaches – Tor and I2P – to address connection anonymization.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Enter Tor&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Tor is a well-known anonymization scheme for IP addresses. The name is an acronym that stands for The Onion Router, because the Tor network wraps your message in multiple layers of encryption. Instead of routing your internet connection through one ISP, Tor bounces the connection between many relay computers on the Tor peer-to-peer network.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWpRuEZG4syAgUWaPpaESNXXXAk8o1Yy1dtDahwLrs2xm9X2_kwna-NehvveVCppEJqPixYwnAWiHBtvcbdCvCgfcNmR757c2QJ4EwGDxkdG6-wrw6aXhneVmVDUr6spwySNP2DgAg-q0/s1600/tor.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;591&quot; data-original-width=&quot;785&quot; height=&quot;481&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWpRuEZG4syAgUWaPpaESNXXXAk8o1Yy1dtDahwLrs2xm9X2_kwna-NehvveVCppEJqPixYwnAWiHBtvcbdCvCgfcNmR757c2QJ4EwGDxkdG6-wrw6aXhneVmVDUr6spwySNP2DgAg-q0/s640/tor.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
This changes the message’s IP address many times, making it difficult to trace back to the original sender. With TOR, no one node knows the whole route a message will take. The message quickly becomes anonymous and untraceable. A directory service identifies the path for connections.&lt;br /&gt;
&lt;br /&gt;
Tor is a peer-to-peer network. As you use Tor, you’re also acting as a relay node for other messages getting bounced around the Tor network.&lt;br /&gt;
&lt;br /&gt;
Verge implements Tor as standard for its transactions to anonymize user connections to the blockchain. Making interactions more difficult to link to an IP address.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;I2P&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
The next generation solution to connection anonymization is I2P. While Tor provides directory-based circuit routing, I2P allows for dynamic routing of information packets. There’s no directory on I2P, so the responsive routing of the network can avoid congestion and interruptions.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXziK1G3Uv9zTMjgirU-za8GClzZ7RA-KLZ0N8fa0BFU1dAA7fLUtOBbwZVDwI195yRFF-11vytp-jxcHuj4H9_NS4uama9KWgWpJImOMZrpJjIGUM40xtwi4Ue2v6xq-DXB4dBE4BLWM/s1600/i2p.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;545&quot; data-original-width=&quot;714&quot; height=&quot;488&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXziK1G3Uv9zTMjgirU-za8GClzZ7RA-KLZ0N8fa0BFU1dAA7fLUtOBbwZVDwI195yRFF-11vytp-jxcHuj4H9_NS4uama9KWgWpJImOMZrpJjIGUM40xtwi4Ue2v6xq-DXB4dBE4BLWM/s640/i2p.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I2P also divides the routing into two separate tunnels, one outgoing and another incoming. That means that the messages you send to another computer or website follow a different path from the messages you receive in response. Anyone listening in would only see half of the message history, like listening in on only half of a phone call where you don’t know who is speaking or who they’re speaking to.&lt;br /&gt;
&lt;br /&gt;
Tor was intended as a portal for anonymously accessing the ordinary internet. I2P provides a much more robust experience, leading to the creation of a private network within the internet. I2P is a true darknet, with applications written specifically for I2P.&lt;br /&gt;
&lt;br /&gt;
Verge leverages I2P technology for its network as well. You have the option to route your transactions through Tor or I2P but IP anonymization is standard on Verge. Since the entire Verge blockchain is anonymous, the entire community becomes much more difficult to track.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Wraith Protocol&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
The Wraith Protocol allows users to choose between public and private blockchain transactions. Public transactions would provide transparency and speed. Private blockchain transactions wouldn’t be publicly reviewable at all.&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
They plan to accomplish these private transactions using stealth addresses routed through Tor. Stealth addresses send funds to one-time use addresses. Only the recipient can identify and redeem funds sent to a stealth address. Stealth addresses are an important component of how &lt;a href=&quot;https://coincentral.com/what-is-monero/&quot; target=&quot;_blank&quot;&gt;Monero&lt;/a&gt;, a leading privacy coin, operates. However, Monero also provides more complex cryptography and other features that guarantee its privacy more effectively.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifTid5yT9F0xikBgF9px3ydfogKulzRAuyx8o-uqHKFPZhhA89J8UV1P_iQvOYKK04GvYj3WuflknsIrMKC2gxnuTtVyXHhpWZCCcHQcyyr3rqZh4G3VyrvHSMrgciQRzIeqmH3OGSgjo/s1600/wraith.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;488&quot; data-original-width=&quot;817&quot; height=&quot;380&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifTid5yT9F0xikBgF9px3ydfogKulzRAuyx8o-uqHKFPZhhA89J8UV1P_iQvOYKK04GvYj3WuflknsIrMKC2gxnuTtVyXHhpWZCCcHQcyyr3rqZh4G3VyrvHSMrgciQRzIeqmH3OGSgjo/s640/wraith.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
Verge’s cryptography is based on elliptic curves. &lt;a href=&quot;https://www.coindesk.com/math-behind-bitcoin/&quot; target=&quot;_blank&quot;&gt;Elliptic curve cryptography&lt;/a&gt; is well-established and very cool. It’s a key part of Bitcoin, and Verge uses a slight variant of the Bitcoin known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman&quot; target=&quot;_blank&quot;&gt;Elliptic-Curve Diffie Hellman&lt;/a&gt;. It allows parties to share and agree on transaction keys and signatures without an observer learning anything.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Wallets&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Verge utilizes the Electrum wallet, originally designed for Bitcoin. Electrum supports Tor and I2P integration. It also allows for secure offline storage of tokens. When you need to send XVG, you can sign the transaction with your private key offline. Once signed, you can broadcast the transaction from an online computer that doesn’t have access to your private keys.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Electrum also supports passphrase key recovery and multisignature, meaning you could require multiple confirmations to send a transaction, increasing security. Finally, the Electrum wallet connects to decentralized servers that index the blockchain. There’s no need to operate a full node or download the entire blockchain transaction history.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Android Wallets&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Verge will also support two Android wallets. One for Tor and another for I2P. These mobile wallets include security measures like PIN codes and biometric locking. They also support QR codes to pull balances from paper wallets.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Messaging&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Verge has implemented options for messaging transactions, as well. You can send XVG via Telegram, Discord, Twitter, or IRC. It’s simple to send tokens using only a person’s username. A bot will process the transaction and place the funds in a holding address. It’ll then send a message to the recipient with instructions on how to claim the funds. Verge is not the only cryptocurrency to implement messaging payments, but it represents a big leap forward in user experience from an ease of use standpoint.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Messaging payments on Slack and Steem are coming to XVG later this year.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Mining&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Verge is among a small handful of projects that are testing out multi-algorithm consensus. This means miners can mine XVG in five different ways. All of the algorithms are proof of work based. However, some favor &lt;a href=&quot;https://coincentral.com/asic-gpu-cpu-mining/&quot; target=&quot;_blank&quot;&gt;ASIC hardware while others are GPU compatible&lt;/a&gt; or lighter.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The five algorithms are Scrypt, X17, Lyra2rev2, myr-groestl and blake2s. &lt;a href=&quot;https://coincentral.com/what-is-digibyte/&quot; target=&quot;_blank&quot;&gt;Digibyte&lt;/a&gt; pioneered this multialgorithm approach. The benefit is greater decentralization as multiple algorithms mean many different types of mining rigs can participate in XVG mining.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Verge has a target 30-second block time, split between the five algorithms. In total, there will be 16.5 billion XVG, with 9 billion mined in the first year (2014) and 1 billion every year thereafter.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;XVG Coin&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
XVG, originally DogeCoinDark, launched without an ICO or premine. The developers bought Verge coins just like anyone else.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Verge is currently in the top 30 cryptocurrencies worldwide. It is listed on many major exchanges including Binance and Bittrex.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Future Plans&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Verge has several future plans that could make the project more compelling as a complete privacy solution.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Atomic Swaps&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Starting in 2018, Verge hopes to implement support for &lt;a href=&quot;https://coincentral.com/what-are-atomic-swaps-a-beginners-guide/&quot; target=&quot;_blank&quot;&gt;atomic swaps&lt;/a&gt; with most major cryptocurrencies. Atomic swaps use hash-locks and time-locks to freeze tokens on one blockchain in exchange for the release of tokens on another chain. Verge hopes interoperability with other chains will make it a go-to privacy provider.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Smart contracts&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
The Rootstock project plans to add a sidechain to Verge that processes smart contracts. It will be Turing complete and comparable to Ethereum. It hasn’t yet launched, so those claims are unverified as yet.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
RSK tokens on Rootstock can be pegged to Verge tokens so they’ll have the same value. You can deposit XVG on Verge and spend corresponding RSK on the Rootstock side chain.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Rootstock claims they’ve made a breakthrough in smart contract scalability. Their goal is 2,000 tx/s using off-chain settlement solutions similar to &lt;a href=&quot;https://coincentral.com/lightning-network-beginners-guide/&quot; target=&quot;_blank&quot;&gt;Lightning Network&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Verge is interesting insofar as it’s a decentralized, open source project. However, its lack of formal structure could also be a drawback. Most serious crypto projects these days have a foundation behind them leading development and setting a roadmap.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The project also needs outside review. While many of the technologies they’re implementing have been tested elsewhere, Verge could use a dose of legitimacy from an independent source.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
They also don’t have the same kind of resources as their competitors in the privacy space. Monero, Z Cash, and Dash have hundreds of collaborators on their Githubs. Verge only has 12.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That said, hiding IP addresses is an important frontier for blockchain anonymity. If they can solve anonymous smart contracts, that would be a unique breakthrough for the space.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;This &lt;a href=&quot;https://coincentral.com/verge-cryptocurrency-xvg-beginners-guide/&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; by Bennett Garner was originally published at CoinCentral.com.&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/in-depth-look-at-verge-cryptocurrency.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizP4EmJb6fGJ3hE9Nb5przmO3ekrPEvasFtyvMhME0v4yLTS33dl31eZcahPiDYh1h1AN54Rw1vrwPOS02V9nqIrtU_T_ArgqpYHhi_OuBDLcf70aFSW2LuTnyWEImyvhEciK_UZdJjlw/s72-c/verge.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-2646933351915223383</guid><pubDate>Fri, 04 May 2018 15:12:00 +0000</pubDate><atom:updated>2018-05-13T16:00:59.213+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Akka</category><category domain="http://www.blogger.com/atom/ns#">Akka Streams</category><category domain="http://www.blogger.com/atom/ns#">Alpakka</category><category domain="http://www.blogger.com/atom/ns#">Amazon Web Services</category><category domain="http://www.blogger.com/atom/ns#">AWS</category><category domain="http://www.blogger.com/atom/ns#">AWS S3</category><category domain="http://www.blogger.com/atom/ns#">Parallel Programming</category><category domain="http://www.blogger.com/atom/ns#">Play Framework</category><category domain="http://www.blogger.com/atom/ns#">Reactive Programming</category><category domain="http://www.blogger.com/atom/ns#">Reactive Streams</category><category domain="http://www.blogger.com/atom/ns#">Scala</category><title>Stream a file to AWS S3 using Akka Streams (via Alpakka) in Play Framework</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
In this blog post we’ll see how a file can be streamed from a client (eg: browser) to Amazon S3 (AWS S3) using Alpakka’s AWS S3 connector. Aplakka&amp;nbsp;provides various Akka Stream connectors, integration patterns and data transformations for integration use cases.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
The example in this blog post uses Play Framework to provide a user interface to submit a file from a web page directly to AWS S3 without creating any temporary files (on the storage space) during the process. The file will be streamed to AWS S3 using S3’s multipart upload API.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCwicJVe_tjX2R1sAaiCGquEqU8RI8jluppL6FVK2CtbBkPxHO7gCpzD_okmyNUc003vZR9YqmEtgkg3borP_Q8mSmAu2dsTtmu-HPnTlmNDaB50PSNRlhlVk3nJzBzydyVja2AQQl00k/s1600/akka-streams.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;194&quot; data-original-width=&quot;259&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCwicJVe_tjX2R1sAaiCGquEqU8RI8jluppL6FVK2CtbBkPxHO7gCpzD_okmyNUc003vZR9YqmEtgkg3borP_Q8mSmAu2dsTtmu-HPnTlmNDaB50PSNRlhlVk3nJzBzydyVja2AQQl00k/s1600/akka-streams.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjasbNWOzTFWPkRNQQNuyhKoZVZg-tSfeB8_4KnFjsSU_6PIp7C-atDjXFK7-HRnkl3BZDzhC1NcmjuzdLWkZf7gPrJ8oCxMCxbrMJepgTOgTKdemqMW6FCr5nMuxwUebLu6fjhmqfJs7M/s1600/play_full_color.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;836&quot; data-original-width=&quot;1600&quot; height=&quot;166&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjasbNWOzTFWPkRNQQNuyhKoZVZg-tSfeB8_4KnFjsSU_6PIp7C-atDjXFK7-HRnkl3BZDzhC1NcmjuzdLWkZf7gPrJ8oCxMCxbrMJepgTOgTKdemqMW6FCr5nMuxwUebLu6fjhmqfJs7M/s320/play_full_color.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
(To understand this blog post basic knowledge of Play Framework and Akka Streams is required. Also, check out &lt;a href=&quot;https://developer.lightbend.com/blog/2018-02-06-reactive-streams-ee4j/index.html&quot; target=&quot;_blank&quot;&gt;What can Reactive Streams offer EE4J&lt;/a&gt; by James Roper and also check its &lt;a href=&quot;https://developer.lightbend.com/blog/2018-02-06-reactive-streams-ee4j/index.html#servlet-io&quot; target=&quot;_blank&quot;&gt;Servlet IO section&lt;/a&gt;&amp;nbsp;to fully understand the extent to which the example mentioned in this blog post can be helpful)&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Let’s begin by looking at the artifacts used for achieving the task at hand&lt;/div&gt;
&lt;ol style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 24px 1.5em; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;li style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Scala 2.11.11&lt;/li&gt;
&lt;li style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Play Framework 2.6.10&lt;/li&gt;
&lt;li style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Alpakka S3 0.18&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Now moving on to the fun part, let’s see what the code base will look like. We’ll first create a class for interacting with AWS S3 using the Alpakka S3 connector, let’s name the class as AwsS3Client.&lt;br /&gt;
&lt;span id=&quot;more-48904&quot; style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;@Singleton
class AwsS3Client @Inject()(system: ActorSystem, materializer: Materializer) {

  private val awsCredentials = new BasicAWSCredentials(&quot;AWS_ACCESS_KEY_ID&quot;, &quot;AWS_SECRET_ACCESS_KEY&quot;)
  private val awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials)
  private val regionProvider =
    new AwsRegionProvider {
      def getRegion: String = &quot;us-west-2&quot;
    }
  private val settings = new S3Settings(MemoryBufferType, None, awsCredentialsProvider, regionProvider, false, None, ListBucketVersion2)
  private val s3Client = new S3Client(settings)(system, materializer)

  def s3Sink(bucketName: String, bucketKey: String): Sink[ByteString, Future[MultipartUploadResult]] =
    s3Client.multipartUpload(bucketName, bucketKey)
}&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
From the first line it can be seen the class is marked as a Singleton, this is because we do not want multiple instances of this class to be created. From the next line it can be seen that&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;ActorSystem&lt;/strong&gt;&amp;nbsp;and&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Materializer&lt;/strong&gt;&amp;nbsp;is injected which is required for configuring the Alpakka’s AWS S3 client. The next few lines are for configuring an instance of Alpakka’s AWS S3 client which will be used for interfacing with your AWS S3 bucket. Also, in the last section of the class there’s a behavior which returns a Akka Streams&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Sink&lt;/strong&gt;, of type&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Sink[ByteSring, Future[MultipartUploadResult]]&lt;/strong&gt;, this&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Sink&lt;/strong&gt;&amp;nbsp;does the job of sending the file stream to AWS S3 bucket using AWS multipart upload API.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
In order to make this class workable replace&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;AWS_ACCESS_KEY_ID&lt;/strong&gt;&amp;nbsp;and&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;AWS_SECRET_ACCESS_KEY&lt;/strong&gt;&amp;nbsp;with your AWS S3 access key and secret key respectively. And replace&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;us-west-2&lt;/strong&gt;&amp;nbsp;with your respective AWS region.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Next, let’s look at how the&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;s3Sink&lt;/strong&gt;&amp;nbsp;behavior of this call can be used to connect our Play Framework’s controller with AWS S3 multipart upload API. But before doing that and slightly digressing from the example [bear with me, it’s going to build up the example further :)], if you followed my previous blog post —&amp;nbsp;&lt;a href=&quot;http://www.ubertechblog.com/2018/05/streaming-data-from-postgresql-using-akka-streams-and-slick-in-play-framework.html&quot; rel=&quot;noopener&quot; style=&quot;background: transparent; border: 0px; color: #743399; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;&quot; target=&quot;_blank&quot;&gt;Streaming data from PostgreSQL using Akka Streams and Slick in Play Framework&lt;/a&gt;&amp;nbsp;[containing Customer Management example] — you might have seen how a CustomerController was used to build a functionality wherein a Play Framework’s route was available to stream the customer data directly from PostgreSQL into a downloadable CSV file (without the need to buffering data as file on storage space). This blog post builds an example on top of the Customer Management example highlighted in the previous blog post. So, we’re going to use the same CustomerController but modify it a bit in terms of adding a new Play Framework’s Action for accepting the file from the web page.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
For simplicity, let’s name the controller Action as&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;upload&lt;/strong&gt;, this Action is used for accepting a file from a web page via one of the reverse route. Let’s first look at the controller code base and then we’ll discuss about the reverse route.&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;@Singleton
class CustomerController @Inject()(cc: ControllerComponents, awsS3Client: AwsS3Client)
                                  (implicit ec: ExecutionContext) extends AbstractController(cc) {

  def upload: Action[MultipartFormData[MultipartUploadResult]] =
    Action(parse.multipartFormData(handleFilePartAwsUploadResult)) { request =&amp;gt;
      val maybeUploadResult =
        request.body.file(&quot;customers&quot;).map {
          case FilePart(key, filename, contentType, multipartUploadResult) =&amp;gt;
            multipartUploadResult
          }
 
      maybeUploadResult.fold(
        InternalServerError(&quot;Something went wrong!&quot;)
      )(uploadResult =&amp;gt;
        Ok(s&quot;File ${uploadResult.key} upload to bucket ${uploadResult.bucket}&quot;)
      )
    }

   private def handleFilePartAwsUploadResult: Multipart.FilePartHandler[MultipartUploadResult] = {
     case FileInfo(partName, filename, contentType) =&amp;gt;
       val accumulator = Accumulator(awsS3Client.s3Sink(&quot;test-ocr&quot;, filename))

       accumulator map { multipartUploadResult =&amp;gt;
         FilePart(partName, filename, contentType, multipartUploadResult)
       }
   }
}

&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Dissecting the controller code base, it can be seen that the controller is a singleton and the&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;AwsS3Client&lt;/strong&gt;&amp;nbsp;class that was created earlier is injected in the controller along with the Play&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;ControllerComponents&lt;/strong&gt;&amp;nbsp;and&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;ExecutionContext&lt;/strong&gt;.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Let’s look at the private behavior of the CustomerController first, i.e&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;handleFilePartAwsUploadResult&lt;/strong&gt;. It can be seen that the return type of this behavior is&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;Multipart.FilePartHandler[MultipartUploadResult]&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
which is nothing but a Scala type defined inside Play’s Multipart object:&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;type FilePartHandler[A] = FileInfo =&amp;gt; Accumulator[ByteString, FilePart[A]]&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
It should be noted here that the example uses&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;multipart/form-data&lt;/strong&gt;&amp;nbsp;encoding for file upload, so&amp;nbsp;the default&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;multipartFormData&lt;/strong&gt;&amp;nbsp;parser is used by providing&amp;nbsp;a&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;FilePartHandler&lt;/strong&gt;&amp;nbsp;of type&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;FilePartHandler[MultipartUploadResult]&lt;/strong&gt;. The type of&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;FilePartHandler&lt;/strong&gt;&amp;nbsp;is&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;MultipartUploadResult&lt;/strong&gt;&amp;nbsp;because Alpakka AWS S3 Sink is of type&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Sink[ByteString, Future[MultipartUploadResult]]&lt;/strong&gt;&amp;nbsp;to which the file will be finally sent to.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Looking at this private behavior and understanding what it does, it accepts a case class of type&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;FileInfo&lt;/strong&gt;, creates an&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Accumulator&lt;/strong&gt;&amp;nbsp;from s3Sink and then finally maps the result of the Accumulator to a result of type FilePart.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;NOTE:&lt;/strong&gt;&amp;nbsp;Accumulator is essentially a lightweight wrapper around Akka Sink that gets materialized to a Future. It provides convenient methods for working directly with Future as well as transforming the inputs.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Moving ahead and understanding the&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;upload&lt;/strong&gt;&amp;nbsp;Action, it looks like any other normal Play Framework Action with the only difference that the request body is being parsed to&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;MultipartFormData&lt;/strong&gt;&amp;nbsp;and then handled via our custom&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;FilePartHandler&lt;/strong&gt;, i.e&amp;nbsp;&lt;strong style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;handleFilePartAwsUploadResult&lt;/strong&gt;, which was discussed earlier.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
For connecting everything together, we need to enable an endpoint to facilitate this file upload and a view to be able to submit a file. Let’s add a new reverse route to the Play’s route file:&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;POST /upload controllers.CustomerController.upload&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
and a view to enable file upload from the user interface&lt;/div&gt;
&lt;pre style=&quot;background: rgb(247, 247, 247); border: 0px; color: #222222; font-family: &amp;quot;Courier 10 Pitch&amp;quot;, Courier, monospace; font-size: 15px; line-height: 21px; margin-bottom: 24px; overflow: auto; padding: 1.5em; text-size-adjust: 140%; vertical-align: baseline;&quot;&gt;@import helper._

@()(implicit request: RequestHeader)

@main(&quot;Customer Management Portal&quot;) {
  &amp;lt;h1&amp;gt;&amp;lt;b&amp;gt;Upload Customers to AWS S3&amp;lt;/b&amp;gt;&amp;lt;/h1&amp;gt;
  @helper.form(CSRF(routes.CustomerController.upload()), &#39;enctype -&amp;gt; &quot;multipart/form-data&quot;) {
    &amp;lt;input type=&quot;file&quot; name=&quot;customers&quot;&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;input type=&quot;submit&quot;&amp;gt;
  }
}&lt;/pre&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Note the CSRF which is required for the form as it is enabled by default in Play Framework.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
The entire code base is available at the following repository&amp;nbsp;&lt;a href=&quot;https://github.com/mavericksid/playakkastreams&quot; rel=&quot;noopener&quot; style=&quot;background: transparent; border: 0px; color: #743399; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;&quot; target=&quot;_blank&quot;&gt;playakkastreams&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
Hope this helps, shout out your queries in the comment section :)&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin: 0px; padding: 0px;&quot;&gt;&lt;span style=&quot;font-size: xx-small;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; margin: 0px; padding: 0px;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/stream-a-file-to-aws-s3-using-akka-streams-via-alpakka-in-play-framework.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCwicJVe_tjX2R1sAaiCGquEqU8RI8jluppL6FVK2CtbBkPxHO7gCpzD_okmyNUc003vZR9YqmEtgkg3borP_Q8mSmAu2dsTtmu-HPnTlmNDaB50PSNRlhlVk3nJzBzydyVja2AQQl00k/s72-c/akka-streams.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-5347647650899774699</guid><pubDate>Tue, 01 May 2018 15:53:00 +0000</pubDate><atom:updated>2018-05-01T21:24:58.279+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Microsoft</category><category domain="http://www.blogger.com/atom/ns#">Microsoft SQL Server</category><category domain="http://www.blogger.com/atom/ns#">Parallel Programming</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><category domain="http://www.blogger.com/atom/ns#">Scala</category><category domain="http://www.blogger.com/atom/ns#">Slick</category><category domain="http://www.blogger.com/atom/ns#">SQL</category><title>Using Microsoft SQL Server with Scala Slick</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
This blog post shows simple CRUD operations on Microsoft SQL Server using Scala Slick version 3.2.3. You might be thinking what’s really great about it? Duh! But until Scala Slick 3.2.x was released, using commercial databases was within the horizon of an additional closed source package know as Slick Extensions which supported Slick drivers for following databases&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Oracle&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;IBM DB2&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Microsoft SQL Server&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnlOQJTinbDxwoEp5vWWsVtx0iO2j1gBSnYsTJD0Ylan7VYG3e8QSQLzsTFZobibzp3O2T_l8PtsvQFg8GDvJHAaMfUg-P_7fn3G1gazpRSE7PrPlwc4eqalkAsHr8KTFeNQ3RR4nvubc/s1600/microsoft+%25281%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;575&quot; data-original-width=&quot;1567&quot; height=&quot;233&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnlOQJTinbDxwoEp5vWWsVtx0iO2j1gBSnYsTJD0Ylan7VYG3e8QSQLzsTFZobibzp3O2T_l8PtsvQFg8GDvJHAaMfUg-P_7fn3G1gazpRSE7PrPlwc4eqalkAsHr8KTFeNQ3RR4nvubc/s640/microsoft+%25281%2529.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Library dependency used for Slick Extensions&lt;/div&gt;
&lt;pre class=&quot;literal-block&quot; style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;libraryDependencies += &quot;com.typesafe.slick&quot; %% &quot;slick-extensions&quot; % &quot;3.0.0&quot;
&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
But with the newer version of Slick, i.e 3.2.x these drivers are now available within the Slick core package as open source release which can also be seen from the&amp;nbsp;&lt;a href=&quot;http://slick.lightbend.com/news/2017/02/24/slick-3.2.0-released.html&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;change log&lt;/a&gt;&amp;nbsp;as well.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
If you find yourself struggling with a setup to make Microsoft SQL Server work with Scala Slick in your project, maybe because of the lack of resources available on the web, then read up further :)&lt;/div&gt;
&lt;h2 style=&quot;background-color: white; box-sizing: border-box; clear: both; color: #141412; font-family: Bitter, Georgia, serif; font-size: 30px; line-height: 1.3; margin: 25px 0px;&quot;&gt;
&lt;span style=&quot;box-sizing: border-box;&quot;&gt;TL;DR&lt;/span&gt;&lt;/h2&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
SQL Server database configurations&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;sqlserver = {
 driver = &quot;slick.jdbc.SQLServerProfile$&quot;
 db {
 host = ${?SQLSERVER_HOST}
 port = ${?SQLSERVER_PORT}
 databaseName = ${?SQLSERVER_DB_NAME}

 url = &quot;jdbc:sqlserver://&quot;${sqlserver.db.host}&quot;:&quot;${sqlserver.db.port}&quot;;databaseName=&quot;${sqlserver.db.databaseName}
 user = ${?SQLSERVER_USERNAME}
 password = ${?SQLSERVER_PASSWORD}
 }
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Database instance&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;val dbConfig: DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig(&quot;sqlserver&quot;)
val db: JdbcProfile#Backend#Database = dbConfig.db&lt;/pre&gt;
&lt;h2 style=&quot;background-color: white; box-sizing: border-box; clear: both; color: #141412; font-family: Bitter, Georgia, serif; font-size: 30px; line-height: 1.3; margin: 25px 0px;&quot;&gt;
&lt;span style=&quot;box-sizing: border-box;&quot;&gt;SBT project setup&lt;/span&gt;&lt;/h2&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
For the example used in this blog post following dependencies and versions of respective artifacts are used&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Scala 2.11.11&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;SBT 0.13.17&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Slick 3.2.3&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;HikariCP 3.2.3&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Mssql JDBC&amp;nbsp;6.2.1.jre8&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
which inside our&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;build.sbt&lt;/span&gt;&amp;nbsp;file will look like the following set of instructions&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;name := &quot;mssql-example&quot;

version := &quot;1.0&quot;

scalaVersion := &quot;2.11.11&quot;

libraryDependencies ++= Seq(
 &quot;com.typesafe.slick&quot; %% &quot;slick&quot; % &quot;3.2.3&quot;,
 &quot;com.typesafe.slick&quot; %% &quot;slick-hikaricp&quot; % &quot;3.2.3&quot;,
 &quot;com.microsoft.sqlserver&quot; % &quot;mssql-jdbc&quot; % &quot;6.2.1.jre8&quot;
)&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and the instructions of&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;build.properties&lt;/span&gt;&amp;nbsp;file will be&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;sbt.version = 0.13.17&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
The settings required to configure Microsoft SQL Server should go inside&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;application.conf&lt;/span&gt;file, whose instructions would be to specify the details of our database&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXtrQoTZLDP36-fiC1NpiFaFxNb-eZi_-og6m1jVK095ylkDf7rOAico0nketxnfE0faFX0D8Q2cRo_IoyDgenlELg54yigOw6cifX7HH7FN8m-cS-7tFjeKF8DE4gmEODKA3dFY-ML0A/s1600/slick.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;200&quot; data-original-width=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXtrQoTZLDP36-fiC1NpiFaFxNb-eZi_-og6m1jVK095ylkDf7rOAico0nketxnfE0faFX0D8Q2cRo_IoyDgenlELg54yigOw6cifX7HH7FN8m-cS-7tFjeKF8DE4gmEODKA3dFY-ML0A/s1600/slick.jpeg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;sqlserver = {
 driver = &quot;slick.jdbc.SQLServerProfile$&quot;
 db {
  host = ${?SQLSERVER_HOST}
  port = ${?SQLSERVER_PORT}
  databaseName = ${?SQLSERVER_DB_NAME}

  url = &quot;jdbc:sqlserver://&quot;${sqlserver.db.host}&quot;:&quot;${sqlserver.db.port}&quot;;databaseName=&quot;${sqlserver.db.databaseName}
  user = ${?SQLSERVER_USERNAME}
  password = ${?SQLSERVER_PASSWORD}
 }
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
where it can be seen that SQLSERVER_HOST,&amp;nbsp;SQLSERVER_PORT,&amp;nbsp;SQLSERVER_DB_NAME,&amp;nbsp;SQLSERVER_USERNAME and&amp;nbsp;SQLSERVER_PASSWORD are to be provided as environment variables.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now moving onto our FRM (Functional Relational Mapping) and repository setup, the following import will be used for MS SQL Server Slick driver’s API&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;import slick.jdbc.SQLServerProfile.api._&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
And thereafter the FRM will look same as the rest of the FRM’s delineated on the official Slick documentation. For the example on this blog let’s use the following table structure&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;CREATE TABLE user_profiles (
 id         INT IDENTITY (1, 1) PRIMARY KEY,
 first_name VARCHAR(100) NOT NULL,
 last_name  VARCHAR(100) NOT NULL
)&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
whose functional relational mapping will look like this:&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;class UserProfiles(tag: Tag) extends Table[UserProfile](tag, &quot;user_profiles&quot;) {

 def id: Rep[Int] = column[Int](&quot;id&quot;, O.PrimaryKey, O.AutoInc)

 def firstName: Rep[String] = column[String](&quot;first_name&quot;)

 def lastName: Rep[String] = column[String](&quot;last_name&quot;)

 def * : ProvenShape[UserProfile] = (id, firstName, lastName) &amp;lt;&amp;gt;(UserProfile.tupled, UserProfile.unapply) // scalastyle:ignore

}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Moving further up with the CRUD operations, they are fairly straightforward as per the integrated query model provided by Slick, which can be seen from the following UserProfileRepository class&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;class UserProfileRepository {

 val userProfileQuery: TableQuery[UserProfiles] = TableQuery[UserProfiles]

 def insert(user: UserProfile): Future[Int] =
  db.run(userProfileQuery += user)

 def get(id: Int): Future[Option[UserProfile]] =
  db.run(
   userProfileQuery
    .filter(_.id === id)
    .take(1)
    .result
    .headOption)

 def update(id: Int, firstName: String): Future[Int] =
  db.run(
   userProfileQuery
    .filter(_.id === id)
    .map(_.firstName)
    .update(firstName))

 def delete(id: Int): Future[Int] =
  db.run(userProfileQuery.filter(_.id === id).delete)&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Lastly, in order to get the database instance using the configurations provided in&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;application.conf&lt;/span&gt;&amp;nbsp;file, the following code snippet can be used&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;val dbConfig: DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig(&quot;sqlserver&quot;)
val db: JdbcProfile#Backend#Database = dbConfig.db&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Working codebase of this example is available at the following repository:&amp;nbsp;&lt;a href=&quot;https://github.com/mavericksid/scala-slick-mssql&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;scala-slick-mssql.&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Also, if you’re interested in knowing how data can be directly streamed from PostgreSQL to a client using Akka Stream and Scala Slick then you might find the following article useful:&amp;nbsp;&lt;a href=&quot;http://www.ubertechblog.com/2018/05/streaming-data-from-postgresql-using-akka-streams-and-slick-in-play-framework.html&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Streaming data from PostgreSQL using Akka Streams and Slick in Play Framework&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
This blog post has been inspired by an endeavor to make Microsoft SQL Server work with Slick and an answer on StackOverFlow which is the reference of the configurations.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Hope this helps :)&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/using-microsoft-sql-server-with-scala-slick.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnlOQJTinbDxwoEp5vWWsVtx0iO2j1gBSnYsTJD0Ylan7VYG3e8QSQLzsTFZobibzp3O2T_l8PtsvQFg8GDvJHAaMfUg-P_7fn3G1gazpRSE7PrPlwc4eqalkAsHr8KTFeNQ3RR4nvubc/s72-c/microsoft+%25281%2529.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-8727858677800448325</guid><pubDate>Tue, 01 May 2018 15:45:00 +0000</pubDate><atom:updated>2018-05-01T21:25:14.445+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Akka</category><category domain="http://www.blogger.com/atom/ns#">Akka Streams</category><category domain="http://www.blogger.com/atom/ns#">Parallel Programming</category><category domain="http://www.blogger.com/atom/ns#">Play Framework</category><category domain="http://www.blogger.com/atom/ns#">PostgreSQL</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><category domain="http://www.blogger.com/atom/ns#">Reactive Streams</category><category domain="http://www.blogger.com/atom/ns#">Scala</category><category domain="http://www.blogger.com/atom/ns#">Slick</category><category domain="http://www.blogger.com/atom/ns#">Streaming</category><title>Streaming data from PostgreSQL using Akka Streams and Slick in Play Framework</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px; margin: 0px; padding: 0px;&quot;&gt;In this blog post I’ll try to explain the process wherein you can stream data directly from PostgreSQL database using Scala Slick (which is Scala’s database access/query library) and Akka Streams (which is an implementation of Reactive Streams specification on top of Akka toolkit) in Play Framework. The process is going to be pretty straightforward in terms of implementation where data is read from one of the tables in your SQL database as stream and then it is&amp;nbsp;sent/streamed to one of the REST end point configured to download this data.&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTCh1WWPSiOw6Ni9UobJpjnedlgzHutvW8YlDKCz1NT3XF1nEpfYcvEaJy6xAn1QML0PoG9RmxShLoDX_dWxVuw3RMK5QmLT5fFz3DWNlRo39nFTKoEy5zc-2egdv5fgiLXxWMVRs5u4I/s1600/sl6.jpg&quot; imageanchor=&quot;1&quot; style=&quot;color: #646464; margin: 0px 1em; padding: 0px; text-decoration-line: none;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1200&quot; data-original-width=&quot;1600&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTCh1WWPSiOw6Ni9UobJpjnedlgzHutvW8YlDKCz1NT3XF1nEpfYcvEaJy6xAn1QML0PoG9RmxShLoDX_dWxVuw3RMK5QmLT5fFz3DWNlRo39nFTKoEy5zc-2egdv5fgiLXxWMVRs5u4I/s400/sl6.jpg&quot; style=&quot;border: none; height: auto; margin: 0px; max-width: 100%; padding: 0px;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
For better understanding let’s take an example of an application or service which is used for administering a huge customer base of an organisation/company. The person involved in administering the customer base wants to get the entire data-set of customers for let’s say auditing purpose. Based on requirements it would sometimes make sense to stream this data directly into a downloadable file which is what we are going to do in this blog post.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
(For this blog post you should have a basic knowledge of using Play Framework and Slick library)&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLIs4gOOdJxeh8XHpzpOMgK6CxzTacDW2X_gmFzFcOYWkYutmcqigVxIr4fd7ASvYB-1Srm4Z2HoNlDLS_6oPfaGBSWROPE8SlSOvcmmVsR1Bprl-5xQAut0gXiTh77-BsebYOm8ZaCCc/s1600/play_full_color.png&quot; imageanchor=&quot;1&quot; style=&quot;color: #646464; margin: 0px 1em; padding: 0px; text-decoration-line: none;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;836&quot; data-original-width=&quot;1600&quot; height=&quot;209&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLIs4gOOdJxeh8XHpzpOMgK6CxzTacDW2X_gmFzFcOYWkYutmcqigVxIr4fd7ASvYB-1Srm4Z2HoNlDLS_6oPfaGBSWROPE8SlSOvcmmVsR1Bprl-5xQAut0gXiTh77-BsebYOm8ZaCCc/s400/play_full_color.png&quot; style=&quot;border: none; height: auto; margin: 0px; max-width: 100%; padding: 0px;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
The example uses following dependencies&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; list-style: none; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;Play Framework 2.6.10 (“com.typesafe.play” % “sbt-plugin” % “2.6.10”)&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;Play-Slick 3.0.1 (“com.typesafe.play” %% “play-slick” % “3.0.1”)&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;Akka Streams 2.5.8 (“com.typesafe.akka” %% “akka-stream” % “2.5.8”)&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;PostgreSQL 42.1.4 (“org.postgresql” % “postgresql” % “42.1.4”)&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Let’s start by assuming we have a customer table in our PostgreSQL database which has the following structure&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHs_4ArBbRhWb4X11VMz0HSlQJJScD4nmkw2A9iwue_7BkUccLJwdzrDGSM5PNaXN4rkHdbrLLfLqNUhmKZ1r9o4saQL3cJHAPJdCa_iqwBoiPo9zKC-O4egLWW2lznW87d_MP1AFM_AQ/s1600/postgresql.png&quot; imageanchor=&quot;1&quot; style=&quot;color: #646464; margin: 0px 1em; padding: 0px; text-decoration-line: none;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;280&quot; data-original-width=&quot;610&quot; height=&quot;183&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHs_4ArBbRhWb4X11VMz0HSlQJJScD4nmkw2A9iwue_7BkUccLJwdzrDGSM5PNaXN4rkHdbrLLfLqNUhmKZ1r9o4saQL3cJHAPJdCa_iqwBoiPo9zKC-O4egLWW2lznW87d_MP1AFM_AQ/s400/postgresql.png&quot; style=&quot;border: none; height: auto; margin: 0px; max-width: 100%; padding: 0px;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;CREATE TABLE customers (
  id        BIGSERIAL PRIMARY KEY,
  firstname VARCHAR(255) NOT NULL,
  lastname  VARCHAR(255),
  email     VARCHAR(255)
);&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Slick’s functional relational mapping corresponding to this table structure should look like this&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;case class Customer(id: Long,
                    firstName: String,
                    lastName: String,
                    email: String)

trait CustomerTable extends HasDatabaseConfigProvider[slick.jdbc.JdbcProfile] {
  
  import profile.api._

  val customerQuery: TableQuery[CustomerMapping] = TableQuery[CustomerMapping]

  private[models] class CustomerMapping(tag: Tag) extends Table[Customer](tag, &quot;customers&quot;) {

    def id: Rep[Long] = column[Long](&quot;id&quot;, O.PrimaryKey, O.AutoInc)

    def firstName: Rep[String] = column[String](&quot;firstname&quot;)

    def lastName: Rep[String] = column[String](&quot;lastname&quot;)

    def email: Rep[String] = column[String](&quot;email&quot;)

    def * : ProvenShape[Customer] = (id, firstName, lastName, email) &amp;lt;&amp;gt;(Customer.tupled, Customer.unapply)

  }

}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Now let’s use the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;customerQuery&lt;/span&gt;&amp;nbsp;to get data from the customers table in the form of&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;DatabasePublisher&lt;/span&gt;&amp;nbsp;of type Customer, i.e&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;DatabasePublisher[Customer]&lt;/span&gt;, which is Slick’s implementation of reactive stream’s&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;Publisher&lt;/span&gt;&amp;nbsp;where Publisher is the (potential) unbounded sequence of elements that publishes the elements according to the demand from the Subscriber. We will define this inside&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;CustomerRepository&lt;/span&gt;.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; color: #777777; font-family: Lora; font-size: 15px; margin: 0px; padding: 0px; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicwKnpeLqMo25zK03ad7uecydx4NZwZtRTCi58wnlHn6yCMglw-sBkF7BU9LjiU_-BnKLNSRkb-UMek6BpQSfKOFk9HVPJFJpiCUFDrmHhrzuXpc74Gni2Hu5FYB8z-Q23oc1XNQKiyZc/s1600/slick.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;color: #646464; margin: 0px 1em; padding: 0px; text-decoration-line: none;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;200&quot; data-original-width=&quot;300&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicwKnpeLqMo25zK03ad7uecydx4NZwZtRTCi58wnlHn6yCMglw-sBkF7BU9LjiU_-BnKLNSRkb-UMek6BpQSfKOFk9HVPJFJpiCUFDrmHhrzuXpc74Gni2Hu5FYB8z-Q23oc1XNQKiyZc/s400/slick.jpeg&quot; style=&quot;border: none; height: auto; margin: 0px; max-width: 100%; padding: 0px;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
&lt;br style=&quot;margin: 0px; padding: 0px;&quot; /&gt;&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;def customers: DatabasePublisher[Customer] =
  db.stream(
    customerQuery
      .result
      .withStatementParameters(
         rsType = ResultSetType.ForwardOnly,
         rsConcurrency = ResultSetConcurrency.ReadOnly,
         fetchSize = 10000)
      .transactionally)&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Certain things to be noted when using PostgreSQL for streaming data/records, which is also noted in&amp;nbsp;&lt;a href=&quot;http://slick.lightbend.com/doc/3.2.0-M1/dbio.html&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; margin: 0px; padding: 0px; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Slick’s Official documentation&lt;/a&gt;:&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; list-style: none; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;The use of&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;transactionally&lt;/span&gt;&amp;nbsp;which enforces the code to run on a single Connection with auto commit set as false [setAutoCommit(false)], by default slick is set to run in auto commit mode.&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;The use of&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;fetchSize&lt;/span&gt;&amp;nbsp;so that the JDBC driver does not fetch all rows to the memory (i.e on client side) at once but instead fetch the specified number of rows at a time.&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;ResultSetType.ForwardOnly&lt;/span&gt;&amp;nbsp;sets the type to allow results to be read sequentially so that the cursor will only move forward.&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box; list-style: decimal; margin: 0px 0px 12px; padding: 0px;&quot;&gt;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;ResultSetConcurrency.ReadOnly&lt;/span&gt;&amp;nbsp;makes sure that the ResultSet may not be updated.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Only if all of the above is done will the streaming work properly for PostgreSQL else it won’t and the actions inside the stream behavior will fetch the entire dataset.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
So, the database repository code base is now sorted out. Let’s focus on the controller and how it’ll stream this data to a downloadable file.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
We can create a new Play controller for the purpose of managing all APIs related to the customers and this controller has access to the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;CustomerRepository&lt;/span&gt;&amp;nbsp;we created earlier in which the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;customers&lt;/span&gt;&amp;nbsp;method is defined and implemented.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
We’ll use Play’s simple Result to stream the data to our client, i.e to the person administering the customers on /customers API (added to Play routes) by providing the customer stream to HttpEntity.Streamed case class like this&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;Result(
      header = ResponseHeader(OK, Map(CONTENT_DISPOSITION → s&quot;attachment; filename=customers.csv&quot;)),
      body = HttpEntity.Streamed(csvSource, None, None))&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
The entire controller method would look something like this&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;def customers: Action[AnyContent] = Action { implicit request =&amp;gt;
  val customerDatabasePublisher = customerRepository.customers
  val customerSource = Source.fromPublisher(customerDatabasePublisher)

  val headerCSVSource = Source.single(ByteString(&quot;&quot;&quot;&quot;First Name&quot;,&quot;Last Name&quot;,&quot;Email&quot;&quot;&quot;&quot; + &quot;\n&quot;))
  val customerCSVSource =
    customerSource.map(data =&amp;gt; ByteString(s&quot;&quot;&quot;&quot;${data.firstName}&quot;,&quot;${data.lastName}&quot;,&quot;${data.email}&quot;&quot;&quot;&quot; + &quot;\n&quot;))
  
  val csvSource = Source.combine(headerCSVSource, customerCSVSource)(Concat[ByteString])

  Result(
        header = ResponseHeader(OK, Map(CONTENT_DISPOSITION → s&quot;attachment; filename=customers.csv&quot;)),
        body = HttpEntity.Streamed(csvSource, None, None))
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Note that the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;DatabasePublisher[Customer]&lt;/span&gt;&amp;nbsp;is converted to&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;Source&lt;/span&gt;&amp;nbsp;of Customer using the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;Source.fromPublisher&lt;/span&gt;&amp;nbsp;helper method which is used to create a Source from Publisher.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Rest of the manipulations are done on the Source to convert the data into readable CSV file format.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Also, note the use of&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;Source.combine&lt;/span&gt;&amp;nbsp;method which is used to combine sources with fan-in strategy which in our case is&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700; margin: 0px; padding: 0px;&quot;&gt;Concat&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
Hope this helps :)&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
The entire code base is available in the following repository&amp;nbsp;&lt;a href=&quot;https://github.com/mavericksid/playakkastreams&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; margin: 0px; padding: 0px; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;playakkastreams&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 0px 0px 24px; padding: 0px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; margin: 0px; padding: 0px; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/streaming-data-from-postgresql-using-akka-streams-and-slick-in-play-framework.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTCh1WWPSiOw6Ni9UobJpjnedlgzHutvW8YlDKCz1NT3XF1nEpfYcvEaJy6xAn1QML0PoG9RmxShLoDX_dWxVuw3RMK5QmLT5fFz3DWNlRo39nFTKoEy5zc-2egdv5fgiLXxWMVRs5u4I/s72-c/sl6.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-5840097079869816816</guid><pubDate>Tue, 01 May 2018 14:57:00 +0000</pubDate><atom:updated>2018-05-01T20:29:49.500+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><category domain="http://www.blogger.com/atom/ns#">Reverse Proxy Server</category><title>NGINX – Understanding and Setting up a reverse proxy server</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Let’s start by understanding what a reverse proxy server means and then I’ll lay down the steps for setting up such a server using our beloved NGINX.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
A reverse proxy server is one which helps in directing client requests to other (usually backend) servers or to multiple applications hosted on the same server on different ports. You can think of it as an abstraction layer that re-routes traffic from the proxy server to your respective (aforementioned) setup.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
But wait, why would one need such kind of a setup? A reverse proxy server helps in&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Loading balancing your application backend&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Establishing security by adding an additional (publicly accessible) abstraction layer hiding one or multiple (private) servers inside a local area network&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Hosting multiple applications on a single server using multi-port setup instead of resorting to IPv6&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;Boosting performance by compressing traffic on the abstraction layer instead of your web servers&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Moving onto the how part, let’s see how can such a reverse proxy server be setup easily for the use case wherein a single server has multiple web applications hosted on it (to understand the other use cases, i.e 1 and 2, you might want to refer to the following blog post –&amp;nbsp;&lt;a href=&quot;http://www.ubertechblog.com/2018/05/nginx-load-balancing-your-application-made-easy.html&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Loading balancing your application made easy&lt;/a&gt;). Let’s say two separate applications are running on your server at port 9000 and 9001. So the location of these applications from the perspective of your server would be&amp;nbsp;&lt;a href=&quot;http://localhost:9000/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://localhost:9000&lt;/a&gt;and&amp;nbsp;http://localhost:9001.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
(For this example the NGINX setup used is on Ubuntu 16.04 LTS using NGINX version 1.10.0)&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Begin by adding a new virtual server configuration file at&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;/etc/nginx/sites-available&lt;/span&gt;&amp;nbsp;where&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;/etc/nginx&lt;/span&gt;&amp;nbsp;is usually the location where NGINX is setup. Let’s name this file as&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;example.com&lt;/span&gt;&amp;nbsp;and add the following instructions to it&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
  listen 80;
  server_name example.com www.example.com;

  location / {
    proxy_pass http://localhost:9000;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
From the instructions we can see that the domain names example.com and&amp;nbsp;&lt;a href=&quot;http://www.example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://www.example.com&lt;/a&gt;&amp;nbsp;are redirecting the traffic to your application running at&amp;nbsp;&lt;a href=&quot;http://localhost:9000/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://localhost:9000&lt;/a&gt;&amp;nbsp;on the server.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now, add another virtual server configurations file at the same location but name that file as&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;example.org&lt;/span&gt;&amp;nbsp;and add the following instructions to it&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80;
 server_name example.org www.example.org;

 location / {
   proxy_pass http://localhost:9001;
   proxy_set_header Host $http_host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
You’ll notice there’s a difference in the instructions of this virtual server wherein domain example.org and&amp;nbsp;&lt;a href=&quot;http://www.example.org/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://www.example.org&lt;/a&gt;&amp;nbsp;are pointing to a separate application running at&amp;nbsp;&lt;a href=&quot;http://localhost:9001/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://localhost:9001&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now create the soft links of the two files added to&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;/etc/nginx/sites-available&lt;/span&gt;&amp;nbsp;inside&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;/etc/nginx/sites-enabled&lt;/span&gt;&amp;nbsp;and restart NGINX.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Soft links to virtual server configuration files can be created using&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;sudo ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/example.org&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
With this setup all traffic from&amp;nbsp;&lt;a href=&quot;http://example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;http://example.org/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.org&lt;/a&gt;&amp;nbsp;will be proxied to&amp;nbsp;&lt;a href=&quot;http://localhost:9000/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://localhost:9000&lt;/a&gt;&amp;nbsp;and&amp;nbsp;http://localhost:9001 respectively using our NGINX virtual server configurations.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-understanding-and-setting-up-a-reverse-proxy-server.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-983569145440223547</guid><pubDate>Tue, 01 May 2018 14:55:00 +0000</pubDate><atom:updated>2018-05-01T20:30:14.444+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><category domain="http://www.blogger.com/atom/ns#">SSL</category><title>NGINX – Redirecting HTTP to HTTPS</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Using HTTPS is highly recommended and I cannot stop when explaining the benefits of using it! Also something which is more important is to make sure when HTTPS is setup it is ensured that all traffic via HTTP is blocked in a way that it is redirected to HTTPS. This can be easily achieved by giving NGINX the following set of instructions in the virtual server configurations.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Begin by setting up the virtual server for your application so that a domain name points to it. A simple virtual server configuration using SSL is as follows&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 443 ssl;
 server_name example.com;
 
 ssl_certificate /path/to/your/example.com.crt;
 ssl_certificate_key /path/to/your/example.com.key;

 root /path/to/your/content;
 index index.html;
 include /etc/nginx/mime.types;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now setup the redirect from HTTP to HTTPS using:&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80;
 server_name example.com;
 return 301 https://example.com$request_uri;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
this redirects&amp;nbsp;&lt;a href=&quot;http://example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com&lt;/a&gt;&amp;nbsp;to&amp;nbsp;&lt;a href=&quot;https://example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;https://example.com&lt;/a&gt;&amp;nbsp;along with the URI in the request using the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;return&lt;/span&gt;&amp;nbsp;directive and status code 301. For example,&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;a href=&quot;http://example.com/user/1&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com/user/1&lt;/a&gt;&amp;nbsp;would be redirected to&amp;nbsp;https://example.com/user/1.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-redirecting-http-to-https.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-9181652726793849604</guid><pubDate>Tue, 01 May 2018 14:53:00 +0000</pubDate><atom:updated>2018-05-01T20:30:41.571+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">Load Balancing</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><title>NGINX – Load Balancing your application made easy</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Often there are requirements to load balance your application in order to scale out and make your application more performant and NGINX can be used to do just that! It can distribute your traffic to several application servers.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
There are several load balancing methods available in NGINX which are&lt;/div&gt;
&lt;ol style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin: 16px 0px; padding: 0px 0px 0px 40px;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;round robin – wherein the requests are distributed in a&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Round-robin&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;round-robin&lt;/a&gt;&amp;nbsp;fashion&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;least connected – request is sent to the server with least number of active connections&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;ip hash – uses a hash-function to determine a server for sending the request&lt;/li&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;weighted – distributes requests based on servers’ weight specified&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
I’ll try to elaborate more on it by describing an architecture wherein there’s a set of static content which is made available via NGINX on a domain name and this static content has certain dynamic aspects which are loaded from your application backend. Application backend is what would be load balanced here.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Let’s start with our static content first and assume it is available at /path/to/your/content. A sample NGINX configuration for this would look something like&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 server_name example.com;

 root /path/to/your/content;
 index index.html;
 include /etc/nginx/mime.types;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
where the domain example.com points to our static content available at&amp;nbsp;/path/to/your/content.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now, in order to render your dynamic content you’ll need a way in your static files to specifiy where that content should be made available from. For that you’ll need to provide the API details. But let’s try to do it via NGINX configurations. Let’s try to make your API available on the same domain as instructed in the configurations above but via URI which is /api. A way of doing it is by configuring the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;location&lt;/span&gt;&amp;nbsp;directive in your&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;server {}&lt;/span&gt;&amp;nbsp;block configurations to offload all traffic from the specified URI to your application backend and the configuration of which could look something like&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;location /api/ {
 proxy_pass http://api/;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection &#39;upgrade&#39;;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
proxy_pass – used to pass a request to a proxied server&lt;br /&gt;
proxy_http_version – sets the HTTP protocol version to 1.1&lt;br /&gt;
proxy_set_header – is used to set the headers from client to proxied server&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
But how do you instruct NGINX where /api points to? It is done using the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;upstream&lt;/span&gt;directive which has to be configured inside the&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;http {}&lt;/span&gt;&amp;nbsp;block usually located inside nginx.conf file. A sample configurations looks something like this&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;http {
 upstream api {
  server address-of-your-application-backend.com;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Once the aforementioned is done all traffic from&amp;nbsp;&lt;a href=&quot;http://example.com/api&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com/api&lt;/a&gt;&amp;nbsp;will be redirected to the upstream server as specified in the upstream configurations.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
For example, the information of a user of your application is available on your application backend at /user/:id API. This information can now be easily accessed using&amp;nbsp;&lt;a href=&quot;http://example.com/api/user/1&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com/api/user/1&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Henceforth, upstream is where things start getting interesting which is where the load balancing instructions are specified. You can specifiy multiple servers inside the upstream block&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;http {
 upstream api {
  server address-of-your-application-backend-1.com;
  server address-of-your-application-backend-2.com;
  server address-of-your-application-backend-3.com;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
You can see that the load balancing method is not specified in the configurations above and it defaults to round-robin. All requests to get the dynamic data are now re-routed to servers specified in the upstream block in round-robin fashion.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Load balancing method can be specified inside the upstream block like this&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;http {
 upstream api {
  least_conn;
  server address-of-your-application-backend-1.com;
  server address-of-your-application-backend-2.com;
  server address-of-your-application-backend-3.com;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Hope this helps in better understanding of NGINX load balancing and how it can be achieved as a part of your application architecture.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-load-balancing-your-application-made-easy.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-6354276333429224951</guid><pubDate>Tue, 01 May 2018 14:51:00 +0000</pubDate><atom:updated>2018-05-01T20:31:06.406+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><title>NGINX – Redirecting traffic between www and non-www domain</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Just in case you ever wondered whether the re-routing from&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;www to non-www&lt;/span&gt;&amp;nbsp;or&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;non-www to www&lt;/span&gt;&amp;nbsp;domain is possible using NGINX then you bet it is! In fact it is very simple and can be done using the following steps&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
1. Redirecting from www to non-www&lt;br /&gt;
Setup a initial virtual server block to point your domain to your content, a simple example would look something like this:&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80;
 server_name example.com;

 root /path/to/your/content/;
 index index.html;
 include /etc/nginx/mime.types;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and then setup another virtual server block for the redirect&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80;
 server_name www.example.com;
 return 301 http://example.com$request_uri;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
which will simply redirect the traffic from&amp;nbsp;&lt;a href=&quot;http://www.example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://www.example.com&lt;/a&gt;&amp;nbsp;to&amp;nbsp;&lt;a href=&quot;http://example.com/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://example.com&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
2. Redirecting from non-www to www&lt;br /&gt;
I believe by now you might have understood how it works and doing the reverse is even more easy which is by using the following instructions&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80;
 server_name example.com;
 return 301 http://www.example.com$request_uri;
}

server {
 listen 80;
 server_name www.example.com;

 root /path/to/your/content/;
 index index.html;
 include /etc/nginx/mime.types;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-redirecting-traffic-between-www-and-non-www-domain.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4e9GOGzaNherrYMd1HOIQ_LRFqozq_5zyj3Z1qPkPG1zfMqTXaqXC1eDBnp2jRyzBMjhsK2KVVmOs-BbSrY7R9WIx33hLcp3l18G8N7WPoJ6wcfn4d90_0KMPyTrIUnSolL2fWna1d_M/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-6503886012769433422</guid><pubDate>Tue, 01 May 2018 14:47:00 +0000</pubDate><atom:updated>2018-05-01T20:31:44.031+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">IP Filtering</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><title>NGINX – Restrict access to Geographical Locations using GeoIP module</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
In this post I’ll try to explain how NGINX GeoIP module can be used to restrict access to your web-portal/website only to a specific geographical region.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW3xVg1RveI1RCF8aEN7_istxb1h9UnkfdqEG1EELhcaMwkLMAdc6SS8auqZ1bOHNWfpb-D-LiXYs5kSMYEclapATeTljbcBHRZNJhFPazxpZ_qpcXGynLbIg9Aq9nrfNO07o59aCsQSQ/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW3xVg1RveI1RCF8aEN7_istxb1h9UnkfdqEG1EELhcaMwkLMAdc6SS8auqZ1bOHNWfpb-D-LiXYs5kSMYEclapATeTljbcBHRZNJhFPazxpZ_qpcXGynLbIg9Aq9nrfNO07o59aCsQSQ/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Begin by verifying NGINX GeoIP module is installed on the server which can be done via&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;nginx -V&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
if you can see&amp;nbsp;–with-http_geoip_module in the output you are ready to use the GeoIP database with NGINX but if not you can install it on the server using the following command (for ubuntu)&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;apt-get install geoip-database libgeoip1&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
this will install GeoIP database usually at the following location&amp;nbsp; /usr/share/GeoIP/GeoIP.dat.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Go ahead and re-configure your nginx.conf file, usually located inside /etc/nginx/ folder based on your installation, by adding following instructions inside&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;http {}&lt;/span&gt;&amp;nbsp;block&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;geoip_country /usr/share/GeoIP/GeoIP.dat;

map $geoip_country_code $allowed_country {
 default&amp;nbsp;no;
 US yes;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
this sets&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;$allowed_country&lt;/span&gt;&amp;nbsp;to&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;yes&lt;/span&gt;&amp;nbsp;if your webportal/website is being accessed from USA. For all other locations trying to access your server the default value will be used which is&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;no&lt;/span&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now you can configure your virtual server configurations by adding the following instructions inside&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;server {}&lt;/span&gt;&amp;nbsp;block.&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;if ($allowed_country = no) {
 return 403;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and this will block all the traffic, except for USA, to your virtual server by returning the 403 status code.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
As the blocking is done based on the information of IP addresses available inside the GeoIP database it’d make sense to update the database at regular intervals which can be easily done using a cron job. You can use the following script (geoIP-update.sh) to make it happen&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;#!/bin/bash
cd /usr/share/GeoIP
echo =============== updating database===============
wget&amp;nbsp;&quot;http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz&quot;&amp;nbsp;-P /YOUR/PATH/HERE || { echo&amp;nbsp;&#39;Cannot download database, exiting.&#39;&amp;nbsp;; exit&amp;nbsp;1; }
gunzip /YOUR/PATH/HERE/GeoIP.dat.gz
mv -f /YOUR/PATH/HERE/GeoIP.dat /usr/share/GeoIP/&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and schedule a job via&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;crontab -e&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
by adding the following&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;* 12 * * 3 /usr/share/GeoIP/geoIP-update.sh&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Make sure to modify&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;* 12 * * 3&lt;/span&gt;&amp;nbsp;according to your update interval requirements.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-restrict-access-to-geographical.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW3xVg1RveI1RCF8aEN7_istxb1h9UnkfdqEG1EELhcaMwkLMAdc6SS8auqZ1bOHNWfpb-D-LiXYs5kSMYEclapATeTljbcBHRZNJhFPazxpZ_qpcXGynLbIg9Aq9nrfNO07o59aCsQSQ/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-7659672801572900129</guid><pubDate>Tue, 01 May 2018 14:41:00 +0000</pubDate><atom:updated>2018-05-01T20:32:12.394+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><category domain="http://www.blogger.com/atom/ns#">SSL</category><title>NGINX – Disable direct access (via http and https) to a website using IP address</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
For the requirements wherein direct access to a website using IP address has to be disabled/blocked, following steps can be followed&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8RxQnPA9QTVeOJoW72Npy40YoWRA9CLRvMwB1aWgGbMz_as8geFBXVsFVvNTgng8MYJxfEXH5NyX2LdtGB-WF7G-sAU8SuGDerbNKYDGn32C3HhFCrZ_Q3Vb2ZhyirHgRyMnZjapdRdQ/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;147&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8RxQnPA9QTVeOJoW72Npy40YoWRA9CLRvMwB1aWgGbMz_as8geFBXVsFVvNTgng8MYJxfEXH5NyX2LdtGB-WF7G-sAU8SuGDerbNKYDGn32C3HhFCrZ_Q3Vb2ZhyirHgRyMnZjapdRdQ/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
To disable/block direct access to IP for port 80 create a new or add to an existing (as required) server configurations as follows&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 80 default_server;
 server_name _;
 return 404;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
where _ catches all the domain names pointing to your server’s IP address and the configuration will block all traffic to your IP address (&lt;a href=&quot;http://your_ip_address/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://YOUR_IP_ADDRESS&lt;/a&gt;) by returning the default 404 Not Found Nginx page.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
To disable/block direct access to IP for port 443 use the following in one of your server configurations block&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;if ($host != &quot;example.com&quot;) {
 return 404;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
example&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 443 ssl;
 server_name example.com
 
 ssl_certificate /etc/nginx/ssl/example.com.crt;
 ssl_certificate_key /etc/nginx/ssl/example.com.key;

 if ($host != &quot;example.com&quot;) {
  return 404;
 }
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
this will block all traffic to&amp;nbsp;&lt;a href=&quot;https://your_ip_address/&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;https://YOUR_IP_ADDRESS&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Hope this helps!&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-disable-direct-access-via-http.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8RxQnPA9QTVeOJoW72Npy40YoWRA9CLRvMwB1aWgGbMz_as8geFBXVsFVvNTgng8MYJxfEXH5NyX2LdtGB-WF7G-sAU8SuGDerbNKYDGn32C3HhFCrZ_Q3Vb2ZhyirHgRyMnZjapdRdQ/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-7552781820657431493</guid><pubDate>Tue, 01 May 2018 14:38:00 +0000</pubDate><atom:updated>2018-05-01T20:32:41.249+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">DevOps</category><category domain="http://www.blogger.com/atom/ns#">NGINX</category><category domain="http://www.blogger.com/atom/ns#">PFX</category><category domain="http://www.blogger.com/atom/ns#">SSL</category><title>NGINX – Easiest way to setup SSL using .pfx files</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
I’ll try to explain the easiest way to use a .pfx file that can be used to install SSL on NGINX.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn1zZaHKiK7_aLaVxydChsH4gy2RQdVbyRvzv2pyjOATK821TV2EppWN0LopH2svRIDPaCnmdAyXkvpIzewF3B2ZVrBcz7gNRdxlA4kgLoaI-PoTfjnyi-AxU63cNshqP9DJSm_wLfi6s/s1600/nginx.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;144&quot; data-original-width=&quot;626&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn1zZaHKiK7_aLaVxydChsH4gy2RQdVbyRvzv2pyjOATK821TV2EppWN0LopH2svRIDPaCnmdAyXkvpIzewF3B2ZVrBcz7gNRdxlA4kgLoaI-PoTfjnyi-AxU63cNshqP9DJSm_wLfi6s/s640/nginx.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
We’ll start by extracting the CRT file using&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; font-weight: 700;&quot;&gt;openssl&lt;/span&gt;&amp;nbsp;with the following command&lt;/div&gt;
&lt;pre class=&quot;shell&quot; style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;openssl pkcs12 -in ./YOUR-PFX-FILE.pfx -clcerts -nokeys -out domain.crt&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Followed by extracting the private key with the following command&lt;/div&gt;
&lt;pre class=&quot;shell&quot; style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;openssl pkcs12 -in ./YOUR-PFX-FILE.pfx -nocerts -nodes -out domain.rsa&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Now we can proceed by setting up a most simple NGINX server using the following configurations&lt;/div&gt;
&lt;pre style=&quot;background: rgb(245, 245, 245); box-sizing: border-box; color: #666666; font-size: 14px; hyphens: none; margin-bottom: 20px; margin-top: 20px; overflow: auto; padding: 20px; white-space: pre-wrap; word-wrap: break-word;&quot;&gt;server {
 listen 443 ssl;
 server_name domain.com domain.com;
 ssl_certificate /path/to/your/CRT_file/domain.crt;
 ssl_certificate_key /path/to/your/RSA_file/domain.rsa;

 root /mnt/coming-soon/bushbeans;
 index index.html;
 include /etc/nginx/mime.types;
}&lt;/pre&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Voila! All done.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/nginx-easiest-way-to-setup-ssl-using.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn1zZaHKiK7_aLaVxydChsH4gy2RQdVbyRvzv2pyjOATK821TV2EppWN0LopH2svRIDPaCnmdAyXkvpIzewF3B2ZVrBcz7gNRdxlA4kgLoaI-PoTfjnyi-AxU63cNshqP9DJSm_wLfi6s/s72-c/nginx.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-5929853190569856748</guid><pubDate>Tue, 01 May 2018 14:35:00 +0000</pubDate><atom:updated>2018-05-01T20:06:51.915+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Linux</category><category domain="http://www.blogger.com/atom/ns#">Remote Profiling</category><category domain="http://www.blogger.com/atom/ns#">SSH</category><title>Remote profiling using SSH Port Forwarding (SSH Tunneling) on Linux</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;In this blog post I’ll lay out few steps that are needed for remote profiling using SSH Port Forwarding (SSH Tunneling) using Yourkit profiler.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK71U94DcmWJNBDvJn3m6w5_is9UlrPHyCbMDVS5kI4XJ4eLKFzO0i_tqAoHc4neIK-1Wg-bqBfKMKW3T0EfXlRtbJz-bZs8XTwt8qMLXUDEG7UsE6mVB65Anqmp0CE7XvH9JSbw4cB4Y/s1600/yourkit.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;532&quot; data-original-width=&quot;981&quot; height=&quot;345&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK71U94DcmWJNBDvJn3m6w5_is9UlrPHyCbMDVS5kI4XJ4eLKFzO0i_tqAoHc4neIK-1Wg-bqBfKMKW3T0EfXlRtbJz-bZs8XTwt8qMLXUDEG7UsE6mVB65Anqmp0CE7XvH9JSbw4cB4Y/s640/yourkit.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;b style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Steps to be followed on remote machine:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;1) Download Yourkit profiler from official Yourkit website.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;2) Extract the downloaded file anywhere.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;3) What we need to do now is find the file named&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;libyjpagent.so&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;in the extracted folder corresponding to the system architecture of your remote machine. In my case it is located in&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;yjp-2013-build-13086/bin/linux-x86-64.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;4) Copy the&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;libyjpagent.so&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;file to any convenient location (if required), I copied it to&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;/tmp/yjp&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;folder.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;5) Add the following VM option to the command line of your Java application:&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; font-style: italic; margin: 0px; padding: 0px 3em; quotes: none; vertical-align: baseline;&quot;&gt;
&lt;div style=&quot;background: transparent; border: 0px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;-agentpath:/tmp/yjp/libyjpagent.so=port=7878&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Here 7878 is the port that you will port forward to.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;6) Your remote machine is all set for profiling.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;b style=&quot;background: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Steps to be followed on local machine:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;1) Port forward to remote machine by executing the following command on terminal:&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; font-style: italic; margin: 0px; padding: 0px 3em; quotes: none; vertical-align: baseline;&quot;&gt;
&lt;div style=&quot;background: transparent; border: 0px; margin-bottom: 24px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;ssh -N -f 1.2.3.4 -L 8085:1.2.3.4:7878&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Explanation of what is going on in the above command:&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;-L 8085:1.2.3.4:7878&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;is forwarding port 7878 from 1.2.3.4 to localhost port 8085&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;-N -f&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;parameters are forcing the ssh to go to background.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;2) Download Yourkit profiler from official Yourkit website on you local machine as well.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;3) Extract the downloaded file anywhere.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;4) From terminal go to the following folder:&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;yjp-2013-build-13086/bin&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;and start Yourkit profiler using&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;sh yjp.sh.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;5) Now from yourkit profiler choose&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;“Connect to remote application”&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;option and enter&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;courier new&amp;quot; , monospace; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;localhost:8085&lt;/span&gt;&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&amp;nbsp;in the pop-up that asks for the link to your remote application.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: rgb(255, 255, 255); border: 0px; color: #333333; font-family: &amp;quot;PT Serif&amp;quot;, serif; font-size: 16px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;6) Yourkit will start profiling your Java application on remote machine now.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;background: transparent; border: 0px; font-family: &amp;quot;verdana&amp;quot; , sans-serif; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;em style=&quot;box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/remote-profiling-using-ssh-port.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK71U94DcmWJNBDvJn3m6w5_is9UlrPHyCbMDVS5kI4XJ4eLKFzO0i_tqAoHc4neIK-1Wg-bqBfKMKW3T0EfXlRtbJz-bZs8XTwt8qMLXUDEG7UsE6mVB65Anqmp0CE7XvH9JSbw4cB4Y/s72-c/yourkit.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-4120508851661779662</guid><pubDate>Tue, 01 May 2018 14:30:00 +0000</pubDate><atom:updated>2018-05-01T20:00:32.862+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Clojure</category><category domain="http://www.blogger.com/atom/ns#">Parallel Programming</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><title>Parallelism in Clojure</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
An axiom of microprocessor development stating that the number of transistors on integrated circuits doubles approximately every two years is analogous to the fact the processing power doubles during the same period, relative to the cost or size. This has lead to the need of parallelism in programming languages and Clojure is one such language which provides a variety of functions for your multi-threaded code. In this article we’ll discuss about futures, atoms and refs which are all a consequential part of parallel programming.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSCJA1mhX9cVU5jERhbFaMHyW7JVqMe_qg9d3e14W_D9-r0il9ZzwwvaDCw2kNXZOaMBNBuK9VnFbNRQVEKZC6XJaB15hMRa6k33L14pcJ5fK1edFevd1cNCObofZK1V4CwCp826TZWFU/s1600/clojure.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;116&quot; data-original-width=&quot;396&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSCJA1mhX9cVU5jERhbFaMHyW7JVqMe_qg9d3e14W_D9-r0il9ZzwwvaDCw2kNXZOaMBNBuK9VnFbNRQVEKZC6XJaB15hMRa6k33L14pcJ5fK1edFevd1cNCObofZK1V4CwCp826TZWFU/s1600/clojure.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;b&gt;Futures&lt;/b&gt;&lt;br /&gt;
Futures are supported out-of-box in clojure. They can be used to simply start a new memory intensive operation in a new thread which typically runs in a thread pool. Dereferencing a future may yield a result immediately or it will block until the future is done.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Let’s start with an example of a memory intensive operation. Here, we will try to write a range of numerical values in separate files, with each write operation for a file done with a separate future.&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6
7&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;      (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;doall&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;         (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;map&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;            (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;fn &lt;/span&gt;[&lt;span style=&quot;color: #996633;&quot;&gt;n&lt;/span&gt;] (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;future&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;spit&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;gensym &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;test&quot;&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;.txt&quot;&lt;/span&gt;)
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;                                        (&lt;span style=&quot;color: #007020;&quot;&gt;apply str &lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;doall &lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;map inc &lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;range &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;n&lt;/span&gt;)))))))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;            [&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;10000000&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1000000&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;10000000&lt;/span&gt;])))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #aa6600;&quot;&gt;&#39;user/a&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;In the above code doall causes the entire lazyseq to reside in memory at one time. As “map” maps through the vector of length 3, so 3 futures are started where each future starts a new spit operation on test[random number].txt files to write the range of numbers defined by the vector “[10000000 1000000 10000000]”. The above code will return a lazyseq of futures which will be stored in “a”.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Now let’s check when the future gets completed by using the following code:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;map &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;future-done?&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt;)
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;false&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;true&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;false&lt;/span&gt;)
 &lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;map &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;future-done?&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt;)
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;true&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;true&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;false&lt;/span&gt;)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;future-done? returns true if the following future is done. On my system the future operation with range of “10000000” takes more time as compared to the range of “1000000”.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;So, “(map future-done? a)” for the first time returns (false true false), meaning that the second future is done but the first and third futures are still processing.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;After awhile, “(map future-done? a)” returns (true true false), meaning that first and second futures are done.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;The order of completion of futures may vary on your system, but eventually all will be done after awhile. This means that you can offload heavy operations in different threads and continue with other tasks.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;b&gt;Atoms&lt;/b&gt;&lt;br /&gt;
In the most simple terms atoms are uncoordinated and synchronous. We use atoms only when one identity needs to be updated synchronously. Synchronous access means that all values are updated before continuing further with the next update. Atoms simply ensures that in a multi-threaded environment the values of atom are either updated entirely or not at all.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
We’ll start with the most basic example:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;atom&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:firstname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:lastname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;}))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #aa6600;&quot;&gt;&#39;user/a&lt;/span&gt;
 &lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt;
 {&lt;span style=&quot;color: #aa6600;&quot;&gt;:firstname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;, &lt;span style=&quot;color: #aa6600;&quot;&gt;:lastname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Here we’ve defined a map as an atom. In order to find the value stored in an atom we use deref or a short form of deref “@”. Dereferencing returns the value stored in “a”, in this case we get the map defined during initialization.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;To change the value of an atom we can either use swap! or reset!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;assoc &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:firstname&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%2&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:lastname&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%3&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Sidharth&quot;&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Khattri&quot;&lt;/span&gt;)
 {&lt;span style=&quot;color: #aa6600;&quot;&gt;:firstname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Sidharth&quot;&lt;/span&gt;, &lt;span style=&quot;color: #aa6600;&quot;&gt;:lastname&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Khattri&quot;&lt;/span&gt;}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;swap! takes atom as the first argument and the function to apply on the value stored in the atom as the second argument. In the above case we’ve defined an anonymous function that associates a new value to the previously defined map and returns that new value. Internally swap! applies compare-and-set! on the new values to cross check for any race conditions. If their exist a race condition i.e if two threads are trying to apply same function on the atom simultaneously and if the value of the atom has changed since they first began swapping, the loser thread will try to swap again until the present value is same as the last commit.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;reset!&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;)
 &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
reset! sets the value of atom to a new value without regard for the previously stored value in the atom.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;b&gt;Refs&lt;/b&gt;&lt;br /&gt;
Unlike atoms, refs are coordinated and are used for synchronous access. They are used when multiple identities have to be changed synchronously and they use Software Transactional Memory System (STM) for memory transactions. Any changes to the values of refs have to be done in transactional blocks, i.e sync or dosync.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Refs are defined in the same way atoms are defined:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-to-be-done&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;ref &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;{&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;,&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;2&lt;/span&gt;,&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;3&lt;/span&gt;,&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;4&lt;/span&gt;,&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;}))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #aa6600;&quot;&gt;&#39;user/task-to-be-done&lt;/span&gt;
 &lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-done&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;ref &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;{}))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #aa6600;&quot;&gt;&#39;user/task-done&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Here, we have defined two tasks that have to be updated simultaneously, i.e task-to-be-done and task-done, which are defined as refs containing hashsets.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;defn &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;update-values&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;value&lt;/span&gt;]
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;      (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;dosync&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;        (&lt;span style=&quot;color: #007020;&quot;&gt;alter &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-to-be-done&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;disj &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;value&lt;/span&gt;)
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;_=&amp;gt;&lt;/span&gt;          (&lt;span style=&quot;color: #007020;&quot;&gt;alter &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-done&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;conj &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;value&lt;/span&gt;)))
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #aa6600;&quot;&gt;&#39;user/check&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Then we define a function – update-values, to alter the values of both the refs simultaneously in the dosync transactional block. “alter” is used to change the in-transactional-value of the refs. “disj” returns a new set that does not contain the key(s) passed as the argument. Similarly, “conj” returns a new set that contains the key(s) passed as the argument.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;update-values&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;)
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;{&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;}
 &lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-to-be-done&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;{&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;2&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;3&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;4&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;}
 &lt;span style=&quot;color: #996633;&quot;&gt;user=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;task-done&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;{&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
On passing some value to “update-values” function, the values of both refs are updated simultaneously. In order to view the values stored in refs we use the same deref or “@” as used in atoms. Dereferencing task-to-be-done and @task-done returns the values stored in the refs.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Thus refs are used for managing multiple data structures in transactional blocks, atomically.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/parallelism-in-clojure.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSCJA1mhX9cVU5jERhbFaMHyW7JVqMe_qg9d3e14W_D9-r0il9ZzwwvaDCw2kNXZOaMBNBuK9VnFbNRQVEKZC6XJaB15hMRa6k33L14pcJ5fK1edFevd1cNCObofZK1V4CwCp826TZWFU/s72-c/clojure.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-2068607159322597020</guid><pubDate>Tue, 01 May 2018 14:06:00 +0000</pubDate><atom:updated>2018-05-01T20:00:50.793+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Apache</category><category domain="http://www.blogger.com/atom/ns#">Apache Curator</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><category domain="http://www.blogger.com/atom/ns#">Scala</category><category domain="http://www.blogger.com/atom/ns#">Zookeeper</category><title>How to setup and use Zookeeper in Scala using Apache Curator</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
In order to use Zookeeper to manage your project’s configurations across the cluster, first we will setup the zookeeper ensemble on our local machine (setup is for testing on a single machine) by following these steps:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrZuZQuFOPYDE-F1U-OOZX1OU_AMGLcr6amOaVxKqQdTvwtO7zhua_A-HBWWhW7Tt3Sl3gUpdtXmL6GKNW1nm9Si7msignBnh9Hby_Xo3Ai0z6_aeDKbbvHakEOpmRxshpSU8ne8iI18g/s1600/scala-zookeeper.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;275&quot; data-original-width=&quot;800&quot; height=&quot;219&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrZuZQuFOPYDE-F1U-OOZX1OU_AMGLcr6amOaVxKqQdTvwtO7zhua_A-HBWWhW7Tt3Sl3gUpdtXmL6GKNW1nm9Si7msignBnh9Hby_Xo3Ai0z6_aeDKbbvHakEOpmRxshpSU8ne8iI18g/s640/scala-zookeeper.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
1) Download a stable zookeeper release&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
2) Unpack it at three places and rename it to:&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;/home/user/Desktop/zookeeper1,
/home/user/Desktop/zookeeper2, and
/home/user/Desktop/zookeeper3
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
3) In order to use zookeeper we will need to setup configuration files for all servers.&lt;br /&gt;
Make a new file zoo.cfg,&lt;br /&gt;
/home/user/Desktop/zookeeper1/conf/zoo.cfg&lt;br /&gt;
and add following details:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;tickTime&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2000
&lt;span style=&quot;color: #996633;&quot;&gt;initLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;10
&lt;span style=&quot;color: #996633;&quot;&gt;syncLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;5
&lt;span style=&quot;color: #996633;&quot;&gt;dataDir&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;/home/user/Desktop/zookeeperData1
&lt;span style=&quot;color: #996633;&quot;&gt;clientPort&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2181
server.1&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2888:3888
server.2&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2889:3889
server.3&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2890:3890
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Similarly,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;/home/user/Desktop/zookeeper2/conf/zoo.cfg, as:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;tickTime&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2000
&lt;span style=&quot;color: #996633;&quot;&gt;initLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;10
&lt;span style=&quot;color: #996633;&quot;&gt;syncLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;5
&lt;span style=&quot;color: #996633;&quot;&gt;dataDir&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;/home/user/Desktop/zookeeperData2
&lt;span style=&quot;color: #996633;&quot;&gt;clientPort&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2182
server.1&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2888:3888
server.2&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2889:3889
server.3&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2890:3890
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;And,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;/home/user/Desktop/zookeeper3/conf/zoo.cfg, as:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #996633;&quot;&gt;tickTime&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2000
&lt;span style=&quot;color: #996633;&quot;&gt;initLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;10
&lt;span style=&quot;color: #996633;&quot;&gt;syncLimit&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;5
&lt;span style=&quot;color: #996633;&quot;&gt;dataDir&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;/home/user/Desktop/zookeeperData3
&lt;span style=&quot;color: #996633;&quot;&gt;clientPort&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt;2183
server.1&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2888:3888
server.2&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2889:3889
server.3&lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; localhost:2890:3890
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
4) Now we will have to define each server’s id by making a new file in:&lt;br /&gt;
/home/user/Desktop/zookeeperData1/myid&lt;br /&gt;
which should have: 1&lt;br /&gt;
/home/user/Desktop/zookeeperData2/myid&lt;br /&gt;
which should have: 2&lt;br /&gt;
/home/user/Desktop/zookeeperData3/myid&lt;br /&gt;
which should have: 3&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
5) Next, we will start zookeeper ensemble for each server in 3 different terminals:&lt;br /&gt;
cd /home/user/Desktop/zookeeper1&lt;br /&gt;
bin/zkServer.sh start&lt;br /&gt;
cd /home/user/Desktop/zookeeper2&lt;br /&gt;
bin/zkServer.sh start&lt;br /&gt;
cd /home/user/Desktop/zookeeper3&lt;br /&gt;
bin/zkServer.sh start&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
6) Now we will add some data in one of the ZNode of the zookeeper ensemble by following steps:&lt;br /&gt;
a) bin/zkCli.sh&lt;br /&gt;
b) create /test_node “Some data”&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
7) Then we will write the following code in order to setup a watcher for zookeeper node so as to get stored data from zookeeper server using apache curator as a library to interact with our zookeeper server.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Add the following dependency in your build.sbt file:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;libraryDependencies &lt;span style=&quot;color: #333333;&quot;&gt;++=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Seq&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;
&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;org.apache.curator&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;curator-framework&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;2.6.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;org.apache.curator&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;curator-recipes&quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;2.6.0&quot;&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px 0px 24px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
and use this to interact with the zookeeper server:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;ZookeeperClient&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
 
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; logger &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getLogger&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getClass&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getName&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
 
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def&lt;/span&gt; main&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;args&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;Array&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;])&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; retryPolicy &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;ExponentialBackoffRetry&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; curatorZookeeperClient &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;CuratorFrameworkFactory&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;newClient&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;localhost:2181,localhost:2182,localhost:2183&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; retryPolicy&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
  curatorZookeeperClient&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;start
  curatorZookeeperClient&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getZookeeperClient&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;blockUntilConnectedOrTimedOut
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; znodePath &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/test_node&quot;&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; originalData &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;curatorZookeeperClient&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getData&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;forPath&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;znodePath&lt;span style=&quot;color: #333333;&quot;&gt;))&lt;/span&gt; &lt;span style=&quot;color: #888888;&quot;&gt;// This should be &quot;Some data&quot;&lt;/span&gt;
 
  &lt;span style=&quot;color: #888888;&quot;&gt;/* Zookeeper NodeCache service to get properties from ZNode */&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; nodeCache &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;NodeCache&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;curatorZookeeperClient&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; znodePath&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
  nodeCache&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getListenable&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;addListener&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;NodeCacheListener&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
 
  &lt;span style=&quot;color: #555555; font-weight: bold;&quot;&gt;@Override&lt;/span&gt;
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def&lt;/span&gt; nodeChanged &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
   &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; dataFromZNode &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; nodeCache&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getCurrentData
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;val&lt;/span&gt; newData &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;currentData&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getData&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #888888;&quot;&gt;// This should be some new data after it is changed in the Zookeeper ensemble&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;case&lt;/span&gt; ex&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333399; font-weight: bold;&quot;&gt;Exception&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;=&amp;gt;&lt;/span&gt; logger&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;error&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Exception while fetching properties from zookeeper ZNode, reason &quot;&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt; ex&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;getCause&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
  &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;

  nodeCache&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;start
  &lt;span style=&quot;color: #333333;&quot;&gt;})&lt;/span&gt;
 &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;entry-content&quot; style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px auto; max-width: 604px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; width: 603.99px; word-spacing: 0px; word-wrap: break-word;&quot;&gt;
&lt;div style=&quot;box-sizing: border-box; margin: 0px 0px 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;em style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;source sans pro&amp;quot;, helvetica, sans-serif; font-size: 16px;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/05/how-to-setup-and-use-zookeeper-in-scala.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrZuZQuFOPYDE-F1U-OOZX1OU_AMGLcr6amOaVxKqQdTvwtO7zhua_A-HBWWhW7Tt3Sl3gUpdtXmL6GKNW1nm9Si7msignBnh9Hby_Xo3Ai0z6_aeDKbbvHakEOpmRxshpSU8ne8iI18g/s72-c/scala-zookeeper.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-4771857773158833365</guid><pubDate>Mon, 30 Apr 2018 17:54:00 +0000</pubDate><atom:updated>2018-05-01T20:01:10.050+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Clojure</category><category domain="http://www.blogger.com/atom/ns#">Google</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><title>Google Sign-In using Clojure</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
Last time I wrote an article for providing&amp;nbsp;&lt;a href=&quot;http://www.ubertechblog.com/2018/04/facebook-sign-in-using-clojure.html&quot; rel=&quot;noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot; title=&quot;Facebook Sign-In using Clojure&quot;&gt;Facebook Sign-In using&amp;nbsp;Clojure&lt;/a&gt;. This article will guide you to add Google Sign-In functionality in your web application using clojure. We’ll use compojure.core for routing, clj-http.client for http requests, cheshire.core for parsing json and noir.response for redirections.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr_oXF5zeNNAPpzfz2P2zQI53JgZzzCjVsxefRuDTd3KmA5TnJMwVcJfqtMmXpjr5chcepsgvqA2OaTYvkBPx0BJlDLpCpG8TPAOccY6NpEt3ts1vsjuFcdLOTZUCmGDvTDGy1eP-qJY0/s1600/Clojure_logo.svg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1200&quot; data-original-width=&quot;1200&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr_oXF5zeNNAPpzfz2P2zQI53JgZzzCjVsxefRuDTd3KmA5TnJMwVcJfqtMmXpjr5chcepsgvqA2OaTYvkBPx0BJlDLpCpG8TPAOccY6NpEt3ts1vsjuFcdLOTZUCmGDvTDGy1eP-qJY0/s200/Clojure_logo.svg.png&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsv3EZW0-8PZoVVMRuWK9nOWLdKw4RLoKPsfOJv9gfn7zGL5gixaZihjcGCnPV3z_fhTd1GzDTTK18fM9mhTOeeFNC-W578lR023xurCcWUcIblO9wt1wyrsPc6d78RrkXgWjgDWfLkjI/s1600/evolving_google_identity_share.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;800&quot; data-original-width=&quot;1600&quot; height=&quot;160&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsv3EZW0-8PZoVVMRuWK9nOWLdKw4RLoKPsfOJv9gfn7zGL5gixaZihjcGCnPV3z_fhTd1GzDTTK18fM9mhTOeeFNC-W578lR023xurCcWUcIblO9wt1wyrsPc6d78RrkXgWjgDWfLkjI/s320/evolving_google_identity_share.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
First, make a new google project to get your project’s Client ID and Client Secret Key from this URL:&amp;nbsp;&lt;a href=&quot;https://console.developers.google.com/project&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;https://console.developers.google.com/project&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px 0px 24px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
Now define a new namespace as:&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;ns &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;exampleapp.routes.google&lt;/span&gt;
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;compojure.core&lt;/span&gt;)
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:require&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;clj-http.client&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;client&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;cheshire.core&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;parse&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;noir.response&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;resp&lt;/span&gt;]))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
In “google” namespace, define following variables:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your project&#39;s client id&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;http://localhost:3000/auth_google&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;login-uri&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_SECRET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your project&#39;s client secret key&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;google-user&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;atom&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:google-id&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-name&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-email&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;}))
 
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;red&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com/o/oauth2/auth?&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;scope=email%20profile&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;redirect_uri=&quot;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;ring.util.codec/url-encode&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;response_type=code&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;client_id=&quot;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;ring.util.codec/url-encode&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;approval_prompt=force&quot;&lt;/span&gt;))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
“red” defines the request url on which the user is redirected to ask for user permission for user details. We use ring.util.codec/url-encode to encode the url details. ring.util.codec/url-encode uses UTF-8 encoding by default.&lt;/div&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Define routes in “google” namespace in order to redirect a user to the url defined by “red” as follows:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;defroutes&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;google-routes&lt;/span&gt;
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/google&quot;&lt;/span&gt; [] (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;red&lt;/span&gt;)))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
After user provides permission to your google project, you will get an authorization code on the the redirect uri that you mentioned in your google project, the same that you defined in your namespace, i.e&amp;nbsp;&lt;a href=&quot;http://localhost:3000/auth_google&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;http://localhost:3000/auth_google&lt;/a&gt;.&lt;/div&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Now define a new route in google-routes as:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/auth_google&quot;&lt;/span&gt; {&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:query-params&lt;/span&gt;}
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;google&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and a new function in order to get the access code and user details as:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;defn &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;google&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;]
 (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;let &lt;/span&gt;[&lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/post&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com/o/oauth2/token&quot;&lt;/span&gt;
                                          {&lt;span style=&quot;color: #aa6600;&quot;&gt;:form-params&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:code&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;code&quot;&lt;/span&gt;)
                                                         &lt;span style=&quot;color: #aa6600;&quot;&gt;:client_id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt;
                                                         &lt;span style=&quot;color: #aa6600;&quot;&gt;:client_secret&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_SECRET&lt;/span&gt;
                                                         &lt;span style=&quot;color: #aa6600;&quot;&gt;:redirect_uri&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;
                                                         &lt;span style=&quot;color: #aa6600;&quot;&gt;:grant_type&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;authorization_code&quot;&lt;/span&gt;}})
       &lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;parse/parse-string&lt;/span&gt; (&lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/get&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://www.googleapis.com/oauth2/v1/userinfo?access_token=&quot;&lt;/span&gt;
 (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;parse/parse-string&lt;/span&gt; (&lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt;)) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;access_token&quot;&lt;/span&gt;)))))]
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;google-user&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;assoc &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%2&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-name&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%3&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-email&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%4&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;id&quot;&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;name&quot;&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;email&quot;&lt;/span&gt;))))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
In the above function we use clj-http’s “post” to make a post request to get access token followed by “get” to get user information. Then we use cheshire.core’s “parse-string” to parse json response and convert it into clojure object and save the information in the atom defined as “google-user”.&lt;/div&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;Entire “google” namespace is as follows:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;ns &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;exampleapp.routes.google&lt;/span&gt;
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;compojure.core&lt;/span&gt;)
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:require&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;clj-http.client&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;client&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;cheshire.core&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;parse&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;noir.response&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;resp&lt;/span&gt;]))
 
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your project&#39;s client id&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;http://localhost:3000/auth_google&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;login-uri&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_SECRET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your project&#39;s client secret key&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;google-user&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;atom&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:google-id&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-name&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-email&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;}))
 
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;red&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com/o/oauth2/auth?&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;scope=email%20profile&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;redirect_uri=&quot;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;ring.util.codec/url-encode&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;response_type=code&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;client_id=&quot;&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;ring.util.codec/url-encode&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt;) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;&quot;&lt;/span&gt;
              &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;approval_prompt=force&quot;&lt;/span&gt;))
 
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;defn &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;google&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;]
 (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;let &lt;/span&gt;[&lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/post&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://accounts.google.com/o/oauth2/token&quot;&lt;/span&gt;
                                          {&lt;span style=&quot;color: #aa6600;&quot;&gt;:form-params&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:code&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;code&quot;&lt;/span&gt;)
                                           &lt;span style=&quot;color: #aa6600;&quot;&gt;:client_id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_ID&lt;/span&gt;
                                           &lt;span style=&quot;color: #aa6600;&quot;&gt;:client_secret&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;CLIENT_SECRET&lt;/span&gt;
                                           &lt;span style=&quot;color: #aa6600;&quot;&gt;:redirect_uri&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;
                                           &lt;span style=&quot;color: #aa6600;&quot;&gt;:grant_type&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;authorization_code&quot;&lt;/span&gt;}})
       &lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;parse/parse-string&lt;/span&gt; (&lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/get&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://www.googleapis.com/oauth2/v1/userinfo?access_token=&quot;&lt;/span&gt;
 (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;parse/parse-string&lt;/span&gt; (&lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt;)) &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;access_token&quot;&lt;/span&gt;)))))]
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;google-user&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;assoc &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%2&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-name&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%3&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:google-email&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%4&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;id&quot;&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;name&quot;&lt;/span&gt;) (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;email&quot;&lt;/span&gt;))))
 
(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;defroutes&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;google-routes&lt;/span&gt;
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/auth_google&quot;&lt;/span&gt; {&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:query-params&lt;/span&gt;}
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;google&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;))
 
(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/google&quot;&lt;/span&gt; [] (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;resp/redirect&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;red&lt;/span&gt;)))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;span style=&quot;background-color: transparent;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/04/google-sign-in-using-clojure_30.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr_oXF5zeNNAPpzfz2P2zQI53JgZzzCjVsxefRuDTd3KmA5TnJMwVcJfqtMmXpjr5chcepsgvqA2OaTYvkBPx0BJlDLpCpG8TPAOccY6NpEt3ts1vsjuFcdLOTZUCmGDvTDGy1eP-qJY0/s72-c/Clojure_logo.svg.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-5288794882110877393</guid><pubDate>Mon, 30 Apr 2018 14:52:00 +0000</pubDate><atom:updated>2018-05-01T20:00:59.480+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Clojure</category><category domain="http://www.blogger.com/atom/ns#">Facebook</category><category domain="http://www.blogger.com/atom/ns#">Programming</category><title>Facebook Sign-in using Clojure</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
In order to provide Facebook sign-in functionality you need to create a new Facebook App from this url:&amp;nbsp;&lt;a href=&quot;https://developers.facebook.com/docs/facebook-login&quot; rel=&quot;nofollow&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot;&gt;https://developers.facebook.com/docs/facebook-login&lt;/a&gt;. Provide the redirection URI that you’ll use for the App. After setting up the app you’ll get an App ID and App Secret key.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDCZoHMW45P6ikDVXtjJoBaPed88aC_W5OnqhvOhwSd2QngMNW2LOggdItNognG-f5XaFOlR4XiBLHNKQCdrOG7SrBlFFr-KKZciy6_jZs015j02XFaLut57kyjWyraB3qJ0E7M9DDQRI/s1600/Clojure_logo.svg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1200&quot; data-original-width=&quot;1200&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDCZoHMW45P6ikDVXtjJoBaPed88aC_W5OnqhvOhwSd2QngMNW2LOggdItNognG-f5XaFOlR4XiBLHNKQCdrOG7SrBlFFr-KKZciy6_jZs015j02XFaLut57kyjWyraB3qJ0E7M9DDQRI/s200/Clojure_logo.svg.png&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZJlsX3vYoyKyEhKerCOXghJT_c3Mo_X_xN7wx2wIf98HvN8gHd4x7GlL0J-igCN0yq_z3s7JE9d4tnmKVSs2zzdameIfZJ3qtQ_xlLmXLyiUh2JCfwKk1tbina7la98-6zTL9ix_zkjE/s1600/2000px-Facebook_New_Logo_%25282015%2529.svg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;602&quot; data-original-width=&quot;1600&quot; height=&quot;75&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZJlsX3vYoyKyEhKerCOXghJT_c3Mo_X_xN7wx2wIf98HvN8gHd4x7GlL0J-igCN0yq_z3s7JE9d4tnmKVSs2zzdameIfZJ3qtQ_xlLmXLyiUh2JCfwKk1tbina7la98-6zTL9ix_zkjE/s200/2000px-Facebook_New_Logo_%25282015%2529.svg.png&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
We’ll use “clj-oauth2.client” to redirect a user to the authentication page, “clj-http.client” for HTTP requests, “cheshire.core” to parse Json string in order to get keywords, “noir.respose” to provide re-directions and “compojure.core” for routing.&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; margin-bottom: 24px;&quot;&gt;
We’ll begin with defining a new namespace:&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;ns &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;exampleapp.routes.facebook&lt;/span&gt;
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:use&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;compojure.core&lt;/span&gt;)
 (&lt;span style=&quot;color: #aa6600;&quot;&gt;:require&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;clj-oauth2.client&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;oauth2&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;noir.response&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;resp&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;clj-http.client&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;client&lt;/span&gt;]
           [&lt;span style=&quot;color: #996633;&quot;&gt;cheshire.core&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:as&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;parse&lt;/span&gt;]))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px 0px 24px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
In facebook namespace define an atom, facebook-user, to store Facebook user details:&lt;/div&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px 0px 24px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;facebook-user&lt;/span&gt;
  (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;atom&lt;/span&gt; {&lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-id&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-name&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-email&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&quot;&lt;/span&gt;}))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif;&quot;&gt;Now include the App ID and App Secret key you just got after creating a new Facebook app along with the redirection URI, in the code below:&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;APP_ID&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your app id&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;APP_SECRET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;your app secret key&quot;&lt;/span&gt;)
(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;http://localhost:3000/auth_facebook&quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; margin: 0px 0px 24px; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;&quot;&gt;
and define an oauth2 map containing all the details required for Facebook log in:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3
4
5
6
7
8
9&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;facebook-oauth2&lt;/span&gt;
 {&lt;span style=&quot;color: #aa6600;&quot;&gt;:authorization-uri&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://graph.facebook.com/oauth/authorize&quot;&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:access-token-uri&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://graph.facebook.com/oauth/access_token&quot;&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:redirect-uri&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:client-id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;APP_ID&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:client-secret&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;APP_SECRET&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:access-query-param&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:access_token&lt;/span&gt;
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:scope&lt;/span&gt; [&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;email&quot;&lt;/span&gt;]
  &lt;span style=&quot;color: #aa6600;&quot;&gt;:grant-type&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;authorization_code&quot;&lt;/span&gt;})&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;We can use “make-auth-request” function defined in “clj-oauth2.client” library to get the redirect URI on which the user should be redirected. The user can now give access to the app we created in first step.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;resp/redirect&lt;/span&gt;
  (&lt;span style=&quot;color: #aa6600;&quot;&gt;:uri&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;oauth2/make-auth-request&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;facebook-oauth2&lt;/span&gt;)))&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
Note that we used noir.response/redirect function to provide the redirection.&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #141412; font-family: &amp;quot;source sans pro&amp;quot; , &amp;quot;helvetica&amp;quot; , sans-serif; font-size: 16px;&quot;&gt;After a Facebook user grant access to the app, we’ll get a response containing access token on the redirection URI we provided while setting up our Facebook app. We’ll use “compojure.core’s” GET to get the response:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;defroutes&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;facebook-routes&lt;/span&gt;
 (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;GET&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;/auth_facebook&quot;&lt;/span&gt; {&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:query-params&lt;/span&gt;} (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;facebook&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;)))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
and pass it to a function in order to get the access token and user details.&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
We’ll use the code below for getting access token and user details:&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;(&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;defn &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;facebook&lt;/span&gt; [&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt;]
 (&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;let &lt;/span&gt;[&lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt; (&lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt; (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/get&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://graph.facebook.com/oauth/access_token?&quot;&lt;/span&gt;
                                                     &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;client_id=&quot;&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;APP_ID&lt;/span&gt;
                                                     &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;redirect_uri=&quot;&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;REDIRECT_URI&lt;/span&gt;
                                                     &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;client_secret=&quot;&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;APP_SECRET&lt;/span&gt;
                                                     &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;&amp;amp;code=&quot;&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;params&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;code&quot;&lt;/span&gt;))))
       &lt;span style=&quot;color: #996633;&quot;&gt;access-token&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;re-find &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;access_token=(.*?)&amp;amp;expires=&quot;&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;access-token-response&lt;/span&gt;) &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;)
       &lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;-&amp;gt; &lt;/span&gt;(&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;client/get&lt;/span&gt; (&lt;span style=&quot;color: #007020;&quot;&gt;str &lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;https://graph.facebook.com/me?access_token=&quot;&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;access-token&lt;/span&gt;))
                        &lt;span style=&quot;color: #aa6600;&quot;&gt;:body&lt;/span&gt;
                        (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;parse/parse-string&lt;/span&gt;))]
  (&lt;span style=&quot;color: #0066bb; font-weight: bold;&quot;&gt;swap!&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;facebook-user&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;#&lt;/span&gt;(&lt;span style=&quot;color: #007020;&quot;&gt;assoc &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-id&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%2&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-name&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%3&lt;/span&gt; &lt;span style=&quot;color: #aa6600;&quot;&gt;:facebook-email&lt;/span&gt; &lt;span style=&quot;color: #996633;&quot;&gt;%4&lt;/span&gt;)
     (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;id&quot;&lt;/span&gt;)
     (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;first_name&quot;&lt;/span&gt;)
     (&lt;span style=&quot;color: #007020;&quot;&gt;get &lt;/span&gt;&lt;span style=&quot;color: #996633;&quot;&gt;user-details&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;email&quot;&lt;/span&gt;))))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #141412; font-family: &amp;quot;Source Sans Pro&amp;quot;, Helvetica, sans-serif; font-size: 16px; margin-bottom: 24px;&quot;&gt;
&lt;em style=&quot;box-sizing: border-box;&quot;&gt;This article was first published on the&amp;nbsp;&lt;a href=&quot;https://blog.knoldus.com/&quot; rel=&quot;nofollow noopener&quot; style=&quot;box-sizing: border-box; color: #bc360a; text-decoration-line: none;&quot; target=&quot;_blank&quot;&gt;Knoldus blog&lt;/a&gt;.&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2018/04/facebook-sign-in-using-clojure.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDCZoHMW45P6ikDVXtjJoBaPed88aC_W5OnqhvOhwSd2QngMNW2LOggdItNognG-f5XaFOlR4XiBLHNKQCdrOG7SrBlFFr-KKZciy6_jZs015j02XFaLut57kyjWyraB3qJ0E7M9DDQRI/s72-c/Clojure_logo.svg.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-6019621684281046692</guid><pubDate>Wed, 25 Oct 2017 17:57:00 +0000</pubDate><atom:updated>2017-10-26T00:33:59.016+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">apple</category><category domain="http://www.blogger.com/atom/ns#">firefox</category><category domain="http://www.blogger.com/atom/ns#">Google</category><category domain="http://www.blogger.com/atom/ns#">image search</category><category domain="http://www.blogger.com/atom/ns#">ios</category><category domain="http://www.blogger.com/atom/ns#">ipad</category><category domain="http://www.blogger.com/atom/ns#">iphone</category><category domain="http://www.blogger.com/atom/ns#">opera</category><category domain="http://www.blogger.com/atom/ns#">reverse image search</category><category domain="http://www.blogger.com/atom/ns#">safari</category><category domain="http://www.blogger.com/atom/ns#">search</category><category domain="http://www.blogger.com/atom/ns#">ucbrowser</category><title>How to search or reverse search images using Google on iPhone and Android</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ZDx9uCEjq-jufd1AddxU_JhKsQwHiGZ5ilius0PlKyGvVyQ-5Papd4JZdTTnTgJtABkcUrN8AB23Nl8xeYAxGv1VoGxfZdukxhOXDtO2NlBx6zM74DRPmcrrlyEPfVBm-xxswUE4HtE/s1600/iphone.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;900&quot; data-original-width=&quot;1600&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ZDx9uCEjq-jufd1AddxU_JhKsQwHiGZ5ilius0PlKyGvVyQ-5Papd4JZdTTnTgJtABkcUrN8AB23Nl8xeYAxGv1VoGxfZdukxhOXDtO2NlBx6zM74DRPmcrrlyEPfVBm-xxswUE4HtE/s640/iphone.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Google has become a universal searching tool and most of us are now accustomed to terms like &quot;let&#39;s google it&quot; instead of &quot;let&#39;s search it on the web&quot;. Almost everyone is aware of what Google is, there would be a very few who don&#39;t know what Google is, I mean very few! Absolutely no one! And most of us also know how to use Google to search an interesting image from Mac or Windows. But wait, is it really easy to search or reverse search an image from mobile devices? I guess it is. But not everyone is aware of how it is done. So this post is all about getting to know ways of searching or reverse searching images on Google via mobile devices.&lt;br /&gt;
&lt;br /&gt;
It does not matter if you&#39;re an iOS or Android user. You might be using browsers like Chrome on your iPhone, iPad or Android devices; or maybe Safari on your Apple devices; or maybe some other browsers like Firefox, Opera, UC Browser if you&#39;re really into those kind of details. Each of these browsers consists of an option to switch to a Desktop site, let&#39;s look at some examples on Google Chrome and Safari browser.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Safari&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Visit Google and then long press on the Refresh button on the top right corner, this should open a small menu with an option to &quot;Request Desktop Site&quot;.&lt;br /&gt;&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyYK_EUvUaVvB4Y9QwEkfTXY9dpOeCd4DsJxB7j_65Vk8kc645IADfyAL0A9r3M5OK77_UgjZbTNCJ3JAr-eexIREB5RGRaIM3FKlL2IpSgOFToZEO4P0IJj6B_9nTz1bGcaLWuJoPUqY/s1600/blog-google.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyYK_EUvUaVvB4Y9QwEkfTXY9dpOeCd4DsJxB7j_65Vk8kc645IADfyAL0A9r3M5OK77_UgjZbTNCJ3JAr-eexIREB5RGRaIM3FKlL2IpSgOFToZEO4P0IJj6B_9nTz1bGcaLWuJoPUqY/s320/blog-google.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI3yPm0ZYq6uSrESYT0CuuYUHM8rseubkW-wx1fKID9-aGF-WyzXybU2ODay8fFbvK2exW5N_uBhJeHdVi6hChFNlifVokf8ayxJ95JON0HmL7NdfGKvDpNVbUN2SmkYxwqCde2HhqyUE/s1600/blog-request-desktop-site.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI3yPm0ZYq6uSrESYT0CuuYUHM8rseubkW-wx1fKID9-aGF-WyzXybU2ODay8fFbvK2exW5N_uBhJeHdVi6hChFNlifVokf8ayxJ95JON0HmL7NdfGKvDpNVbUN2SmkYxwqCde2HhqyUE/s320/blog-request-desktop-site.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Select &quot;Request Desktop Site&quot; and Bam! You&#39;re on the desktop version of Google.&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhogGx3ViK5QBfkOgn_c_rMMFZ03ry11s9mFNTE-JGI7y-3DiUJM5DlWrydEYhKyizQgfiUN8oO2tmr0XdsBYVLIf43sY2INg0gwEJrumJJebtpxd9f6PipjKvJ3IkYSILPRzxn3lSwstY/s1600/blog-google-desktop.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhogGx3ViK5QBfkOgn_c_rMMFZ03ry11s9mFNTE-JGI7y-3DiUJM5DlWrydEYhKyizQgfiUN8oO2tmr0XdsBYVLIf43sY2INg0gwEJrumJJebtpxd9f6PipjKvJ3IkYSILPRzxn3lSwstY/s320/blog-google-desktop.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Now select &quot;Images&quot; from the top right corner on Google web page and it will take you to the Google Image search page.&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4dj9UW90AJSofR0W2Z39OdgXWQ5q9G_iABwnK1jb7sYTcYqApPP0PGfT4BjbeFjbYQ77L7H9FtXVkhmMWoCwYU-FfJbM-qBocTKTUe18lUOALlPKTtL7whzBsAXuFt6XU0Eo7qe_Itg0/s1600/blog-google-image-search.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4dj9UW90AJSofR0W2Z39OdgXWQ5q9G_iABwnK1jb7sYTcYqApPP0PGfT4BjbeFjbYQ77L7H9FtXVkhmMWoCwYU-FfJbM-qBocTKTUe18lUOALlPKTtL7whzBsAXuFt6XU0Eo7qe_Itg0/s320/blog-google-image-search.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Now click on the small Camera icon in the Google search box from Step 3 and you&#39;ll get an option to upload an image from your device or paste the image URL. Select &quot;Upload an Image&quot; option and a small menu will open giving you options to select an image from your picture gallery or the take a picture right away using your camera. Tada! Your Google image search is completed.&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhymLcM9wQJETdQhmld3FIkwJJvVsM3nsg5pYSqS1F0hZY4sIwxdJZofKQx9Rt_egColZqyvA2XlyXKy3Jc8AXNEse-WcrqW8-k2wXARTIsnXq71taSQOeEOrtUsciu_KMx9kzY9dlraHE/s1600/blog-google-upload.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhymLcM9wQJETdQhmld3FIkwJJvVsM3nsg5pYSqS1F0hZY4sIwxdJZofKQx9Rt_egColZqyvA2XlyXKy3Jc8AXNEse-WcrqW8-k2wXARTIsnXq71taSQOeEOrtUsciu_KMx9kzY9dlraHE/s320/blog-google-upload.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;br /&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;b&gt;On Chrome&lt;/b&gt;&lt;br /&gt;
From Google Chrome mobile browser you can follow a similar kind of approach as done from Safari browser, but things get a tad easier on Google Chrome browser wherein the images can be directly searched from any webpage by just using an option from menu. But let&#39;s look into the first approach prior to moving onto the second one.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For the first approach, i.e by using Desktop site&lt;/div&gt;
&lt;div&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Visit Google on Chrome browser and click on the 3 dots icon on the top right corner from which you can see there&#39;s an option to &quot;Request Desktop Site&quot; again. Select this option.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHBXDwG-aGckFZl9yUCrHSDGyOgwGgc3HPrYuk3JZ-9T30-I1nBbIcZO8o7ynOBGAeizZ9ow3DZu0xjrrX0MsdX_siQs7xaJc5qqsTAoRi8m-uFbyevykw-IORVQgSJKPSE7Pr1D_Cna0/s1600/blog-chrome-menu.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHBXDwG-aGckFZl9yUCrHSDGyOgwGgc3HPrYuk3JZ-9T30-I1nBbIcZO8o7ynOBGAeizZ9ow3DZu0xjrrX0MsdX_siQs7xaJc5qqsTAoRi8m-uFbyevykw-IORVQgSJKPSE7Pr1D_Cna0/s320/blog-chrome-menu.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Now follow Step 2 through 4 from Safari browser tutorial as mentioned earlier. Voila! Google image search or reverse search again.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
For the second approach, i.e by using Google Chrome feature&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Just in case you want to reverse search any image available on a webpage directly instead to first downloading and saving that image on your device and then searching or reverse searching it, long press on the image in question to get a menu like this one&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOaEtRX1kUtoY9UGGTK4TSgjF1XRdd70b97i6WU-ydFTpJi25T5riY6ioH8AC2pPL2CHQPPoyLHzU2QeAXtHBoKs4HK4HgdXy05o3kxsuYFLG92CefuYYp0Mm5E1dUP5U-sRhScYm2Zbs/s1600/blog-chrome-search-image.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1334&quot; data-original-width=&quot;750&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOaEtRX1kUtoY9UGGTK4TSgjF1XRdd70b97i6WU-ydFTpJi25T5riY6ioH8AC2pPL2CHQPPoyLHzU2QeAXtHBoKs4HK4HgdXy05o3kxsuYFLG92CefuYYp0Mm5E1dUP5U-sRhScYm2Zbs/s320/blog-chrome-search-image.jpg&quot; width=&quot;179&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Select &quot;Search Google for This image&quot; option and you&#39;re good to go! Reverse image search on Google right from the menu option.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;b&gt;On Other Mobile Browsers&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
Similar kind of approach can be followed on any other browser if an option to request desktop site is available. Moreover, you can permanently request desktop sites by configuring it in your mobile browser settings if it is available which will save you the pain to manually requesting for a desktop site.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Let us know if you found this tutorial helpful or if there are any other options available to reverse search an image on Google from a mobile device in the comment section below.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2017/10/how-to-search-or-reverse-search-images-using-google-on-iphone-and-android.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ZDx9uCEjq-jufd1AddxU_JhKsQwHiGZ5ilius0PlKyGvVyQ-5Papd4JZdTTnTgJtABkcUrN8AB23Nl8xeYAxGv1VoGxfZdukxhOXDtO2NlBx6zM74DRPmcrrlyEPfVBm-xxswUE4HtE/s72-c/iphone.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-7505638139673353535</guid><pubDate>Fri, 08 Mar 2013 18:30:00 +0000</pubDate><atom:updated>2013-03-09T00:09:40.216+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">blogger</category><category domain="http://www.blogger.com/atom/ns#">Blogging</category><category domain="http://www.blogger.com/atom/ns#">How To</category><category domain="http://www.blogger.com/atom/ns#">picasa</category><category domain="http://www.blogger.com/atom/ns#">slideshow</category><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>How To Add A Slideshow From Picasa Web Albums To Blogger or Wordpress</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Adding a Slideshow in your blog posts can always be a good option in order to present your content in a better way. Many sites offer services to make customized slideshows with a choice of &quot;free&quot; and &quot;premium&quot; services and the &quot;free&quot; option always have certain limitations. A better way to make a slideshow is to use Picasa Web Albums, with an added advantage of the 5GB storage provided by Google. You can also write your own slideshow code, but that would be a bit difficult.&lt;br /&gt;
&lt;br /&gt;
Your slideshow will look something like this:&lt;br /&gt;
&lt;div style=&quot;font-family: arial,sans-serif; font-size: 13px; width: 400px;&quot;&gt;
&lt;div&gt;
&lt;embed flashvars=&quot;host=picasaweb.google.com&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F106274129264638044294%2Falbumid%2F5852803705306993985%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCKySg9v3z6S2Sg%26hl%3Den_US&quot; height=&quot;267&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; src=&quot;https://picasaweb.google.com/s/c/bin/slideshow.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;400&quot;&gt;&lt;/embed&gt;&lt;/div&gt;
&lt;span style=&quot;float: left;&quot;&gt;&lt;a href=&quot;https://picasaweb.google.com/106274129264638044294/FacebookNewNewsFeeds?authuser=0&amp;amp;authkey=Gv1sRgCKySg9v3z6S2Sg&amp;amp;feat=flashalbum&quot; style=&quot;color: #3964c2;&quot;&gt;View all&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;a href=&quot;http://www.ubertechblog.com/2013/03/new-facebook-news-feeds-and-how-to-get-it-asap.html&quot; style=&quot;color: #3964c2;&quot;&gt;How To Get New Facebook News Feeds&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
1. In order to make a slideshow from Google Picasa Web Album, goto the following link: &lt;a href=&quot;https://picasaweb.google.com/home&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://picasaweb.google.com/home&lt;/a&gt;, log in to your Google account. If you don&#39;t have a Google+ profile then Picasa Web Album will open automatically but if you have a Google+ profile then you&#39;ll be redirected to your albums in your Google+ profile. In that case, a small message in a yellow box will popup at the top of the screen which will provide an option to go back to Picasa Web Album. After clicking on it, you&#39;ll be redirected to Picasa Web Album. &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQjXxf9lhBnuDxzKlZ2p93Vg5iQT92pKNdhZAdUEZhe4Pcs6EyKBVlewvrFD3shyphenhyphenT9GfIIcJS_3xheKes3_J4NpRNFu_06rHt7O9a162BgX4rh-KHbYl0Ru0VjNjmA-7uoCmiaxWUx8e4/s1600/slideshow-picasa-album.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQjXxf9lhBnuDxzKlZ2p93Vg5iQT92pKNdhZAdUEZhe4Pcs6EyKBVlewvrFD3shyphenhyphenT9GfIIcJS_3xheKes3_J4NpRNFu_06rHt7O9a162BgX4rh-KHbYl0Ru0VjNjmA-7uoCmiaxWUx8e4/s400/slideshow-picasa-album.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2. Now in order to create a slideshow, begin with uploading your photos from the upload option at the top bar.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKVluGKeEYuIkZUD_j-Ysq0_AtCVVADR9u6aeuVi3QE6dalYfatEBbd-fvkYkaaapKj5aOOVtsYVJxrTKJjmdslEvnxNC7ln_m0FvQiM0AZSWY_3Zfrh2I1Msq8rgdoecE39C4PL7c4Kc/s1600/slideshow-picasa-album-2.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;81&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKVluGKeEYuIkZUD_j-Ysq0_AtCVVADR9u6aeuVi3QE6dalYfatEBbd-fvkYkaaapKj5aOOVtsYVJxrTKJjmdslEvnxNC7ln_m0FvQiM0AZSWY_3Zfrh2I1Msq8rgdoecE39C4PL7c4Kc/s400/slideshow-picasa-album-2.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
3. After completing the upload process open the newly created album. Now on the right side bar you&#39;ll find an option of &quot;Link to this Album.&quot; Clicking on it will display another option of &quot;Embed Slideshow.&quot; Selecting Embed Slideshow&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXym6s15awi9p5lBKp4840c1kAaxsCsj9BQJuRjGkEiIwfaWhY8QHuCeGimCtwT-2tnGBFjXkPxZPSGJXxRa_ASsFLhV0pils4pmLlNjxA0JaJmSr4RInumSw6YOaCL37feq42goC4d_U/s1600/slideshow-picasa-album-1.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;284&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXym6s15awi9p5lBKp4840c1kAaxsCsj9BQJuRjGkEiIwfaWhY8QHuCeGimCtwT-2tnGBFjXkPxZPSGJXxRa_ASsFLhV0pils4pmLlNjxA0JaJmSr4RInumSw6YOaCL37feq42goC4d_U/s320/slideshow-picasa-album-1.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
will popup a small window with some more options to customize your slideshow, like the one shown in the screenshot below:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg126K3ZiDqWjnpPsROLYsuhiDia5Lnj7FvBVcVRjZITHpTdSUWiDd4WfdKO9JX8aUcgglbdOHr8WKI0kaKxeRN1Bz1Qxt-MkL0fjENEmsy-RHrIP9xwwH51E703rDkU6w0ulvYfNLXPDk/s1600/slideshow-picasa-album-3.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;211&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg126K3ZiDqWjnpPsROLYsuhiDia5Lnj7FvBVcVRjZITHpTdSUWiDd4WfdKO9JX8aUcgglbdOHr8WKI0kaKxeRN1Bz1Qxt-MkL0fjENEmsy-RHrIP9xwwH51E703rDkU6w0ulvYfNLXPDk/s400/slideshow-picasa-album-3.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
4. Check the &quot;HTML Links&quot; option to get the HTML code of your slideshow. Copy and paste this code to the desired place. Quite Easy!&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2013/03/how-to-add-a-slideshow-from-picasa-web-albums-to-blogger-or-wordpress.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQjXxf9lhBnuDxzKlZ2p93Vg5iQT92pKNdhZAdUEZhe4Pcs6EyKBVlewvrFD3shyphenhyphenT9GfIIcJS_3xheKes3_J4NpRNFu_06rHt7O9a162BgX4rh-KHbYl0Ru0VjNjmA-7uoCmiaxWUx8e4/s72-c/slideshow-picasa-album.JPG" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-3906796692834764817.post-6071628473817651541</guid><pubDate>Fri, 08 Mar 2013 02:51:00 +0000</pubDate><atom:updated>2013-03-09T17:30:01.576+05:30</atom:updated><category domain="http://www.blogger.com/atom/ns#">Facebook</category><category domain="http://www.blogger.com/atom/ns#">How To</category><category domain="http://www.blogger.com/atom/ns#">News Feeds</category><category domain="http://www.blogger.com/atom/ns#">Social Media</category><title>New Facebook News Feeds And How To Get It ASAP</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhag_3m8fyTMTTQqSyKZHx5u9b3QGKK803UhUDiI9AKKh6_4ROEQkT7CHJIKSD9K2TjxyD2WwoW6e2_w3O2S2v1Hn_6KENAPs8v4nvu6iVX3xZQiO3p03N_YZmg4NqkNir8Qqn__ygJ_38/s1600/facebook-new-timeline.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;195&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhag_3m8fyTMTTQqSyKZHx5u9b3QGKK803UhUDiI9AKKh6_4ROEQkT7CHJIKSD9K2TjxyD2WwoW6e2_w3O2S2v1Hn_6KENAPs8v4nvu6iVX3xZQiO3p03N_YZmg4NqkNir8Qqn__ygJ_38/s400/facebook-new-timeline.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
On&amp;nbsp;Thursday,&amp;nbsp;Facebook unveiled its new News Feeds&amp;nbsp;that offers a host of new options. The revamped version of the news feeds, inspired by mobile design of Facebook, will allow a user to adjust their feeds the way they want. It offers Multiple feeds in which a user can customize their feeds with options like friends, photos, music, following, games along with an option of a simple chronological news feed, most recent.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Although Facebook will automatically roll out this revamped version of news feed sooner or later, users can manually join the waiting list by clicking on the &quot;Join Waiting List&quot; button located at the bottom of this page &lt;a href=&quot;https://www.facebook.com/about/newsfeed&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://www.facebook.com/about/newsfeed&lt;/a&gt;.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw3vKf_xoxjQmEinHq83AEzgd7kunqEBYvtabpjsPA0bOTDvZb7XpmA0l37qGl4RQfRlaVDkB3LSpu80g_-7fAbZ_qJw1FhI82_uxpevDSx0HYlG4dCW9O6Xr9NdXdiifw2T-gUOHLCjs/s1600/new-facebook-feeds.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;253&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw3vKf_xoxjQmEinHq83AEzgd7kunqEBYvtabpjsPA0bOTDvZb7XpmA0l37qGl4RQfRlaVDkB3LSpu80g_-7fAbZ_qJw1FhI82_uxpevDSx0HYlG4dCW9O6Xr9NdXdiifw2T-gUOHLCjs/s400/new-facebook-feeds.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The newer version of news feeds will take away all the clutter and bring all the goodness of what is offered in Facebook mobile - bigger pictures covering 50% of the news feeds, iconized side bar, better cover design etc.&lt;/div&gt;
&lt;div style=&quot;font-family: arial,sans-serif; font-size: 13px; width: 600px;&quot;&gt;
&lt;div&gt;
&lt;embed flashvars=&quot;host=picasaweb.google.com&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F106274129264638044294%2Falbumid%2F5852803705306993985%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCKySg9v3z6S2Sg%26hl%3Den_US&quot; height=&quot;400&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; src=&quot;https://picasaweb.google.com/s/c/bin/slideshow.swf&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;600&quot;&gt;&lt;/embed&gt;&lt;/div&gt;
&lt;span style=&quot;float: left;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;Copyright UberTechBlog 2015 at http://www.ubertechblog.com&lt;/div&gt;</description><link>http://www.ubertechblog.com/2013/03/new-facebook-news-feeds-and-how-to-get-it-asap.html</link><author>noreply@blogger.com (Sidharth)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhag_3m8fyTMTTQqSyKZHx5u9b3QGKK803UhUDiI9AKKh6_4ROEQkT7CHJIKSD9K2TjxyD2WwoW6e2_w3O2S2v1Hn_6KENAPs8v4nvu6iVX3xZQiO3p03N_YZmg4NqkNir8Qqn__ygJ_38/s72-c/facebook-new-timeline.JPG" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>