3939import com .g42cloud .sdk .core .http .LocationType ;
4040import com .g42cloud .sdk .core .http .SdkFormDataBody ;
4141import com .g42cloud .sdk .core .impl .DefaultHttpClient ;
42+ import com .g42cloud .sdk .core .progress .ProgressInputStream ;
43+ import com .g42cloud .sdk .core .progress .ProgressRequest ;
44+ import com .g42cloud .sdk .core .progress .SimpleProgressManager ;
4245import com .g42cloud .sdk .core .utils .CastUtils ;
4346import com .g42cloud .sdk .core .utils .ExceptionUtils ;
47+ import com .g42cloud .sdk .core .utils .HttpUtils ;
4448import com .g42cloud .sdk .core .utils .JsonUtils ;
4549import com .g42cloud .sdk .core .utils .StringUtils ;
4650import org .slf4j .Logger ;
4751import org .slf4j .LoggerFactory ;
4852
53+ import java .io .BufferedInputStream ;
4954import java .net .MalformedURLException ;
5055import java .net .URL ;
5156import java .time .OffsetDateTime ;
@@ -185,7 +190,7 @@ public <ReqT, ResT> ResT syncInvokeHttp(ReqT request, HttpRequestDef<ReqT, ResT>
185190 }
186191 printAccessLog (httpRequest , httpResponse , exchange );
187192 handleException (httpRequest , httpResponse );
188- return extractResponse (httpResponse , reqDef );
193+ return extractResponse (httpRequest , httpResponse , reqDef );
189194 } finally {
190195 SdkExchangeCache .removeExchange (exchangeId );
191196 }
@@ -233,7 +238,7 @@ public <ReqT, ResT> CompletableFuture<ResT> asyncInvokeHttp(ReqT request, HttpRe
233238 return httpClient .asyncInvokeHttp (validHttpRequest ).thenApplyAsync (httpResponse -> {
234239 printAccessLog (finalValidHttpRequest , httpResponse , exchange );
235240 handleException (finalValidHttpRequest , httpResponse );
236- return extractResponse (httpResponse , reqDef );
241+ return extractResponse (finalValidHttpRequest , httpResponse , reqDef );
237242 }, httpConfig .getExecutorService ()).whenCompleteAsync ((r , e ) ->
238243 SdkExchangeCache .removeExchange (exchangeIdRef .get ()), httpConfig .getExecutorService ());
239244 }, httpConfig .getExecutorService ());
@@ -285,9 +290,15 @@ protected <ReqT, ResT> HttpRequest buildRequest(ReqT request, HttpRequestDef<Req
285290 }
286291 }
287292
288- // upload
289- if (request instanceof SdkStreamRequest ) {
290- httpRequestBuilder .withBody (((SdkStreamRequest ) request ).extractBody ());
293+ // handle upload/download progress
294+ if (request instanceof ProgressRequest ) {
295+ ProgressRequest progressRequest = (ProgressRequest ) request ;
296+ httpRequestBuilder .withProgressListener ((progressRequest .getProgressListener ()))
297+ .withProgressInterval (progressRequest .getProgressInterval () > 0 ?
298+ progressRequest .getProgressInterval () : Constants .DEFAULT_PROGRESS_INTERVAL );
299+ if (request instanceof SdkStreamRequest ) {
300+ httpRequestBuilder .withBody (((SdkStreamRequest ) request ).extractBody ());
301+ }
291302 }
292303
293304 httpRequestBuilder .addHeader (Constants .USER_AGENT , "g42cloud-usdk-java/3.0" );
@@ -311,12 +322,13 @@ private void buildRequestBody(HttpRequest.HttpRequestBuilder httpRequestBuilder,
311322 } else if (reqValue instanceof SdkSerializable ) {
312323 httpRequestBuilder .withBodyAsString (((SdkSerializable <?>) reqValue ).serialize ());
313324 } else {
314- httpRequestBuilder .withBodyAsString (JsonUtils .toJSON (reqValue ));
325+ String bodyString = reqValue instanceof String ? (String ) reqValue : JsonUtils .toJSON (reqValue );
326+ httpRequestBuilder .withBodyAsString (bodyString );
315327 }
316328 }
317329
318330 private void buildQueryParams (HttpRequest .HttpRequestBuilder httpRequestBuilder , String fieldName ,
319- Object reqValue ) {
331+ Object reqValue ) {
320332 if (reqValue instanceof Collection ) {
321333 httpRequestBuilder .addQueryParam (fieldName , buildCollectionQueryParams (reqValue ));
322334 } else if (reqValue instanceof Map ) {
@@ -380,52 +392,75 @@ private void handleException(HttpRequest httpRequest, HttpResponse httpResponse)
380392 }
381393 }
382394
383- private <ReqT , ResT > ResT extractResponse (HttpResponse httpResponse , HttpRequestDef <ReqT , ResT > reqDef ) {
384- int code = httpResponse . getStatusCode ();
395+ private <T > T processTextBasedType (HttpResponse httpResponse , HttpRequestDef <?, T > reqDef )
396+ throws InstantiationException , IllegalAccessException {
385397
386- try {
387- ResT resT ;
388- String stringResult = httpResponse .getBodyAsString ();
389- String respContentType = httpResponse .getContentType ();
390-
391- if (Objects .nonNull (respContentType )
392- && (respContentType .startsWith (Constants .MEDIATYPE .APPLICATION_OCTET_STREAM )
393- || respContentType .startsWith (Constants .MEDIATYPE .IMAGE )
394- || respContentType .startsWith (Constants .MEDIATYPE .APPLICATION_BSON ))) {
395- resT = reqDef .getResponseType ().newInstance ();
396- if (resT instanceof SdkStreamResponse ) {
397- resT = CastUtils .cast (((SdkStreamResponse ) resT ).parseBody (httpResponse .getBody ()));
398- }
399- } else {
400- if (SdkSerializable .class .isAssignableFrom (reqDef .getResponseType ())) {
401- resT = deserializeSerializableResponse (reqDef .getResponseType (), stringResult );
402- } else if (!reqDef .hasResponseField (Constants .BODY )) {
403- resT = JsonUtils .toObjectIgnoreUnknown (stringResult , reqDef .getResponseType ());
404- if (Objects .isNull (resT )) {
405- resT = reqDef .getResponseType ().newInstance ();
406- }
398+ T response ;
399+ String stringResult = httpResponse .getBodyAsString ();
400+ int statusCode = httpResponse .getStatusCode ();
401+ if (SdkSerializable .class .isAssignableFrom (reqDef .getResponseType ())) {
402+ // Processes the response that implements the SdkSerializable interface
403+ response = deserializeSerializableResponse (reqDef .getResponseType (), stringResult );
404+ } else if (!reqDef .hasResponseField (Constants .BODY )) {
405+ // process response without body
406+ response = JsonUtils .toObjectIgnoreUnknown (stringResult , reqDef .getResponseType ());
407+ if (Objects .isNull (response )) {
408+ response = reqDef .getResponseType ().newInstance ();
409+ }
407410
408- if (reqDef .hasResponseField (String .valueOf (code ))) {
409- Field <ResT , ?> resTField = reqDef .getResponseField (String .valueOf (code ));
410- resTField .writeValueSafe (resT ,
411- JsonUtils .toObjectIgnoreUnknown (stringResult , resTField .getFieldType ()),
412- resTField .getFieldType ());
413- }
411+ if (reqDef .hasResponseField (String .valueOf (statusCode ))) {
412+ Field <T , ?> resTField = reqDef .getResponseField (String .valueOf (statusCode ));
413+ resTField .writeValueSafe (response ,
414+ JsonUtils .toObjectIgnoreUnknown (stringResult , resTField .getFieldType ()),
415+ resTField .getFieldType ());
416+ }
414417
415- } else {
416- resT = reqDef .getResponseType ().newInstance ();
417- Field <ResT , ?> responseField = reqDef .getResponseField (Constants .BODY );
418- Object obj = responseToObject (stringResult , responseField );
419- responseField .writeValueSafe (resT , obj , responseField .getFieldType ());
418+ } else {
419+ // process response with body[object, map, list, string...]
420+ response = reqDef .getResponseType ().newInstance ();
421+ Field <T , ?> responseField = reqDef .getResponseField (Constants .BODY );
422+ Object obj = responseToObject (stringResult , responseField );
423+ responseField .writeValueSafe (response , obj , responseField .getFieldType ());
424+
425+ if (reqDef .hasResponseField (String .valueOf (statusCode ))) {
426+ Field <T , ?> resTField = reqDef .getResponseField (String .valueOf (statusCode ));
427+ resTField .writeValueSafe (response , obj , resTField .getFieldType ());
428+ }
429+ }
420430
421- if (reqDef .hasResponseField (String .valueOf (code ))) {
422- Field <ResT , ?> resTField = reqDef .getResponseField (String .valueOf (code ));
423- resTField .writeValueSafe (resT , obj , resTField .getFieldType ());
424- }
425- }
431+ return response ;
432+ }
433+
434+ private <T > T processStreamType (HttpRequest httpRequest , HttpResponse httpResponse , HttpRequestDef <?, T > reqDef )
435+ throws InstantiationException , IllegalAccessException {
436+
437+ T response = reqDef .getResponseType ().newInstance ();
438+ if (response instanceof SdkStreamResponse ) {
439+ if (Objects .nonNull (httpRequest .getProgressListener ())) {
440+ SimpleProgressManager progressManager = new SimpleProgressManager (
441+ httpResponse .getContentLength (), 0 ,
442+ httpRequest .getProgressListener (), httpRequest .getProgressInterval ());
443+ ((SdkStreamResponse ) response ).parseBody (new BufferedInputStream (
444+ new ProgressInputStream (httpResponse .getBody (), progressManager ),
445+ Constants .DEFAULT_READ_BUFFER_STREAM ));
446+ } else if (Objects .nonNull (httpResponse .getContentType ())
447+ && HttpUtils .isBsonContentType (httpResponse .getContentType ())) {
448+ response = CastUtils .cast (((SdkStreamResponse ) response ).parseBody (httpResponse .getBodyAsBytes ()));
449+ } else {
450+ response = CastUtils .cast (((SdkStreamResponse ) response ).parseBody (httpResponse .getBody ()));
426451 }
452+ }
453+
454+ return response ;
455+ }
456+
457+ private <ReqT , ResT > ResT extractResponse (
458+ HttpRequest httpRequest , HttpResponse httpResponse , HttpRequestDef <ReqT , ResT > reqDef ) {
459+
460+ try {
461+ ResT finalResT = HttpUtils .isTextBasedContentType (httpResponse .getContentType ()) ?
462+ processTextBasedType (httpResponse , reqDef ) : processStreamType (httpRequest , httpResponse , reqDef );
427463
428- ResT finalResT = resT ;
429464 reqDef .getResponseFields ().forEach (resTField -> {
430465 if (resTField .getLocation () == LocationType .Header ) {
431466 fillHeaderField (httpResponse , finalResT , resTField );
0 commit comments