<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Balaji Srinivasan</title>
    <description>The latest articles on DEV Community by Balaji Srinivasan (@balaaagi).</description>
    <link>https://dev.to/balaaagi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F321989%2F955205af-3514-46eb-865e-cf5f51b08ff5.jpg</url>
      <title>DEV Community: Balaji Srinivasan</title>
      <link>https://dev.to/balaaagi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/balaaagi"/>
    <language>en</language>
    <item>
      <title>Running Spring Boot Test via docker</title>
      <dc:creator>Balaji Srinivasan</dc:creator>
      <pubDate>Sat, 27 Mar 2021 12:29:53 +0000</pubDate>
      <link>https://dev.to/balaaagi/testing-spring-boot-apps-1ipe</link>
      <guid>https://dev.to/balaaagi/testing-spring-boot-apps-1ipe</guid>
      <description>&lt;p&gt;Spring boot becoming a common defacto for writing micro-services in the Java ecosystem. We have a lot of frameworks and options to write unit and integration tests are available. Below are the few resources, that I have looked upon in the past to improve my unit testing skills&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.sivalabs.in/2020/02/spring-boot-integration-testing-using-testcontainers-starter"&gt;Test Containers&lt;/a&gt; - By Siva&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.baeldung.com/spring-boot-testing"&gt;Testing Spring Boot&lt;/a&gt;- By Baeldung&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are not going to discuss in detail writing unit-testing. But setting up the necessary things that enable us to independently write end-to-end tests for our spring boot applications. &lt;/p&gt;

&lt;h2&gt;
  
  
  Assumption
&lt;/h2&gt;

&lt;p&gt;Our application is going to be a simple backend service connected with a database. In our case, let's assume it is Postgres. Based on your application architecture the same template can be changed. Below the types of tests we have &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controller Level Tests&lt;/li&gt;
&lt;li&gt;Service Level Tests&lt;/li&gt;
&lt;li&gt;Core Business Logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time we might miss validating our repository/data layer via tests under the assumption all will be fine. But if we do it, it is always good to ensure we don't end up with weird data issues in production. As I mentioned above &lt;code&gt;TestContainers&lt;/code&gt; are a good way to write tests including embedded databases. Cored database schema migrations are integrated into the application bootup. We can use tools like &lt;code&gt;flyway&lt;/code&gt; or &lt;code&gt;liquibase&lt;/code&gt; to do this. &lt;/p&gt;

&lt;h2&gt;
  
  
  Settings
&lt;/h2&gt;

&lt;p&gt;For our application, we should have the below properties &lt;code&gt;src/test/java/resource/application.properties&lt;/code&gt; for effective testing&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;We have passed our values to be env variables. You can refer &lt;a href="https://balaaagi.in/post/envsinspringboot/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Base Image
&lt;/h3&gt;

&lt;p&gt;Create a base image for your projects and push it to some registry. Either docker hub or anything which can be accessed. Please keep this base image minimal without any confidential details of your project. Let's assume we have a base image named &lt;code&gt;orgname/base-springboot&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;We would need a &lt;code&gt;docker-compose.yml&lt;/code&gt; file to have this setup working end to end. Below is a docker-compose that can be used for reference&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;h2&gt;
  
  
  How to Run the tests?
&lt;/h2&gt;

&lt;p&gt;Below is the simple command that can be used to run the tests&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up --abort-on-container-exit --exit-code-from application_under_test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What the above command does is spins the DB, application and runs the tests. If a test failed it gets exit. The same command can be used in CI/CD pipelines also. To fasten the process the base image should be built with all common dependencies.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>java</category>
      <category>docker</category>
    </item>
    <item>
      <title>Environment Variables In Spring Boot Application</title>
      <dc:creator>Balaji Srinivasan</dc:creator>
      <pubDate>Tue, 15 Dec 2020 15:33:43 +0000</pubDate>
      <link>https://dev.to/balaaagi/environment-variables-in-spring-boot-application-3mnc</link>
      <guid>https://dev.to/balaaagi/environment-variables-in-spring-boot-application-3mnc</guid>
      <description>&lt;p&gt;Spring Boot lets you externalize &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config"&gt;configurations&lt;/a&gt; for our application. Lets take a simple application which connects to database and perform some operations on it. Standard configuration for this kind of app would be the database related details. Below is one sample &lt;code&gt;properties&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.datasource.url=${JDBC_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like this we might have more properties specific to our application also which we want to have it as dynamic configurations that can be passed when application startup. In order to have these have different across different environments like dev,staging,production. Spring boot provides us with &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-files-profile-specific"&gt;option &lt;/a&gt; to have environment specific files with different values for different environments.&lt;/p&gt;

&lt;p&gt;Below are few common practices developers follow which has its own pros and cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Commit secrets in these files as part of the code base&lt;/li&gt;
&lt;li&gt; Commit only local configuration in the code base and as part of deployment pipeline copy environment specific files from different repository and build the package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we are having separate profile files then we might need to have separate start-up scripts for each to ensure right profile details are passed. If we are copying files at the time of the build for any change in secrets or configurations we might need to build the package again to take effect.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://12factor.net/config"&gt;12factor&lt;/a&gt; apps its good practice to store configurations in environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can we achieve this?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We can avoid multiple property files and have only one file as below
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.datasource.url=${JDBC_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above helps in multiple ways&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No need to rebuild the package again if there is any change in configuration.&lt;/li&gt;
&lt;li&gt;One common properties file versioned as part of code base.&lt;/li&gt;
&lt;li&gt;Build pipelines would be generic. Same builds can be used across all environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When running as containers
&lt;/h3&gt;

&lt;p&gt;If we are running our application as containers we need to pass the environment variables while starting the application. This can be taken care by a deployment pipeline.If there is a change in value just a restart of the container is enough&lt;/p&gt;

&lt;h3&gt;
  
  
  When running as fat jars
&lt;/h3&gt;

&lt;p&gt;If we are running our application as normal jars then best practice would be to set the environment variables as part of the host machine and start the application. &lt;/p&gt;

&lt;h3&gt;
  
  
  What about local development/tests
&lt;/h3&gt;

&lt;p&gt;For tests I would recommend to have dedicated properties file. For local development we can do it two ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have one &lt;code&gt;.env&lt;/code&gt; file in local and &lt;code&gt;source&lt;/code&gt; them before starting the application&lt;/li&gt;
&lt;li&gt;We can give default values to properties if not present in environment as &lt;code&gt;spring.datasource.username=${DB_USERNAME:username}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key thing to note here is the deployment process. I will cover a detailed blog on how the deployment pipeline can be done for such a setup of spring boot application.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>12factorapps</category>
      <category>configurations</category>
    </item>
    <item>
      <title>Simple State Machines In Java</title>
      <dc:creator>Balaji Srinivasan</dc:creator>
      <pubDate>Sun, 06 Dec 2020 15:34:27 +0000</pubDate>
      <link>https://dev.to/balaaagi/simple-state-machines-in-java-3mdo</link>
      <guid>https://dev.to/balaaagi/simple-state-machines-in-java-3mdo</guid>
      <description>&lt;h2&gt;
  
  
  What is a State Machine ?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Finite-state_machine"&gt;Wikipedia defines a finite-state machine (FSM)&lt;/a&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an abstract machine that can be in exactly one of a finite number of states at any given time. &lt;br&gt;
The FSM can change from one state to another in response to some external inputs; the change from one state to another is called a transition. &lt;br&gt;
An FSM is defined by a list of its states, its initial state, and the conditions for each transition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is way to program a model so that it is at one particular state at any moment. &lt;/p&gt;

&lt;p&gt;The world is filled with state machines which we can see anywhere in our daily usage. Below are few&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Road Traffic Signale Red -&amp;gt; Yellow -&amp;gt; Green&lt;/li&gt;
&lt;li&gt;Coffee Vending Machine&lt;/li&gt;
&lt;li&gt;E-commerce Portal Ordering&lt;/li&gt;
&lt;li&gt;Online Trip Booking&lt;/li&gt;
&lt;li&gt;Many Cron Jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing State Machines In Java
&lt;/h2&gt;

&lt;p&gt;There are many ways which we can implement state machines. In Java world itself we have many libraries using which we can model these states&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://projects.spring.io/spring-statemachine/"&gt;Spring State Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hekailiang/squirrel"&gt;Squirrel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can also implement them using a standard &lt;code&gt;State Design pattern&lt;/code&gt; [example] &lt;a href="https://www.journaldev.com/1751/state-design-pattern-java"&gt;https://www.journaldev.com/1751/state-design-pattern-java&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;What if we don't want to add any external dependencies?&lt;br&gt;
What if we want to have simple state machine and control it via our own logic?&lt;/p&gt;
&lt;h2&gt;
  
  
  State Machines Using Enums in Java
&lt;/h2&gt;

&lt;p&gt;Many of us would have used Uber or Ola at-least once. Lets try implementing the trip booking state machine using Java Enums&lt;/p&gt;

&lt;p&gt;What are the ideal states in trip booking?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trip Booked&lt;/li&gt;
&lt;li&gt;Driver Assigned&lt;/li&gt;
&lt;li&gt;Driver Reached&lt;/li&gt;
&lt;li&gt;Trip Started&lt;/li&gt;
&lt;li&gt;Trip Ended&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="/images/tripstatemachine.png" class="article-body-image-wrapper"&gt;&lt;img src="/images/tripstatemachine.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Simple Implementation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;TRIPCREATED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;DRIVERASSSIGNED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;DRIVERREACHED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;TRIPSTARTED&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;TRIPENDED&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The above enum can be used across our application for maintaining the state of the trip. Even in database this can be used by using the string value of the enum. Example &lt;code&gt;TripStates.TRIPCREATED.name()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we have implemented the state machine but how to ensure proper state transition happens. One simple way is to include a function within the enum and check it across whenever we are trying to change the state of a trip&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;canChangeTripState&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="n"&gt;fromState&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="n"&gt;toState&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fromState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ordinal&lt;/span&gt;&lt;span class="o"&gt;()&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;toState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ordinal&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above function needs to be called wherever state changes needs to happen. This helps in moving states in forward manner.&lt;br&gt;
But there is problem with this. We will be able to move a trip from trip created to trip started. The above implementation might not solve the real constraint we would like to introduce like a trip cannot be marked as started without marking as reached.&lt;/p&gt;

&lt;p&gt;How can we achieve this with just enum?&lt;/p&gt;

&lt;p&gt;Java Enums can have additional fields to it. We can leverage that to solve this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;TRIPCREATED&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;[]{})),&lt;/span&gt;
    &lt;span class="no"&gt;DRIVERASSSIGNED&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TRIPCREATED&lt;/span&gt;&lt;span class="o"&gt;})),&lt;/span&gt;
    &lt;span class="no"&gt;DRIVERREACHED&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRIVERASSSIGNED&lt;/span&gt;&lt;span class="o"&gt;})),&lt;/span&gt;
    &lt;span class="no"&gt;TRIPSTARTED&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRIVERREACHED&lt;/span&gt;&lt;span class="o"&gt;})),&lt;/span&gt;
    &lt;span class="no"&gt;TRIPENDED&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TRIPSTARTED&lt;/span&gt;&lt;span class="o"&gt;}));&lt;/span&gt;


    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validFromStates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;


    &lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validFromStates&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validFromStates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validFromStates&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;canChangeTripState&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="n"&gt;fromState&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TripStates&lt;/span&gt; &lt;span class="n"&gt;toState&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;toState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validFromStates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fromState&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look we are maintaining &lt;code&gt;validFromStates&lt;/code&gt; in order easily expand this to other cases where a trip can ended even from different states. Example: CustomerNotReachable etc..&lt;/p&gt;

&lt;p&gt;The above is a simple implementation that can be used. But if we wanted to have more logic within this state transitions we can still leverage but we need to hook the above model with other design patterns.&lt;/p&gt;

</description>
      <category>java</category>
      <category>cleancode</category>
      <category>software</category>
      <category>finitestatemachine</category>
    </item>
    <item>
      <title>Managing multiple git account</title>
      <dc:creator>Balaji Srinivasan</dc:creator>
      <pubDate>Sun, 24 May 2020 06:46:05 +0000</pubDate>
      <link>https://dev.to/balaaagi/managing-multiple-git-account-1ddd</link>
      <guid>https://dev.to/balaaagi/managing-multiple-git-account-1ddd</guid>
      <description>&lt;p&gt;Lot of companies requests developers to create dedicated &lt;code&gt;git&lt;/code&gt; accounts to access work related git projects. It is good from security and access control perspective but it is a pain from developers who wish to work on personal projects in their private accounts. Lot of times commits goes in the name of work accounts or the otherway. I have also gone through this that is why have setup my work laptop as below such that there is clear segregation of usage of git accounts&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisite
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You should be using ssh based git access which most of the devs would be using. I still find still few are using http based and giving creds each time 🤦‍♂️&lt;/li&gt;
&lt;li&gt;You should be used to segregate your office work space (code folders) from your private workspace
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Folder Structure
&lt;/h3&gt;

&lt;p&gt;I usually go with the below folder structures. This has helped me in maintaining a clean structure and managing multiple git accounts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── personal
│   └── workspace
│       ├── repo1
│       └── repo2
└── work
    └── workspace
        ├── workrepo1
        └── workrepo2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSH Keys
&lt;/h3&gt;

&lt;p&gt;Ensure you create two different &lt;code&gt;ssh&lt;/code&gt; keys for each of your git accounts. Please refer this &lt;a href="https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent"&gt;link&lt;/a&gt;.&lt;br&gt;
Once you have the keys ensure to follow this ensure to configure the corresponding &lt;code&gt;Github&lt;/code&gt; account with corresponding keys. Follow this &lt;a href="https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account"&gt;link&lt;/a&gt;.&lt;br&gt;
Since you have generated two keys two private key files would be present.&lt;/p&gt;
&lt;h4&gt;
  
  
  SSH Configuration
&lt;/h4&gt;

&lt;p&gt;Since we have two different ssh keys we need to configure it to use it. Below are the ssh configs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host github.com
   HostName github.com
   User git
   IdentityFile ~/.ssh/&amp;lt;private key filename of private account&amp;gt;

Host &amp;lt;githubwork.com&amp;gt;    
   HostName github.com
   User git
   IdentityFile ~/.ssh/&amp;lt;private key filename of work account&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Git Configuration
&lt;/h3&gt;

&lt;p&gt;Here I will be setting the default &lt;code&gt;git config&lt;/code&gt; as my private account and configure work &lt;code&gt;git&lt;/code&gt; account specific to work associated directories. But we can do the other way based on how we are structuring our workspace.&lt;br&gt;
Below is configuration in default &lt;code&gt;git config&lt;/code&gt; in &lt;code&gt;/.gitconfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[user]
    name = Personal Git Account Name
    email = personalemailassociatedwithpersonalgit@somedomain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above will ensure all the git operations uses the above config across your machine.&lt;/p&gt;

&lt;h4&gt;
  
  
  Work Related Git Configuration
&lt;/h4&gt;

&lt;p&gt;In the same &lt;code&gt;~/.gitconfig&lt;/code&gt; add these lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[includeIf "gitdir:~/work/"]
    path = ~/work/.gitconfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we have done is used the &lt;code&gt;includeif&lt;/code&gt;.&lt;a href="https://git-scm.com/docs/git-config#_conditional_includes"&gt;Conditional Includes&lt;/a&gt; was introduced from git 2.13. Ensure you have this version of &lt;code&gt;git&lt;/code&gt; to use this feature. It actually includes &lt;code&gt;gitconfig&lt;/code&gt; dynamically based on the conditions. In this case if the git working directory is &lt;code&gt;~/work&lt;/code&gt; it uses the &lt;code&gt;.gitconfig&lt;/code&gt; from the &lt;code&gt;~/work/.gitconfig&lt;/code&gt;.&lt;br&gt;
Below are the contents of this config file inside &lt;code&gt;~/work/.gitconfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[user]
    name = Work Git Account Name
    email = workacountemail@domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Work on repositories from Both Account
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To clone a repo from work account you need to follow this since you have configured the &lt;code&gt;ssh&lt;/code&gt; - &lt;code&gt;git clone git@githubwork.com:&amp;lt;repopath&amp;gt;.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To clone a repo from private account you need to follow this since you have configured the &lt;code&gt;ssh&lt;/code&gt; - &lt;code&gt;git clone git@github.com:&amp;lt;repopath&amp;gt;.git&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the &lt;code&gt;git&lt;/code&gt; operations on corresponding repos ensure to follow the corresponding configs. You can customize more configurations in this custom git configs. &lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
