Making Camel upgrades as light as a breeze


Upgrading a software application to a newer version is never a trivial task and leads often to a manual time-consuming process. That’s why the Red Hat build of Apache Camel aims to simplify the process and minimize effort by offering tools for automated migration. The solution varies depending on the flavor of the project. Camel Extensions for Quarkus relies on different commands than the Camel for Spring Boot. The underlying layer takes advantage of the  OpenRewrite ecosystem in both cases.

Basic concepts

Let’s concentrate on the basic aspects of the automatic migrations.

  • Recipes 
    Recipes are the cornerstone of OpenRewrite. Recipe serves as a smallest unit covering a simple change in the source code. Recipes are cumulative and relate to a specific version. You can see recipes for Red Hat build of Apache Camel in the upstream repository .
  • Tool output 
    OpenRewrite tool logs information on the console output. There you can find details about source files modified by the recipes.
  • Limitations 
    Keep in mind that only the files within the project itself are migrated. In case that the BOM version is inherited i.e. through a parent module, the BOM version won’t be changed even though the sources of the project will be migrated to a target version. That may break the project until the parent module is migrated as well. 

Red Hat build of Apache Camel on Quarkus

Upgrade of Camel Extensions for Quarkus is covered by the Quarkus CLI tool by running the update command, introduced in Red Hat build of Quarkus 2.13

The update command brings several benefits.

  • Automates upgrade of project dependencies.
  • Upgrades source code (in cases, where automatization can be applied).
  • Allows migration to the latest LTS version while skipping some LTS streams entirely.
  • The latest recipes are available to the CLI tool immediately with the new release.

Let’s explain a special endpoint used by Quarkus CLI tool for keeping track of released versions, called registry:

  • Quarkus tooling has to be aware of the latest releases of Red Hat build of Quarkus and Camel Extensions for Quarkus (part of Red Hat build of Apache Camel). The update command contacts Quarkus registry to get up-to-date information about recent releases.

The Quarkus CLI tool drives the workflow of the recipes:

  • Appropriate recipes are selected according to the registry, target version and the recipes version (more details are shared in the demo chapter). The selected recipes are handed over to the OpenRewrite tooling. OpenRewrite applies the recipes on the source code thereby upgrading it.
  • The logged output shows the detailed information about the process itself.

 

A brief look at the upgrade guides, such as Apache Camel 3.x Upgrade Guide or Apache Camel 4.x Upgrade Guide confirms that upgrading can involve a significant amount of effort. Migrating across multiple versions of Camel is even more challenging and adds an extra amount of complexity to the process.

 

Demo time

Let’s not waste any more time with the theory and let’s better discuss a practical example of the Red Hat build of Apache Camel upgrade using Quarkus CLI. 

The whole process is as simple as executing a single command from the root directory of the migrated project.

#Migration to the latest version of Camel Extensions for Quarkus (in the time of Red Hat build of Quarkus 3.15.2)
mvn io.quarkus.platform:quarkus-maven-plugin:3.15.2:update 

The update command recognizes several parameters. Let’s mention the most important ones:

  • stream – CLI tool migrates the application to the latest available version (of Red Hat build of Apache Camel) by default. To override such behavior, please append parameter stream to update the project to a particular stream. Here is the example of such command:
#Migrate to the latest version of Camel Extensions for Quarkus from stream 3.8.x
mvn io.quarkus.platform:quarkus-maven-plugin:3.15.2:update -Dstream=3.8
  • quarkusUpdateRecipes – the update command applies the latest recipes distributed as a maven dependency io.quarkus:quarkus-update-recipes. The latest version is used by default. Sometimes, it might be handy to specify a different target version. 
#Migrate to the latest version of Camel Extensions for Quarkus from stream 3.8.x using the specific version of recipes 1.0.22
mvn io.quarkus.platform:quarkus-maven-plugin:3.15.2:update -Dstream=3.15 -DquarkusUpdateRecipes=1.0.22

Let’s run a migration command on the testing project. The multi-module testing project imports the Red Hat build of Quarkus BOM of versioncom.redhat.quarkus.platform:quarkus-bom:3.2.10.-Final-redhat-00002

 

Migrate to the next LTS version

Let’s migrate to the next LTS version (which is 3.8.x in our case). The command is

mvn io.quarkus.platform:quarkus-maven-plugin:3.15.2:update -Dstream=3.8

When the migration process starts, the update command prints the information obtained from the registry into a console output. Here is our output:

[INFO] Looking for the newly published extensions in registry.quarkus.io
[INFO] Detected project Java version: 17
[INFO] Detected project Java version: 17
[INFO] Instructions to update this project from '3.2.10.Final-redhat-00002' to '3.8.6'

As you can see in the snippet above, something appears to be wrong. Red Hat build of Quarkus is upgraded from 3.2.10.Final-redhat-00002 (product version) to 3.8.6 (community version), which is usually not intended.

We already discussed the importance of the quarkus registry for obtaining the latest version of the projects. By default, only the upstream registry is available to the CLI tool. If we need the product registry to be used as well, we need to create a config.yaml file in the $HOME/.quarkus directory. For more details, please follow the guide. The common registry configuration should look like:

registries:
  - registry.quarkus.redhat.com
  - registry.quarkus.io

With the proper registry configuration, the output is correct.

[INFO] Looking for the newly published extensions in registry.quarkus.io
[INFO] Detected project Java version: 17
[INFO] Detected project Java version: 17
[INFO] Instructions to update this project from '3.2.10.Final-redhat-00002' to '3.8.6.SP2-redhat-00002'

Let’s give the tool some time to finish. 

The process contains several phases:

  • Initialization of the tool (fetching the latest recipes via maven and information about versions via registry).
  • Application of the recipes by the OpenRewrite tooling. You can see logged messages about each change made by the recipes. For example 
[WARNING] Changes have been made to customizer/src/test/java/org/apache/camel/quarkus/component/exchange/it/ExchangeLoggerCustomizer.java by:
[WARNING] io.quarkus.updates.camel.camel44.CamelQuarkusMigrationRecipe
[WARNING] org.apache.camel.upgrade.camel44.CamelMigrationRecipe
[WARNING] org.apache.camel.upgrade.camel44.CamelCoreRecipe
  • Logged summary of the migration. The following screenshot shows the end of the successful migration.

 

Output from upgrade (3.2.x to 3.8.x)

Migrate to the latest LTS version (skipping a version)

Let’s migrate to the latest LTS version (which is 3.15.x at this time). Our source project is based on 3.2.x. Upgrading to 3.8.x is unnecessary, the tool can directly upgrade to any newer version (3.15.x in our case).  The command is 

quarkus.platform:quarkus-maven-plugin:3.15.2:update

Quarkus tooling makes sure that all recipes required for the migration to stream 3.8.x and then all recipes required for the migration to stream 3.15.x are used together (in the correct order). The result of the migration is a project based on the Red Hat build of Quarkus 3.15.

[INFO] Looking for the newly published extensions in registry.quarkus.io
[INFO] Detected project Java version: 17
[INFO] Detected project Java version: 17
[INFO] Instructions to update this project from '3.2.10.Final-redhat-00002' to '3.15.2.redhat-00003'

 

Multi module projects

Multi-module maven projects were causing problems in the past.  The OpenRewrite migration tooling added a delayed execution to cover such cases. Currently, when upgrading a multi-module project, the OpenRewrite tooling postpones the migration of all child modules until the end. When the last module is being processed, all delayed migrations are executed. As a result, there’s no need for the special handling of multi-module projects.

If a problem, caused by the structure of a multi-module project appears, you can use a custom script like the following one, to force migration of each module one by one.

find . -type f -name "pom.xml" -execdir sh -c 'mvn io.quarkus.platform:quarkus-maven-plugin:3.15.2:update -N' \;

 

Manual validation

Let me highlight the final step of the process. It’s essential to manually confirm that the project builds without errors and that all tests pass before introducing the upgraded version into production.

Here are the basic steps, which will guide you through the process. 

  1. Verify that the migration was executed for the intended versions. (You can simply do that by checking the beginning of the console output logged by the CLI tool)
  2. Even though we try to cover all necessary upgrade changes by the recipes, in some cases it might not be possible. If there is a compilation error or any test fails, address the missing migration step by manually following the migration guides
    (typically Camel migration guideCamel-quarkus migration guide and Quarkus migration guide).
  3. When the project is compilable and all tests successfully pass, migration is done. You can start using the migrated application with all benefits brought by the newer version.

 

Red Hat Build of Apache Camel for Spring Boot

To upgrade Red Hat Apache Camel for Spring Boot to the latest community version 4.8.0, OpenRewrite standards can be used. The recommended approaches are the following:

  • Upgrade via CLI using Maven, for example:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:LATEST,org.apache.camel.upgrade:camel-upgrade-recipes:LATEST -Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3,org.apache.camel.upgrade.camel40.CamelMigrationRecipe,org.apache.camel.upgrade.camel40.CamelMigrationRecipe,org.apache.camel.upgrade.camel44.CamelMigrationRecipe,org.apache.camel.upgrade.camel45.CamelMigrationRecipe,org.apache.camel.upgrade.camel46.CamelMigrationRecipe,org.apache.camel.upgrade.camel47.CamelMigrationRecipe
  • Configuring the OpenRewrite Maven Plugin on the project pom.xml, for example, an upgrade Maven profile could be used for this purpose:


   
       upgrade
       
           
               upgrade
           
       
       
           
               
                   org.openrewrite.maven
                   rewrite-maven-plugin
                   5.46.1
                   
                       ${maven.multiModuleProjectDirectory}/rewrite.yaml
                       true
                       
                           org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3
                           org.apache.camel.upgrade.camel40.CamelMigrationRecipe
                           org.apache.camel.upgrade.camel44.CamelMigrationRecipe
                           org.apache.camel.upgrade.camel45.CamelMigrationRecipe
                           org.apache.camel.upgrade.camel46.CamelMigrationRecipe
                           org.apache.camel.upgrade.camel47.CamelMigrationRecipe
                           org.apache.camel.upgrade.camel48.CamelBOMMigrationRecipe
                       
                   
                   
                       
                           org.openrewrite.recipe
                           rewrite-spring
                           5.24.1
                       
                       
                           org.apache.camel.upgrade
                           camel-upgrade-recipes
                           4.8.0
                       
                   
               
           
       
   

Once the profile is added to the pom.xml, the upgrade can be executed via 

mvn -Pupgrade rewrite:run

The recipes used in the previous examples are the following:

  • org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3 The UpgradeSpringBoot_3_x recipe takes care of the following migrations:
    • Spring Boot upgrades (2.7.x to 3.3.y, the y micro version depends on the rewrite-spring version)
    • Java 17 upgrades
    • javax to jakarta namespace migration
  • org.apache.camel.upgrade.camel4x.CamelMigrationRecipe The CamelMigrationRecipe takes care of Apache Camel 4.0 to Apache Camel 4.x migration, where 4.x is the latest recipe defined in the artifact camel-upgrade-recipes. These recipes can be found in the Camel Upgrade Recipes repository in particular, the name of each recipe can be specified, for example, the upgrade to Camel 4.4 from Camel 3.20 is done with the recipes org.apache.camel.upgrade.camel40.CamelMigrationRecipe and org.apache.camel.upgrade.camel44.CamelMigrationRecipe.

Therefore the two approaches will migrate Apache Camel syntax and Spring Boot.

A bundled approach for Apache Camel for Spring Boot

Unlike the quarkus upgrade CLI tool, the Camel upgrade recipes do not offer all the features, especially for Camel Spring Boot, but a custom recipe can be created that will provide similar features to the Quarkus one.

For example, to upgrade from Camel 3.20.1.redhat-00109 and Spring Boot 2.7.18, to the latest available Red Hat build of Apache Camel for Spring Boot build 4.8.0.redhat-00022 and Spring Boot 3.3.6 the following recipe.yaml can be used:

---
type: specs.openrewrite.org/v1beta/recipe
name: org.apache.camel.upgrade.camel48.CamelSpringBootMigrationRecipe
displayName: Migrates `camel Spring Boot` application to `Camel Spring Boot 4.8`
description: Migrates `camel Spring Boot` application to `Camel Spring Boot 4.8`
recipeList:
 - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_3
 - org.apache.camel.upgrade.camel47.CamelMigrationRecipe
 - org.apache.camel.upgrade.camel46.CamelMigrationRecipe
 - org.apache.camel.upgrade.camel45.CamelMigrationRecipe
 - org.apache.camel.upgrade.camel44.CamelMigrationRecipe
 - org.apache.camel.upgrade.camel40.CamelMigrationRecipe
 - org.openrewrite.maven.UpgradeDependencyVersion:
     groupId: '*camel*'
     artifactId: 'camel-spring-boot-bom'
     newVersion: 4.8.0.redhat-00022

This recipe is a collection of the Spring Boot recipe and the Camel recipes discussed in the previous chapter, moreover, the UpgradeDependencyVersion recipe will upgrade the Camel Spring Boot platform BOM references.

To use this recipe, a myRecipe.yaml can be created in the root of a Maven project with the CamelSpringBootMigrationRecipe content and the pom.xml profile can be updated accordingly:


   upgrade
   
       
           upgrade
       
   
   
       
           
               org.openrewrite.maven
               rewrite-maven-plugin
               5.46.1
               
                   ${maven.multiModuleProjectDirectory}/myRecipe.yaml
                   true
                   
                       org.apache.camel.upgrade.camel48.CamelSpringBootMigrationRecipe
                   
               
               
                   
                       org.openrewrite.recipe
                       rewrite-spring
                       5.24.1
                   
                   
                       org.apache.camel.upgrade
                       camel-upgrade-recipes
                       4.8.0
                   
               
           
       
   

Summary

You should now have a solid understanding of the CLI tools and their benefit for the migration process. While it may not make migrations effortless, it serves as an essential first step toward simplifying and streamlining the whole journey.



Source link

Related Posts

About The Author

Add Comment