1919
2020package org .apache .cloudstack .storage .feign ;
2121
22-
2322import feign .RequestInterceptor ;
24- import feign .RequestTemplate ;
2523import feign .Retryer ;
26- import org .springframework .cloud .commons .httpclient .ApacheHttpClientFactory ;
24+ import feign .Client ;
25+ import feign .httpclient .ApacheHttpClient ;
26+ import feign .codec .Decoder ;
27+ import feign .codec .Encoder ;
28+ import feign .Response ;
29+ import feign .codec .DecodeException ;
30+ import feign .codec .EncodeException ;
31+ import com .fasterxml .jackson .databind .ObjectMapper ;
32+ import com .fasterxml .jackson .core .JsonProcessingException ;
2733import org .apache .http .conn .ConnectionKeepAliveStrategy ;
2834import org .apache .http .conn .ssl .NoopHostnameVerifier ;
2935import org .apache .http .conn .ssl .SSLConnectionSocketFactory ;
3036import org .apache .http .conn .ssl .TrustAllStrategy ;
3137import org .apache .http .impl .client .CloseableHttpClient ;
38+ import org .apache .http .impl .client .HttpClientBuilder ;
3239import org .apache .http .ssl .SSLContexts ;
3340import org .apache .logging .log4j .LogManager ;
3441import org .apache .logging .log4j .Logger ;
35- import org .springframework .context .annotation .Bean ;
36- import org .springframework .context .annotation .Configuration ;
37- import feign .Client ;
38- import feign .httpclient .ApacheHttpClient ;
42+
3943import javax .net .ssl .SSLContext ;
44+ import java .io .IOException ;
45+ import java .lang .reflect .Type ;
46+ import java .nio .charset .StandardCharsets ;
4047import java .util .concurrent .TimeUnit ;
4148
42- @ Configuration
4349public class FeignConfiguration {
44- private static Logger logger = LogManager .getLogger (FeignConfiguration .class );
50+ private static final Logger logger = LogManager .getLogger (FeignConfiguration .class );
4551
46- private int retryMaxAttempt = 3 ;
47-
48- private int retryMaxInterval = 5 ;
49-
50- private String ontapFeignMaxConnection = "80" ;
51-
52- private String ontapFeignMaxConnectionPerRoute = "20" ;
53-
54- @ Bean
55- public Client client (ApacheHttpClientFactory httpClientFactory ) {
52+ private final int retryMaxAttempt = 3 ;
53+ private final int retryMaxInterval = 5 ;
54+ private final String ontapFeignMaxConnection = "80" ;
55+ private final String ontapFeignMaxConnectionPerRoute = "20" ;
56+ private final ObjectMapper objectMapper = new ObjectMapper ();
5657
58+ public Client createClient () {
5759 int maxConn ;
5860 int maxConnPerRoute ;
5961 try {
@@ -68,10 +70,11 @@ public Client client(ApacheHttpClientFactory httpClientFactory) {
6870 logger .error ("ontapFeignClient: encounter exception while parse the max connection per route from env. setting default value" );
6971 maxConnPerRoute = 2 ;
7072 }
73+
7174 // Disable Keep Alive for Http Connection
7275 logger .debug ("ontapFeignClient: Setting the feign client config values as max connection: {}, max connections per route: {}" , maxConn , maxConnPerRoute );
7376 ConnectionKeepAliveStrategy keepAliveStrategy = (response , context ) -> 0 ;
74- CloseableHttpClient httpClient = httpClientFactory . createBuilder ()
77+ CloseableHttpClient httpClient = HttpClientBuilder . create ()
7578 .setMaxConnTotal (maxConn )
7679 .setMaxConnPerRoute (maxConnPerRoute )
7780 .setKeepAliveStrategy (keepAliveStrategy )
@@ -91,22 +94,55 @@ private SSLConnectionSocketFactory getSSLSocketFactory() {
9194 }
9295 }
9396
97+ public RequestInterceptor createRequestInterceptor () {
98+ return template -> {
99+ logger .info ("Feign Request URL: {}" , template .url ());
100+ logger .info ("HTTP Method: {}" , template .method ());
101+ logger .info ("Headers: {}" , template .headers ());
102+ if (template .body () != null ) {
103+ logger .info ("Body: {}" , new String (template .body ()));
104+ }
105+ };
106+ }
107+
108+ public Retryer createRetryer () {
109+ return new Retryer .Default (1000L , retryMaxInterval * 1000L , retryMaxAttempt );
110+ }
94111
95- @ Bean
96- public RequestInterceptor requestInterceptor () {
97- return new RequestInterceptor () {
112+ public Encoder createEncoder () {
113+ return new Encoder () {
98114 @ Override
99- public void apply (RequestTemplate template ) {
100- logger .info ("Feign Request URL: {}" , template .url ());
101- logger .info ("HTTP Method: {}" , template .method ());
102- logger .info ("Headers: {}" , template .headers ());
103- logger .info ("Body: {}" , template .requestBody ().asString ());
115+ public void encode (Object object , Type bodyType , feign .RequestTemplate template ) throws EncodeException {
116+ try {
117+ String json = objectMapper .writeValueAsString (object );
118+ logger .debug ("Encoding object to JSON: {}" , json );
119+
120+ // Use the String version - it handles charset conversion internally
121+ template .body (json );
122+
123+ template .header ("Content-Type" , "application/json" );
124+ } catch (JsonProcessingException e ) {
125+ throw new EncodeException ("Error encoding object to JSON" , e );
126+ }
104127 }
105128 };
106129 }
107130
108- @ Bean
109- public Retryer feignRetryer () {
110- return new Retryer .Default (1000L , retryMaxInterval * 1000L , retryMaxAttempt );
131+ public Decoder createDecoder () {
132+ return new Decoder () {
133+ @ Override
134+ public Object decode (Response response , Type type ) throws IOException , DecodeException {
135+ if (response .body () == null ) {
136+ return null ;
137+ }
138+ try {
139+ String json = new String (response .body ().asInputStream ().readAllBytes (), StandardCharsets .UTF_8 );
140+ return objectMapper .readValue (json , objectMapper .getTypeFactory ().constructType (type ));
141+ } catch (IOException e ) {
142+ throw new DecodeException (response .status (), "Error decoding JSON response" , response .request (), e );
143+ }
144+ }
145+ };
111146 }
112- }
147+
148+ }
0 commit comments