Repository: camel Updated Branches: refs/heads/camel-2.19.x 3b1cfb00b -> 76de7f99b refs/heads/master 33ff7aee6 -> 42903358b
CAMEL-11594: rest configuration in spring boot should use map instead of list Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/52c5fba7 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/52c5fba7 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/52c5fba7 Branch: refs/heads/master Commit: 52c5fba758b21f31a7dd08b6cd15ace1f8245169 Parents: 33ff7ae Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Jul 26 20:23:03 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Jul 26 20:23:11 2017 +0200 ---------------------------------------------------------------------- .../org/apache/camel/util/CollectionHelper.java | 47 ++++++++++++++++---- .../apache/camel/util/CollectionHelperTest.java | 29 ++++++++++++ ...onfigurationDefinitionAutoConfiguration.java | 21 +++++++++ .../RestConfigurationDefinitionProperties.java | 43 ++++++++---------- .../model/rest/springboot/CamelRestTest.java | 21 ++++++--- .../SpringBootAutoConfigurationMojo.java | 21 +++++++++ 6 files changed, 143 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java b/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java index ab4d898..f5001e6 100644 --- a/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java @@ -5,9 +5,9 @@ * 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 - * + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> * 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. @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -31,7 +32,7 @@ import org.w3c.dom.NodeList; /** * A number of helper methods for working with collections * - * @version + * @version */ public final class CollectionHelper { @@ -50,18 +51,18 @@ public final class CollectionHelper { public static Integer size(Object value) { if (value != null) { if (value instanceof Collection) { - Collection<?> collection = (Collection<?>)value; + Collection<?> collection = (Collection<?>) value; return collection.size(); } else if (value instanceof Map) { - Map<?, ?> map = (Map<?, ?>)value; + Map<?, ?> map = (Map<?, ?>) value; return map.size(); } else if (value instanceof Object[]) { - Object[] array = (Object[])value; + Object[] array = (Object[]) value; return array.length; } else if (value.getClass().isArray()) { return Array.getLength(value); } else if (value instanceof NodeList) { - NodeList nodeList = (NodeList)value; + NodeList nodeList = (NodeList) value; return nodeList.getLength(); } } @@ -83,7 +84,7 @@ public final class CollectionHelper { if (oldValue != null) { List<Object> list; if (oldValue instanceof List) { - list = (List<Object>)oldValue; + list = (List<Object>) oldValue; } else { list = new ArrayList<Object>(); list.add(oldValue); @@ -126,4 +127,32 @@ public final class CollectionHelper { return sb.toString(); } + + /** + * Traverses the given map recursively and flattern the keys by combining them with the optional separator. + * + * @param map the map + * @param separator optional separator to use in key name, for example a hyphen or dot. + * @return the map with flattern keys + */ + public static Map<String, Object> flatternKeysInMap(Map<String, Object> map, String separator) { + Map<String, Object> answer = new LinkedHashMap<>(); + doFlatternKeysInMap(map, "", ObjectHelper.isNotEmpty(separator) ? separator : "", answer); + return answer; + } + + private static void doFlatternKeysInMap(Map<String, Object> source, String prefix, String separator, Map<String, Object> target) { + for (Map.Entry<String, Object> entry : source.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + String newKey = prefix.isEmpty() ? key : prefix + separator + key; + + if (value instanceof Map) { + Map map = (Map) value; + doFlatternKeysInMap(map, newKey, separator, target); + } else { + target.put(newKey, value); + } + } + } } http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/camel-core/src/test/java/org/apache/camel/util/CollectionHelperTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/util/CollectionHelperTest.java b/camel-core/src/test/java/org/apache/camel/util/CollectionHelperTest.java index e433fba..6ded72d 100644 --- a/camel-core/src/test/java/org/apache/camel/util/CollectionHelperTest.java +++ b/camel-core/src/test/java/org/apache/camel/util/CollectionHelperTest.java @@ -19,8 +19,10 @@ package org.apache.camel.util; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import junit.framework.TestCase; @@ -73,4 +75,31 @@ public class CollectionHelperTest extends TestCase { assertEquals(789, value.intValue()); } + public void testCreateSetContaining() throws Exception { + Set<String> set = CollectionHelper.createSetContaining("foo", "bar", "baz"); + assertEquals(3, set.size()); + assertTrue(set.contains("foo")); + assertTrue(set.contains("bar")); + assertTrue(set.contains("baz")); + } + + public void testFlatternKeysInMap() throws Exception { + Map<String, Object> root = new LinkedHashMap<>(); + Map<String, Object> api = new LinkedHashMap<>(); + Map<String, Object> contact = new LinkedHashMap<>(); + contact.put("organization", "Apache Software Foundation"); + api.put("version", "1.0.0"); + api.put("title", "My cool API"); + api.put("contact", contact); + root.put("api", api); + root.put("cors", true); + + Map<String, Object> flattern = CollectionHelper.flatternKeysInMap(root, "."); + assertEquals(4, flattern.size()); + assertEquals(true, flattern.get("cors")); + assertEquals("1.0.0", flattern.get("api.version")); + assertEquals("My cool API", flattern.get("api.title")); + assertEquals("Apache Software Foundation", flattern.get("api.contact.organization")); + } + } http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionAutoConfiguration.java index 067858c..92d49b8 100644 --- a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionAutoConfiguration.java @@ -22,6 +22,7 @@ import javax.annotation.Generated; import org.apache.camel.CamelContext; import org.apache.camel.model.rest.RestConstants; import org.apache.camel.spi.RestConfiguration; +import org.apache.camel.util.CollectionHelper; import org.apache.camel.util.IntrospectionSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -62,6 +63,26 @@ public class RestConfigurationDefinitionAutoConfiguration { IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), definition, properties); definition.setEnableCORS(config.getEnableCors()); + if (config.getApiProperty() != null) { + definition.setApiProperties(new HashMap<>(CollectionHelper + .flatternKeysInMap(config.getApiProperty(), "."))); + } + if (config.getComponentProperty() != null) { + definition.setComponentProperties(new HashMap<>(CollectionHelper + .flatternKeysInMap(config.getComponentProperty(), "."))); + } + if (config.getConsumerProperty() != null) { + definition.setConsumerProperties(new HashMap<>(CollectionHelper + .flatternKeysInMap(config.getConsumerProperty(), "."))); + } + if (config.getDataFormatProperty() != null) { + definition.setDataFormatProperties(new HashMap<>(CollectionHelper + .flatternKeysInMap(config.getDataFormatProperty(), "."))); + } + if (config.getEndpointProperty() != null) { + definition.setEndpointProperties(new HashMap<>(CollectionHelper + .flatternKeysInMap(config.getEndpointProperty(), "."))); + } return definition; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionProperties.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionProperties.java b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionProperties.java index 174134e..9cf3ebb 100644 --- a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionProperties.java +++ b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/rest/springboot/RestConfigurationDefinitionProperties.java @@ -16,11 +16,10 @@ */ package org.apache.camel.model.rest.springboot; -import java.util.List; +import java.util.Map; import javax.annotation.Generated; import org.apache.camel.model.rest.RestBindingMode; import org.apache.camel.model.rest.RestHostNameResolver; -import org.apache.camel.model.rest.RestPropertyDefinition; import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -146,17 +145,17 @@ public class RestConfigurationDefinitionProperties { * Allows to configure as many additional properties for the rest component * in use. */ - private List<RestPropertyDefinition> componentProperty; + private Map<String, Object> componentProperty; /** * Allows to configure as many additional properties for the rest endpoint * in use. */ - private List<RestPropertyDefinition> endpointProperty; + private Map<String, Object> endpointProperty; /** * Allows to configure as many additional properties for the rest consumer * in use. */ - private List<RestPropertyDefinition> consumerProperty; + private Map<String, Object> consumerProperty; /** * Allows to configure as many additional properties for the data formats in * use. For example set property prettyPrint to true to have json outputted @@ -166,17 +165,17 @@ public class RestConfigurationDefinitionProperties { * value xml.out.mustBeJAXBElement is only for the XML data format for the * outgoing. A key without a prefix is a common key for all situations. */ - private List<RestPropertyDefinition> dataFormatProperty; + private Map<String, Object> dataFormatProperty; /** * Allows to configure as many additional properties for the api * documentation (swagger). For example set property api.title to my cool * stuff */ - private List<RestPropertyDefinition> apiProperty; + private Map<String, Object> apiProperty; /** * Allows to configure custom CORS headers. */ - private List<RestPropertyDefinition> corsHeaders; + private Map<String, Object> corsHeaders; public String getComponent() { return component; @@ -322,55 +321,51 @@ public class RestConfigurationDefinitionProperties { this.xmlDataFormat = xmlDataFormat; } - public List<RestPropertyDefinition> getComponentProperty() { + public Map<String, Object> getComponentProperty() { return componentProperty; } - public void setComponentProperty( - List<RestPropertyDefinition> componentProperty) { + public void setComponentProperty(Map<String, Object> componentProperty) { this.componentProperty = componentProperty; } - public List<RestPropertyDefinition> getEndpointProperty() { + public Map<String, Object> getEndpointProperty() { return endpointProperty; } - public void setEndpointProperty( - List<RestPropertyDefinition> endpointProperty) { + public void setEndpointProperty(Map<String, Object> endpointProperty) { this.endpointProperty = endpointProperty; } - public List<RestPropertyDefinition> getConsumerProperty() { + public Map<String, Object> getConsumerProperty() { return consumerProperty; } - public void setConsumerProperty( - List<RestPropertyDefinition> consumerProperty) { + public void setConsumerProperty(Map<String, Object> consumerProperty) { this.consumerProperty = consumerProperty; } - public List<RestPropertyDefinition> getDataFormatProperty() { + public Map<String, Object> getDataFormatProperty() { return dataFormatProperty; } - public void setDataFormatProperty( - List<RestPropertyDefinition> dataFormatProperty) { + public void setDataFormatProperty(Map<String, Object> dataFormatProperty) { this.dataFormatProperty = dataFormatProperty; } - public List<RestPropertyDefinition> getApiProperty() { + public Map<String, Object> getApiProperty() { return apiProperty; } - public void setApiProperty(List<RestPropertyDefinition> apiProperty) { + public void setApiProperty(Map<String, Object> apiProperty) { this.apiProperty = apiProperty; } - public List<RestPropertyDefinition> getCorsHeaders() { + public Map<String, Object> getCorsHeaders() { return corsHeaders; } - public void setCorsHeaders(List<RestPropertyDefinition> corsHeaders) { + public void setCorsHeaders(Map<String, Object> corsHeaders) { this.corsHeaders = corsHeaders; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/platforms/spring-boot/components-starter/camel-core-starter/src/test/java/org/apache/camel/model/rest/springboot/CamelRestTest.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-core-starter/src/test/java/org/apache/camel/model/rest/springboot/CamelRestTest.java b/platforms/spring-boot/components-starter/camel-core-starter/src/test/java/org/apache/camel/model/rest/springboot/CamelRestTest.java index cae2ae4..70f23e3 100644 --- a/platforms/spring-boot/components-starter/camel-core-starter/src/test/java/org/apache/camel/model/rest/springboot/CamelRestTest.java +++ b/platforms/spring-boot/components-starter/camel-core-starter/src/test/java/org/apache/camel/model/rest/springboot/CamelRestTest.java @@ -24,7 +24,7 @@ import org.apache.camel.Processor; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.seda.SedaEndpoint; -import org.apache.camel.impl.ActiveMQUuidGenerator; +import org.apache.camel.impl.DefaultUuidGenerator; import org.apache.camel.spi.RestApiConsumerFactory; import org.apache.camel.spi.RestConfiguration; import org.apache.camel.spi.RestConsumerFactory; @@ -40,7 +40,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; - @DirtiesContext @RunWith(SpringRunner.class) @EnableAutoConfiguration @@ -55,10 +54,15 @@ import org.springframework.test.context.junit4.SpringRunner; "camel.springboot.xml-routes=false", "camel.rest.enabled=true", "camel.rest.component=dummy-rest", - "camel.rest.host=localhost" + "camel.rest.host=localhost", + "camel.rest.data-format-property.prettyPrint=true", + "camel.rest.api-property.api.title=My cool API", + "camel.rest.api-property.api.version=1.0.0", + "camel.rest.api-property.cors=true" } ) public class CamelRestTest { + @Autowired private CamelContext context; @@ -68,6 +72,11 @@ public class CamelRestTest { String result = template.requestBody("seda:get-say-hello", "test", String.class); Assert.assertEquals("Hello World", result); + + Assert.assertEquals("true", context.getRestConfiguration().getDataFormatProperties().get("prettyPrint")); + Assert.assertEquals("My cool API", context.getRestConfiguration().getApiProperties().get("api.title")); + Assert.assertEquals("1.0.0", context.getRestConfiguration().getApiProperties().get("api.version")); + Assert.assertEquals("true", context.getRestConfiguration().getApiProperties().get("cors")); } // *********************************** @@ -125,9 +134,9 @@ public class CamelRestTest { // just use a seda endpoint for testing purpose String id; if (uriTemplate != null) { - id = ActiveMQUuidGenerator.generateSanitizedId(basePath + uriTemplate); + id = DefaultUuidGenerator.generateSanitizedId(basePath + uriTemplate); } else { - id = ActiveMQUuidGenerator.generateSanitizedId(basePath); + id = DefaultUuidGenerator.generateSanitizedId(basePath); } // remove leading dash as we add that ourselves if (id.startsWith("-")) { @@ -154,7 +163,7 @@ public class CamelRestTest { Map<String, Object> parameters) throws Exception { // just use a seda endpoint for testing purpose - String id = ActiveMQUuidGenerator.generateSanitizedId(contextPath); + String id = DefaultUuidGenerator.generateSanitizedId(contextPath); // remove leading dash as we add that ourselves if (id.startsWith("-")) { id = id.substring(1); http://git-wip-us.apache.org/repos/asf/camel/blob/52c5fba7/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java ---------------------------------------------------------------------- diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java index 984cfea..c8b9a18 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java @@ -416,6 +416,8 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { if ("java.util.List<org.apache.camel.model.PropertyDefinition>".equalsIgnoreCase(type)) { type = "java.util.Map<java.lang.String, java.lang.String>"; + } else if ("java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>".equalsIgnoreCase(type)) { + type = "java.util.Map<java.lang.String, java.lang.Object>"; } if ("enableCORS".equalsIgnoreCase(name)) { @@ -469,6 +471,7 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { javaClass.addImport("java.util.Map"); javaClass.addImport("java.util.HashMap"); + javaClass.addImport("org.apache.camel.util.CollectionHelper"); javaClass.addImport("org.apache.camel.util.IntrospectionSupport"); javaClass.addImport("org.apache.camel.CamelContext"); javaClass.addImport("org.apache.camel.model.rest.RestConstants"); @@ -508,6 +511,24 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { + "// as enable-c-o-r-s if left uppercase in Configuration\n" + "definition.setEnableCORS(config.getEnableCors());\n" + "\n" + + "if (config.getApiProperty() != null) {\n" + + " definition.setApiProperties(new HashMap<>(CollectionHelper.flatternKeysInMap(config.getApiProperty(), \".\")));\n" + + "}\n" + + "if (config.getComponentProperty() != null) {\n" + + " definition.setComponentProperties(new HashMap<>(CollectionHelper.flatternKeysInMap(config.getComponentProperty(), \".\")));\n" + + "}\n" + + "if (config.getConsumerProperty() != null) {\n" + + " definition.setConsumerProperties(new HashMap<>(CollectionHelper.flatternKeysInMap(config.getConsumerProperty(), \".\")));\n" + + "}\n" +// + "if (config.getCorsHeaders() != null) {\n" +// + " definition.setCorsHeaders(new HashMap<>(config.getCorsHeaders()));\n" +// + "}\n" + + "if (config.getDataFormatProperty() != null) {\n" + + " definition.setDataFormatProperties(new HashMap<>(CollectionHelper.flatternKeysInMap(config.getDataFormatProperty(), \".\")));\n" + + "}\n" + + "if (config.getEndpointProperty() != null) {\n" + + " definition.setEndpointProperties(new HashMap<>(CollectionHelper.flatternKeysInMap(config.getEndpointProperty(), \".\")));\n" + + "}\n" + "return definition;" );