<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[IAmAndrew]]></title><description><![CDATA[Diary of frustrations and lessons learned with Spring Boot]]></description><link>https://andrewzc.com/</link><image><url>https://andrewzc.com/favicon.png</url><title>IAmAndrew</title><link>https://andrewzc.com/</link></image><generator>Ghost 1.25</generator><lastBuildDate>Sat, 04 Apr 2026 01:18:35 GMT</lastBuildDate><atom:link href="https://andrewzc.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Connecting to multiple Message Broker Addresses over STOMP (Spring Boot) - Part 1]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I had to rely my Spring Boot application on connecting to an external message broker, Amazon MQ for example instead of my own self hosting message broker such as RabbitMQ.</p>
<p>Fortunately! The Spring Team had already developed this implementation, <strong>BUT</strong> there are additional tweaks needed to support for STOMP. As</p></div>]]></description><link>https://andrewzc.com/stomp/</link><guid isPermaLink="false">5baffd12db99b93277ada8bd</guid><dc:creator><![CDATA[Andrew Wong]]></dc:creator><pubDate>Sat, 29 Sep 2018 22:48:30 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I had to rely my Spring Boot application on connecting to an external message broker, Amazon MQ for example instead of my own self hosting message broker such as RabbitMQ.</p>
<p>Fortunately! The Spring Team had already developed this implementation, <strong>BUT</strong> there are additional tweaks needed to support for STOMP. As a reference, this implementation is only available in <strong>Spring Messaging 4.3.x</strong>, refer to this <a href="https://jira.spring.io/browse/SPR-12452">Jira Ticket</a> for this new release which uses the <code>Reactor2TcpClient</code> method which accepts a <code>Supplier&lt;InetSocketAddress&gt;</code> in which we will be using to supply our message broker addresses.</p>
<p>Taking a deep dive into the <a href="https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference/html/websocket.html#websocket-stomp-handle-broker-relay-configure">Spring Documentation</a> for multiple broker address support, let's take a look at this code snippet here.</p>
<pre><code class="language-java">private Reactor2TcpClient&lt;byte[]&gt; createTcpClient() {

    Supplier&lt;InetSocketAddress&gt; addressSupplier = new Supplier&lt;InetSocketAddress&gt;() {
        @Override
        public InetSocketAddress get() {
            // Select address to connect to ...
        }
    };

    StompDecoder decoder = new StompDecoder();
    Reactor2StompCodec codec = new Reactor2StompCodec(new StompEncoder(), decoder);
    return new Reactor2TcpClient&lt;&gt;(addressSupplier, codec);
}
</code></pre>
<p>The <code>createTcpClient()</code> method returns a <code>Reactor2TcpClient</code> which implements <code>TcpOperations&lt;P&gt;</code>. This is extremely important as we will be using this method for <code>StompBrokerRelayMessageHandler</code> to configure its TcpClient.</p>
<p>The crucial part is in the override method above. Whenever there is a failure to establish a websocket connection to one of the message broker address, then the <code>get()</code> method is automatically called to retrieve a different address to connect to which allows for failover because our STOMP tcp client is explicitly set to this method.</p>
<p>A simple STOMP broker message example code simply looks like this:</p>
<pre><code class="language-java">@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {    
    registry.enableStompBrokerRelay(&quot;/queue&quot;, /topic&quot;)
    .setRelayHost(&quot;&lt;hostname&gt;&quot;)
    .setRelayPort(&quot;&lt;port&gt;&quot;)
    .setSystemLogin(&quot;&lt;broker login&gt;&quot;)
    .setSystemPasscode(&quot;&lt;broker password&gt;&quot;)
    .setTcpClient(createTcpClient());
    registry.setApplicationDestinationPrefixes(&quot;/app&quot;);
  }

    private Reactor2TcpClient&lt;byte[]&gt; createTcpClient() {

        Supplier&lt;InetSocketAddress&gt; addressSupplier = new Supplier&lt;InetSocketAddress&gt;() {
            @Override
            public InetSocketAddress get() {
                // Select address to connect to ...
            }
        };

        StompDecoder decoder = new StompDecoder();
        Reactor2StompCodec codec = new Reactor2StompCodec(new StompEncoder(), decoder);
        return new Reactor2TcpClient&lt;&gt;(addressSupplier, codec);
    }

}
</code></pre>
<p>Excellent! Are we done yet? Unfortunately no...if you have set up your own local message broker, you are pretty much done here. However, for external message brokers, SSL handshake is needed in which the <code>Reactor2TcpClient</code> constructor did not implement.</p>
<p>Nonetheless, it is not difficult as the Spring Team has already done a great job in implementing this, and all we need to do is copy some of their methods to fit our needs by creating a custom Stomp Factory class that supports SSL.</p>
<p>Stay tune for Part 2 as I will be taking a dive into the <code>Reactor2TcpClient</code> class, and we will begin to understand how we can extract ideas from this class to implement our own custom STOMP configuration!</p>
</div>]]></content:encoded></item><item><title><![CDATA[Configuration Properties Not Loading in Spring Boot Test]]></title><description><![CDATA[<div class="kg-card-markdown"><p>While trying to test a service layer class which loads properties from a configuration file that reads the information from either an <code>application.yml</code> or a <code>application.properties</code>, I kept running into an issue in which all of the properties were returning <code>null</code>.</p>
<p>My test service class was simple. I</p></div>]]></description><link>https://andrewzc.com/loading-configuration-properties-in-spring-boot-test/</link><guid isPermaLink="false">5b667ac2db99b93277ada8a0</guid><dc:creator><![CDATA[Andrew Wong]]></dc:creator><pubDate>Sun, 05 Aug 2018 04:22:41 GMT</pubDate><media:content url="https://andrewzc.com/content/images/2018/08/1huzg9U.jpg" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://andrewzc.com/content/images/2018/08/1huzg9U.jpg" alt="Configuration Properties Not Loading in Spring Boot Test"><p>While trying to test a service layer class which loads properties from a configuration file that reads the information from either an <code>application.yml</code> or a <code>application.properties</code>, I kept running into an issue in which all of the properties were returning <code>null</code>.</p>
<p>My test service class was simple. I figured hmm, maybe loading a properties file is relatively straightforward and a simple injection will do the trick, something like :</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
public class SomeServiceTest {
    @Autowired
    private MyConfigProperties configProperties;
}
</code></pre>
<p>For reference, my <code>application.yml</code> looks something like this:</p>
<pre><code class="language-yaml">myApp:
  someProperty: someKey
</code></pre>
<p>And the <code>MyConfigProperties</code> located in our main project:</p>
<pre><code class="language-java">@ConfigurationProperties(prefix = &quot;myApp&quot;)
public class MyConfigProperties {
    private String someProperty;
    public String getSomeProperty() { return someProperty; }
    public void setSomeProperty(String someProperty) { this.setSomeProperty = setSomeProperty; }
}
</code></pre>
<hr>
<p>When I tried to load <code>someProperty</code>, the value return by this key is always <code>null</code>. I couldn't figure out why is this happening. The bean property was injected correctly since the class <code>MyConfigProperties</code> is referenced correctly.</p>
<p>After some time of head banging and Googling, I realized that my service test class needs to know that <code>MyConfigProperties</code> is a <strong>ConfigurationProperties</strong> type.</p>
<p>The solution to this issue is to first create an application test class. This class is located at a directory higher than the rest of the test classes, and the test classes can load/specify this application test class as a configuration class. So, we create this file in:</p>
<pre><code>src/test/java/com/packageName/
</code></pre>
<p>while the rest of the service test classes lives in:</p>
<pre><code>src/test/java/com/packageName/service/
</code></pre>
<p>So, I created a TestApp class loaded with <code>MyConfigProperties</code>:</p>
<pre><code class="language-java">@EnableAutoConfiguration
@EnableConfigurationProperties(value = { MyConfigProperties.class })
public class TestApp {}
</code></pre>
<p>The main idea of <code>@EnableConfigurationProperties</code> is to look for a <code>@ConfigurationProperties</code> annotation in the <code>MyConfigProperties</code> and load this bean.</p>
<p>Now! A slight modification to our test service class, and we are done with this problem.</p>
<p>I then load the necessary context configuration such that my test profile knows which configuration class to load and proceeds to inject the necessary configuration files from it. The modified service class looks like:</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
@ContextConfiguration(classes = TestApp.class, initializers = ConfigFileApplicationContextInitializer.class)
public class SomeServiceTest {

    @Autowired
    private MyConfigProperties configProperties;
    
    @Test
    public void testPropertiesNotNull() {   
        Assertions.assertThat(
            configProperties.getSomeProperty())
            .isNotNull();
    }
}
</code></pre>
<p>Once I ran this test, I was so happy that it finally worked! Okay, it works, great, but why did this change made it work?</p>
<p>In our service test class, we specifically use <code>@ContextConfiguration</code> to allow us to load an <strong>ApplicationContext</strong>, in our case, <code>TestApp.class</code> that contains the necessary dependencies we need (configuration files). The <code>initializers=ConfigFileApplicationContextInitializer.class</code> specifically tells the loaded <strong>ApplicationContext</strong> to read configuration properties from our <code>application.yml</code> or <code>application.properties</code> file.</p>
<p>As quoted from the <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-configfileapplicationcontextinitializer-test-utility">Spring docs</a>:</p>
<blockquote>
<p>ConfigFileApplicationContextInitializer is an ApplicationContextInitializer that you can apply to your tests to load Spring Boot application.properties files.</p>
</blockquote>
<p>So there you have it! This was one out of the many moments that I struggle to find solutions from springdocs and stackoverflow.</p>
<p>As always, hope you enjoy reading, and more spring boot frustrations but happy yet fruitful learning experiences coming soon!</p>
</div>]]></content:encoded></item><item><title><![CDATA[A Simple SpringBoot Test Example]]></title><description><![CDATA[An example to showcase on how a simple spring boot unit test works.]]></description><link>https://andrewzc.com/springboot-test/</link><guid isPermaLink="false">5b5812f7717bbc0fff61a262</guid><category><![CDATA[Spring Boot Test]]></category><dc:creator><![CDATA[Andrew Wong]]></dc:creator><pubDate>Wed, 25 Jul 2018 00:42:59 GMT</pubDate><media:content url="https://andrewzc.com/content/images/2018/07/spring-by-pivotal-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://andrewzc.com/content/images/2018/07/spring-by-pivotal-1.png" alt="A Simple SpringBoot Test Example"><p><strong>Introduction</strong></p>
<ul>
<li>This series guides you on writing a simple spring boot unit test from scratch.</li>
</ul>
<p>Let's generate a SpringBoot Application by using <a href="https://start.spring.io/">Spring Initialzr</a> built by the lovely people at Pivotal!</p>
<p>The only dependencies we will need is an in-memory database H2 for now. Being an in-memory database, this means that everytime the application is restarted, all previous transactions/records will be flushed. This makes it great for caching purposes, just like Redis.</p>
<p>Below is an example of how Spring Initialzr looks like:</p>
<p><img src="https://andrewzc.com/content/images/2018/08/Screen-Shot-2018-07-24-at-17.14.20.png" alt="A Simple SpringBoot Test Example"></p>
<p>Let IntelliJ/Eclipse auto-import the necessary dependencies, gradle wrapper, etc. As a reference, our current directory structure will be something as of the following:</p>
<p><img src="https://andrewzc.com/content/images/2018/08/Screen-Shot-2018-07-24-at-17.18.17.png" alt="A Simple SpringBoot Test Example"></p>
<p>Notice that we have both a <code>main</code> and a <code>test</code> directory, indicating that our business logic lives in the <code>main</code> directory and all of our integration/unit tests lives in the <code>test</code> directory.</p>
<p>Looking at the main application, <code>UnitTestApplication</code> in this case, notice that we have <code>@SpringBootApplication</code> annotated. This is important, as our test is entirely dependent on it. Whenever we fire up a unit test, it will try to look for a Spring Context (registered beans) configuration, and all beans registered in their respective configurations are registered through this annotation.</p>
<p>Now, let's create a package named <code>service</code> and within that package, we will create a service class named <code>HelloWorldService</code>. Now, let's add a method to this service class:</p>
<pre><code class="language-java">@Service
public class HelloWorldService {

    public HelloWorldService() {}

    public String sayHello() {
        return &quot;Hello World&quot;;
    }
}
</code></pre>
<p>Very simple, all this service does is say <strong>Hello World</strong>!</p>
<p>Within our test directory, we do the same by creating a new package named <code>service</code>, but now, we create a test service class named <code>HelloWorldTest</code>. It is important that both the <code>main</code> and <code>test</code> shares the same folder structure, because as our code scales and complexity grows, we will begin to have many different configurations, services and the structure of folders will determine where the test looks for these configurations!!!</p>
<p>So, let's create our test class:</p>
<pre><code class="language-java">@RunWith(SpringRunner.class)
public class HelloWorldServiceTest {

    private HelloWorldService helloWorldService;

    @Before
    public void before() {
        this.helloWorldService = new HelloWorldService();
    }

    @Test
    public void testSayHelloWorld() {
        Assertions.assertThat(helloWorldService.sayHello()).isEqualToIgnoringCase(&quot;hello world&quot;);
    }
</code></pre>
<p>In this class, we annotated it with <code>@RunWith(SpringRunner.class)</code>, The <code>@RunWith</code> is specific to JUnit and it tells Spring which strategy to use to fire up Spring Context, in this case, <code>SpringRunner.class</code>.</p>
<p>If you have seen a SpringBoot test, you might say that wheres is the <code>@SpringBootTest</code> annotation? Remember carefully! We are doing a unit test here, so there is no need to fire the entire Spring Context up. As a reference, the <code>@SpringBootTest</code> tells the test to load the entire Spring Context (beans) everytime this test is fired.</p>
<p>The reason we do not need this is because all we are testing is whether <code>HelloWorldService.sayHello()</code> will <code>return &quot;Hello World</code>. We do need require other configuration dependencies in cases like unit tests.</p>
<p>The <code>@Before</code> annotation, specific to JUnit tells the test that before testing a method, run this configuration. In our case, we are instantiating our service class giving it a new reference.</p>
<p>Then, the <code>@Test</code> annotation is the method that we are actually testing. We used the <code>assertJ</code> library and expect that the return method of <code>helloWorldService.sayHello()</code> should return the correct response.</p>
<p>Voila! We just completed a simple unit test in SpringBoot. There is a lot to understand since everything is hidden behind these annotations but this is precisely why it makes Spring Boot so powerful and easy to get started with what you need.</p>
<p>This is my first post, and I hope my explanations have helped as I am only about a year into learning SpringBoot.</p>
<p>I will be continuously posting my frustrations and solutions I've found as well as how I came to these solutions.</p>
]]></content:encoded></item></channel></rss>