This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push: new 9f82f9ed84 Register @PropertyInject classes for reflection 9f82f9ed84 is described below commit 9f82f9ed84997b26e73522e9f100770ea42964ad Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Wed May 1 07:47:09 2024 +0100 Register @PropertyInject classes for reflection Fixes #6016 --- .../core/deployment/PropertyInjectProcessor.java | 66 ++++++++++++++ .../camel/quarkus/component/bean/BeanResource.java | 10 ++ .../camel/quarkus/component/bean/BeanRoutes.java | 2 + .../component/bean/PropertyInjectedFieldBean.java | 42 +++++++++ .../bean/PropertyInjectedFieldMethodBean.java | 32 +++++++ .../component/bean/PropertyInjectedMethodBean.java | 36 ++++++++ .../bean/src/main/resources/application.properties | 4 + .../quarkus/component/bean/PropertyInjectIT.java | 23 +++++ .../quarkus/component/bean/PropertyInjectTest.java | 101 +++++++++++++++++++++ 9 files changed, 316 insertions(+) diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/PropertyInjectProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/PropertyInjectProcessor.java new file mode 100644 index 0000000000..beefe88da4 --- /dev/null +++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/PropertyInjectProcessor.java @@ -0,0 +1,66 @@ +/* + * 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.quarkus.core.deployment; + +import java.util.HashSet; +import java.util.Set; + +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import org.apache.camel.PropertyInject; +import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.AnnotationTarget.Kind; +import org.jboss.jandex.DotName; +import org.jboss.jandex.MethodInfo; + +/** + * Build steps for processing usage of {@link PropertyInject}. + */ +public class PropertyInjectProcessor { + private static final DotName PROPERTY_INJECT_DOTNAME = DotName.createSimple(PropertyInject.class.getName()); + + @BuildStep + void registerForReflection( + BuildProducer<ReflectiveClassBuildItem> reflectiveClass, + CombinedIndexBuildItem combinedIndex) { + Set<String> propertyInjectClasses = new HashSet<>(); + combinedIndex.getIndex() + .getAnnotations(PROPERTY_INJECT_DOTNAME) + .forEach(annotationInstance -> { + AnnotationTarget target = annotationInstance.target(); + Kind kind = target.kind(); + if (kind == Kind.FIELD) { + propertyInjectClasses.add(target.asField().declaringClass().name().toString()); + } + + if (kind == Kind.METHOD || kind == Kind.METHOD_PARAMETER) { + MethodInfo methodInfo = kind == Kind.METHOD ? target.asMethod() : target.asMethodParameter().method(); + DotName dotName = methodInfo.declaringClass().name(); + propertyInjectClasses.add(dotName.toString()); + } + }); + + if (!propertyInjectClasses.isEmpty()) { + reflectiveClass.produce(ReflectiveClassBuildItem.builder(propertyInjectClasses.toArray(new String[0])) + .fields(true) + .methods(true) + .build()); + } + } +} diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java index fc8450a354..ffb3958864 100644 --- a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanResource.java @@ -30,6 +30,7 @@ import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import org.apache.camel.CamelContext; import org.apache.camel.Exchange; @@ -202,4 +203,13 @@ public class BeanResource { .map(b -> b.getName()).collect(Collectors.toSet()); } + @Path("/propertyInject") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String propertyInject( + @QueryParam("beanName") String beanName, + @QueryParam("beanMethod") String beanMethod) { + Map<String, Object> headers = Map.of("beanName", beanName, "beanMethod", beanMethod); + return template.requestBodyAndHeaders("direct:propertyInject", null, headers, String.class); + } } diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java index 67397d28cd..5069daee35 100644 --- a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/BeanRoutes.java @@ -110,6 +110,8 @@ public class BeanRoutes extends RouteBuilder { from("direct:produceInterface") .process(e -> e.getMessage().setBody("produceInterface " + e.getMessage().getBody(String.class))); + from("direct:propertyInject") + .toD("bean:${header.beanName}?method=${header.beanMethod}"); } @SuppressWarnings("unchecked") diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldBean.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldBean.java new file mode 100644 index 0000000000..41cc4f72bc --- /dev/null +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldBean.java @@ -0,0 +1,42 @@ +/* + * 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.quarkus.component.bean; + +import org.apache.camel.PropertyInject; + +public class PropertyInjectedFieldBean { + @PropertyInject("my.injected.property.a") + private String injectedPropertyA; + + @PropertyInject(value = "my.injected.property.b", defaultValue = "Test @PropertyInject default") + private String injectedPropertyB; + + @PropertyInject(value = "Hello {{my.injected.property.a}} Placeholder") + private String injectedPropertyC; + + public String getInjectedPropertyA() { + return injectedPropertyA; + } + + public String getInjectedPropertyB() { + return injectedPropertyB; + } + + public String getInjectedPropertyC() { + return injectedPropertyC; + } +} diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldMethodBean.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldMethodBean.java new file mode 100644 index 0000000000..1e3a0bd59b --- /dev/null +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedFieldMethodBean.java @@ -0,0 +1,32 @@ +/* + * 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.quarkus.component.bean; + +import org.apache.camel.PropertyInject; + +public class PropertyInjectedFieldMethodBean { + @PropertyInject("my.injected.property.a") + private String injectedPropertyA; + + public String getInjectedPropertyA() { + return injectedPropertyA; + } + + public String getInjectedPropertyE(@PropertyInject("my.injected.property.e") String value) { + return value; + } +} diff --git a/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedMethodBean.java b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedMethodBean.java new file mode 100644 index 0000000000..d27918a1c9 --- /dev/null +++ b/integration-test-groups/foundation/bean/src/main/java/org/apache/camel/quarkus/component/bean/PropertyInjectedMethodBean.java @@ -0,0 +1,36 @@ +/* + * 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.quarkus.component.bean; + +import org.apache.camel.PropertyInject; + +public class PropertyInjectedMethodBean { + private String injectedPropertyD; + + @PropertyInject("my.injected.property.d") + public void setInjectedPropertyD(String value) { + this.injectedPropertyD = value; + } + + public String getInjectedPropertyD() { + return injectedPropertyD; + } + + public String getInjectedPropertyE(@PropertyInject("my.injected.property.e") String value) { + return value; + } +} diff --git a/integration-test-groups/foundation/bean/src/main/resources/application.properties b/integration-test-groups/foundation/bean/src/main/resources/application.properties index 06aeb9fd2b..8d522c8da9 100644 --- a/integration-test-groups/foundation/bean/src/main/resources/application.properties +++ b/integration-test-groups/foundation/bean/src/main/resources/application.properties @@ -17,3 +17,7 @@ # A test value my.foo.property = foo + +my.injected.property.a = Test @PropertyInject +my.injected.property.d = Test @PropertyInject Setter Method +my.injected.property.e = Test @PropertyInject Method Argument diff --git a/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectIT.java b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectIT.java new file mode 100644 index 0000000000..b0f046df03 --- /dev/null +++ b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectIT.java @@ -0,0 +1,23 @@ +/* + * 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.quarkus.component.bean; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class PropertyInjectIT extends PropertyInjectTest { +} diff --git a/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectTest.java b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectTest.java new file mode 100644 index 0000000000..7b2b514d7a --- /dev/null +++ b/integration-test-groups/foundation/bean/src/test/java/org/apache/camel/quarkus/component/bean/PropertyInjectTest.java @@ -0,0 +1,101 @@ +/* + * 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.quarkus.component.bean; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.Matchers.is; + +@QuarkusTest +class PropertyInjectTest { + + @Test + void propertyInjectedField() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedFieldBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyA") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject")); + } + + @Test + void propertyInjectedFieldWithDefault() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedFieldBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyB") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject default")); + } + + @Test + void propertyInjectedFieldWithPlaceholder() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedFieldBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyC") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Hello Test @PropertyInject Placeholder")); + } + + @Test + void propertyInjectedSetterMethod() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedMethodBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyD") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject Setter Method")); + } + + @Test + void propertyInjectedMethodArgument() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedMethodBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyE") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject Method Argument")); + } + + @Test + void propertyInjectedFieldAndMethod() { + RestAssured.given() + .queryParam("beanName", PropertyInjectedFieldMethodBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyA") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject")); + + RestAssured.given() + .queryParam("beanName", PropertyInjectedFieldMethodBean.class.getName()) + .queryParam("beanMethod", "getInjectedPropertyE") + .get("/bean/propertyInject") + .then() + .statusCode(200) + .body(is("Test @PropertyInject Method Argument")); + } +}