<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Rahul Kumar on Medium]]></title>
        <description><![CDATA[Stories by Rahul Kumar on Medium]]></description>
        <link>https://medium.com/@ats1999?source=rss-054c4f323ff3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*2959IJ_EavnKGIyJ6o-cXg.png</url>
            <title>Stories by Rahul Kumar on Medium</title>
            <link>https://medium.com/@ats1999?source=rss-054c4f323ff3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 22:47:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ats1999/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Building PgGateway #1 | Why I’m building PgGateway]]></title>
            <link>https://medium.com/@ats1999/building-pggateway-1-why-im-building-pggateway-85aea7fcc543?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/85aea7fcc543</guid>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[pgbouncer]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Sat, 01 Aug 2026 06:55:31 GMT</pubDate>
            <atom:updated>2026-08-01T06:55:31.050Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>PostgreSQL</strong> powers some of the world’s largest applications, yet the layer between an application and the database hasn’t evolved nearly as much as the database itself.</p><p><strong>GitHub:</strong> <a href="https://github.com/ats1999/PgGateway">https://github.com/ats1999/PgGateway</a></p><p>Today, if you need connection pooling over network, you deploy PgBouncer. If you need load balancing, you configure another component. If you want read/write routing, auditing, observability, security policies, or custom query handling, you often end up stitching together multiple tools , or implementing the logic inside your application.</p><p>I started <strong>PgGateway</strong> to bring these capabilities into a single, extensible platform.</p><p>PgGateway will be a <strong>PostgreSQL connection pooler, proxy, load balancer, and query router</strong> built with extensibility as a first-class goal.</p><h3>Why another PostgreSQL proxy?</h3><p>Projects like PgBouncer have proven that a lightweight connection pooler can dramatically improve PostgreSQL scalability without altering the infrastructure of reacrhecture of the application layer.</p><p>PgGateway isn’t trying to replace what PgBouncer does well.</p><p>Instead, it’s exploring what comes next.</p><p>The idea is to combine multiple infrastructure components into one system:</p><ul><li>Connection Pooling</li><li>PostgreSQL Proxy</li><li>Load Balancing</li><li>Read/Write Routing</li><li>Failover Handling</li><li>Observability</li><li>Extensibility</li></ul><p>Rather than deploying multiple services for each responsibility, PgGateway aims to provide a single protocol-aware layer between applications and PostgreSQL.</p><p><strong>GitHub:</strong> <a href="https://github.com/ats1999/PgGateway">https://github.com/ats1999/PgGateway</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=85aea7fcc543" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Built ZeroTrust, Because Sensitive Data Shouldn’t Live in Plain Text]]></title>
            <link>https://medium.com/@ats1999/i-built-zerotrust-because-sensitive-data-shouldnt-live-in-plain-text-134ff67f7ec4?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/134ff67f7ec4</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Wed, 29 Jul 2026 14:08:30 GMT</pubDate>
            <atom:updated>2026-07-29T14:08:30.522Z</atom:updated>
            <content:encoded><![CDATA[<p>Like many developers, I’ve seen sensitive information end up everywhere, Google Docs, Slack, Sheets, Notion pages, internal wikis, and random files.</p><p>Passwords, API keys, AWS credentials, database details, wherever it’s convenient.</p><p>The problem is simple: <strong>convenient storage isn’t always secure storage.</strong></p><p>So I built <strong>ZeroTrust</strong>, an open-source vault designed around one idea: <strong>your sensitive data should remain encrypted wherever it is stored.</strong></p><h3>How it works</h3><p>ZeroTrust encrypts your data before storing it. It uses Google Drive, only the encrypted ciphertext is uploaded, your actual secrets never leave the application in plain text.</p><p>That means your storage provider stores the data, but doesn’t need to know what’s inside it.</p><p>ZeroTrust is also <strong>open source and self-hostable</strong>, so you can inspect the code, run it yourself, and stay in control of your data.</p><p>You don’t need server, it’s serverless.</p><h3>Why open source?</h3><p>For a tool that handles passwords and credentials, “trust me” isn’t good enough.</p><p>You should be able to see how your data is encrypted, where it goes, and what the application does with it.</p><p>That’s why ZeroTrust is open source.</p><h3>Let’s Go</h3><ul><li><a href="https://github.com/ats1999/ZeroTrust">https://github.com/ats1999/ZeroTrust</a></li><li><a href="https://zero-trust-pi.vercel.app/">https://zero-trust-pi.vercel.app/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=134ff67f7ec4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Bit Flags: The Right Way to Store Boolean Flags Efficiently]]></title>
            <link>https://medium.com/@ats1999/using-bit-flags-the-right-way-to-store-boolean-flags-efficiently-aa789781e3a2?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/aa789781e3a2</guid>
            <category><![CDATA[dsa-courses]]></category>
            <category><![CDATA[bit-manipulation]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Thu, 25 Jun 2026 02:49:47 GMT</pubDate>
            <atom:updated>2026-06-25T02:49:47.020Z</atom:updated>
            <content:encoded><![CDATA[<p>Every application stores boolean values.</p><pre>CAN_EDIT = true<br>IS_MODIFIED = false<br>IS_EDITED = true<br>USE_AFTER = false</pre><p>At first glance, this seems perfectly fine. But what happens when you need to store dozens of such flags for billions of records?</p><p>Instead of storing each flag individually, you can pack all of them into a single integer using <strong>bit flags</strong>.</p><p>This technique has been used for decades in operating systems, databases, game engines, network protocols, and high-performance applications because it’s incredibly memory-efficient and fast.</p><p>Let’s see how it works.</p><h3>What are Bit Flags?</h3><p>A bit flag uses each <strong>individual bit</strong> inside an integer to represent one boolean value.</p><p>A binary number:</p><pre>00000000</pre><p>contains <strong>8 bits</strong>.</p><p>Each bit can be either:</p><ul><li>0 → false</li><li>1 → true</li></ul><p>Instead of storing eight separate booleans, we can store all eight inside a single byte.</p><p>For example:</p><pre>Bit Position</pre><pre>7 6 5 4 3 2 1 0<br>0 0 1 0 1 1 0 1</pre><p>Suppose these represent:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SNcTFt_oDHZGppCX2-KUYA.png" /></figure><p>If the value is</p><pre>00101101</pre><p>then:</p><ul><li>Can Read ✅</li><li>Can Delete ✅</li><li>Is Admin ✅</li><li>Premium User ✅</li></ul><p>Everything else is false.</p><h3>Why Use Bit Flags?</h3><p>Imagine storing permissions.</p><p>Without bit flags:</p><pre>{<br>  &quot;canRead&quot;: true,<br>  &quot;canWrite&quot;: false,<br>  &quot;canDelete&quot;: true,<br>  &quot;isAdmin&quot;: true,<br>  &quot;premium&quot;: false,<br>  &quot;verified&quot;: true<br>}</pre><p>That’s six separate boolean values.</p><p>With bit flags:</p><pre>flags = 45</pre><p>where</p><pre>45 = 00101101</pre><p>One integer replaces multiple booleans.</p><h3>Assigning Bit Values</h3><p>Each flag gets a unique power of two.</p><pre>Read        = 1       (00000001)<br>Write       = 2       (00000010)<br>Delete      = 4       (00000100)<br>Admin       = 8       (00001000)<br>Premium     = 16      (00010000)<br>Verified    = 32      (00100000)</pre><p>Notice only one bit is set in each value.</p><h3>Combining Flags</h3><p>Use the OR operator (|).</p><p>Java:</p><pre>int permissions = READ | DELETE | VERIFIED;</pre><p>Binary:</p><pre>00000001<br>00000100<br>00100000<br>---------<br>00100101</pre><p>Result:</p><pre>37</pre><p>Now 37 stores three permissions.</p><h3>Checking a Flag</h3><p>Use AND (&amp;).</p><pre>if ((permissions &amp; DELETE) != 0) {<br>    System.out.println(&quot;Delete allowed&quot;);<br>}</pre><p>Why?</p><pre>00100101<br>00000100<br>---------<br>00000100</pre><p>Non-zero means the bit exists.</p><h3>Adding a Flag</h3><p>Suppose you want to add Admin permission.</p><pre>permissions |= ADMIN;</pre><p>Before:</p><pre>00100101</pre><p>After:</p><pre>00101101</pre><p>Only that bit changes.</p><h3>Removing a Flag</h3><p>Use:</p><pre>permissions &amp;= ~ADMIN;</pre><p>Example:</p><p>Before</p><pre>00101101</pre><p>Admin mask</p><pre>00001000</pre><p>Invert</p><pre>11110111</pre><p>AND</p><pre>00100101</pre><p>Admin is removed.</p><h3>Toggling a Flag</h3><p>Use XOR (^).</p><pre>permissions ^= PREMIUM;</pre><p>If Premium was OFF → it becomes ON.</p><p>If Premium was ON → it becomes OFF.</p><h3>Java Example</h3><pre>public class PermissionDemo {</pre><pre>    static final int READ = 1;<br>    static final int WRITE = 2;<br>    static final int DELETE = 4;<br>    static final int ADMIN = 8;</pre><pre>    public static void main(String[] args) {</pre><pre>        int permissions = READ | DELETE;</pre><pre>        permissions |= ADMIN;</pre><pre>        if ((permissions &amp; DELETE) != 0) {<br>            System.out.println(&quot;Delete allowed&quot;);<br>        }</pre><pre>        permissions &amp;= ~READ;</pre><pre>        System.out.println(permissions);<br>    }<br>}</pre><h3>Memory Savings</h3><p>Suppose you have:</p><ul><li>32 boolean flags</li><li>1 billion records</li></ul><p>Without bit flags:</p><pre>32 × 1,000,000,000 = 32,000,000,000 bytes ≈ 29.8 GiB ≈ 32 GB</pre><p>Using one integer:</p><pre>4 bytes/record<br>4 × 1,000,000,000 = 4,000,000,000 bytes ≈ 3.73 GiB ≈ 4 GB</pre><p>That’s an <strong>87.5% reduction</strong> in storage for this simplified example. Actual savings depend on the language, object layout, and serialization format.</p><h3>Real-World Uses</h3><p>Bit flags are everywhere.</p><h3>Operating Systems</h3><p>File permissions</p><pre>Read<br>Write<br>Execute</pre><p>Linux uses bit masks extensively.</p><h3>Game Development</h3><p>Character abilities</p><pre>Invisible<br>Flying<br>Poisoned<br>Shielded</pre><p>One integer tracks them all.</p><h3>Networking</h3><p>TCP packets use bits for flags like:</p><ul><li>SYN</li><li>ACK</li><li>FIN</li><li>RST</li></ul><p>A few bits describe the packet state.</p><h3>Databases</h3><p>Instead of storing:</p><pre>isDeleted<br>isVerified<br>isPremium<br>isAdmin</pre><p>Store:</p><pre>status = 41</pre><p>Decode whenever needed.</p><h3>Conclusion</h3><p>Bit flags are one of the simplest yet most effective optimization techniques available.</p><p>They let you:</p><ul><li>Store dozens of boolean values in a single integer</li><li>Reduce memory usage</li><li>Improve cache efficiency</li><li>Perform fast permission and state checks using bitwise operations</li></ul><p>Whether you’re building a database schema, a game engine, an operating system, or a high-performance backend service, bit flags are a valuable tool to keep in your programming toolbox.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aa789781e3a2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Best Practices for Managing Configuration in Spring Boot.]]></title>
            <link>https://medium.com/@ats1999/best-practices-for-managing-configuration-in-spring-boot-083e518be36f?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/083e518be36f</guid>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[ci-cd-pipeline]]></category>
            <category><![CDATA[configuration]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Sat, 11 Oct 2025 04:47:23 GMT</pubDate>
            <atom:updated>2025-10-11T04:47:23.662Z</atom:updated>
            <content:encoded><![CDATA[<p>Configurations are essential to application. Over the time, different ways of supplying configuration have evolved. They all have their own pros/cons. In this blog, i’ll discuss some of widely used configuration methods.</p><h3>What is config?</h3><p>Configs are set of properties which affects behaviour application at run time. For example, database urls, storage path, smtp credentials, etc. There are many different ways to supply configuration to application. But, we’ll stick to the most appropriate configuration methods in spring apps.</p><h4>Ways of supplying configuration to application</h4><blockquote>Please comment if there are any other way to supply configuration</blockquote><ul><li>Config files (config.json, config.yaml, application.properties)</li><li>System environment variables</li><li>Command line arguments</li><li>External config server(Zookeeper, etcd, spring cloud config, AWS AppConfig)</li></ul><p>Every approach have their own pros and cons, i’ll talk about them in minimal possible details.</p><h4><strong><em>Config Files</em></strong></h4><p>It is the easiest way to supply configuration to any application. But, it comes with risk of exposing config files to git intentionally, or unintentionally.</p><p>Think about a project which is committing config files to git, but keeping only none sensitive configuration from day one.</p><p>An <strong><em>intern</em></strong> joined team, and committed sensitive configuration to git. Or a production outage happens in the mid-night and you committed sensitive configuration to git. Now, everybody knows your database password.</p><p>Such mistakes can be avoided by not committing config files to git and adding config file path into <strong><em>.gitignore</em></strong>. Now your <strong><em>intern</em></strong> can’t commit credentials to git. But, it creates another problem. Sharing of configurations and keeping it up to date.</p><p>Assume that a new <strong><em>intern</em></strong> joined your team and he doesn’t have config file, so he couldn’t create development setup. He is reaching out to senior developers, and everybody is busy in urgent meetings. So, <strong><em>intern</em></strong> is just sitting idle.</p><p>Or someone just merged code in master which requires new configs. Production was deployed with new configs, but he forgot to inform every one in the team. You just pulled the code, but it’s no longer working in your development setup. You debugged the code for hours and then got to know that, the issue was due to missing configs.</p><p>To solve the above problem, a sample config file can be committed to git every time a new config is added into application (config.sample, application-dev.properties, config.sample.yaml etc). But, it creates maintenance problem.</p><p>If you add new config, you must have to update sample config files. If you missed doing so, your teams mates may waste hours debugging the issue which shouldn’t exist.</p><p>The best solution is to mix environment variable and config file approach, which spring boot natively supports.</p><pre># application.propertis<br>database.url=${DATABASE_URL}<br>database.password=${DATABASE_PASSWORD}<br><br># DATABASE_URL, DATABASE_PASSWORD are name of environment variables which are injected by spring boot at run time</pre><p>By config file and environment variables, we can get rid of all problems described above. No way to expose credentials to git/public. Sample config file is always maintained by default, so need to debug for hours.</p><h4>System environment variables</h4><p>System environment variables are the oldest way of supplying configurations before spring boot, json/yaml era. It is still widely used. It has the benefits of supplying different environment variables in different environment, e.g local, prod, CI/CD etc.</p><p>It has zero risk of exposing secrets to git or public. But, it has similar maintenance issues like config files. You need to keep a sample env file in git and make sure that it’s up to date. If you failed to do so, you’ll need to face problems described above.</p><p>There are threats associated with environment variables as well, if someone gain access to your program, then he could easily get access to all environment variables.</p><h4>Command line arguments</h4><p>Command line arguments are configs which are supplied at the time of starting a program. It’s good for supply some application properties, like heap memory size, etc, but not suitable for supplying entire configs.</p><h4>External config server</h4><p>External config servers are the components which keeps the configuration in remote location and supplies configuration on demand. It can be combined with configs file to pull only configs which are specified in config file. So, it’ll eliminate problems like missing config in sample files discussed above.</p><p>External config servers are immune to attackers gaining all credentials if they get access to your application. Credentials can be stored in encrypted format.</p><p>External config servers also have it’s own disadvantage. You need to maintain one more component in your system, it must have enough system resources to serve configs, it must be highly available, because your application depends on this.</p><h4>Conclusion</h4><p>If you are a small team/company and don’t have infrastructure to maintain external config server, then go with <strong><em>config</em></strong> <strong><em>file + environment</em></strong> variable approach. But, if you can afford, then go with external config <strong><em>file + config server</em></strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=083e518be36f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SSE vs WebSocket | Choosing the right tool for the job]]></title>
            <link>https://medium.com/@ats1999/sse-vs-websocket-choosing-the-right-tool-for-the-job-a2c372e30fd3?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/a2c372e30fd3</guid>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[websocket]]></category>
            <category><![CDATA[system-design-concepts]]></category>
            <category><![CDATA[realtime-applications]]></category>
            <category><![CDATA[https]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Wed, 26 Feb 2025 18:23:23 GMT</pubDate>
            <atom:updated>2025-02-26T18:23:23.250Z</atom:updated>
            <content:encoded><![CDATA[<h3>SSE (Server Sent Event)</h3><p>SSE is nothing but a long running HTTP connection that can be used by server to continuously stream data to client. It uses a special MIME <strong><em>text/event-stream</em></strong>. On the server, all you need to set the following header</p><pre>Content-Type: text/event-stream<br>Cache-Control: no-cache<br>Connection: keep-alive</pre><p>Learn more about SSE</p><ul><li><a href="https://stackoverflow.com/questions/7636165/how-do-server-sent-events-actually-work">https://stackoverflow.com/questions/7636165/how-do-server-sent-events-actually-work</a></li><li><a href="https://html5doctor.com/server-sent-events/">https://html5doctor.com/server-sent-events/</a></li><li><a href="https://html.spec.whatwg.org/multipage/server-sent-events.html#reestablish-the-connection">https://html.spec.whatwg.org/multipage/server-sent-events.html#reestablish-the-connection</a></li></ul><h3>WebSocket</h3><p>In a nutshell, WebSocket enables bidirectional, full-duplex communication between client and server over a persistent single TCP socket connection.</p><h3>When to use SSE?</h3><ul><li>When communication is uni directional(Server to Client)</li><li>SSE is simpler to scale than WebSocket, because it uses the same old plan HTML constructs.</li><li>When only one client is involved in any communication</li><li>e.g notification</li></ul><h3>When to use WebSocket?</h3><ul><li>When bi-directional communication is needed</li><li>When multiple client are communicating together</li><li>e.g real time chat application</li></ul><p>Happy Coding 😆</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a2c372e30fd3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Designing a Scalable Auto-Increment System for Grouped Identifiers in PostgreSQL]]></title>
            <link>https://medium.com/@ats1999/designing-a-scalable-auto-increment-system-for-grouped-identifiers-in-postgresql-d103721453bb?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/d103721453bb</guid>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[system-design-concepts]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Mon, 10 Feb 2025 03:06:40 GMT</pubDate>
            <atom:updated>2025-02-10T03:06:40.650Z</atom:updated>
            <content:encoded><![CDATA[<p>We often use identifier in software to uniquely identify either a resource or an entity. The two most commonly used type of identifiers are <strong><em>monotonically increasing counter</em></strong> and <strong><em>UUID</em></strong>.</p><p>For some applications, such as task management systems(JIRA), a human friendly identifiers are preferred.</p><blockquote><em>JIRA</em> makes it easy for us to share task with others due to its ID system. Every card in <em>JIRA</em> uses a numeric id that is easy to read, remember and share. We’ll try to explore similar, generic solution in this post. Scope will be limited to PostgreSQL database.</blockquote><p>Consider we are trying to build the following <strong>Task</strong> table in PostgresSQL for <strong><em>JIRA</em></strong>. The challenge is to keep every task id unique to the board.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*muDaoaWUjPNgImb1dyvpXQ.png" /></figure><h4>Method #1</h4><ul><li><a href="https://neon.tech/postgresql/postgresql-tutorial/postgresql-serial">Using auto increment</a></li></ul><p>Auto increment column keeps the counter unique to the table. So, every insert will get a unique counter value irrespective of the board.</p><p>To solve this problem we can keep different table for different board and have a auto increment column for task.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*51-bgBVdwTAXJ2PSlFGnuQ.png" /></figure><p>It works if we have a small number of board, but the solution is simply not feasible when we have thousands/millions of boards.</p><h4>Method #2</h4><ul><li><a href="https://www.postgresql.org/docs/current/sql-createsequence.html">Using PostgresSQL sequence</a></li></ul><p>PostgresSQL sequence aren’t tied to any table, rather they are database level counters. We can create a sequence for each board and generates counter using that sequence.</p><p>It solves our problem, but still it’s inefficient in terms of storage overhead.</p><p>Every sequence roughly takes around <strong><em>~8Kb</em></strong>. If we have 1 million sequence, then it’ll take around <strong><em>~8GB </em></strong>of space. Its inefficient to waste <strong><em>~8GB</em></strong> memory just to store 1 million counters.</p><p><strong>Method #3</strong></p><ul><li>Using id table</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/696/1*taCqtValIMBbR87jPhMDZg.png" /></figure><p>Id table allows us to store counters and update counter. It doesn’t require additional storage.</p><blockquote>Below query can be used to update and get the latest counter</blockquote><pre># get next counter<br>UPDATE counter<br>SET <br>  count = count+1<br>WHERE <br>  group_name = &quot;board.1&quot;<br>RETURNING count</pre><h4>Conclusion</h4><p>The <strong>counter table approach</strong> provides a scalable way to generate <strong>group-specific auto-incrementing IDs</strong> without excessive storage costs. It ensures efficient, readable, and shareable IDs, making it a practical solution for applications like JIRA-style task management systems.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d103721453bb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exploring Spring Cloud Config and Integration with JDBC(PostgreSQL)]]></title>
            <link>https://medium.com/@ats1999/exploring-spring-cloud-config-and-integration-with-jdbc-postgresql-fbcacdf0a1be?source=rss-054c4f323ff3------2</link>
            <guid isPermaLink="false">https://medium.com/p/fbcacdf0a1be</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[configuration-management]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[spring-boot]]></category>
            <dc:creator><![CDATA[Rahul Kumar]]></dc:creator>
            <pubDate>Sun, 11 Aug 2024 12:45:39 GMT</pubDate>
            <atom:updated>2024-08-11T12:45:39.557Z</atom:updated>
            <content:encoded><![CDATA[<p>Spring Cloud Config is a client/server approach for storing and serving distributed configurations across multiple micro-services and environments.</p><figure><img alt="Spring Cloud Config — by ats1999" src="https://cdn-images-1.medium.com/max/829/1*0GXZRgqJoi1iH32bSgmFww.png" /></figure><p>In this blog we’ll explore what is spring cloud config, spring cloud config client/server setup, querying config server using HTTP and spring cloud config client and many more.</p><blockquote>Happy Reading :)</blockquote><h3>Why should we use <em>spring cloud config</em> despite better alternatives?</h3><p>There plenty other other alternatives for managing micro service configurations, for example <a href="https://www.vaultproject.io/">vaultproject.io</a>, AWS AppConfig, Apache ZooKeeper, etc.<strong> </strong>But the best thing with spring cloud config is it’s native integration with spring boot. You are no longer responsible for writing configurations inside <em>application.properties</em> or <em>application.yaml</em>.</p><p>You can share same configurations between multiple micro-services, create different set of configurations for different profile for example, <em>production</em> profile and <em>development</em> profile. You can create configurations for different git branches, for example separate configuration for <em>development</em> branch and <em>feature</em> branch. Being a central configuration system, you can share your configuration with your team in real-time.</p><p>Spring cloud config creates and abstraction layer between your micro-services and configuration storage system. It supplies configuration to your micro-services in consistent structure regardless of the underlying configuration storage.</p><p>And off course, it can be used with any other programming language not just Java(Spring Boot). It exposes a HTTP API which can be used in any programming language. In fact we have NodeJs package which integrates spring cloud config, check it out <a href="https://www.npmjs.com/package/spring-cloud-config">here</a>.</p><h3>What exactly spring cloud config does?</h3><p>The Main thing we need to understand here is that, spring cloud config doesn’t store configurations itself. It creates an abstraction layer between your micro-services and configuration storage. Being and abstraction, you can connect it with any other storage system like MySql, AWS S3, Git Repository, Disk Files.</p><p>It allows you to fetch your config from any storage system of your choice. Update config inside your micro-service when there is any change in config, add authentication, config encryption and decryption, etc .</p><h3>Spring Cloud Config — Configuration structure</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/1*4q1NYV_Ev65n9U2_QR5ezw.png" /></figure><p>Spring cloud config stores configs as key/value pairs and every pair of key/value is scoped by application, profile and label. For example see below table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/893/1*iYSl9ebo_pgBYDdm_iFWlA.png" /></figure><h3>How to setup spring cloud config server with JDBC?</h3><blockquote>I am assuming that you have installed JDK, maven, MySql or PostgreSQL.</blockquote><p>To setup spring cloud config all you need to do is add few dependencies into <em>pom.xml</em> and specify few properties into <em>application.properties</em>.</p><p>We needed the following dependencies to get started</p><ul><li><strong><em>spring-boot-started-web</em></strong> — this dependency is required to serve HTTP traffic for configs query.</li><li><strong><em>spring-cloud-config-server</em></strong> — this dependency exposes HTTP routes to serve config.</li><li><strong><em>postgresql</em></strong> — this dependency helps in communicating with postgresql. If you are using anyother database, use appropriate db connector.</li><li><strong><em>spring-boot-starter-data-jdbc</em></strong> — this dependency will be used by <strong><em>spring-cloud-config-server</em></strong> to fetch configs from database.</li></ul><pre>&lt;dependencyManagement&gt;<br>    &lt;dependencies&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;<br>            &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;<br>            &lt;version&gt;2023.0.3&lt;/version&gt;<br>            &lt;type&gt;pom&lt;/type&gt;<br>            &lt;scope&gt;import&lt;/scope&gt;<br>        &lt;/dependency&gt;<br>    &lt;/dependencies&gt;<br>&lt;/dependencyManagement&gt;<br><br>&lt;dependencies&gt;<br>      &lt;dependency&gt;<br>          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br>          &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;<br>      &lt;/dependency&gt;<br>      &lt;dependency&gt;<br>          &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;<br>          &lt;artifactId&gt;spring-cloud-config-server&lt;/artifactId&gt;<br>      &lt;/dependency&gt;<br>      &lt;dependency&gt;<br>          &lt;groupId&gt;org.postgresql&lt;/groupId&gt;<br>          &lt;artifactId&gt;postgresql&lt;/artifactId&gt;<br>          &lt;scope&gt;runtime&lt;/scope&gt;<br>      &lt;/dependency&gt;<br>      &lt;dependency&gt;<br>          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br>          &lt;artifactId&gt;spring-boot-starter-data-jdbc&lt;/artifactId&gt;<br>      &lt;/dependency&gt;<br>&lt;/dependencies&gt;</pre><h4>Create a database and table for storing configs</h4><pre>CREATE DATABASE config_db;<br><br># connect to db<br>\c config_db<br><br>CREATE TABLE PROPERTIES(application varchar(55),profile varchar(50), label varchar(50),&quot;KEY&quot; varchar(255), &quot;VALUE&quot; text);</pre><p>Spring cloud config JDBC integration requires a table named <em>properties</em> with <em>application, profile, label, KEY, VALUE</em> columns.</p><blockquote><em>KEY, VALUE</em> needs to be in uppercase in PostgreSQL, haven’t tested behaviour in other SQL servers</blockquote><p>Know more about JDBC integration — <a href="https://docs.spring.io/spring-cloud-config/reference/server/environment-repository/jdbc-backend.html">https://docs.spring.io/spring-cloud-config/reference/server/environment-repository/jdbc-backend.html</a></p><p>Add below config into <strong><em>application.properties</em></strong></p><pre>spring.application.name=config-server<br>server.port=8888<br>spring.threads.virtual.enabled=true<br>spring.profiles.active=jdbc<br>spring.datasource.url=jdbc:postgresql://localhost:5432/config_db<br>spring.datasource.username=postgres<br>spring.datasource.password=rahul</pre><blockquote><em>spring.profiles.active=jdbc</em> is required to tell the spring cloud config server that we are using <strong>JDBC</strong> backend for storing configs.</blockquote><h3>Querying spring cloud config server via HTTP</h3><blockquote>I am assuming that you have started config server after doing setup steps as mentioned above and server is listening on 8888.</blockquote><p>Once spring cloud config server is started you can query server using either HTTP endpoints and via spring cloud config java client.</p><blockquote>Let’s explore querying via HTTP methods here, we will explore integration with spring boot apps later in this blog.</blockquote><pre>application,profile,label,KEY,VALUE<br>account_app,dev,master,server.servlet.context-path,/account<br>account_app,dev,feature,server.servlet.context-path,/acc<br>account_app,production,master,spring.threads.virtual.enabled,true<br>spring_apps,dev,master,spring.datasource.username,rahul_dev<br>spring_apps,dev,master,spring.datasource.password,FMOxUnns7iTZlVu29GVsVCXgg<br>spring_apps,production,master,spring.datasource.password,CnhRa1gxUjdnb2diemZXZ05qbnlhR2pPbmF<br>spring_apps,production,master,spring.datasource.username,rahul_prod</pre><p>You can populate above CSV data into properties table of you database. Once populated we can query config. To query config we need to specify <em>application, profile and labe</em>l.</p><p>When you make GET requests on <a href="http://localhost:8888/account_app/dev/master">http://localhost:8888/account_app/dev/master</a> then we’ll get the following data for <strong><em>application</em></strong> account_app, <strong><em>profile</em></strong> dev and <strong><em>label</em></strong> master.</p><pre>{<br>  &quot;name&quot;: &quot;account_app&quot;,<br>  &quot;profiles&quot;: [<br>    &quot;dev&quot;<br>  ],<br>  &quot;label&quot;: &quot;master&quot;,<br>  &quot;version&quot;: null,<br>  &quot;state&quot;: null,<br>  &quot;propertySources&quot;: [<br>    {<br>      &quot;name&quot;: &quot;account_app-dev&quot;,<br>      &quot;source&quot;: {<br>        &quot;server.servlet.context-path&quot;: &quot;/account&quot;<br>      }<br>    }<br>  ]<br>}</pre><p>Often we want to have common configs across micro-services and environments. You can specify multiple comma separated applications and profiles to get combined properties like below</p><p><a href="http://localhost:8888/account_app,spring_apps/dev,production/master">http://localhost:8888/account_app,spring_apps/dev,production/master</a></p><pre>{<br>  &quot;name&quot;: &quot;account_app,spring_apps&quot;,<br>  &quot;profiles&quot;: [<br>    &quot;dev,production&quot;<br>  ],<br>  &quot;label&quot;: &quot;master&quot;,<br>  &quot;version&quot;: null,<br>  &quot;state&quot;: null,<br>  &quot;propertySources&quot;: [<br>    {<br>      &quot;name&quot;: &quot;spring_apps-production&quot;,<br>      &quot;source&quot;: {<br>        &quot;spring.datasource.password&quot;: &quot;CnhRa1gxUjdnb2diemZXZ05qbnlhR2pPbmF&quot;,<br>        &quot;spring.datasource.username&quot;: &quot;rahul_prod&quot;<br>      }<br>    },<br>    {<br>      &quot;name&quot;: &quot;account_app-production&quot;,<br>      &quot;source&quot;: {<br>        &quot;spring.threads.virtual.enabled&quot;: &quot;true&quot;<br>      }<br>    },<br>    {<br>      &quot;name&quot;: &quot;spring_apps-dev&quot;,<br>      &quot;source&quot;: {<br>        &quot;spring.datasource.username&quot;: &quot;rahul_dev&quot;,<br>        &quot;spring.datasource.password&quot;: &quot;FMOxUnns7iTZlVu29GVsVCXgg&quot;<br>      }<br>    },<br>    {<br>      &quot;name&quot;: &quot;account_app-dev&quot;,<br>      &quot;source&quot;: {<br>        &quot;server.servlet.context-path&quot;: &quot;/account&quot;<br>      }<br>    }<br>  ]<br>}</pre><p>Often we need to override one branch config with another in development for testing. For example override configs of <strong><em>development</em></strong> branch with <strong><em>feature</em></strong> branch. Currently, it’s not supported by spring cloud config sever, but you can implement custom environment repository to achieve desired behaviour. Visit <a href="https://docs.spring.io/spring-cloud-config/reference/server/environment-repository/custom-enviroment-repository.html">here</a> for more information.</p><h3>Integrating spring cloud config server in micro-services</h3><p>I am assuming that you are using spring micro-service, for other languages and environments you can use HTTP methods or implement custom solution.</p><blockquote>If you are using NodeJs, you can try <a href="https://www.npmjs.com/package/spring-cloud-config">https://www.npmjs.com/package/spring-cloud-config</a></blockquote><pre>&lt;dependencyManagement&gt;<br>    &lt;dependencies&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;<br>            &lt;artifactId&gt;spring-cloud-dependencies&lt;/artifactId&gt;<br>            &lt;version&gt;2023.0.3&lt;/version&gt;<br>            &lt;type&gt;pom&lt;/type&gt;<br>            &lt;scope&gt;import&lt;/scope&gt;<br>        &lt;/dependency&gt;<br>    &lt;/dependencies&gt;<br>&lt;/dependencyManagement&gt;<br><br>// add this into dependencies<br>&lt;dependency&gt;<br>    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;<br>    &lt;artifactId&gt;spring-cloud-starter-config&lt;/artifactId&gt;<br>&lt;/dependency&gt;<br></pre><blockquote><strong><em>spring-cloud-starter-config</em></strong> is a client library that fetches config from spring cloud config server.</blockquote><p>Add following properties into your <strong><em>application.properties</em></strong> file</p><pre>spring.config.import=configserver:http://localhost:8888<br><br># value for application<br>spring.cloud.config.name=spring_apps,account_app<br><br>spring.cloud.config.profile=dev,production<br>spring.cloud.config.label=master</pre><p>Spring cloud config client maps server properties to spring <em>Environment</em> and <em>PropertySource</em> abstractions. So, you no longer need to specify properties into <em>application.properties</em> file.</p><p>For example, <strong><em>spring-kafka</em></strong> often needs following properties to be present in <em>application.properties</em> file.</p><pre>spring.kafka.bootstrap-servers=localhost:9092<br>spring.kafka.consumer.group-id=my-group<br>spring.kafka.consumer.auto-offset-reset=earliest<br>spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer<br>spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer<br>spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer<br>spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer</pre><p>Once you have integrated spring cloud config, you can directly add them into SQL table instead of <em>application.properties</em>.</p><h4>Reading spring cloud config programatically</h4><p>You can read configs manually from spring <em>Environment</em> object using config key.</p><pre>@RestController<br>@RequestMapping(&quot;/config&quot;)<br>public class ClientClass {<br>  @Autowired private Environment environment;<br><br>  @GetMapping<br>  public String getConfig(@RequestParam String key) {<br>    return environment.getProperty(key);<br>  }<br>}<br><br>// try /config?key=spring.threads.virtual.enabled</pre><p>You can use <strong><em>@Value</em></strong> annotation as well to read configs</p><pre>@RestController<br>@RequestMapping(&quot;/config&quot;)<br>public class ClientClass {<br>  @Value(&quot;${spring.threads.virtual.enabled}&quot;)<br>  private String isVirtualThreadEnabled;<br><br>  @GetMapping<br>  public String getConfig() {<br>    return isVirtualThreadEnabled;<br>  }<br>}</pre><blockquote>Now it’s end of the blog, hope you it helped you in any way :)</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fbcacdf0a1be" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>