Jekyll v4.0.02024-03-07T03:44:52Zhttps://tech.asimio.net/Asimio TechOrlando L Oteroorlando.otero@asimio.netWriting integration tests with Testcontainers and Cosmos DB Docker emulator for Spring Boot applications2024-02-28T00:00:00Zhttps://tech.asimio.net/2024/02/28/Cosmos-DB-Spring-Boot-2-Integration-Tests-Testcontainers.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p>As part of your organization’s modernization effort, your team is writing <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications that store data to, and retrieve data from <span class="codeRef">Azure</span> <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span>s instead of relational databases.</p>
<p>You might have <a href="https://tech.asimio.net/2023/08/28/Writing-Dynamic-Azure-Cosmos-DB-Queries-Spring-Data-Cosmos-ReactiveCosmosTemplate.html">written dynamic Cosmos DB queries using Spring Data Cosmos and ReactiveCosmosTemplate</a>.</p>
<p>Your integration tests might be connecting to a dedicated <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> hosted in <span class="codeRef">Azure</span>, which increases your organization’s subscription cost.</p>
<p>You could instead be using a dedicated <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> emulator <span class="codeRef">Docker</span> container you would need to make sure is running, and which ports it listens on, before you <a href="https://tech.asimio.net/2023/09/08/Cosmos-DB-Spring-Boot-2-Integration-Tests-Seed-Data.html">seed test data</a> and run every test.</p>
<p>Or you might not have integration tests at all. But you also know integration testing is one of the keys to deploy often and with confidence.</p>
<p>This blog post shows you how to write integration tests with <span class="codeRef">Testcontainers</span> and the <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> <span class="codeRef">Docker</span> emulator for <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications. <br />
Listening on available ports instead of hard-coding them. And importing the <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> self-signed emulator certificate to a temporal <span class="codeRef">Java</span> truststore your tests could use. <br />
All these automated.</p>
<p><img src="https://tech.asimio.net/images/springboot-testcontainers-cosmosdb-docker-emulator.png" alt="Testcontainers and Cosmos DB Docker emulator" title="Testcontainers and Cosmos DB Docker emulator" class="center-image" /></p>
Deploying Spring Boot applications from a Maven repository to Azure Spring Apps with Azure CLI2023-10-26T00:00:00Zhttps://tech.asimio.net/2023/10/26/Deploy-Spring-Boot-Azure-Spring-Apps-Maven-Repository-Azure-CLI.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p><span class="codeRef">Azure</span> <span class="codeRef">Spring</span> <span class="codeRef">Apps</span> is a platform as a service (<span class="codeRef">PaaS</span>) and one of the services <span class="codeRef">Azure</span> offers for your organization to run <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications.</p>
<p>With very little effort, you can provision the <span class="codeRef">Azure</span> <span class="codeRef">Spring</span> <span class="codeRef">Apps</span> infrastructure required to deploy and run <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> Web, RESTful, Batch, etc. applications. This allows your team to spend more time with the applications’ business logic.</p>
<p>This blog post covers provisioning the <span class="codeRef">Azure</span> <span class="codeRef">Spring</span> <span class="codeRef">Apps</span> infrastructure using <span class="codeRef">Azure</span> <span class="codeRef">CLI</span> to deploy a <a href="https://tech.asimio.net/2020/09/01/Using-Azure-Blob-Storage-as-your-Maven-Repository.html">Spring Boot application previously stored in a Maven repository hosted in an Azure Blob Storage container</a>.</p>
<p><img src="https://tech.asimio.net/images/azure-spring-apps-deploy-spring-boot.png" alt="Deploying Spring Boot applications to Azure Spring Apps" title="Deploying Spring Boot applications to Azure Spring Apps" class="center-image" /></p>
Writing integration tests with GreenMail and Jsoup for Spring Boot applications that send Emails2023-10-13T00:00:00Z2023-11-15T00:00:00Zhttps://tech.asimio.net/2023/10/13/GreenMail-Jsoup-Spring-Boot-2-Integration-Tests-Emails.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p>Your organization implemented and deployed <a href="https://tech.asimio.net/2023/09/24/Email-Spring-Boot-2-Thymeleaf.html">Spring Boot applications to send emails from Thymeleaf templates</a>.</p>
<p>Let’s say they include reports with confidential content, intellectual property, or sensitive data. Is your organization testing these emails?</p>
<p>How would you verify these emails are being sent to the expected recipients?</p>
<p>How would you assert these emails include the expected data, company logo, and/or file attachments?</p>
<p>This blog post shows you how to write integration tests with <span class="codeRef">GreenMail</span> and <span class="codeRef">Jsoup</span> for <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications that send emails.</p>
<p><img src="https://tech.asimio.net/images/send-report-email-controller-integration-test.png" alt="Integration tests with GreenMail and Jsoup" title="Integration tests with GreenMail and Jsoup" class="center-image" /></p>
Sending Emails with Spring Boot 2 and Thymeleaf2023-09-24T00:00:00Zhttps://tech.asimio.net/2023/09/24/Email-Spring-Boot-2-Thymeleaf.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p>Your team used <span class="codeRef">Java</span> and <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> to implement Logistics functionality, or a Hotel reservation system, or an e-commerce Shopping Cart, you name it.</p>
<p>Now Business folks would like to receive emails with daily shipment reports, or weekly bookings, or abandoned shopping carts.</p>
<p>Business people would like to get emails with consolidated data to take decisions based on these reports.</p>
<p><span class="codeRef">Spring</span> Framework, specifically <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> includes seamless integration with template engines to send <span class="codeRef">HTML</span> and/or text emails.</p>
<p>This blog post covers how to send <span class="codeRef">HTML</span> and text emails using <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> and <span class="codeRef">Thymeleaf</span> template engine.</p>
<p><img src="https://tech.asimio.net/images/springboot2-thymeleaf-email.png" alt="Sending HTML and text emails with Spring Boot and Thymeleaf" title="Sending HTML and text emails with Spring Boot and Thymeleaf" class="center-image" /></p>
Extract Certificate and add it to a Truststore Programmatically2023-09-10T00:00:00Z2024-02-28T00:00:00Zhttps://tech.asimio.net/2023/09/10/Extract-Certificate-Create-Truststore-Programmatically.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p>A few days ago I was working on the accompanying source code for:</p>
<ul>
<li>
<p><a href="https://tech.asimio.net/2023/09/08/Cosmos-DB-Spring-Boot-2-Integration-Tests-Seed-Data.html">Seeding Cosmos DB Data to run Spring Boot 2 Integration Tests</a></p>
</li>
<li>
<p><a href="https://tech.asimio.net/2023/08/28/Writing-Dynamic-Azure-Cosmos-DB-Queries-Spring-Data-Cosmos-ReactiveCosmosTemplate.html">Writing dynamic Cosmos DB queries using Spring Data Cosmos repositories and ReactiveCosmosTemplate</a></p>
</li>
</ul>
<p>blog posts, and ran into the same issue a few times.</p>
<p>The previously running <code class="highlighter-rouge">azure-cosmos-emulator</code> <span class="codeRef">Docker</span> container wouldn’t start.</p>
<p>I had to run a new <code class="highlighter-rouge">azure-cosmos-emulator</code> container, but every time I ran a new container, the emulator’s <span class="codeRef">PEM</span>-encoded certificate changed. That meant the <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> application failed to start because it couldn’t connect to the <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> anymore. The <span class="codeRef">SSL</span> handshake failed.</p>
<p>A manual solution involved running a <a href="https://tech.asimio.net/resources/code-snippets/add-cosmos-emulator-cert-truststore-bash-shell-script/">bash script that deletes the invalid certificate from the TrustStore, and adds a new one</a> generated during the new <span class="codeRef">Docker</span> container start-up process.</p>
<p>That would be fine if you only need to use this approach once or two during the development phase.</p>
<p>But this manual approach won’t work for running Integration Tests as part of your <span class="codeRef">CI/CD</span> pipeline, regardless if an <code class="highlighter-rouge">azure-cosmos-emulator</code> container is already running, or if you rely on <a href="/2024/02/28/Cosmos-DB-Spring-Boot-2-Integration-Tests-Testcontainers.html">Testcontainers</a> to run a new one.</p>
<div class="alert alert-success" role="alert"><i class="fa fa-check-circle-o" aria-hidden="true"></i> <b>Tip:</b>
Read on to learn <a href="/2024/02/28/Cosmos-DB-Spring-Boot-2-Integration-Tests-Testcontainers.html">how to use Testcontainers to write Integration Tests for Cosmos DB applications</a>.
</div>
<p>This blog post covers how to programmatically extract an <span class="codeRef">SSL</span> certificate from a secure connection and add it to a <span class="codeRef">TrustStore</span> that you can use in your integration tests, for instance.</p>
<div class="alert alert-danger" role="alert"><i class="fa fa-exclamation-circle" aria-hidden="true"></i> <b>Warning:</b>
A word of caution, be aware of adding a self-signed certificate to a production <span class="codeRef">TrustStore</span>. It’s not recommended and you should have very good reasons to do so.
</div>
<p><img src="https://tech.asimio.net/images/diff-cosmos-emulator-certificates.png" alt="New Cosmos DB emulator containers generate different PEM files" title="New Cosmos DB emulator containers generate different PEM files" /></p>
Seeding Cosmos DB Data to run Spring Boot 2 Integration Tests2023-09-08T00:00:00Z2024-02-28T00:00:00Zhttps://tech.asimio.net/2023/09/08/Cosmos-DB-Spring-Boot-2-Integration-Tests-Seed-Data.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="overview">1. OVERVIEW</h3>
<p>Let’s say you are deploying your <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> <span class="codeRef">RESTful</span> applications to <span class="codeRef">Azure</span>.</p>
<p>Some of these <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications might have been modernization rewrites to use <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> instead of a relational database.</p>
<p>You might have even <a href="https://tech.asimio.net/2023/08/28/Writing-Dynamic-Azure-Cosmos-DB-Queries-Spring-Data-Cosmos-ReactiveCosmosTemplate.html">added support to write dynamic Cosmos DB queries using Spring Data Cosmos</a>. And let’s also assume you wrote <a href="https://tech.asimio.net/2019/04/08/Splitting-Unit-and-Integration-Tests-using-Maven-and-Surefire-plugin.html">unit tests for REST controllers, business logic, and utility classes</a>.</p>
<p>Now you need to write integration tests to verify the interaction between different parts of the system work well, including retrieving from, and storing to, a <span class="codeRef">NoSQL</span> database like <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span>.</p>
<p>This blog post shows you how to write a custom <span class="codeRef">Spring</span>’s <span class="codeRef">TestExecutionListener</span> to seed data in a <span class="codeRef">Cosmos</span> database container. Each <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> integration test will run starting from a known <span class="codeRef">Cosmos</span> container state, so that you won’t need to force the tests to run in a specific order.</p>
<p><img src="https://tech.asimio.net/images/integration-tests-spring-boot-cosmos-db-seed-data.png" alt="Seed data for integration tests in Spring Boot and Azure Cosmos DB applications" title="Seed data for integration tests in Spring Boot and Azure Cosmos DB applications" class="center-image" /></p>
Writing dynamic Cosmos DB queries using Spring Data Cosmos repositories and ReactiveCosmosTemplate2023-08-28T00:00:00Z2024-02-28T00:00:00Zhttps://tech.asimio.net/2023/08/28/Writing-Dynamic-Azure-Cosmos-DB-Queries-Spring-Data-Cosmos-ReactiveCosmosTemplate.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="introduction">1. OVERVIEW</h3>
<p>Let’s say you need to write a <span class="codeRef">RESTful</span> endpoint that takes a number of request parameters, and use them to filter out data from a database.</p>
<p>Something like:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/api/users?firstName=...&lastName=...
</code></pre></div></div>
<p>Some of the request parameters are optional, so you would only include query conditions in each <span class="codeRef">SQL</span> statement depending on the request parameters sent with each request.</p>
<p>You’ll be writing dynamic <span class="codeRef">SQL</span> queries.</p>
<p>I have covered different solutions when the data comes from a relational database:</p>
<ul>
<li><a href="https://tech.asimio.net/2021/07/26/Writing-dynamic-SQL-queries-using-Spring-Data-JPA-Repositories-and-EntityManager.html">Writing dynamic SQL queries using Spring Data JPA repositories and EntityManager</a></li>
<li><a href="https://tech.asimio.net/2020/11/21/Implementing-dynamic-SQL-queries-using-Spring-Data-JPA-Specification-and-Criteria-API.html">Writing dynamic SQL queries using Spring Data JPA Specification and Criteria API</a></li>
<li><a href="https://tech.asimio.net/2023/01/31/Writing-dynamic-SQL-queries-using-Spring-Data-JPA-Repositories-Hibernate-and-Querydsl.html">Writing dynamic SQL queries using Spring Data JPA repositories and Querydsl</a></li>
</ul>
<p>But what if the data store is not a relational database? What if the data store is a <span class="codeRef">NoSQL</span> database?</p>
<p>More specifically, what if the database is <span class="codeRef">Azure</span> <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span>?</p>
<p>This tutorial teaches you how to extend <span class="codeRef">Spring</span> <span class="codeRef">Data</span> <span class="codeRef">Cosmos</span> for your repositories to access the <span class="codeRef">ReactiveCosmosTemplate</span> so that you can write dynamic <span class="codeRef">Cosmos</span> <span class="codeRef">DB</span> queries.</p>
<p><img src="https://tech.asimio.net/images/spring-data-and-cosmos-db.png" alt="Spring Data and Azure Cosmos DB" title="Spring Data and Azure Cosmos DB" class="center-image" /></p>
Unit testing Spring's TransationTemplate, TransactionCallback with JUnit and Mockito2023-08-21T00:00:00Zhttps://tech.asimio.net/2023/08/21/Unit-Testing-Spring-TransationTemplate-TransactionCallback-JUnit-Mockito.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="introduction">1. OVERVIEW</h3>
<p>Let’s say you had to write a Business Service implementation using <span class="codeRef">Spring</span>’s <span class="codeRef">TransactionTemplate</span> instead of the <span class="codeRef">@Transactional</span> annotation.</p>
<p>As a quick example, you need to retrieve a film reviews from external partners using <span class="codeRef">RESTful</span> <span class="codeRef">APIs</span>. <br />
You also need to update this film-related relational database tables rows. <br />
And lastly, you need to publish a <span class="codeRef">JMS</span> message for interested parties to process these changes.</p>
<p>A made up example, but the point is that you need to write a Business Logic that involves sending <span class="codeRef">RESTful</span> <span class="codeRef">API</span> requests to external services, executing multiple <span class="codeRef">SQL</span> statements, and publishing a message to a <span class="codeRef">JMS</span> Queue.</p>
<p>You have already realized that the <span class="codeRef">RESTful</span> <span class="codeRef">API</span> requests and publishing a <span class="codeRef">JMS</span> message shouldn’t be part of the <span class="codeRef">JDBC</span> transaction, so you end up using <span class="codeRef">TransactionTemplate</span>, and a code snippet similar to:</p>
Pushing Spring Boot 2 Docker images to Microsoft ACR2023-08-10T00:00:00Z2023-08-10T00:00:00Zhttps://tech.asimio.net/2023/08/10/Pushing-Spring-Boot-2-Docker-images-to-Microsoft-ACR.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="introduction">1. OVERVIEW</h3>
<p><a href="https://tech.asimio.net/2018/08/10/Simplifying-packaging-Spring-Boot-2-applications-into-Docker-images-using-Google-Jib.html">Google’s jib-maven-plugin</a>, <a href="https://tech.asimio.net/2016/04/05/Microservices-using-Spring-Boot-Jersey-Swagger-and-Docker.html#package-docker-image">Spotify’s docker-maven-plugin</a>, and <span class="codeRef">spring-boot-maven-plugin</span> since <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> 2.3 help you to build <span class="codeRef">Docker</span> images for your <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications.</p>
<p>You might also want to store these <span class="codeRef">Docker</span> images in a private <span class="codeRef">Docker</span> registry.</p>
<p><span class="codeRef">Microsoft</span>’s Azure Container Registry (<span class="codeRef">ACR</span>) is a cheap option to store both, public and private <span class="codeRef">Docker</span> images.</p>
<p>It would even makes more sense to use <span class="codeRef">ACR</span> if your organization is already invested in other <span class="codeRef">Azure</span> services.</p>
<p><img src="https://tech.asimio.net/images/push-azure-acr-repository.png" alt="Storing a Docker image in an Azure Container Registry" title="Storing a Docker image in an Azure Container Registry" class="center-image" />
<em>Spring Boot application in a Docker image stored in a private Azure Container Registry</em></p>
<p>This tutorial covers setting up the <span class="codeRef">Azure</span> infrastructure and <span class="codeRef">Maven</span> configuration to push a <span class="codeRef">Docker</span> image to a private <span class="codeRef">ACR</span> repository.</p>
Configuring JSON-Formatted Logs in Spring Boot applications with Slf4j, Logback and Logstash2023-08-01T00:00:00Zhttps://tech.asimio.net/2023/08/01/Formatting-JSON-Logs-in-Spring-Boot-2-applications-with-Slf4j-Logback-and-Logstash.htmlOrlando L Oteroorlando.otero@asimio.net
<h3 id="introduction">1. OVERVIEW</h3>
<p>Logging is an important part of application development.</p>
<p>It helps you to troubleshoot issues, to follow execution flows, not only inside the application, but also when spawning multiple requests across different services.</p>
<p>Logging also helps you to capture data and replicate production bugs in a development environment.</p>
<p>Often times, searching logs efficiently is a daunting task. That’s why there are plenty of Log Aggregators such as <span class="codeRef">Splunk</span>, <span class="codeRef">ELK</span>, <span class="codeRef">Datadog</span>, <span class="codeRef">AWS</span> <span class="codeRef">CloudWatch</span>, and many more, that help with capturing, standardizing, and consolidating logs to assist with log indexing, analysis, and searching.</p>
<p>Standard-formatted log messages like:</p>
<pre><code class="language-log">2023-08-01 12:43:44.421 INFO 73710 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
</code></pre>
<p>are easy to read by Engineers but not so easy to parse by Log Aggregators, especially if the log format keeps changing.</p>
<p>This blog post helps you to configure <span class="codeRef">Spring</span> <span class="codeRef">Boot</span> applications to format log messages as <span class="codeRef">JSON</span> using <span class="codeRef">Slf4j</span>, <span class="codeRef">Logback</span> and <span class="codeRef">Logstash</span>, and having them ready to be fed to Log Aggregators.</p>
<p><img src="https://tech.asimio.net/images/springboot-logback-json.png" alt="Spring Boot JSON-formatted logs with Slf4j, Logback, and Logstash" title="JSON-formatted logs in Spring Boot applications using Slf4j, Logback, and Logstash" class="center-image" /></p>