This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit eba38a52355da86e22e2c985b336267d62df22b2 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Jun 23 06:05:38 2020 +0200 CAMEL-15224: camel-api-component - Avoid reflection when configured nested configuration classes. --- .../camel/component/olingo4/Olingo4Endpoint.java | 60 +++++++++++++++++----- .../olingo4/Olingo4ComponentConsumerTest.java | 16 ++++-- .../support/component/AbstractApiEndpoint.java | 1 + .../camel/support/component/ApiConsumerHelper.java | 3 +- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Endpoint.java b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Endpoint.java index bf7fc09..b9e462d 100644 --- a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Endpoint.java +++ b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Endpoint.java @@ -19,19 +19,23 @@ package org.apache.camel.component.olingo4; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.apache.camel.Category; import org.apache.camel.Consumer; +import org.apache.camel.ExtendedCamelContext; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.component.olingo4.internal.Olingo4ApiCollection; import org.apache.camel.component.olingo4.internal.Olingo4ApiName; import org.apache.camel.component.olingo4.internal.Olingo4Constants; import org.apache.camel.component.olingo4.internal.Olingo4PropertiesHelper; +import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; +import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.component.AbstractApiEndpoint; import org.apache.camel.support.component.ApiMethod; import org.apache.camel.support.component.ApiMethodPropertiesHelper; @@ -59,7 +63,7 @@ public class Olingo4Endpoint extends AbstractApiEndpoint<Olingo4ApiName, Olingo4 // unparsed variants private static final String UREAD_METHOD = "uread"; - private final Set<String> endpointPropertyNames; + private Set<String> olingo4endpointPropertyNames; @UriParam private Olingo4Configuration configuration; @@ -68,16 +72,7 @@ public class Olingo4Endpoint extends AbstractApiEndpoint<Olingo4ApiName, Olingo4 public Olingo4Endpoint(String uri, Olingo4Component component, Olingo4ApiName apiName, String methodName, Olingo4Configuration endpointConfiguration) { super(uri, component, apiName, methodName, Olingo4ApiCollection.getCollection().getHelper(apiName), endpointConfiguration); - this.configuration = endpointConfiguration; - - // get all endpoint property names - endpointPropertyNames = new HashSet<>(getPropertiesHelper().getValidEndpointProperties(component.getCamelContext(), configuration)); - // avoid adding edm as queryParam - endpointPropertyNames.add(EDM_PROPERTY); - endpointPropertyNames.add(ENDPOINT_HTTP_HEADERS_PROPERTY); - endpointPropertyNames.add(SERVICE_URI_PROPERTY); - endpointPropertyNames.add(FILTER_ALREADY_SEEN); } @Override @@ -113,13 +108,50 @@ public class Olingo4Endpoint extends AbstractApiEndpoint<Olingo4ApiName, Olingo4 @Override public void configureProperties(Map<String, Object> options) { - super.configureProperties(options); - // handle individual query params - parseQueryParams(options); + // filter out options that are with $ as they are for query + Map<String, Object> query = new LinkedHashMap<>(); + Map<String, Object> known = new LinkedHashMap<>(); + options.forEach((k, v) -> { + if (k.startsWith("$")) { + query.put(k, v); + } else { + known.put(k, v); + } + }); + options.keySet().removeIf(known::containsKey); + // configure on configuration first to be reflection free + PropertyConfigurer configurer = getCamelContext().adapt(ExtendedCamelContext.class).getConfigurerResolver().resolvePropertyConfigurer(configuration.getClass().getSimpleName(), getCamelContext()); + if (configurer != null) { + PropertyBindingSupport.build() + .withConfigurer(configurer) + .withIgnoreCase(true) + .withTarget(configuration) + .withCamelContext(getCamelContext()) + .withProperties(known) + .withRemoveParameters(true) + .bind(); + } + super.configureProperties(known); + if (!known.isEmpty()) { + // handle individual query params + query.putAll(known); + } + // and remove from original options as it was used by query + options.keySet().removeIf(query::containsKey); + // this will parse query and expand these $ keys into the actual query keys + parseQueryParams(query); + // and restore back to options + options.putAll(query); } @Override protected void afterConfigureProperties() { + olingo4endpointPropertyNames = new HashSet<>(getEndpointPropertyNames()); + olingo4endpointPropertyNames.add(EDM_PROPERTY); + olingo4endpointPropertyNames.add(ENDPOINT_HTTP_HEADERS_PROPERTY); + olingo4endpointPropertyNames.add(SERVICE_URI_PROPERTY); + olingo4endpointPropertyNames.add(FILTER_ALREADY_SEEN); + // set default inBody if (!(READ_METHOD.equals(methodName) || DELETE_METHOD.equals(methodName) || UREAD_METHOD.equals(methodName)) && inBody == null) { inBody = DATA_PROPERTY; @@ -210,7 +242,7 @@ public class Olingo4Endpoint extends AbstractApiEndpoint<Olingo4ApiName, Olingo4 continue; } - if (!endpointPropertyNames.contains(paramName)) { + if (!olingo4endpointPropertyNames.contains(paramName)) { // add to query params final Object value = entry.getValue(); diff --git a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java index 28d33bc..81e6024 100644 --- a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java +++ b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java @@ -18,7 +18,9 @@ package org.apache.camel.component.olingo4; import java.util.Iterator; +import org.apache.camel.CamelContext; import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.olingo.client.api.domain.ClientCollectionValue; @@ -52,6 +54,14 @@ public class Olingo4ComponentConsumerTest extends AbstractOlingo4TestSupport { startCamelContext(); } + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + context.adapt(ExtendedCamelContext.class).getBeanIntrospection().setLoggingLevel(LoggingLevel.INFO); + context.adapt(ExtendedCamelContext.class).getBeanIntrospection().setExtendedStatistics(true); + return context; + } + @Test public void testConsumerQueryWithExpand() throws Exception { int expectedMsgCount = 1; @@ -83,9 +93,9 @@ public class Olingo4ComponentConsumerTest extends AbstractOlingo4TestSupport { } // should be reflection free - // TODO: We are down to 10 calls now - // long counter = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter(); - // assertEquals(0, counter); + // TODO: We are down to 2 calls now (from unit test itself) +// long counter = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter(); +// assertEquals(0, counter); } /** diff --git a/core/camel-support/src/main/java/org/apache/camel/support/component/AbstractApiEndpoint.java b/core/camel-support/src/main/java/org/apache/camel/support/component/AbstractApiEndpoint.java index d18f8d2..c3693fb 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/component/AbstractApiEndpoint.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/component/AbstractApiEndpoint.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; diff --git a/core/camel-support/src/main/java/org/apache/camel/support/component/ApiConsumerHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/component/ApiConsumerHelper.java index 6ffe292..27d7a99 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/component/ApiConsumerHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/component/ApiConsumerHelper.java @@ -49,7 +49,8 @@ public final class ApiConsumerHelper { ApiMethod result; // find one that takes the largest subset of endpoint parameters - final Set<String> argNames = new HashSet<>(endpoint.getEndpointPropertyNames()); + Set<String> names = endpoint.getEndpointPropertyNames(); + final Set<String> argNames = new HashSet<>(names); propertyNamesInterceptor.interceptPropertyNames(argNames); List<ApiMethod> filteredMethods = endpoint.methodHelper.filterMethods(