This is an automated email from the ASF dual-hosted git repository. fmariani pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-upgrade-recipes.git
commit 588dad1c1299b2ddcff10ed6a611d193bd56ab92 Author: Croway <federico.mariani.1...@gmail.com> AuthorDate: Fri Feb 21 14:13:59 2025 +0100 Configurations upgrade --- .../src/main/resources/META-INF/rewrite/4.10.yaml | 1 + .../main/resources/META-INF/rewrite/latest.yaml | 1 + .../upgrade/CamelPropertiesAndYamlUpdate.java | 151 +++++++++++++++++++++ .../upgrade/PatternMatcherChangePropertyKey.java | 127 +++++++++++++++++ .../main/resources/META-INF/rewrite/latest.yaml | 1 + .../apache/camel/upgrade/CamelPropertiesTest.java | 91 +++++++++++++ 6 files changed, 372 insertions(+) diff --git a/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/4.10.yaml b/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/4.10.yaml index cbac268..784e03f 100644 --- a/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/4.10.yaml +++ b/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/4.10.yaml @@ -28,6 +28,7 @@ recipeList: - org.apache.camel.upgrade.camel45.CamelMigrationRecipe - org.apache.camel.upgrade.camel44.CamelMigrationRecipe - org.apache.camel.upgrade.camel40.CamelMigrationRecipe + - org.apache.camel.upgrade.CamelPropertiesAndYamlUpdate - org.openrewrite.maven.UpgradeDependencyVersion: groupId: '*camel*' artifactId: 'camel-spring-boot-bom' diff --git a/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml b/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml index 3dd3c1b..0ec8f3f 100644 --- a/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml +++ b/camel-spring-boot-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml @@ -30,6 +30,7 @@ recipeList: - org.apache.camel.upgrade.camel40.CamelMigrationRecipe - org.apache.camel.upgrade.UpgradeToJava17 - org.apache.camel.upgrade.JavaVersion17 + - org.apache.camel.upgrade.CamelPropertiesAndYamlUpdate - org.openrewrite.maven.UpgradeDependencyVersion: groupId: '*camel*' artifactId: 'camel-spring-boot-bom' diff --git a/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/CamelPropertiesAndYamlUpdate.java b/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/CamelPropertiesAndYamlUpdate.java new file mode 100644 index 0000000..7927154 --- /dev/null +++ b/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/CamelPropertiesAndYamlUpdate.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.upgrade; + +import org.openrewrite.Recipe; +import org.openrewrite.properties.ChangePropertyKey; +import org.openrewrite.yaml.ChangeKey; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Recipe for updating Apache Camel configuration properties and YAML keys. + * <p> + * This recipe handles the migration of Apache Camel configuration keys according to updated + * naming conventions while preserving their values. It focuses on three main types of changes: + * <ul> + * <li>Converting 'camel.springboot.*' prefixes to 'camel.main.*'</li> + * <li>Converting 'camel.routeController.*' to lowercase 'camel.routecontroller.*'</li> + * <li>Moving tracing-related properties from 'camel.main' to 'camel.trace'</li> + * <li>Preserving specific properties that should keep the 'springboot' prefix</li> + * </ul> + * + */ +public class CamelPropertiesAndYamlUpdate extends Recipe { + + @Override + public String getDisplayName() { + return "Change Apache Camel properties key"; + } + + @Override + public String getDescription() { + return "Change Apache Camel properties and YAML keys leaving the value intact."; + } + + @Override + public List<Recipe> getRecipeList() { + List<Recipe> recipes = new ArrayList<>(); + // camel.springboot.* to camel.main.* updates + UpdateSpringBootToMain(recipes); + + // camel.routeController.* to camel.routecontroller.* updates + routeController(recipes); + // camel.main to camel.trace + trace(recipes); + + // Some properties need the springboot prefix, let's fix those + FixMainToSpringBoot(recipes); + + return recipes; + } + + private void trace(List<Recipe> recipes) { + fullConfigurationUpdate(recipes, Map.of( + "camel.main.backlogTracing", "camel.trace.enabled", + "camel.main.backlogTracingStandby", "camel.trace.backlogTracingStandby", + "camel.main.backlogTracingTemplates", "camel.trace.backlogTracingTemplates")); + } + + private void routeController(List<Recipe> recipes) { + Map<String, String> oldNewProperties = new HashMap<>(); + // Special configurations + oldNewProperties.putAll(Map.of( + "camel.main.routeControllerSuperviseEnabled", "camel.routecontroller.enabled", + "camel.springboot.routeControllerSuperviseEnabled", "camel.routecontroller.enabled", + "camel.main.backlogTracing", "camel.trace.enabled", + "camel.main.backlogTracingStandby", "camel.trace.backlogTracingStandby", + "camel.main.backlogTracingTemplates", "camel.trace.backlogTracingTemplates" + )); + // Common configurations + oldNewProperties.putAll(Map.of( + "camel.main.routeControllerInitialDelay", "camel.routecontroller.initialDelay", + "camel.main.routeControllerBackOffDelay", "camel.routecontroller.backOffDelay", + "camel.main.routeControllerBackOffMaxAttempts", "camel.routecontroller.backOffMaxAttempts", + "camel.main.routeControllerBackOffMaxDelay", "camel.routecontroller.backOffMaxDelay", + "camel.main.routeControllerBackOffMaxElapsedTime", "camel.routecontroller.backOffMaxElapsedTime", + "camel.main.routeControllerBackOffMultiplier", "camel.routecontroller.backOffMultiplier", + "camel.main.routeControllerIncludeRoutes", "camel.routecontroller.includeRoutes", + "camel.main.routeControllerExcludeRoutes", "camel.routecontroller.excludeRoutes", + "camel.main.routeControllerThreadPoolSize", "camel.routecontroller.threadPoolSize" + ) + ); + + // sometimes, backoff is mispelled..... + oldNewProperties.putAll(Map.of( + "camel.main.routeControllerBackoffDelay", "camel.routecontroller.backOffDelay", + "camel.main.routeControllerBackoffMaxAttempts", "camel.routecontroller.backOffMaxAttempts", + "camel.main.routeControllerBackoffMaxDelay", "camel.routecontroller.backOffMaxDelay", + "camel.main.routeControllerBackoffMaxElapsedTime", "camel.routecontroller.backOffMaxElapsedTime", + "camel.main.routeControllerBackoffMultiplier", "camel.routecontroller.backOffMultiplier" + )); + + fullConfigurationUpdate(recipes, oldNewProperties); + } + + private static void fullConfigurationUpdate(List<Recipe> recipes, Map<String, String> oldNewProperties) { + for (Map.Entry<String, String> entry : oldNewProperties.entrySet()) { + recipes.add( + new ChangePropertyKey(entry.getKey(), entry.getValue(), + null, null) + ); + recipes.add( + new org.openrewrite.yaml.ChangePropertyKey( + entry.getKey(), entry.getValue(), null, null, null) + ); + } + } + + private void FixMainToSpringBoot(List<Recipe> recipes) { + fullConfigurationUpdate(recipes, Map.of( + "camel.main.main-run-controller", "camel.springboot.main-run-controller", + "camel.main.include-non-singletons", "camel.springboot.include-non-singletons", + "camel.main.warn-on-early-shutdown", "camel.springboot.warn-on-early-shutdown", + "camel.main.mainRunController", "camel.springboot.main-run-controller", + "camel.main.includeNonSingletons", "camel.springboot.include-non-singletons", + "camel.main.warnOnEarlyShutdown", "camel.springboot.warn-on-early-shutdown" + )); + } + + private static void UpdateSpringBootToMain(List<Recipe> recipes) { + recipes.add( + new PatternMatcherChangePropertyKey( + "camel.springboot", "camel.main", List.of( + "camel.springboot.main-run-controller", + "camel.springboot.include-non-singletons", + "camel.springboot.warn-on-early-shutdown" + )) + ); + + recipes.add( + new ChangeKey("$.camel.springboot", "main") + ); + } +} diff --git a/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/PatternMatcherChangePropertyKey.java b/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/PatternMatcherChangePropertyKey.java new file mode 100644 index 0000000..2eb0f63 --- /dev/null +++ b/camel-upgrade-recipes/src/main/java/org/apache/camel/upgrade/PatternMatcherChangePropertyKey.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.upgrade; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Option; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.properties.PropertiesVisitor; +import org.openrewrite.properties.tree.Properties; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A recipe that changes property keys in property files by replacing a specified key prefix + * and applying CamelCase formatting to any remaining suffix. + */ +public class PatternMatcherChangePropertyKey extends Recipe { + + @Option(displayName = "Old property key", + description = "The property key to rename.", + example = "management.metrics.binders.files.enabled") + String oldPropertyKey; + + @Option(displayName = "New property key", + description = "The new name for the key identified by `oldPropertyKey`.", + example = "management.metrics.enable.process.files") + String newPropertyKey; + + @Option(displayName = "Exclusions", + description = "Regexp for exclusions", + example = "camel.springboot.main-run-controller") + List<String> exclusions = new ArrayList<>(); + + public PatternMatcherChangePropertyKey() {} + + public PatternMatcherChangePropertyKey(String oldPropertyKey, String newPropertyKey, List<String> exclusions) { + this.oldPropertyKey = oldPropertyKey; + this.newPropertyKey = newPropertyKey; + this.exclusions = exclusions == null ? new ArrayList<>() : exclusions; + } + + @Override + public String getDisplayName() { + return "Change property key and apply CamelCase format"; + } + + @Override + public String getDescription() { + return "Change property key applying CamelCase format leaving the value intact."; + } + + @Override + public TreeVisitor<?, ExecutionContext> getVisitor() { + return new PatternMatcherChangePropertyKey.ChangePropertyKeyVisitor<>(); + } + + public class ChangePropertyKeyVisitor<P> extends PropertiesVisitor<P> { + public ChangePropertyKeyVisitor() { + } + + @Override + public Properties visitEntry(Properties.Entry entry, P p) { + for (String exclusion : exclusions) { + if (entry.getKey().equals(exclusion)) { + return super.visitEntry(entry, p); + } + } + + Pattern pattern = Pattern.compile("(" + oldPropertyKey + ")" + "(.*)"); + Matcher matcher = pattern.matcher(entry.getKey()); + if (matcher.find()) { + if(matcher.group(2).startsWith(".")) { + entry = entry.withKey(newPropertyKey + matcher.group(2)); + } else { + String newSuffix = + matcher.group(2).substring(0, 1).toLowerCase() + matcher.group(2).substring(1); + + entry = entry.withKey(newPropertyKey + "." + newSuffix); + } + } + + return super.visitEntry(entry, p); + } + } + + public String getOldPropertyKey() { + return oldPropertyKey; + } + + public void setOldPropertyKey(String oldPropertyKey) { + this.oldPropertyKey = oldPropertyKey; + } + + public String getNewPropertyKey() { + return newPropertyKey; + } + + public void setNewPropertyKey(String newPropertyKey) { + this.newPropertyKey = newPropertyKey; + } + + public List<String> getExclusions() { + return exclusions; + } + + public void setExclusions(List<String> exclusions) { + this.exclusions = exclusions; + } +} diff --git a/camel-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml b/camel-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml index 6ffb196..88139ec 100644 --- a/camel-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml +++ b/camel-upgrade-recipes/src/main/resources/META-INF/rewrite/latest.yaml @@ -29,6 +29,7 @@ recipeList: - org.apache.camel.upgrade.camel40.CamelMigrationRecipe - org.apache.camel.upgrade.UpgradeToJava17 - org.apache.camel.upgrade.JavaVersion17 + - org.apache.camel.upgrade.CamelPropertiesAndYamlUpdate - org.openrewrite.maven.UpgradeDependencyVersion: groupId: 'org.apache.camel' artifactId: '*' diff --git a/camel-upgrade-recipes/src/test/java/org/apache/camel/upgrade/CamelPropertiesTest.java b/camel-upgrade-recipes/src/test/java/org/apache/camel/upgrade/CamelPropertiesTest.java new file mode 100644 index 0000000..cfc0f7f --- /dev/null +++ b/camel-upgrade-recipes/src/test/java/org/apache/camel/upgrade/CamelPropertiesTest.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.upgrade; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.properties.Assertions.properties; +import static org.openrewrite.yaml.Assertions.yaml; + +public class CamelPropertiesTest implements RewriteTest { + + @Test + void propertiesFile() { + rewriteRun( + recipeSpec -> recipeSpec.recipes( + new CamelPropertiesAndYamlUpdate()), + properties( + """ + camel.main.routeControllerSuperviseEnabled=true + another.ignored.property=true + camel.springboot.name = Foo + camel.springboot.main-run-controller=Should be ignored! + camel.main.routeControllerBackOffMultiplier=5 + camel.springboot.routeControllerInitialDelay = 5000 + camel.springboot.routeControllerBackoffDelay = 5000 + camel.springboot.routeControllerBackoffMaxAttempts = 10 + """, + """ + camel.routecontroller.enabled=true + another.ignored.property=true + camel.main.name = Foo + camel.springboot.main-run-controller=Should be ignored! + camel.routecontroller.backOffMultiplier=5 + camel.routecontroller.initialDelay = 5000 + camel.routecontroller.backOffDelay = 5000 + camel.routecontroller.backOffMaxAttempts = 10 + """ + ) + ); + } + + @Test + void yamlFile() { + rewriteRun( + recipeSpec -> recipeSpec.recipes( + new CamelPropertiesAndYamlUpdate()), + yaml( + """ + camel: + springboot: + main-run-controller: 'Should be ignored!' + name: 'Foo' + routeControllerBackOffDelay: true + main: + routeControllerBackOffMultiplier: 5 + another: + ignored: + property: true + """, + """ + camel: + main: + name: 'Foo' + routecontroller.backOffMultiplier: 5 + routecontroller.backOffDelay: true + springboot.main-run-controller: 'Should be ignored!' + another: + ignored: + property: true + """ + ) + ); + } + + +}