This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch pf in repository https://gitbox.apache.org/repos/asf/camel.git
commit 11cc91bace56c580952dc16ca98a223e7d98eac8 Author: Claus Ibsen <[email protected]> AuthorDate: Tue Feb 15 10:47:54 2022 +0100 CAMEL-17647: camel-core - Properties component should support pluggable functions --- .../org/apache/camel/properties-function/base64 | 2 + .../base64/Base64PropertiesFunction.java | 35 +++++++++----- .../base64/Base64PropertiesFunctionTest.java | 47 ++++++++++++++++++ .../properties/PropertiesFunctionResolver.java | 55 +++++++++++++++++----- .../camel/spi/annotations/PropertiesFunction.java | 25 +++++----- 5 files changed, 125 insertions(+), 39 deletions(-) diff --git a/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64 b/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64 new file mode 100644 index 0000000..bb73781 --- /dev/null +++ b/components/camel-base64/src/generated/resources/META-INF/services/org/apache/camel/properties-function/base64 @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.dataformat.base64.Base64PropertiesFunction diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java b/components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java similarity index 51% copy from core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java copy to components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java index 1e04d3f..4eedd37 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java +++ b/components/camel-base64/src/main/java/org/apache/camel/dataformat/base64/Base64PropertiesFunction.java @@ -14,21 +14,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.spi; +package org.apache.camel.dataformat.base64; -/** - * Pluggable Factory for creating custom {@link PropertiesFunction}. - */ -public interface PropertiesFunctionFactory { +import org.apache.camel.spi.PropertiesFunction; +import org.apache.commons.codec.binary.Base64; + [email protected]("base64") +public class Base64PropertiesFunction implements PropertiesFunction { + + private final int lineLength = Base64.MIME_CHUNK_SIZE; + private final byte[] lineSeparator = { '\r', '\n' }; + private final Base64 codec; - /** - * Service factory key. - */ - String FACTORY = "properties-function"; + public Base64PropertiesFunction() { + this.codec = new Base64(lineLength, lineSeparator, true); + } - /** - * Creates the {@link PropertiesFunction} - */ - PropertiesFunction createPropertiesFunction(); + @Override + public String getName() { + return "base64"; + } + @Override + public String apply(String remainder) { + byte[] arr = codec.decode(remainder); + return new String(arr); + } } diff --git a/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java b/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java new file mode 100644 index 0000000..462c672 --- /dev/null +++ b/components/camel-base64/src/test/java/org/apache/camel/dataformat/base64/Base64PropertiesFunctionTest.java @@ -0,0 +1,47 @@ +/* + * 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.dataformat.base64; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +public class Base64PropertiesFunctionTest extends CamelTestSupport { + + @Test + public void testBase64() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Hello Camel"); + + template.sendBody("direct:start", "Hello"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + // Q2FtZWw== is the word Camel + .setBody(simple("${body} {{base64:Q2FtZWw==}}")) + .to("mock:result"); + } + }; + } +} diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java index f6cff57..ec1d733 100644 --- a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesFunctionResolver.java @@ -24,15 +24,20 @@ import org.apache.camel.CamelContextAware; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.spi.FactoryFinder; import org.apache.camel.spi.PropertiesFunction; -import org.apache.camel.spi.PropertiesFunctionFactory; -import org.apache.camel.support.ResolverHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Resolver for built-in and custom {@link PropertiesFunction}. */ public final class PropertiesFunctionResolver implements CamelContextAware { + public static final String RESOURCE_PATH = "META-INF/services/org/apache/camel/properties-function/"; + + private static final Logger LOG = LoggerFactory.getLogger(PropertiesFunctionResolver.class); + private CamelContext camelContext; + private FactoryFinder factoryFinder; private final Map<String, PropertiesFunction> functions = new LinkedHashMap<>(); public PropertiesFunctionResolver() { @@ -80,20 +85,44 @@ public final class PropertiesFunctionResolver implements CamelContextAware { public PropertiesFunction resolvePropertiesFunction(String name) { PropertiesFunction answer = functions.get(name); if (answer == null) { - // it may be a custom function from a 3rd party JAR so use factory finder - ExtendedCamelContext ecc = camelContext.adapt(ExtendedCamelContext.class); - FactoryFinder finder = ecc.getBootstrapFactoryFinder(PropertiesFunctionFactory.FACTORY); - - PropertiesFunctionFactory factory - = ResolverHelper.resolveService(ecc, finder, name, PropertiesFunctionFactory.class).orElse(null); - if (factory != null) { - answer = factory.createPropertiesFunction(); - if (answer != null) { - functions.put(name, answer); - } + answer = resolve(camelContext, name); + if (answer != null) { + functions.put(name, answer); } } return answer; } + private PropertiesFunction resolve(CamelContext context, String name) { + // use factory finder to find a custom implementations + Class<?> type = null; + try { + type = findFactory(name, context); + } catch (Exception e) { + // ignore + } + + if (type != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Found PropertiesFunction: {} via: {}{}", type.getName(), factoryFinder.getResourcePath(), name); + } + if (PropertiesFunction.class.isAssignableFrom(type)) { + PropertiesFunction answer = (PropertiesFunction) context.getInjector().newInstance(type, false); + CamelContextAware.trySetCamelContext(answer, camelContext); + return answer; + } else { + throw new IllegalArgumentException("Type is not a PropertiesFunction implementation. Found: " + type.getName()); + } + } + + return null; + } + + private Class<?> findFactory(String name, CamelContext context) { + if (factoryFinder == null) { + factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH); + } + return factoryFinder.findClass(name).orElse(null); + } + } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java similarity index 65% rename from core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java rename to tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java index 1e04d3f..7e9e966 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunctionFactory.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/PropertiesFunction.java @@ -14,21 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.spi; +package org.apache.camel.spi.annotations; -/** - * Pluggable Factory for creating custom {@link PropertiesFunction}. - */ -public interface PropertiesFunctionFactory { +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; - /** - * Service factory key. - */ - String FACTORY = "properties-function"; +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Target({ ElementType.TYPE }) +@ServiceFactory("properties-function") +public @interface PropertiesFunction { - /** - * Creates the {@link PropertiesFunction} - */ - PropertiesFunction createPropertiesFunction(); + String value(); }
