Remove deprecated AWS classes
This commit is contained in:
@@ -29,6 +29,8 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
/**
|
/**
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
|
//TODO - do we actually need it?????
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@AutoConfigureBefore(FunctionExporterAutoConfiguration.class)
|
@AutoConfigureBefore(FunctionExporterAutoConfiguration.class)
|
||||||
@ConditionalOnClass(DestinationResolver.class)
|
@ConditionalOnClass(DestinationResolver.class)
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019-2021 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
|
||||||
import org.springframework.core.env.MapPropertySource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds default properties to the environment for running a custom runtime in AWS.
|
|
||||||
*
|
|
||||||
* @author Dave Syer
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
*/
|
|
||||||
public class CustomRuntimeEnvironmentPostProcessor implements EnvironmentPostProcessor {
|
|
||||||
|
|
||||||
private static final String CUSTOM_RUNTIME = "spring.cloud.function.aws.custom";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
|
||||||
SpringApplication application) {
|
|
||||||
if (!environment.containsProperty(CUSTOM_RUNTIME)) {
|
|
||||||
Map<String, Object> defaults = getDefaultProperties(environment);
|
|
||||||
defaults.put(CUSTOM_RUNTIME, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Object> getDefaultProperties(
|
|
||||||
ConfigurableEnvironment environment) {
|
|
||||||
if (environment.getPropertySources().contains("defaultProperties")) {
|
|
||||||
MapPropertySource source = (MapPropertySource) environment
|
|
||||||
.getPropertySources().get("defaultProperties");
|
|
||||||
return source.getSource();
|
|
||||||
}
|
|
||||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
|
||||||
environment.getPropertySources()
|
|
||||||
.addLast(new MapPropertySource("defaultProperties", map));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2020 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.amazonaws.services.lambda.runtime.Context;
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.messaging.MessageHeaders;
|
|
||||||
import org.springframework.messaging.support.GenericMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dave Syer
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
* @author Semyon Fishman
|
|
||||||
* @author Markus Gulden
|
|
||||||
*
|
|
||||||
* @deprecated since 3.1 in favor of {@link FunctionInvoker}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class SpringBootApiGatewayRequestHandler extends
|
|
||||||
SpringBootRequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper mapper;
|
|
||||||
|
|
||||||
public SpringBootApiGatewayRequestHandler(Class<?> configurationClass) {
|
|
||||||
super(configurationClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpringBootApiGatewayRequestHandler() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object convertEvent(APIGatewayProxyRequestEvent event) {
|
|
||||||
Object deserializedBody = event.getBody() != null ? deserializeBody(event) : Optional.empty();
|
|
||||||
return functionAcceptsMessage()
|
|
||||||
? new GenericMessage<>(deserializedBody, getHeaders(event))
|
|
||||||
: deserializedBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean functionAcceptsMessage() {
|
|
||||||
return ((FunctionInvocationWrapper) function()).isInputTypeMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object deserializeBody(APIGatewayProxyRequestEvent event) {
|
|
||||||
try {
|
|
||||||
return this.mapper.readValue(
|
|
||||||
(event.getIsBase64Encoded() != null && event.getIsBase64Encoded())
|
|
||||||
? new String(Base64.decodeBase64(event.getBody())) : event.getBody(),
|
|
||||||
getInputType());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Cannot convert event", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MessageHeaders getHeaders(APIGatewayProxyRequestEvent event) {
|
|
||||||
Map<String, Object> headers = new HashMap<>();
|
|
||||||
if (event.getHeaders() != null) {
|
|
||||||
headers.putAll(event.getHeaders());
|
|
||||||
}
|
|
||||||
if (event.getQueryStringParameters() != null) {
|
|
||||||
headers.putAll(event.getQueryStringParameters());
|
|
||||||
}
|
|
||||||
if (event.getPathParameters() != null) {
|
|
||||||
headers.putAll(event.getPathParameters());
|
|
||||||
}
|
|
||||||
headers.put("httpMethod", event.getHttpMethod());
|
|
||||||
headers.put("request", event);
|
|
||||||
return new MessageHeaders(headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected APIGatewayProxyResponseEvent convertOutput(Object output) {
|
|
||||||
if (functionReturnsMessage(output)) {
|
|
||||||
Message<?> message = (Message<?>) output;
|
|
||||||
return new APIGatewayProxyResponseEvent()
|
|
||||||
.withStatusCode((Integer) message.getHeaders()
|
|
||||||
.getOrDefault("statuscode", HttpStatus.OK.value()))
|
|
||||||
.withHeaders(toResponseHeaders(message.getHeaders()))
|
|
||||||
.withBody(serializeBody(message.getPayload()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new APIGatewayProxyResponseEvent()
|
|
||||||
.withStatusCode(HttpStatus.OK.value())
|
|
||||||
.withBody(serializeBody(output));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean functionReturnsMessage(Object output) {
|
|
||||||
return output instanceof Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> toResponseHeaders(MessageHeaders messageHeaders) {
|
|
||||||
Map<String, String> responseHeaders = new HashMap<>();
|
|
||||||
messageHeaders
|
|
||||||
.forEach((key, value) -> responseHeaders.put(key, value.toString()));
|
|
||||||
return responseHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String serializeBody(Object body) {
|
|
||||||
try {
|
|
||||||
return this.mapper.writeValueAsString(body);
|
|
||||||
}
|
|
||||||
catch (JsonProcessingException e) {
|
|
||||||
throw new IllegalStateException("Cannot convert output", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(APIGatewayProxyRequestEvent event, Context context) {
|
|
||||||
Object response = super.handleRequest(event, context);
|
|
||||||
if (returnsOutput()) {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new APIGatewayProxyResponseEvent()
|
|
||||||
.withStatusCode(HttpStatus.OK.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2020 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.amazonaws.kinesis.deagg.RecordDeaggregator;
|
|
||||||
import com.amazonaws.services.kinesis.clientlibrary.types.UserRecord;
|
|
||||||
import com.amazonaws.services.lambda.runtime.Context;
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.messaging.support.GenericMessage;
|
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param <E> payload type
|
|
||||||
* @param <O> response type
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @author Halvdan Hoem Grelland
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
*
|
|
||||||
* @deprecated since 3.1 in favor of {@link FunctionInvoker}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class SpringBootKinesisEventHandler<E, O>
|
|
||||||
extends SpringBootRequestHandler<KinesisEvent, O> {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper mapper;
|
|
||||||
|
|
||||||
public SpringBootKinesisEventHandler() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpringBootKinesisEventHandler(Class<?> configurationClass) {
|
|
||||||
super(configurationClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public List<O> handleRequest(KinesisEvent event, Context context) {
|
|
||||||
return (List<O>) super.handleRequest(event, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object convertEvent(KinesisEvent event) {
|
|
||||||
List<E> payloads = deserializePayloads(event.getRecords());
|
|
||||||
|
|
||||||
if (((FunctionInvocationWrapper) function()).isInputTypeMessage()) {
|
|
||||||
return wrapInMessages(payloads);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return payloads;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Message<E>> wrapInMessages(List<E> payloads) {
|
|
||||||
return payloads.stream().map(GenericMessage::new).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<E> deserializePayloads(List<KinesisEvent.KinesisEventRecord> records) {
|
|
||||||
return RecordDeaggregator.deaggregate(records).stream()
|
|
||||||
.map(this::deserializeUserRecord).collect(toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private E deserializeUserRecord(UserRecord userRecord) {
|
|
||||||
try {
|
|
||||||
byte[] jsonBytes = userRecord.getData().array();
|
|
||||||
return (E) this.mapper.readValue(jsonBytes, getInputType());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Cannot convert event", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2019 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.amazonaws.services.lambda.runtime.Context;
|
|
||||||
import com.amazonaws.services.lambda.runtime.RequestHandler;
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
import org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer;
|
|
||||||
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param <E> event type
|
|
||||||
* @param <O> result types
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class SpringBootRequestHandler<E, O> extends AbstractSpringFunctionAdapterInitializer<Context>
|
|
||||||
implements RequestHandler<E, Object> {
|
|
||||||
|
|
||||||
public SpringBootRequestHandler(Class<?> configurationClass) {
|
|
||||||
super(configurationClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpringBootRequestHandler() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleRequest(E event, Context context) {
|
|
||||||
initialize(context);
|
|
||||||
Object input = acceptsInput() ? convertEvent(event) : "";
|
|
||||||
Publisher<?> output = apply(extract(input));
|
|
||||||
return result(input, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
protected <T> T result(Object input, Publisher<?> output) {
|
|
||||||
List<O> result = new ArrayList<>();
|
|
||||||
for (Object value : Flux.from(output).toIterable()) {
|
|
||||||
if (value instanceof Message<?> && !((FunctionInvocationWrapper) this.function()).isOutputTypeMessage()) {
|
|
||||||
value = ((Message<?>) value).getPayload();
|
|
||||||
}
|
|
||||||
result.add(convertOutput(value));
|
|
||||||
}
|
|
||||||
if (isSingleValue(input) && result.size() == 1) {
|
|
||||||
return (T) result.get(0);
|
|
||||||
}
|
|
||||||
return (T) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean acceptsInput() {
|
|
||||||
Type inputType = ((FunctionInvocationWrapper) this.function()).getInputType();
|
|
||||||
return inputType == null || inputType.equals(Void.class) ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean returnsOutput() {
|
|
||||||
Type outputType = ((FunctionInvocationWrapper) this.function()).getOutputType();
|
|
||||||
return outputType == null || outputType.equals(Void.class) ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSingleValue(Object input) {
|
|
||||||
return !(input instanceof Collection);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Flux<?> extract(Object input) {
|
|
||||||
if (input instanceof Collection) {
|
|
||||||
return Flux.fromIterable((Iterable<?>) input);
|
|
||||||
}
|
|
||||||
return Flux.just(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Object convertEvent(E event) {
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected O convertOutput(Object output) {
|
|
||||||
return (O) output;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017-2019 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import com.amazonaws.services.lambda.runtime.Context;
|
|
||||||
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dave Syer
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
*/
|
|
||||||
public class SpringBootStreamHandler extends AbstractSpringFunctionAdapterInitializer<Context>
|
|
||||||
implements RequestStreamHandler {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private ObjectMapper mapper;
|
|
||||||
|
|
||||||
public SpringBootStreamHandler() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpringBootStreamHandler(Class<?> configurationClass) {
|
|
||||||
super(configurationClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
|
|
||||||
initialize(context);
|
|
||||||
Object value = convertStream(input);
|
|
||||||
Publisher<?> flux = apply(extract(value));
|
|
||||||
this.mapper.writeValue(output, result(value, flux));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initialize(Context context) {
|
|
||||||
super.initialize(context);
|
|
||||||
if (this.mapper == null) {
|
|
||||||
this.mapper = new ObjectMapper();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Flux<?> extract(Object input) {
|
|
||||||
if (input instanceof Collection) {
|
|
||||||
return Flux.fromIterable((Iterable<?>) input);
|
|
||||||
}
|
|
||||||
return Flux.just(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Will convert to POJOP or generic map unless user
|
|
||||||
* explicitly requests InputStream (e.g., Function<InputStream, ?>).
|
|
||||||
*/
|
|
||||||
private Object convertStream(InputStream input) {
|
|
||||||
Object convertedResult = input;
|
|
||||||
try {
|
|
||||||
Class<?> inputType = getInputType();
|
|
||||||
if (!InputStream.class.isAssignableFrom(inputType)) {
|
|
||||||
convertedResult = this.mapper.readValue(input, inputType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Cannot convert event stream", e);
|
|
||||||
}
|
|
||||||
return convertedResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2019 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.messaging.support.GenericMessage;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dimitry Declercq
|
|
||||||
* @author Markus Gulden
|
|
||||||
*/
|
|
||||||
public class SpringBootApiGatewayRequestHandlerTests {
|
|
||||||
|
|
||||||
private SpringBootApiGatewayRequestHandler handler;
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
public void after() {
|
|
||||||
System.clearProperty("function.name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void supplierBean() {
|
|
||||||
System.setProperty("function.name", "supplier");
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(FunctionConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody())
|
|
||||||
.isEqualTo("\"hello!\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBean() {
|
|
||||||
System.setProperty("function.name", "function");
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(FunctionConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
request.setBody("{\"value\":\"foo\"}");
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody())
|
|
||||||
.isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
|
|
||||||
APIGatewayProxyRequestEvent bodyEncryptedRequest = new APIGatewayProxyRequestEvent();
|
|
||||||
bodyEncryptedRequest.setBody(
|
|
||||||
Base64.getEncoder().encodeToString("{\"value\":\"foo\"}".getBytes()));
|
|
||||||
bodyEncryptedRequest.setIsBase64Encoded(true);
|
|
||||||
|
|
||||||
output = this.handler.handleRequest(bodyEncryptedRequest, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody())
|
|
||||||
.isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumerBean() {
|
|
||||||
System.setProperty("function.name", "consumer");
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(FunctionConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
request.setBody("\"strVal\":\"test for consumer\"");
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionMessageBean() {
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(
|
|
||||||
FunctionMessageConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
request.setBody("{\"value\":\"foo\"}");
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("spring"))
|
|
||||||
.isEqualTo("cloud");
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody())
|
|
||||||
.isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionMessageBeanWithRequestParameters() {
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(
|
|
||||||
FunctionMessageEchoReqParametersConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
request.setPathParameters(Collections.singletonMap("path", "pathValue"));
|
|
||||||
request.setQueryStringParameters(Collections.singletonMap("query", "queryValue"));
|
|
||||||
request.setHeaders(Collections.singletonMap("test-header", "headerValue"));
|
|
||||||
request.setHttpMethod("GET");
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("path"))
|
|
||||||
.isEqualTo("pathValue");
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("query"))
|
|
||||||
.isEqualTo("queryValue");
|
|
||||||
assertThat(
|
|
||||||
((APIGatewayProxyResponseEvent) output).getHeaders().get("test-header"))
|
|
||||||
.isEqualTo("headerValue");
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getHeaders().get("httpMethod"))
|
|
||||||
.isEqualTo("GET");
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody())
|
|
||||||
.isEqualTo("{\"value\":\"body\"}");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionMessageBeanWithEmptyResponse() {
|
|
||||||
this.handler = new SpringBootApiGatewayRequestHandler(
|
|
||||||
FunctionMessageConsumerConfig.class);
|
|
||||||
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
|
|
||||||
|
|
||||||
Object output = this.handler.handleRequest(request, null);
|
|
||||||
assertThat(output).isInstanceOf(APIGatewayProxyResponseEvent.class);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getStatusCode())
|
|
||||||
.isEqualTo(200);
|
|
||||||
assertThat(((APIGatewayProxyResponseEvent) output).getBody()).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Consumer<String> consumer() {
|
|
||||||
return v -> System.out.println(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Supplier<String> supplier() {
|
|
||||||
return () -> "hello!";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionMessageConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Message<Foo>, Message<Bar>> function() {
|
|
||||||
return (foo -> {
|
|
||||||
Map<String, Object> headers = Collections.singletonMap("spring", "cloud");
|
|
||||||
return new GenericMessage<>(
|
|
||||||
new Bar(foo.getPayload().getValue().toUpperCase()), headers);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionMessageEchoReqParametersConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Message<Foo>, Message<Bar>> function() {
|
|
||||||
return (message -> {
|
|
||||||
Map<String, Object> headers = new HashMap<>();
|
|
||||||
headers.put("path", message.getHeaders().get("path"));
|
|
||||||
headers.put("query", message.getHeaders().get("query"));
|
|
||||||
headers.put("test-header", message.getHeaders().get("test-header"));
|
|
||||||
headers.put("httpMethod", message.getHeaders().get("httpMethod"));
|
|
||||||
return new GenericMessage<>(new Bar("body"), headers);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionMessageConsumerConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Consumer<Message<Foo>> function() {
|
|
||||||
return (foo -> {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Foo {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Bar {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Bar() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bar(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2019 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import com.amazonaws.kinesis.agg.AggRecord;
|
|
||||||
import com.amazonaws.kinesis.agg.RecordAggregator;
|
|
||||||
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Halvdan Hoem Grelland
|
|
||||||
*/
|
|
||||||
@Disabled
|
|
||||||
public class SpringBootKinesisEventHandlerTests {
|
|
||||||
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
private SpringBootKinesisEventHandler<Foo, Bar> handler;
|
|
||||||
|
|
||||||
private static KinesisEvent asKinesisEvent(List<Object> payloads) {
|
|
||||||
KinesisEvent kinesisEvent = new KinesisEvent();
|
|
||||||
|
|
||||||
List<KinesisEvent.KinesisEventRecord> kinesisEventRecords = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Object payload : payloads) {
|
|
||||||
KinesisEvent.Record record = new KinesisEvent.Record();
|
|
||||||
record.setData(asJsonByteBuffer(payload));
|
|
||||||
|
|
||||||
KinesisEvent.KinesisEventRecord kinesisEventRecord = new KinesisEvent.KinesisEventRecord();
|
|
||||||
kinesisEventRecord.setKinesis(record);
|
|
||||||
|
|
||||||
kinesisEventRecords.add(kinesisEventRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
kinesisEvent.setRecords(kinesisEventRecords);
|
|
||||||
|
|
||||||
return kinesisEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KinesisEvent asAggregatedKinesisEvent(List<?> payloads) {
|
|
||||||
RecordAggregator aggregator = new RecordAggregator();
|
|
||||||
|
|
||||||
payloads.stream().map(SpringBootKinesisEventHandlerTests::asJsonByteBuffer)
|
|
||||||
.forEach(buffer -> {
|
|
||||||
try {
|
|
||||||
aggregator.addUserRecord("fakePartitionKey", buffer.array());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
fail("Creating aggregated record failed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AggRecord aggRecord = aggregator.clearAndGet();
|
|
||||||
|
|
||||||
KinesisEvent.Record record = new KinesisEvent.Record();
|
|
||||||
record.setData(ByteBuffer.wrap(aggRecord.toRecordBytes()));
|
|
||||||
|
|
||||||
KinesisEvent.KinesisEventRecord wrappingRecord = new KinesisEvent.KinesisEventRecord();
|
|
||||||
wrappingRecord.setKinesis(record);
|
|
||||||
wrappingRecord.setEventVersion("1.0");
|
|
||||||
|
|
||||||
KinesisEvent event = new KinesisEvent();
|
|
||||||
event.setRecords(singletonList(wrappingRecord));
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ByteBuffer asJsonByteBuffer(Object object) {
|
|
||||||
try {
|
|
||||||
return ByteBuffer.wrap(mapper.writeValueAsBytes(object));
|
|
||||||
}
|
|
||||||
catch (JsonProcessingException e) {
|
|
||||||
fail("Setting up test data failed", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBeanHandlesKinesisEvent() throws Exception {
|
|
||||||
this.handler = new SpringBootKinesisEventHandler<>(FunctionConfig.class);
|
|
||||||
|
|
||||||
KinesisEvent event = asKinesisEvent(singletonList(new Foo("foo")));
|
|
||||||
|
|
||||||
List<Bar> output = this.handler.handleRequest(event, null);
|
|
||||||
|
|
||||||
assertThat(output).containsExactly(new Bar("FOO"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBeanHandlesAggregatedKinesisEvent() throws Exception {
|
|
||||||
this.handler = new SpringBootKinesisEventHandler<>(FunctionConfig.class);
|
|
||||||
|
|
||||||
List<Foo> events = asList(new Foo("foo"), new Foo("bar"), new Foo("baz"));
|
|
||||||
KinesisEvent aggregatedEvent = asAggregatedKinesisEvent(events);
|
|
||||||
|
|
||||||
List<Bar> output = this.handler.handleRequest(aggregatedEvent, null);
|
|
||||||
|
|
||||||
assertThat(output).containsExactly(new Bar("FOO"), new Bar("BAR"),
|
|
||||||
new Bar("BAZ"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionMessageBean() throws Exception {
|
|
||||||
this.handler = new SpringBootKinesisEventHandler<>(FunctionMessageConfig.class);
|
|
||||||
|
|
||||||
KinesisEvent event = asKinesisEvent(asList(new Foo("foo"), new Foo("bar")));
|
|
||||||
|
|
||||||
List<Bar> output = this.handler.handleRequest(event, null);
|
|
||||||
|
|
||||||
assertThat(output).containsExactly(new Bar("FOO"), new Bar("BAR"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionMessageConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Message<Foo>, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getPayload().getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Foo {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Foo() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Foo(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Bar {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Bar() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bar(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Bar bar = (Bar) o;
|
|
||||||
return Objects.equals(this.value, bar.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017-2020 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dave Syer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SpringBootRequestHandlerTests {
|
|
||||||
|
|
||||||
private SpringBootRequestHandler<Foo, Bar> handler;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void after() {
|
|
||||||
System.clearProperty("spring.cloud.function.definition");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBean() throws Exception {
|
|
||||||
this.handler = new SpringBootRequestHandler<Foo, Bar>(FunctionConfig.class);
|
|
||||||
Object output = this.handler.handleRequest(new Foo("foo"), null);
|
|
||||||
assertThat(output).isInstanceOf(Bar.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Foo {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Foo(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Bar {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Bar() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bar(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2019 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.function.adapter.aws;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dave Syer
|
|
||||||
* @author Oleg Zhurakousky
|
|
||||||
*/
|
|
||||||
public class SpringBootStreamHandlerTests {
|
|
||||||
|
|
||||||
private SpringBootStreamHandler handler;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void before() {
|
|
||||||
System.clearProperty("function.name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBeanWithJacksonConfig() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(FunctionConfigWithJackson.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionBeanWithoutJacksonConfig() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(FunctionConfigWithoutJackson.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionNonFluxBeanNoCatalog() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(NoCatalogNonFluxFunctionConfig.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void functionFluxBeanNoCatalog() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(NoCatalogFluxFunctionConfig.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void typelessFunctionConfig() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(TypelessFunctionConfig.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"foo\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void inputStreamFunctionConfig() throws Exception {
|
|
||||||
this.handler = new SpringBootStreamHandler(InputStreamFunctionConfig.class);
|
|
||||||
this.handler.initialize(null);
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
this.handler.handleRequest(
|
|
||||||
new ByteArrayInputStream("{\"value\":\"foo\"}".getBytes()), output, null);
|
|
||||||
assertThat(output.toString()).isEqualTo("{\"value\":\"FOO\"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
protected static class NoCatalogNonFluxFunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
protected static class NoCatalogFluxFunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Flux<Foo>, Flux<Bar>> function() {
|
|
||||||
return flux -> flux.map(foo -> new Bar(foo.getValue().toUpperCase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class FunctionConfigWithJackson {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class })
|
|
||||||
protected static class FunctionConfigWithoutJackson {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<Foo, Bar> function() {
|
|
||||||
return foo -> new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class TypelessFunctionConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<?, ?> function() {
|
|
||||||
return value -> {
|
|
||||||
Assert.isTrue(value instanceof Map, "Expected value should be Map");
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Import({ ContextFunctionCatalogAutoConfiguration.class,
|
|
||||||
JacksonAutoConfiguration.class })
|
|
||||||
protected static class InputStreamFunctionConfig {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper mapper;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Function<InputStream, ?> function() {
|
|
||||||
return value -> {
|
|
||||||
try {
|
|
||||||
Foo foo = this.mapper.readValue((InputStream) value, Foo.class);
|
|
||||||
return new Bar(foo.getValue().toUpperCase());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new IllegalStateException("Failed test", e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Foo {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class Bar {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public Bar() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bar(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ import org.springframework.messaging.support.MessageBuilder;
|
|||||||
* @since 3.2
|
* @since 3.2
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class GrpcUtils {
|
public final class GrpcUtils {
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(GrpcUtils.class);
|
private static Log logger = LogFactory.getLog(GrpcUtils.class);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user