This is an automated email from the ASF dual-hosted git repository. nfilotto pushed a commit to branch camel-spring-boot-4.0.x in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
The following commit(s) were added to refs/heads/camel-spring-boot-4.0.x by this push: new 328438381ac CAMEL-19851: camel-http - Allow to configure timeouts natively (#942) 328438381ac is described below commit 328438381ac3e50edaa5b0d503c2a1fa31dfce80 Author: Nicolas Filotto <essob...@users.noreply.github.com> AuthorDate: Thu Sep 14 21:49:46 2023 +0200 CAMEL-19851: camel-http - Allow to configure timeouts natively (#942) ## Motivation The timeout can only be configured like any other complex type, indeed, we need to define a dedicated bean in our Spring context and refer to that bean in the configuration of our component which could be simplified by supporting natively timeouts. ## Modifications: * Add new converters to support natively a timeout in milliseconds expressed as long, integer, or string --- .../springboot/HttpComponentTimeoutConverter.java | 60 ++++++++++ ...rk.boot.autoconfigure.AutoConfiguration.imports | 1 + .../HttpComponentTimeoutConverterTest.java | 125 +++++++++++++++++++++ 3 files changed, 186 insertions(+) diff --git a/components-starter/camel-http-starter/src/main/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverter.java b/components-starter/camel-http-starter/src/main/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverter.java new file mode 100644 index 00000000000..06b9100d584 --- /dev/null +++ b/components-starter/camel-http-starter/src/main/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverter.java @@ -0,0 +1,60 @@ +/* + * 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.component.http.springboot; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.hc.core5.util.Timeout; +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.stereotype.Component; + + +@Configuration(proxyBeanMethods = false) +@ConfigurationPropertiesBinding +@Component +public class HttpComponentTimeoutConverter extends HttpComponentConverter { + + @Override + public Set<ConvertiblePair> getConvertibleTypes() { + Set<ConvertiblePair> answer = new LinkedHashSet<>(); + answer.add(new ConvertiblePair(Integer.class, org.apache.hc.core5.util.Timeout.class)); + answer.add(new ConvertiblePair(Long.class, org.apache.hc.core5.util.Timeout.class)); + answer.add(new ConvertiblePair(String.class, org.apache.hc.core5.util.Timeout.class)); + return answer; + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (source == null) { + return null; + } + if (source instanceof Integer value) { + return Timeout.ofMilliseconds(value.longValue()); + } else if (source instanceof Long value) { + return Timeout.ofMilliseconds(value); + } else if (source instanceof String value) { + if (value.startsWith("#")) { + return super.convert(source, sourceType, targetType); + } + return Timeout.ofMilliseconds(Long.parseLong(value)); + } + return null; + } +} diff --git a/components-starter/camel-http-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/components-starter/camel-http-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 29877893b1d..e92fc17e3f3 100644 --- a/components-starter/camel-http-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/components-starter/camel-http-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -17,3 +17,4 @@ org.apache.camel.component.http.springboot.HttpComponentConverter org.apache.camel.component.http.springboot.HttpComponentAutoConfiguration +org.apache.camel.component.http.springboot.HttpComponentTimeoutConverter diff --git a/components-starter/camel-http-starter/src/test/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverterTest.java b/components-starter/camel-http-starter/src/test/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverterTest.java new file mode 100644 index 00000000000..d89aa6a99a8 --- /dev/null +++ b/components-starter/camel-http-starter/src/test/java/org/apache/camel/component/http/springboot/HttpComponentTimeoutConverterTest.java @@ -0,0 +1,125 @@ +/** + * 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 + * <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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.camel.component.http.springboot; + +import java.nio.charset.StandardCharsets; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.http.HttpComponent; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.impl.bootstrap.HttpServer; +import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + HttpComponentTimeoutConverter.class, + CamelAutoConfiguration.class, + HttpComponentAutoConfiguration.class, + HttpComponentTimeoutConverterTest.TestConfiguration.class + }, + properties = {"camel.component.http.so-timeout = 30000"} +) +class HttpComponentTimeoutConverterTest { + + @Autowired + ProducerTemplate template; + @Autowired + private CamelContext context; + + private static CamelContext currentContext; + private static HttpServer localServer; + + private static String baseUrl; + + @BeforeAll + public static void setUp() throws Exception { + localServer = ServerBootstrap.bootstrap() + .register("/checkSoTimeout", (request, response, ctx) -> { + response.setCode(HttpStatus.SC_OK); + assertNotNull(currentContext); + response.setEntity(new StringEntity(String.valueOf(currentContext.getComponent("http", HttpComponent.class).getSoTimeout().toSeconds()), StandardCharsets.US_ASCII)); + }) + .create(); + localServer.start(); + + baseUrl = "http://localhost:" + localServer.getLocalPort(); + } + + @AfterAll + public static void tearDown() { + if (localServer != null) { + localServer.stop(); + } + } + + @BeforeEach + public void init() { + currentContext = context; + } + + @Test + void checkSoTimeout() { + Exchange exchange = template.request("direct:checkSoTimeout", exchange1 -> {}); + assertNotNull(exchange); + assertNull(exchange.getException()); + Message out = exchange.getMessage(); + assertNotNull(out); + assertEquals("30", out.getBody(String.class)); + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public static class TestConfiguration { + + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:checkSoTimeout").to(baseUrl + "/checkSoTimeout"); + } + }; + } + } +}