GH-317 Polishing and minor refactoring in AzureSpringBootHttpRequestHandler

- Moved convertOutput() to base class and added input value as an argument
- Added javadoc
- fixed checkstyle violations

Resolves #317
Resolves #360
This commit is contained in:
Oleg Zhurakousky
2019-04-29 13:46:13 +02:00
parent 27344d7098
commit f16a2c76cf
4 changed files with 32 additions and 56 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2017-2019 the original author or authors. * Copyright 2019-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,33 +16,32 @@
package org.springframework.cloud.function.adapter.azure; package org.springframework.cloud.function.adapter.azure;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.reactivestreams.Publisher;
import org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.GenericMessage;
import com.microsoft.azure.functions.ExecutionContext; import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpRequestMessage; import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage; import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpResponseMessage.Builder; import com.microsoft.azure.functions.HttpResponseMessage.Builder;
import reactor.core.publisher.Flux; import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.GenericMessage;
/** /**
* Implementation of HTTP Request Handler for Azure which supports
* HttpRequestMessage and HttpResponseMessage the types required by
* Azure Functions for HTTP-triggered functions.
*
* @param <I> input type * @param <I> input type
* @author Markus Gulden * @author Markus Gulden
*
* @since 2.1
*/ */
public class AzureSpringBootHttpRequestHandler<I> extends public class AzureSpringBootHttpRequestHandler<I> extends
AzureSpringBootRequestHandler<HttpRequestMessage<I>, HttpResponseMessage> { AzureSpringBootRequestHandler<HttpRequestMessage<I>, HttpResponseMessage> {
private HttpRequestMessage<I> input;
public AzureSpringBootHttpRequestHandler(Class<?> configurationClass) { public AzureSpringBootHttpRequestHandler(Class<?> configurationClass) {
super(configurationClass); super(configurationClass);
} }
@@ -99,33 +98,13 @@ public class AzureSpringBootHttpRequestHandler<I> extends
return new MessageHeaders(headers); return new MessageHeaders(headers);
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <O> O result(Object input, Publisher<?> output) {
List<Object> result = new ArrayList<>();
for (Object value : Flux.from(output).toIterable()) {
result.add(convertOutput(value));
}
if (isSingleInput(getFunction(), input) && result.size() == 1) {
HttpResponseMessage value = (HttpResponseMessage) result.get(0);
return (O) value;
}
if (isSingleOutput(getFunction(), output) && result.size() == 1) {
HttpResponseMessage value = (HttpResponseMessage) result.get(0);
return (O) value;
}
O value = (O) result;
return value;
}
@Override @Override
protected HttpResponseMessage convertOutput(Object output) { protected HttpResponseMessage convertOutput(Object input, Object output) {
HttpRequestMessage<I> requestMessage = (HttpRequestMessage<I>) input;
if (functionReturnsMessage(output)) { if (functionReturnsMessage(output)) {
Message<?> message = (Message<?>) output; Message<?> message = (Message<?>) output;
Builder builder = this.input Builder builder = requestMessage
.createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK) .createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK)
.body(message.getPayload()); .body(message.getPayload());
for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) { for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
@@ -134,8 +113,7 @@ public class AzureSpringBootHttpRequestHandler<I> extends
return builder.build(); return builder.build();
} }
else { else {
return requestMessage
return this.input
.createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK) .createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK)
.body(output).build(); .body(output).build();
} }
@@ -144,20 +122,13 @@ public class AzureSpringBootHttpRequestHandler<I> extends
@Override @Override
public HttpResponseMessage handleRequest(HttpRequestMessage<I> event, public HttpResponseMessage handleRequest(HttpRequestMessage<I> event,
ExecutionContext context) { ExecutionContext context) {
this.input = event; HttpResponseMessage result = super.handleRequest(event, context);
Object response = super.handleRequest(event, context); if (result == null) {
if (returnsOutput()) { result = event
return (HttpResponseMessage) response;
}
else {
return this.input
.createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK) .createResponseBuilder(com.microsoft.azure.functions.HttpStatus.OK)
.build(); .build();
} }
} return result;
protected boolean returnsOutput() {
return !this.getInspector().getOutputType(function()).equals(Void.class);
} }
protected boolean functionReturnsMessage(Object output) { protected boolean functionReturnsMessage(Object output) {

View File

@@ -103,10 +103,10 @@ public class AzureSpringBootRequestHandler<I, O> extends AbstractSpringFunctionA
return Flux.just(input); return Flux.just(input);
} }
@SuppressWarnings("unchecked") // @SuppressWarnings("unchecked")
protected O convertOutput(Object output) { // protected O convertOutput(I input, Object output) {
return (O) output; // return (O) output;
} // }
protected boolean isSingleInput(Function<?, ?> function, Object input) { protected boolean isSingleInput(Function<?, ?> function, Object input) {
if (!(input instanceof Collection)) { if (!(input instanceof Collection)) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2019-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -31,9 +31,9 @@ import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpResponseMessage.Builder; import com.microsoft.azure.functions.HttpResponseMessage.Builder;
import com.microsoft.azure.functions.HttpStatus; import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.HttpStatusType; import com.microsoft.azure.functions.HttpStatusType;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -262,7 +262,7 @@ public class AzureSpringBootHttpRequestHandlerTests {
private Map<String, String> headers = new HashMap<>(); private Map<String, String> headers = new HashMap<>();
private Object body; private Object body;
public HttpResponseMessageStub(HttpStatusType status, Map<String, String> headers, HttpResponseMessageStub(HttpStatusType status, Map<String, String> headers,
Object body) { Object body) {
this.status = status; this.status = status;
this.headers = headers; this.headers = headers;

View File

@@ -196,10 +196,15 @@ public abstract class AbstractSpringFunctionAdapterInitializer<C> implements Clo
return ""; return "";
} }
//@SuppressWarnings("unchecked")
protected Object convertOutput(Object input, Object output) {
return output;
}
protected <O> O result(Object input, Publisher<?> output) { protected <O> O result(Object input, Publisher<?> output) {
List<Object> result = new ArrayList<>(); List<Object> result = new ArrayList<>();
for (Object value : Flux.from(output).toIterable()) { for (Object value : Flux.from(output).toIterable()) {
result.add(value); result.add(this.convertOutput(input, value));
} }
if (isSingleInput(getFunction(), input) && result.size() == 1) { if (isSingleInput(getFunction(), input) && result.size() == 1) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")