Skip to content

Commit 7e90f83

Browse files
committed
Fix ResponseHandler for return of generic BinaryData types
1 parent a0c7823 commit 7e90f83

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

sdk/clientcore/annotation-processor-test/src/main/java/io/clientcore/annotation/processor/test/SpecialReturnBodiesServiceImpl.java

+31
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
import io.clientcore.core.implementation.utils.UriEscapers;
1111
import io.clientcore.core.models.binarydata.BinaryData;
1212
import java.io.InputStream;
13+
import java.util.List;
1314
import io.clientcore.annotation.processor.test.implementation.SpecialReturnBodiesService;
1415
import io.clientcore.core.instrumentation.logging.ClientLogger;
1516
import io.clientcore.core.serialization.json.JsonSerializer;
1617
import io.clientcore.core.serialization.xml.XmlSerializer;
1718
import io.clientcore.core.http.models.HttpResponseException;
19+
import io.clientcore.core.utils.CoreUtils;
20+
import java.lang.reflect.ParameterizedType;
21+
import io.clientcore.core.serialization.SerializationFormat;
1822

1923
/**
2024
* Initializes a new instance of the SpecialReturnBodiesServiceImpl type.
@@ -147,4 +151,31 @@ public Response<InputStream> getInputStreamWithResponse(String url) {
147151
}
148152
return new Response<>(networkResponse.getRequest(), responseCode, networkResponse.getHeaders(), networkResponse.getValue().toStream());
149153
}
154+
155+
@SuppressWarnings("cast")
156+
@Override
157+
public Response<List<BinaryData>> getListOfBinaryData(String endpoint) {
158+
// Create the HttpRequest.
159+
HttpRequest httpRequest = new HttpRequest().setMethod(HttpMethod.GET).setUri(endpoint + "/type/array/unknown");
160+
// Send the request through the httpPipeline
161+
Response<BinaryData> networkResponse = this.httpPipeline.send(httpRequest);
162+
int responseCode = networkResponse.getStatusCode();
163+
boolean expectedResponse = responseCode == 200;
164+
if (!expectedResponse) {
165+
String errorMessage = networkResponse.getValue().toString();
166+
networkResponse.close();
167+
throw new HttpResponseException(errorMessage, networkResponse, null);
168+
}
169+
List<BinaryData> deserializedResult;
170+
ParameterizedType returnType = CoreUtils.createParameterizedType(List.class, BinaryData.class);
171+
SerializationFormat serializationFormat = CoreUtils.serializationFormatFromContentType(httpRequest.getHeaders());
172+
if (jsonSerializer.supportsFormat(serializationFormat)) {
173+
deserializedResult = CoreUtils.decodeNetworkResponse(networkResponse.getValue(), jsonSerializer, returnType);
174+
} else if (xmlSerializer.supportsFormat(serializationFormat)) {
175+
deserializedResult = CoreUtils.decodeNetworkResponse(networkResponse.getValue(), xmlSerializer, returnType);
176+
} else {
177+
throw new UnsupportedOperationException("None of the provided serializers support the format: " + serializationFormat + ".");
178+
}
179+
return new Response<>(networkResponse.getRequest(), responseCode, networkResponse.getHeaders(), deserializedResult);
180+
}
150181
}

sdk/clientcore/annotation-processor-test/src/main/java/io/clientcore/annotation/processor/test/implementation/SpecialReturnBodiesService.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import io.clientcore.core.annotations.ServiceInterface;
66
import io.clientcore.core.http.annotations.HostParam;
77
import io.clientcore.core.http.annotations.HttpRequestInformation;
8+
import io.clientcore.core.http.annotations.UnexpectedResponseExceptionDetail;
89
import io.clientcore.core.http.models.HttpMethod;
910
import io.clientcore.core.http.models.Response;
1011
import io.clientcore.core.http.pipeline.HttpPipeline;
1112
import io.clientcore.core.models.binarydata.BinaryData;
12-
1313
import java.io.InputStream;
1414
import java.lang.reflect.InvocationTargetException;
15+
import java.util.List;
1516

1617
/**
1718
* Service that tests special return bodies for methods.
@@ -100,4 +101,14 @@ static SpecialReturnBodiesService getNewInstance(HttpPipeline pipeline) {
100101
*/
101102
@HttpRequestInformation(method = HttpMethod.GET, path = "bytes", expectedStatusCodes = { 200 })
102103
Response<InputStream> getInputStreamWithResponse(@HostParam("url") String url);
104+
105+
/**
106+
* Gets a binary payload from the specified URL.
107+
*
108+
* @param endpoint The URL.
109+
* @return A response containing the list of binary data.
110+
*/
111+
@HttpRequestInformation(method = HttpMethod.GET, path = "/type/array/unknown", expectedStatusCodes = { 200 })
112+
@UnexpectedResponseExceptionDetail
113+
Response<List<BinaryData>> getListOfBinaryData(@HostParam("url") String endpoint);
103114
}

sdk/clientcore/annotation-processor/src/main/java/io/clientcore/annotation/processor/utils/ResponseHandler.java

+28-13
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@
1717
import io.clientcore.core.models.binarydata.BinaryData;
1818
import io.clientcore.core.serialization.SerializationFormat;
1919
import io.clientcore.core.utils.CoreUtils;
20-
20+
import java.io.InputStream;
21+
import java.lang.reflect.ParameterizedType;
22+
import java.util.List;
23+
import java.util.stream.Collectors;
2124
import javax.lang.model.element.TypeElement;
2225
import javax.lang.model.type.ArrayType;
2326
import javax.lang.model.type.DeclaredType;
2427
import javax.lang.model.type.TypeKind;
2528
import javax.lang.model.type.TypeMirror;
26-
import java.io.InputStream;
27-
import java.lang.reflect.ParameterizedType;
28-
import java.util.List;
29-
import java.util.stream.Collectors;
3029

3130
/**
3231
* Utility class to generate response body mode assignment and response handling based on the response body mode.
@@ -148,24 +147,40 @@ private static void handleRequestReturn(BlockStmt body, TypeMirror returnType, j
148147
addReturnStatement(body, returnIsResponse, "networkResponse.getValue().toStream()");
149148
} else if (TypeUtil.isTypeOrSubTypeOf(entityType, BinaryData.class)) {
150149
// Return type is a BinaryData. Return the network response body.
151-
// DO NOT close the network response for this return as it will result in the BinaryData either being
152-
// closed or invalid when it is returned.
150+
// DO NOT close the network response for this return as it will result in the BinaryData either being closed or invalid when it is returned.
153151
if (returnIsResponse) {
152+
if (returnType instanceof DeclaredType) {
153+
DeclaredType declaredType = (DeclaredType) returnType;
154+
if (!declaredType.getTypeArguments().isEmpty()
155+
&& ((TypeElement) ((DeclaredType) declaredType.getTypeArguments().get(0)).asElement())
156+
.getQualifiedName()
157+
.contentEquals(List.class.getCanonicalName())) {
158+
// Response<List<BinaryData>> or other generics
159+
handleDeclaredTypes(body, returnType, serializationFormatSet, true);
160+
return;
161+
}
162+
}
163+
// Raw Response or not a DeclaredType
154164
body.addStatement(StaticJavaParser.parseStatement("return networkResponse;"));
155165
} else {
156166
body.addStatement(StaticJavaParser.parseStatement("return networkResponse.getValue();"));
157167
}
158168
} else {
159169
// Fallback to a generalized code path that handles declared types as the entity, which uses deserialization
160170
// to create the return.
161-
String typeCast = determineTypeCast(returnType, body);
171+
handleDeclaredTypes(body, returnType, serializationFormatSet, returnIsResponse);
172+
}
173+
}
162174

163-
// Initialize the variable that will be used in the return statement.
164-
body.addStatement(StaticJavaParser.parseStatement(typeCast + " deserializedResult;"));
165-
handleDeclaredTypeResponse(body, (DeclaredType) returnType, serializationFormatSet, typeCast);
175+
private static void handleDeclaredTypes(BlockStmt body, TypeMirror returnType, boolean serializationFormatSet,
176+
boolean returnIsResponse) {
177+
String typeCast = determineTypeCast(returnType, body);
166178

167-
addReturnStatement(body, returnIsResponse, "deserializedResult");
168-
}
179+
// Initialize the variable that will be used in the return statement.
180+
body.addStatement(StaticJavaParser.parseStatement(typeCast + " deserializedResult;"));
181+
handleDeclaredTypeResponse(body, (DeclaredType) returnType, serializationFormatSet, typeCast);
182+
183+
addReturnStatement(body, returnIsResponse, "deserializedResult");
169184
}
170185

171186
// Helper method that creates the return statement as either Response<T> or T.

0 commit comments

Comments
 (0)