All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.danielliu1123.httpexchange.HttpExchangeProperties Maven / Gradle / Ivy

There is a newer version: 3.3.4
Show newest version
package io.github.danielliu1123.httpexchange;

import static java.util.Objects.isNull;
import static java.util.stream.Collectors.toMap;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;

/**
 * Http Clients Configuration Properties.
 *
 * @author Freeman
 */
@Data
@ConfigurationProperties(HttpExchangeProperties.PREFIX)
public class HttpExchangeProperties implements InitializingBean {
    public static final String PREFIX = "http-exchange";

    /**
     * Whether to enable http exchange autoconfiguration, default {@code true}.
     */
    private boolean enabled = true;
    /**
     * Base packages to scan, use {@link EnableExchangeClients#basePackages} first if configured.
     */
    private Set basePackages = new LinkedHashSet<>();
    /**
     * Exchange client interfaces to register as beans, use {@link EnableExchangeClients#clients} first if configured.
     *
     * @since 3.2.0
     */
    private Set> clients = new LinkedHashSet<>();
    /**
     * Default base url, 'http' scheme can be omitted.
     *
     * 

If loadbalancer is enabled, this value means the service id. * *

    *
  • localhost:8080
  • *
  • http://localhost:8080
  • *
  • https://localhost:8080
  • *
  • localhost:8080/api
  • *
  • user(service id)
  • *
*/ private String baseUrl; /** * Default headers will be added to all the requests. */ private List
headers = new ArrayList<>(); /** * Channels configuration. */ private List channels = new ArrayList<>(); /** * Whether to convert Java bean to query parameters, default value is {@code false}. */ private boolean beanToQueryEnabled = false; /** * Refresh configuration. */ private Refresh refresh = new Refresh(); /** * Client Type, if not specified, an appropriate client type will be set. * *
    *
  • Use {@link ClientType#REST_CLIENT} if none of the methods in the client return Reactive type. *
  • Use {@link ClientType#WEB_CLIENT} if any method in the client returns Reactive type. *
* *

In most cases, there's no need to explicitly specify the client type. * *

NOTE: the {@link #connectTimeout} and {@link #readTimeout} settings are not supported by {@link ClientType#WEB_CLIENT}. * * @see ClientType * @since 3.2.0 */ private ClientType clientType; /** * whether to process {@link org.springframework.web.bind.annotation.RequestMapping} based annotation, * default {@code false}. * *

Recommending to use {@link org.springframework.web.service.annotation.HttpExchange} instead of {@link org.springframework.web.bind.annotation.RequestMapping}. * * @since 3.2.0 */ private boolean requestMappingSupportEnabled = false; /** * Connect timeout duration, specified in milliseconds. * * @since 3.2.0 */ private Integer connectTimeout; /** * Read timeout duration, specified in milliseconds. * * @since 3.2.0 */ private Integer readTimeout; /** * Whether to check unused configuration, default {@code true}. * * @since 3.2.0 */ private boolean warnUnusedConfigEnabled = true; /** * Whether to enable loadbalancer, default {@code true}. * *

Prerequisites: *

    *
  • {@code spring-cloud-starter-loadbalancer} dependency in the classpath.
  • *
  • {@code spring.cloud.loadbalancer.enabled=true}
  • *
* * @since 3.2.0 */ private boolean loadbalancerEnabled = true; /** * Whether to enable http client reuse, default {@code true}. * *

Same {@link Channel} configuration will share the same http client if enabled. * * @since 3.2.2 */ private boolean httpClientReuseEnabled = true; @Data @NoArgsConstructor @AllArgsConstructor public static class Header { /** * Header key. */ private String key; /** * Header values. */ private List values = new ArrayList<>(); } @Override public void afterPropertiesSet() { merge(); } /** * Merge default configuration to channels configuration. */ void merge() { PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); for (Channel chan : channels) { mapper.from(baseUrl).when(e -> isNull(chan.getBaseUrl())).to(chan::setBaseUrl); mapper.from(clientType).when(e -> isNull(chan.getClientType())).to(chan::setClientType); mapper.from(connectTimeout) .when(e -> isNull(chan.getConnectTimeout())) .to(chan::setConnectTimeout); mapper.from(readTimeout).when(e -> isNull(chan.getReadTimeout())).to(chan::setReadTimeout); mapper.from(loadbalancerEnabled) .when(e -> isNull(chan.getLoadbalancerEnabled())) .to(chan::setLoadbalancerEnabled); mapper.from(httpClientReuseEnabled) .when(e -> isNull(chan.getHttpClientReuseEnabled())) .to(chan::setHttpClientReuseEnabled); // defaultHeaders + chan.headers LinkedHashMap> total = headers.stream() .collect(toMap(Header::getKey, Header::getValues, (oldV, newV) -> oldV, LinkedHashMap::new)); for (Header header : chan.getHeaders()) { total.put(header.getKey(), header.getValues()); } List

mergedHeaders = total.entrySet().stream() .map(e -> new Header(e.getKey(), e.getValue())) .toList(); chan.setHeaders(mergedHeaders); } } HttpExchangeProperties.Channel defaultClient() { return new Channel( null, baseUrl, headers, clientType, connectTimeout, readTimeout, loadbalancerEnabled, httpClientReuseEnabled, List.of(), List.of()); } @Data @NoArgsConstructor @AllArgsConstructor public static class Channel { /** * Optional channel name. */ private String name; /** * Base url, use {@link HttpExchangeProperties#baseUrl} if not set. */ private String baseUrl; /** * Default headers will be merged with {@link HttpExchangeProperties#headers}. */ private List
headers = new ArrayList<>(); /** * Client type, use {@link HttpExchangeProperties#clientType} if not set. * *

NOTE: * the {@link #connectTimeout} and {@link #readTimeout} settings are not supported for {@link ClientType#WEB_CLIENT}. * * @see ClientType */ private ClientType clientType; /** * Connection timeout duration, specified in milliseconds. * *

Use {@link HttpExchangeProperties#connectTimeout} if not set. * * @see HttpExchangeProperties#connectTimeout * @since 3.2.0 */ private Integer connectTimeout; /** * Read timeout duration, specified in milliseconds. * *

Use {@link HttpExchangeProperties#readTimeout} if not set. * * @see HttpExchangeProperties#readTimeout * @since 3.2.0 */ private Integer readTimeout; /** * Whether to enable loadbalancer, use {@link HttpExchangeProperties#loadbalancerEnabled} if not set. * * @see HttpExchangeProperties#loadbalancerEnabled * @since 3.2.0 */ private Boolean loadbalancerEnabled; /** * Whether to enable http client reuse, use {@link HttpExchangeProperties#httpClientReuseEnabled} if not set. * * @see HttpExchangeProperties#httpClientReuseEnabled * @since 3.2.2 */ private Boolean httpClientReuseEnabled; /** * Exchange Clients to apply this channel. * *

e.g. client {@code com.example.client.ExampleClient} can be identified by *

    *
  • {@code ExampleClient}, {@code exampleClient}, {@code example-client} (Class simple name) *
  • {@code com.example.client.ExampleClient} (Class canonical name) *
  • {@code com.**.*Client}, {@code com.example.**} (Ant style pattern) *
* *

This is a more flexible alternative to {@link HttpExchangeProperties.Channel#classes}. * * @see Class#getCanonicalName() * @see org.springframework.util.AntPathMatcher */ private List clients = new ArrayList<>(); /** * Exchange Client classes to apply this channel. * *

This is a more IDE-friendly alternative to {@link HttpExchangeProperties.Channel#clients}. */ private List> classes = new ArrayList<>(); } @Data public static class Refresh { public static final String PREFIX = HttpExchangeProperties.PREFIX + ".refresh"; /** * Whether to enable refresh exchange clients, default {@code false}. * *

This feature needs {@code spring-cloud-context} dependency in the classpath. * *

NOTE: This feature is not supported by native image. * * @see Refresh Scope */ private boolean enabled = false; } public enum ClientType { /** * @see RestClient */ REST_CLIENT, /** * @see WebClient */ WEB_CLIENT, /** * @see RestTemplate */ REST_TEMPLATE } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy