Skip to content
This repository has been archived by the owner on Jun 30, 2023. It is now read-only.

Commit

Permalink
fix array path parameter deserialization
Browse files Browse the repository at this point in the history
This change fixes path parameter deserialization when the parameter is
an array-like structure. Previously, this only worked for query
parameters, and a string literal was injected as an array for path
parameters.
  • Loading branch information
tangiel committed Feb 17, 2018
1 parent 968f420 commit 8378711
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.api.server.spi.config.model.ApiParameterConfig;
import com.google.api.server.spi.config.model.ApiSerializationConfig;
import com.google.api.server.spi.response.BadRequestException;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;

import com.fasterxml.jackson.databind.JsonNode;
Expand All @@ -31,6 +32,7 @@

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
Expand All @@ -48,8 +50,10 @@
* by stuffing path and query parameters into the main request body.
*/
public class RestServletRequestParamReader extends ServletRequestParamReader {

private static final Logger logger = Logger
.getLogger(RestServletRequestParamReader.class.getName());
private static final Splitter COMPOSITE_PATH_SPLITTER = Splitter.on(',');

private final Map<String, String> rawPathParameters;
private final Map<String, ApiParameterConfig> parameterConfigMap;
Expand Down Expand Up @@ -99,11 +103,10 @@ public Object[] read() throws ServiceException {
Class<?> parameterClass = parameterMap.get(parameterName);
ApiParameterConfig parameterConfig = parameterConfigMap.get(parameterName);
if (parameterClass != null && parameterConfig.isRepeated()) {
ArrayNode values = (ArrayNode) objectReader.createArrayNode();
ArrayNode values = body.putArray(parameterName);
for (String value : servletRequest.getParameterValues(parameterName)) {
values.add(value);
}
body.set(parameterName, values);
} else {
body.put(parameterName, servletRequest.getParameterValues(parameterName)[0]);
}
Expand All @@ -113,7 +116,14 @@ public Object[] read() throws ServiceException {
String parameterName = entry.getKey();
Class<?> parameterClass = parameterMap.get(parameterName);
if (parameterClass != null && !body.has(parameterName)) {
body.put(parameterName, entry.getValue());
if (parameterConfigMap.get(parameterName).isRepeated()) {
ArrayNode values = body.putArray(parameterName);
for (String value : COMPOSITE_PATH_SPLITTER.split(entry.getValue())) {
values.add(value);
}
} else {
body.put(parameterName, entry.getValue());
}
}
}
for (Entry<String, ApiParameterConfig> entry : parameterConfigMap.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -61,6 +62,7 @@ public class RestServletRequestParamReaderTest {
private EndpointMethod endpointMethod;
private MockHttpServletRequest request;
private ApiSerializationConfig serializationConfig;
private ApiConfig apiConfig;
private ApiMethodConfig methodConfig;

@Before
Expand All @@ -72,13 +74,12 @@ public void setUp() throws Exception {
ServiceContext serviceContext = ServiceContext.create();
serializationConfig = new ApiSerializationConfig();
TypeLoader typeLoader = new TypeLoader();
ApiConfig config = (new ApiConfig.Factory()).create(serviceContext, typeLoader,
TestApi.class);
apiConfig = new ApiConfig.Factory().create(serviceContext, typeLoader, TestApi.class);
ApiConfigAnnotationReader annotationReader = new ApiConfigAnnotationReader();
annotationReader.loadEndpointClass(serviceContext, TestApi.class, config);
annotationReader.loadEndpointClass(serviceContext, TestApi.class, apiConfig);
annotationReader.loadEndpointMethods(serviceContext, TestApi.class,
config.getApiClassConfig().getMethods());
methodConfig = config.getApiClassConfig().getMethods().get(endpointMethod);
apiConfig.getApiClassConfig().getMethods());
methodConfig = apiConfig.getApiClassConfig().getMethods().get(endpointMethod);
}

@Test
Expand Down Expand Up @@ -186,6 +187,20 @@ public void gzippedRequest() throws Exception {
.inOrder();
}

@Test
public void arrayPathParam() throws Exception {
endpointMethod = EndpointMethod.create(TestApi.class,
TestApi.class.getMethod("testArrayPathParam", ArrayList.class));
methodConfig = apiConfig.getApiClassConfig().getMethods().get(endpointMethod);
RestServletRequestParamReader reader = createReader(ImmutableMap.of("values", "4,3,2,1"));

Object[] params = reader.read();

assertThat(params).hasLength(endpointMethod.getParameterClasses().length);
assertThat(params).asList()
.containsExactly(ImmutableList.of("4", "3", "2", "1"));
}

private RestServletRequestParamReader createReader(Map<String, String> rawPathParameters) {
return new RestServletRequestParamReader(endpointMethod, request, null,
serializationConfig, methodConfig, rawPathParameters);
Expand Down Expand Up @@ -213,6 +228,13 @@ public void test(@Named("path") long path, @Named("dates") List<SimpleDate> date
@Named("defaultvalue") @DefaultValue("2015-01-01") SimpleDate defaultValue,
TestResource resource) {
}

@ApiMethod(
name = "testArrayPathParam",
httpMethod = HttpMethod.GET,
path = "testArrayPathParam/{values}")
public void testArrayPathParam(@Named("values") ArrayList<String> values) {
}
}

private static byte[] compress(byte[] bytes) {
Expand Down

0 comments on commit 8378711

Please sign in to comment.