Skip to content

Commit

Permalink
Support consumes and produces on functions exposed to the web. Fixes m…
Browse files Browse the repository at this point in the history
  • Loading branch information
jameskleeh committed Dec 13, 2018
1 parent 0aeb9ad commit c1a7956
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import io.micronaut.function.FunctionBean;
import io.micronaut.function.LocalFunctionRegistry;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.codec.MediaTypeCodec;
import io.micronaut.http.codec.MediaTypeCodecRegistry;
import io.micronaut.inject.BeanDefinition;
Expand Down Expand Up @@ -94,6 +96,13 @@ public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> met
String functionMethod = beanDefinition.getValue(FunctionBean.class, "method", String.class).orElse(null);

UriRoute route = null;
MediaType[] consumes = method.getValue(Consumes.class, String[].class).map((types) ->
Arrays.stream(types).map(MediaType::new).toArray(MediaType[]::new)
).orElse(null);
MediaType[] produces = method.getValue(Produces.class, String[].class).map((types) ->
Arrays.stream(types).map(MediaType::new).toArray(MediaType[]::new)
).orElse(null);

if (Stream.of(java.util.function.Function.class, Consumer.class, BiFunction.class, BiConsumer.class).anyMatch(type -> type.isAssignableFrom(declaringType))) {
if (methodName.equals("accept") || methodName.equals("apply") || methodName.equals(functionMethod)) {
String functionPath = resolveFunctionPath(methodName, declaringType, functionName);
Expand All @@ -111,8 +120,8 @@ public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> met
int size = typeArguments.size();

Argument<?> firstArgument = typeArguments.get(0);
if (size < 3 && ClassUtils.isJavaLangType(firstArgument.getType())) {
route.consumes(MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE);
if (size < 3 && ClassUtils.isJavaLangType(firstArgument.getType()) && consumes == null) {
consumes = new MediaType[] {MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE};
}

if (size < 3) {
Expand All @@ -121,13 +130,13 @@ public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> met

if (size > 1) {
Argument<?> argument = typeArguments.get(size == 3 ? 2 : 1);
if (ClassUtils.isJavaLangType(argument.getType())) {
route.produces(MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE);
if (ClassUtils.isJavaLangType(argument.getType()) && produces == null) {
produces = new MediaType[] {MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE};
}
}
} else {
if (argCount == 1 && ClassUtils.isJavaLangType(method.getArgumentTypes()[0])) {
route.consumes(MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE);
if (argCount == 1 && ClassUtils.isJavaLangType(method.getArgumentTypes()[0]) && consumes == null) {
consumes = new MediaType[] {MediaType.TEXT_PLAIN_TYPE, MediaType.APPLICATION_JSON_TYPE};
}
}
}
Expand All @@ -147,7 +156,9 @@ public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> met
} else {
route = POST(functionPath, beanDefinition, method);
if (argCount == 2 || !ClassUtils.isJavaLangType(argumentTypes[0].getType())) {
route.consumes(MediaType.APPLICATION_JSON_TYPE);
if (consumes == null) {
consumes = new MediaType[] {MediaType.APPLICATION_JSON_TYPE};
}
} else {
route.body(method.getArgumentNames()[0])
.acceptAll();
Expand All @@ -163,6 +174,14 @@ public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> met
LOG.debug("Created Route to Function: {}", route);
}

if (consumes != null) {
route.consumes(consumes);
}

if (produces != null) {
route.produces(produces);
}

ClassLoadingReporter.reportBeanPresent(method.getReturnType().getType());
for (Class argumentType : method.getArgumentTypes()) {
ClassLoadingReporter.reportBeanPresent(argumentType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ class JavaLambdaFunctionSpec extends Specification {
embeddedServer.stop()
}

void "test string supplier with produces"() {
given:
EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer)
RxHttpClient client = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL())

when:
HttpResponse<String> response = client.toBlocking().exchange('/java/supplier/xml', String)

then:
response.code() == HttpStatus.OK.code
response.body() == '<hello></hello>'
response.contentType.get() == MediaType.TEXT_XML_TYPE

cleanup:
embeddedServer.stop()
}

void "test func primitive"() {
given:
Expand Down Expand Up @@ -78,4 +94,20 @@ class JavaLambdaFunctionSpec extends Specification {
cleanup:
embeddedServer.stop()
}

void "test func xml"() {
given:
EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer)
RxHttpClient client = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL())

when:
HttpResponse<String> response = client.toBlocking().exchange(HttpRequest.POST('/java/function/xml', '<hello></hello>').contentType(MediaType.TEXT_XML_TYPE), String)

then:
response.code() == HttpStatus.OK.code
response.body() == "<hello></hello>"

cleanup:
embeddedServer.stop()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import io.micronaut.context.annotation.Factory;
import io.micronaut.function.FunctionBean;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Produces;

import java.util.function.BiFunction;
import java.util.function.Function;
Expand All @@ -19,6 +22,12 @@ Supplier<String> get() {
return () -> "myvalue";
}

@FunctionBean("java/supplier/xml")
@Produces(MediaType.TEXT_XML)
Supplier<String> getXml() {
return () -> "<hello></hello>";
}

// This should work but is currently not implemented
// the reason is because when @FunctionBean is defined on a factory
// we do not go through and visit public Executable methods unless
Expand All @@ -42,6 +51,12 @@ BiFunction<String, String, Name> fullname() {
};
}

@FunctionBean("java/function/xml")
@Consumes(MediaType.TEXT_XML)
Function<String, String> roundXml() {
return (str) -> str;
}

static class Name {
private String name;

Expand Down

0 comments on commit c1a7956

Please sign in to comment.