diff --git a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java index f9fe96749..6f7b7be29 100644 --- a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java +++ b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2017 the original author or authors. + * Copyright 2016-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,8 @@ package com.example; import java.net.URI; import java.util.Arrays; -import org.junit.Ignore; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,6 +27,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.test.context.junit4.SpringRunner; @@ -35,15 +38,24 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Dave Syer + * @author Oleg Zhurakousky */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class SampleApplicationTests { + private HttpHeaders headers; + @LocalServerPort private int port; private TestRestTemplate rest = new TestRestTemplate(); + @Before + public void before() { + headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + } + @Test public void words() { assertThat(rest.getForObject("http://localhost:" + port + "/words", String.class)) @@ -53,7 +65,7 @@ public class SampleApplicationTests { @Test public void uppercase() { assertThat(rest.postForObject("http://localhost:" + port + "/uppercase", - "[{\"value\":\"foo\"}]", String.class)) + new HttpEntity<>("[{\"value\":\"foo\"}]", headers), String.class)) .isEqualTo("[{\"value\":\"FOO\"}]"); } @@ -66,13 +78,13 @@ public class SampleApplicationTests { @Test public void single() { assertThat(rest.postForObject("http://localhost:" + port + "/uppercase", - "{\"value\":\"foo\"}", String.class)).isEqualTo("{\"value\":\"FOO\"}"); + new HttpEntity<>("{\"value\":\"foo\"}", headers), String.class)).isEqualTo("{\"value\":\"FOO\"}"); } @Test public void lowercase() { assertThat(rest.postForObject("http://localhost:" + port + "/lowercase", - "[{\"value\":\"Foo\"}]", String.class)) + new HttpEntity<>("[{\"value\":\"Foo\"}]", headers), String.class)) .isEqualTo("[{\"value\":\"foo\"}]"); } diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RequestProcessor.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RequestProcessor.java index 4f304a219..444a6652e 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RequestProcessor.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RequestProcessor.java @@ -123,38 +123,34 @@ public class RequestProcessor { .flatMap(body -> response(wrapper, body, false)); } - public Mono> post(FunctionWrapper wrapper, String body, - boolean stream) { + public Mono> post(FunctionWrapper wrapper, String body, boolean stream) { Object function = wrapper.handler(); Class inputType = inspector.getInputType(function); Type itemType = getItemType(function); Object input = body; - if (StringUtils.hasText(body) && this.mapper != null) { - if (body.startsWith("[")) { - Class collectionType = Collection.class.isAssignableFrom(inputType) - ? inputType - : Collection.class; + + if (StringUtils.hasText(body)) { + MediaType contentType = wrapper.headers.getContentType(); + if (contentType != null && "text".equalsIgnoreCase(contentType.getType())) { + input = converter.convert(function, body); + } + else if (body.startsWith("[")) { + Class collectionType = Collection.class.isAssignableFrom(inputType) ? inputType : Collection.class; input = mapper.toObject(body, - ResolvableType - .forClassWithGenerics(collectionType, (Class) itemType) - .getType()); + ResolvableType.forClassWithGenerics(collectionType, (Class) itemType).getType()); + } + else if (body.startsWith("{")) { + input = mapper.toObject(body, inputType); + } + else if (body.startsWith("\"")) { + input = body.substring(1, body.length() - 2); } else { - if (inputType == String.class) { - input = body; - } - else if (body.startsWith("{")) { - input = mapper.toObject(body, inputType); - } - else if (body.startsWith("\"")) { - input = body.substring(1, body.length() - 2); - } - else { - input = converter.convert(function, body); - } + input = converter.convert(function, body); } } + return response(wrapper, input, stream); } diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java index b63bc9a74..f862590f9 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java @@ -50,6 +50,7 @@ import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -93,7 +94,7 @@ public class HttpPostIntegrationTests { @Test public void updates() throws Exception { ResponseEntity result = rest.exchange( - RequestEntity.post(new URI("/updates")).body("[\"one\", \"two\"]"), + RequestEntity.post(new URI("/updates")).contentType(MediaType.APPLICATION_JSON).body("[\"one\", \"two\"]"), String.class); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED); assertThat(test.list).hasSize(2); @@ -205,6 +206,15 @@ public class HttpPostIntegrationTests { .isEqualTo("[{\"value\":\"FOO\"},{\"value\":\"BAR\"}]"); } + @Test + public void typelessFunctionPassingArray() throws Exception { + ResponseEntity result = rest.exchange(RequestEntity + .post(new URI("/typelessFunctionExpectingText")).contentType(MediaType.TEXT_PLAIN) + .body("[{\"value\":\"foo\"}]"), String.class); + assertThat(result.getBody()) + .isEqualTo("[{\"value\":\"foo\"}]"); + } + @Test public void bareUppercaseFoo() throws Exception { // Single Foo can be parsed and returns a single value if the function is defined @@ -375,6 +385,20 @@ public class HttpPostIntegrationTests { return value -> new Foo(value.getValue().trim().toUpperCase()); } + @Bean + public Function typelessFunctionExpectingText() { + return value -> { + Assert.isInstanceOf(String.class, value); + return value; + }; + } + +// @Bean +// public Function byteArrayInputFunction() { +//// return value -> new Foo(value.getValue().trim().toUpperCase()); +// throw new UnsupportedOperationException("boom?"); +// } + @Bean public Function, Flux> wrap() { return flux -> flux.log().map(value -> ".." + value + ".."); @@ -396,7 +420,9 @@ public class HttpPostIntegrationTests { @Bean @Qualifier("foos") public Function qualifier() { - return value -> new Foo("[" + value.trim().toUpperCase() + "]"); + return value -> { + return new Foo("[" + value.trim().toUpperCase() + "]"); + }; } @Bean diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HeadersToMessageTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HeadersToMessageTests.java index ae78ae9b5..6dfe74568 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HeadersToMessageTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HeadersToMessageTests.java @@ -32,8 +32,8 @@ import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.HeadersToMessageTests.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpEntity; +import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.test.context.ContextConfiguration; @@ -59,9 +59,9 @@ public class HeadersToMessageTests { @Test public void testBodyAndCustomHeaderFromMessagePropagation() throws Exception { - ResponseEntity postForEntity = rest.postForEntity( - new URI("/functions/employee"), "{\"name\":\"Bob\",\"age\":25}", - String.class); + HttpEntity postForEntity = rest.exchange(RequestEntity + .post(new URI("/functions/employee")).contentType(MediaType.APPLICATION_JSON) + .body("{\"name\":\"Bob\",\"age\":25}"), String.class); assertEquals("{\"name\":\"Bob\",\"age\":25}", postForEntity.getBody()); assertTrue(postForEntity.getHeaders().containsKey("x-content-type")); assertEquals("application/xml", @@ -72,7 +72,7 @@ public class HeadersToMessageTests { @Test public void testHeadersPropagatedByDefault() throws Exception { HttpEntity postForEntity = rest.exchange(RequestEntity - .post(new URI("/functions/vanilla")).header("x-context-type", "rubbish") + .post(new URI("/functions/vanilla")).contentType(MediaType.APPLICATION_JSON).header("x-context-type", "rubbish") .body("{\"name\":\"Bob\",\"age\":25}"), String.class); assertEquals("{\"name\":\"Bob\",\"age\":25,\"foo\":\"bar\"}", postForEntity.getBody()); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java index 545fb4c19..5d030635b 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java @@ -92,7 +92,7 @@ public class HttpPostIntegrationTests { @Test public void updates() throws Exception { ResponseEntity result = rest.exchange( - RequestEntity.post(new URI("/updates")).body("[\"one\", \"two\"]"), + RequestEntity.post(new URI("/updates")).contentType(MediaType.APPLICATION_JSON).body("[\"one\", \"two\"]"), String.class); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED); assertThat(test.list).hasSize(2);