diff --git a/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/RestClientConfiguration.java b/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/RestClientConfiguration.java index d90eaf84f..0449cd631 100644 --- a/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/RestClientConfiguration.java +++ b/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/RestClientConfiguration.java @@ -19,6 +19,7 @@ import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; +import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; @@ -69,12 +70,11 @@ public CloseableHttpClient httpClient() { } @Bean - HttpServiceProxyFactory httpServiceProxyFactory( - RestClient.Builder builder, - ObservationRegistry observationRegistry, - CloseableHttpClient httpClient) { - RestClient restClient = - builder.defaultHeaders( + RestClientCustomizer restClientCustomizer( + ObservationRegistry observationRegistry, CloseableHttpClient httpClient) { + return restClientBuilder -> + restClientBuilder + .defaultHeaders( httpHeaders -> { httpHeaders.setContentType(MediaType.APPLICATION_JSON); httpHeaders.setAccept(List.of(MediaType.APPLICATION_JSON)); @@ -90,9 +90,12 @@ HttpServiceProxyFactory httpServiceProxyFactory( log.info("HTTP Headers: {}", request.getHeaders()); return execution.execute(request, body); - }) - .build(); - RestClientAdapter webClientAdapter = RestClientAdapter.create(restClient); + }); + } + + @Bean + HttpServiceProxyFactory httpServiceProxyFactory(RestClient.Builder restClientBuilder) { + RestClientAdapter webClientAdapter = RestClientAdapter.create(restClientBuilder.build()); return HttpServiceProxyFactory.builderFor(webClientAdapter).build(); } diff --git a/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/WebMvcConfig.java b/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/WebMvcConfig.java index 030dac911..feb596c7b 100644 --- a/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/WebMvcConfig.java +++ b/httpClients/boot-http-proxy/src/main/java/com/example/rest/proxy/config/WebMvcConfig.java @@ -2,20 +2,22 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; +import org.springframework.lang.NonNull; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -@Configuration +@Configuration(proxyBeanMethods = false) @RequiredArgsConstructor public class WebMvcConfig implements WebMvcConfigurer { private final ApplicationProperties properties; @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping(properties.getCors().getPathPattern()) - .allowedMethods(properties.getCors().getAllowedMethods()) - .allowedHeaders(properties.getCors().getAllowedHeaders()) - .allowedOriginPatterns(properties.getCors().getAllowedOriginPatterns()) - .allowCredentials(properties.getCors().isAllowCredentials()); + public void addCorsMappings(@NonNull CorsRegistry registry) { + ApplicationProperties.Cors propertiesCors = properties.getCors(); + registry.addMapping(propertiesCors.getPathPattern()) + .allowedMethods(propertiesCors.getAllowedMethods()) + .allowedHeaders(propertiesCors.getAllowedHeaders()) + .allowedOriginPatterns(propertiesCors.getAllowedOriginPatterns()) + .allowCredentials(propertiesCors.isAllowCredentials()); } } diff --git a/httpClients/boot-rest-template/src/main/java/com/example/rest/template/config/RestTemplateConfiguration.java b/httpClients/boot-rest-template/src/main/java/com/example/rest/template/config/RestTemplateConfiguration.java index bf12fb230..5d44b9a45 100644 --- a/httpClients/boot-rest-template/src/main/java/com/example/rest/template/config/RestTemplateConfiguration.java +++ b/httpClients/boot-rest-template/src/main/java/com/example/rest/template/config/RestTemplateConfiguration.java @@ -1,6 +1,13 @@ package com.example.rest.template.config; -import static com.example.rest.template.utils.AppConstants.*; +import static com.example.rest.template.utils.AppConstants.CONNECTION_TIMEOUT; +import static com.example.rest.template.utils.AppConstants.DEFAULT_KEEP_ALIVE_TIME; +import static com.example.rest.template.utils.AppConstants.IDLE_CONNECTION_WAIT_TIME; +import static com.example.rest.template.utils.AppConstants.MAX_LOCALHOST_CONNECTIONS; +import static com.example.rest.template.utils.AppConstants.MAX_ROUTE_CONNECTIONS; +import static com.example.rest.template.utils.AppConstants.MAX_TOTAL_CONNECTIONS; +import static com.example.rest.template.utils.AppConstants.REQUEST_TIMEOUT; +import static com.example.rest.template.utils.AppConstants.SOCKET_TIMEOUT; import java.time.Duration; import java.util.Iterator; @@ -49,7 +56,7 @@ PoolingHttpClientConnectionManager poolingConnectionManager() { new PoolingHttpClientConnectionManager(registry); poolingConnectionManager.setDefaultSocketConfig( - SocketConfig.custom().setSoTimeout(Timeout.ofSeconds(REQUEST_TIMEOUT)).build()); + SocketConfig.custom().setSoTimeout(Timeout.ofSeconds(SOCKET_TIMEOUT)).build()); poolingConnectionManager.setDefaultConnectionConfig( ConnectionConfig.custom() .setConnectTimeout(Timeout.ofSeconds(CONNECTION_TIMEOUT)) diff --git a/httpClients/boot-restclient/pom.xml b/httpClients/boot-restclient/pom.xml index 095c8a9c1..8a95b62dd 100644 --- a/httpClients/boot-restclient/pom.xml +++ b/httpClients/boot-restclient/pom.xml @@ -29,11 +29,6 @@ org.springframework.boot spring-boot-starter-web - - org.glassfish.jaxb - jaxb-runtime - provided - org.springframework.boot spring-boot-starter-validation diff --git a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/BootRestClientApplication.java b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/BootRestClientApplication.java index df9613c12..1657067eb 100644 --- a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/BootRestClientApplication.java +++ b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/BootRestClientApplication.java @@ -1,9 +1,12 @@ package com.example.restclient.bootrestclient; +import com.example.restclient.bootrestclient.config.ApplicationProperties; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; @SpringBootApplication +@EnableConfigurationProperties({ApplicationProperties.class}) public class BootRestClientApplication { public static void main(String[] args) { diff --git a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/ApplicationProperties.java b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/ApplicationProperties.java new file mode 100644 index 000000000..e8cc1c4ed --- /dev/null +++ b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/ApplicationProperties.java @@ -0,0 +1,30 @@ +package com.example.restclient.bootrestclient.config; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; +import org.springframework.validation.annotation.Validated; + +@Getter +@Setter +@Validated +@ConfigurationProperties("application") +public class ApplicationProperties { + + @NotBlank(message = "External Call URL cant be Blank") + private String externalCallUrl; + + @NestedConfigurationProperty private Cors cors = new Cors(); + + @Getter + @Setter + public static class Cors { + private String pathPattern = "/api/**"; + private String allowedMethods = "*"; + private String allowedHeaders = "*"; + private String allowedOriginPatterns = "*"; + private boolean allowCredentials = true; + } +} diff --git a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/RestClientConfiguration.java b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/RestClientConfiguration.java index fe0b0a314..5cf8c540b 100644 --- a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/RestClientConfiguration.java +++ b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/RestClientConfiguration.java @@ -7,6 +7,7 @@ import java.time.Duration; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.web.client.RestClientCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpRequest; @@ -24,27 +25,33 @@ public class RestClientConfiguration { @Bean - RestClient restClient( - RestClient.Builder builder, + RestClient restClient(RestClient.Builder restClientBuilder) { + return restClientBuilder.build(); + } + + @Bean + RestClientCustomizer restClientCustomizer( + ApplicationProperties applicationProperties, @NonNull BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory) { - String baseUrl = "https://jsonplaceholder.typicode.com"; - DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl); + DefaultUriBuilderFactory factory = + new DefaultUriBuilderFactory(applicationProperties.getExternalCallUrl()); factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT); - return builder.uriBuilderFactory(factory) - .defaultHeaders( - httpHeaders -> { - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - httpHeaders.setAccept(List.of(MediaType.APPLICATION_JSON)); - }) - .requestFactory(bufferingClientHttpRequestFactory) - .requestInterceptor( - (request, body, execution) -> { - logRequest(request, body); - ClientHttpResponse response = execution.execute(request, body); - logResponse(response); - return response; - }) - .build(); + return restClientBuilder -> + restClientBuilder + .uriBuilderFactory(factory) + .defaultHeaders( + httpHeaders -> { + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + httpHeaders.setAccept(List.of(MediaType.APPLICATION_JSON)); + }) + .requestFactory(bufferingClientHttpRequestFactory) + .requestInterceptor( + (request, body, execution) -> { + logRequest(request, body); + ClientHttpResponse response = execution.execute(request, body); + logResponse(response); + return response; + }); } private void logResponse(ClientHttpResponse response) throws IOException { diff --git a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/SwaggerConfig.java b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/SwaggerConfig.java new file mode 100644 index 000000000..a0984b0a8 --- /dev/null +++ b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/SwaggerConfig.java @@ -0,0 +1,12 @@ +package com.example.restclient.bootrestclient.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.servers.Server; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +@OpenAPIDefinition( + info = @Info(title = "rest-client", version = "v1"), + servers = @Server(url = "/")) +public class SwaggerConfig {} diff --git a/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/WebMvcConfig.java b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/WebMvcConfig.java new file mode 100644 index 000000000..2f5532d11 --- /dev/null +++ b/httpClients/boot-restclient/src/main/java/com/example/restclient/bootrestclient/config/WebMvcConfig.java @@ -0,0 +1,24 @@ +package com.example.restclient.bootrestclient.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.lang.NonNull; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration(proxyBeanMethods = false) +@RequiredArgsConstructor +public class WebMvcConfig implements WebMvcConfigurer { + + private final ApplicationProperties properties; + + @Override + public void addCorsMappings(@NonNull CorsRegistry registry) { + ApplicationProperties.Cors propertiesCors = properties.getCors(); + registry.addMapping(propertiesCors.getPathPattern()) + .allowedMethods(propertiesCors.getAllowedMethods()) + .allowedHeaders(propertiesCors.getAllowedHeaders()) + .allowedOriginPatterns(propertiesCors.getAllowedOriginPatterns()) + .allowCredentials(propertiesCors.isAllowCredentials()); + } +} diff --git a/httpClients/boot-restclient/src/main/resources/application.properties b/httpClients/boot-restclient/src/main/resources/application.properties index fa61f01e2..1cecb1aad 100644 --- a/httpClients/boot-restclient/src/main/resources/application.properties +++ b/httpClients/boot-restclient/src/main/resources/application.properties @@ -1,4 +1,6 @@ spring.application.name=boot-restclient -spring.mvc.problemdetails.enabled=true -spring.threads.virtual.enabled=true \ No newline at end of file +spring.mvc.problemdetails.enabled=true +spring.threads.virtual.enabled=true + +application.external-call-url=https://jsonplaceholder.typicode.com