Skip to content

Commit ea4df5f

Browse files
committed
Enable use of nullable maps for headers, params and query
1 parent 3d29724 commit ea4df5f

File tree

3 files changed

+106
-11
lines changed

3 files changed

+106
-11
lines changed

src/main/java/com/microsoft/azure/functions/worker/binding/RpcHttpRequestDataSource.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.util.Arrays;
77
import java.util.List;
88
import java.util.Map;
9+
import java.util.stream.Collectors;
910

11+
import com.microsoft.azure.functions.rpc.messages.NullableTypes;
1012
import org.apache.commons.lang3.reflect.TypeUtils;
1113

1214
import com.microsoft.azure.functions.HttpMethod;
@@ -22,8 +24,10 @@ public RpcHttpRequestDataSource(String name, RpcHttp value) {
2224
super(name, null, HTTP_DATA_OPERATIONS);
2325
this.httpPayload = value;
2426
this.bodyDataSource = BindingDataStore.rpcSourceFromTypedData(null, this.httpPayload.getBody());
25-
this.fields = Arrays.asList(this.httpPayload.getHeadersMap(), this.httpPayload.getQueryMap(),
26-
this.httpPayload.getParamsMap());
27+
this.fields = Arrays.asList(
28+
convertFromNullableMap(this.httpPayload.getNullableHeadersMap()),
29+
convertFromNullableMap(this.httpPayload.getNullableQueryMap()),
30+
convertFromNullableMap(this.httpPayload.getNullableParamsMap()));
2731
this.setValue(this);
2832
}
2933

@@ -45,12 +49,12 @@ public HttpMethod getHttpMethod() {
4549

4650
@Override
4751
public Map<String, String> getHeaders() {
48-
return this.parentDataSource.httpPayload.getHeadersMap();
52+
return convertFromNullableMap(this.parentDataSource.httpPayload.getNullableHeadersMap());
4953
}
5054

5155
@Override
5256
public Map<String, String> getQueryParameters() {
53-
return this.parentDataSource.httpPayload.getQueryMap();
57+
return convertFromNullableMap(this.parentDataSource.httpPayload.getNullableQueryMap());
5458
}
5559

5660
@Override
@@ -86,4 +90,10 @@ public Builder createResponseBuilder(HttpStatus status) {
8690
return new HttpRequestMessageImpl(v, bodyData.getValue());
8791
});
8892
}
93+
94+
private static Map<String, String> convertFromNullableMap(Map<String, NullableTypes.NullableString> nullableMap) {
95+
return nullableMap.entrySet().stream().collect(
96+
Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getValue())
97+
);
98+
}
8999
}

src/main/java/com/microsoft/azure/functions/worker/handler/WorkerInitRequestHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ String execute(WorkerInitRequest request, WorkerInitResponse.Builder response) {
2323
response.putCapabilities("TypedDataCollection", "TypedDataCollection");
2424
response.putCapabilities("WorkerStatus", "WorkerStatus");
2525
response.putCapabilities("RpcHttpBodyOnly", "RpcHttpBodyOnly");
26+
response.putCapabilities("UseNullableValueDictionaryForHttp", "UseNullableValueDictionaryForHttp");
2627
response.putCapabilities("RpcHttpTriggerMetadataRemoved", "RpcHttpTriggerMetadataRemoved");
2728
response.putCapabilities("HandlesWorkerTerminateMessage", "HandlesWorkerTerminateMessage");
2829
response.setWorkerMetadata(composeWorkerMetadata());

src/test/java/com/microsoft/azure/functions/worker/binding/tests/RpcHttpRequestDataSourceTest.java

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.lang.reflect.Method;
66
import java.lang.reflect.Parameter;
77
import java.util.*;
8+
9+
import com.microsoft.azure.functions.rpc.messages.NullableTypes.NullableString;
810
import com.microsoft.azure.functions.HttpRequestMessage;
911
import com.microsoft.azure.functions.HttpStatus;
1012
import com.microsoft.azure.functions.rpc.messages.RpcHttp;
@@ -26,13 +28,23 @@ public void HttpRequestIntBody(HttpRequestMessage<Integer> request) {
2628
public void HttpRequestBinaryBody(HttpRequestMessage<byte[]> request) {
2729
}
2830

29-
public static RpcHttp getTestRpcHttp(Object inputBody) throws Exception {
31+
public static RpcHttp getTestRpcHttp(
32+
Object inputBody,
33+
Map<String, String> headersMap,
34+
Map<String, String> queryMap) throws Exception {
3035
TypedData.Builder dataBuilder = TypedData.newBuilder();
3136
RpcHttp.Builder httpBuilder = RpcHttp.newBuilder()
3237
.setStatusCode(Integer.toString(HttpStatus.OK.value()));
33-
Map<String, String> headers = new HashMap<>();
34-
headers.put("header", "testHeader");
35-
headers.forEach(httpBuilder::putHeaders);
38+
if (headersMap != null) {
39+
for (String key : headersMap.keySet()) {
40+
httpBuilder.putNullableHeaders(key, NullableString.newBuilder().setValue(headersMap.get(key)).build());
41+
}
42+
}
43+
if (queryMap != null) {
44+
for (String key : queryMap.keySet()) {
45+
httpBuilder.putNullableQuery(key, NullableString.newBuilder().setValue(queryMap.get(key)).build());
46+
}
47+
}
3648
RpcUnspecifiedDataTarget bodyTarget = new RpcUnspecifiedDataTarget();
3749
Object body = inputBody;
3850
bodyTarget.setValue(body);
@@ -41,14 +53,86 @@ public static RpcHttp getTestRpcHttp(Object inputBody) throws Exception {
4153
return httpBuilder.build();
4254
}
4355

56+
@Test
57+
public void rpcHttpDataSource_To_HttpRequestMessage_NullableQueryParamsEmpty() throws Exception {
58+
59+
Method httpRequestMessageStringBodyMethod = getFunctionMethod("HttpRequestStringBody");
60+
Map<String, String> queryMap = new HashMap<String, String>() {{
61+
put("name", "");
62+
}};
63+
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
64+
String sourceKey = "testRpcHttp";
65+
RpcHttp input = getTestRpcHttp(null, null, queryMap);
66+
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
67+
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
68+
parameters[0].getParameterizedType());
69+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
70+
HttpRequestMessage<?> requestMsg = (HttpRequestMessage<?>) actualArg.getValue();
71+
assertEquals(requestMsg.getQueryParameters().get("name"), "");
72+
}
73+
74+
@Test
75+
public void rpcHttpDataSource_To_HttpRequestMessage_NullableQueryParamsNonEmpty() throws Exception {
76+
77+
Method httpRequestMessageStringBodyMethod = getFunctionMethod("HttpRequestStringBody");
78+
Map<String, String> queryMap = new HashMap<String, String>() {{
79+
put("name", "random");
80+
}};
81+
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
82+
String sourceKey = "testRpcHttp";
83+
RpcHttp input = getTestRpcHttp(null, null, queryMap);
84+
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
85+
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
86+
parameters[0].getParameterizedType());
87+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
88+
HttpRequestMessage<?> requestMsg = (HttpRequestMessage<?>) actualArg.getValue();
89+
assertEquals(requestMsg.getQueryParameters().get("name"), "random");
90+
}
91+
92+
@Test
93+
public void rpcHttpDataSource_To_HttpRequestMessage_NullableHeadersEmpty() throws Exception {
94+
95+
Method httpRequestMessageStringBodyMethod = getFunctionMethod("HttpRequestStringBody");
96+
Map<String, String> headersMap = new HashMap<String, String>() {{
97+
put("cookie", "");
98+
}};
99+
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
100+
String sourceKey = "testRpcHttp";
101+
RpcHttp input = getTestRpcHttp(null, headersMap, null);
102+
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
103+
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
104+
parameters[0].getParameterizedType());
105+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
106+
HttpRequestMessage<?> requestMsg = (HttpRequestMessage<?>) actualArg.getValue();
107+
assertEquals(requestMsg.getHeaders().get("cookie"), "");
108+
}
109+
110+
@Test
111+
public void rpcHttpDataSource_To_HttpRequestMessage_NullableHeadersNonEmpty() throws Exception {
112+
113+
Method httpRequestMessageStringBodyMethod = getFunctionMethod("HttpRequestStringBody");
114+
Map<String, String> headersMap = new HashMap<String, String>() {{
115+
put("cookie", "foo=bar");
116+
}};
117+
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
118+
String sourceKey = "testRpcHttp";
119+
RpcHttp input = getTestRpcHttp(null, headersMap, null);
120+
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
121+
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
122+
parameters[0].getParameterizedType());
123+
BindingData actualArg = actualBindingData.orElseThrow(WrongMethodTypeException::new);
124+
HttpRequestMessage<?> requestMsg = (HttpRequestMessage<?>) actualArg.getValue();
125+
assertEquals(requestMsg.getHeaders().get("cookie"), "foo=bar");
126+
}
127+
44128
@Test
45129
public void rpcHttpDataSource_To_HttpRequestMessage_StringBody() throws Exception {
46130

47131
Method httpRequestMessageStringBodyMethod = getFunctionMethod("HttpRequestStringBody");
48132

49133
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
50134
String sourceKey = "testRpcHttp";
51-
RpcHttp input = getTestRpcHttp("testStringBody");
135+
RpcHttp input = getTestRpcHttp("testStringBody", null, null);
52136
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
53137
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
54138
parameters[0].getParameterizedType());
@@ -64,7 +148,7 @@ public void rpcHttpDataSource_To_HttpRequestMessage_IntegerBody() throws Excepti
64148

65149
Parameter[] parameters = httpRequestMessageStringBodyMethod.getParameters();
66150
String sourceKey = "testRpcHttp";
67-
RpcHttp input = getTestRpcHttp(1234);
151+
RpcHttp input = getTestRpcHttp(1234, null, null);
68152
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
69153
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
70154
parameters[0].getParameterizedType());
@@ -82,7 +166,7 @@ public void rpcHttpDataSource_To_HttpRequestMessage_byteArrayBody() throws Excep
82166
String sourceKey = "testRpcHttp";
83167
String expectedString = "Example String";
84168
byte[] inputBytes = expectedString.getBytes();
85-
RpcHttp input = getTestRpcHttp(inputBytes);
169+
RpcHttp input = getTestRpcHttp(inputBytes, null, null);
86170
RpcHttpRequestDataSource rpcHttp = new RpcHttpRequestDataSource(sourceKey, input);
87171
Optional<BindingData> actualBindingData = rpcHttp.computeByName(sourceKey,
88172
parameters[0].getParameterizedType());

0 commit comments

Comments
 (0)