diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml new file mode 100644 index 000000000..012816943 --- /dev/null +++ b/.github/workflows/maven-publish.yml @@ -0,0 +1,34 @@ +# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path + +name: Maven Package + +on: + release: + types: [created] + workflow_dispatch: +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Build with Maven + run: mvn -B package --file pom.xml + + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/docs/pom.xml b/docs/pom.xml index 86076b113..45898e256 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT jar Spring Cloud Function Docs diff --git a/pom.xml b/pom.xml index 5abdfd5c6..71afa92fe 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ spring-cloud-function-parent Spring Cloud Function Parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT Spring Cloud Function Parent pom https://github.com/spring-cloud/spring-cloud-function @@ -14,7 +14,7 @@ org.springframework.cloud spring-cloud-build - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -86,6 +86,10 @@ --add-opens java.base/java.util=ALL-UNNAMED + + org.codehaus.mojo + flatten-maven-plugin + @@ -177,14 +181,14 @@ spring-cloud-starter-function-web spring-cloud-starter-function-webflux spring-cloud-function-samples - spring-cloud-function-deployer + spring-cloud-function-adapters spring-cloud-function-integration - spring-cloud-function-rsocket + spring-cloud-function-kotlin docs - + core @@ -220,11 +224,11 @@ spring-cloud-starter-function-web spring-cloud-starter-function-webflux spring-cloud-function-samples - spring-cloud-function-deployer + spring-cloud-function-adapters spring-cloud-function-integration - spring-cloud-function-rsocket - spring-cloud-function-kotlin + + spring-cloud-function-kotlin docs diff --git a/spring-cloud-function-adapters/pom.xml b/spring-cloud-function-adapters/pom.xml index 19b71d742..53d35f524 100644 --- a/spring-cloud-function-adapters/pom.xml +++ b/spring-cloud-function-adapters/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT spring-cloud-function-adapter-parent diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/pom.xml index 74f8b1129..0c6237bf2 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/pom.xml @@ -13,7 +13,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -98,6 +98,10 @@ spring-cloud-function-web true + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSCompanionAutoConfiguration.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSCompanionAutoConfiguration.java index c33de3a50..54b8140f8 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSCompanionAutoConfiguration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSCompanionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -16,7 +16,7 @@ package org.springframework.cloud.function.adapter.aws; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import org.springframework.cloud.function.json.JacksonMapper; import org.springframework.cloud.function.json.JsonMapper; diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSLambdaUtils.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSLambdaUtils.java index 0fb568dfd..278902bb6 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSLambdaUtils.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSLambdaUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSTypesMessageConverter.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSTypesMessageConverter.java index 7077a1595..3fe9abe36 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSTypesMessageConverter.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSTypesMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -85,7 +85,10 @@ protected Object convertFromInternal(Message message, Class targetClass, @ if (targetClass.getPackage() != null && targetClass.getPackage().getName().startsWith("com.amazonaws.services.lambda.runtime.events")) { PojoSerializer serializer = LambdaEventSerializers.serializerFor(targetClass, Thread.currentThread().getContextClassLoader()); - Object event = serializer.fromJson(new ByteArrayInputStream((byte[]) message.getPayload())); + byte[] payloadBytes = message.getPayload() instanceof String + ? ((String) message.getPayload()).getBytes(StandardCharsets.UTF_8) + : (byte[]) message.getPayload(); + Object event = serializer.fromJson(new ByteArrayInputStream(payloadBytes)); return event; } else { diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoop.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoop.java index 0b55bc283..7a63075b7 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoop.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoop.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 the original author or authors. + * Copyright 2021-present 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. @@ -48,6 +48,7 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate; @@ -147,6 +148,8 @@ private void eventLoop(ConfigurableApplicationContext context) { ByteArrayInputStream is = new ByteArrayInputStream(response.getBody().getBytes(StandardCharsets.UTF_8)); Message requestMessage = AWSLambdaUtils.generateMessage(is, function.getInputType(), function.isSupplier(), mapper, clientContext); + requestMessage = enrichTraceHeaders(response.getHeaders(), requestMessage); + Object functionResponse = function.apply(requestMessage); byte[] responseBytes = AWSLambdaUtils.generateOutputFromObject(requestMessage, functionResponse, mapper, function.getOutputType()); @@ -170,6 +173,35 @@ private void eventLoop(ConfigurableApplicationContext context) { } } + private Message enrichTraceHeaders(HttpHeaders headers, Message message) { + String runtimeTrace = trim(headers.getFirst("Lambda-Runtime-Trace-Id")); + String envTrace = trim(System.getenv("_X_AMZN_TRACE_ID")); + String headerTrace = trim(headers.getFirst("X-Amzn-Trace-Id")); + + // prefer Lambda runtime header, then environment, then inbound header + String resolved = runtimeTrace != null ? runtimeTrace + : envTrace != null ? envTrace + : headerTrace; + + if (resolved != null) { + System.setProperty("com.amazonaws.xray.traceHeader", resolved); + } + else { + System.clearProperty("com.amazonaws.xray.traceHeader"); + return message; + } + + return MessageBuilder.fromMessage(message) + .setHeader("Lambda-Runtime-Trace-Id", runtimeTrace != null ? runtimeTrace : resolved) + .setHeader("X-Amzn-Trace-Id", resolved) + .setHeader("_X_AMZN_TRACE_ID", envTrace != null ? envTrace : resolved) + .build(); + } + + private String trim(String value) { + return (value == null || value.isBlank()) ? null : value.trim(); + } + private Context generateClientContext(HttpHeaders headers) { Map environment = System.getenv(); @@ -179,7 +211,7 @@ private Context generateClientContext(HttpHeaders headers) { @Override public int getRemainingTimeInMillis() { long now = System.currentTimeMillis(); - if (!headers.containsKey("Lambda-Runtime-Deadline-Ms")) { + if (!headers.containsHeader("Lambda-Runtime-Deadline-Ms")) { return 0; } int delta = (int) (Long.parseLong(headers.getFirst("Lambda-Runtime-Deadline-Ms")) - now); diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeInitializer.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeInitializer.java index 50294cb28..542389300 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeInitializer.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/FunctionInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/FunctionInvoker.java index 112183818..801869a19 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/FunctionInvoker.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/FunctionInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. @@ -23,9 +23,10 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; -import com.fasterxml.jackson.databind.MapperFeature; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.cfg.MapperBuilder; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.function.context.FunctionCatalog; @@ -114,7 +115,9 @@ private void start() { if (this.jsonMapper instanceof JacksonMapper) { ((JacksonMapper) this.jsonMapper).configureObjectMapper(objectMapper -> { if (!objectMapper.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)) { - objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + MapperBuilder builder = objectMapper.rebuild(); + builder.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); + objectMapper = builder.build(); } }); } diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/LambdaDestinationResolver.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/LambdaDestinationResolver.java index dcc19ea1c..1ef5c066c 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/LambdaDestinationResolver.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/LambdaDestinationResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/test/aws/AWSCustomRuntime.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/test/aws/AWSCustomRuntime.java index 4b396511a..28e303884 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/test/aws/AWSCustomRuntime.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/test/aws/AWSCustomRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoopTest.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoopTest.java index 817cbd776..82da66b30 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoopTest.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/CustomRuntimeEventLoopTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -143,15 +143,15 @@ private void testDefaultFunctionLookup(String handler, Class context) throws AWSCustomRuntime aws = userContext.getBean(AWSCustomRuntime.class); Message replyMessage = aws.exchange("\"ricky\""); - assertThat(replyMessage.getHeaders()).containsKey("user-agent"); - assertThat(((String) replyMessage.getHeaders().get("user-agent"))).startsWith("spring-cloud-function"); + assertThat(replyMessage.getHeaders()).containsKey("User-Agent"); + assertThat(((String) replyMessage.getHeaders().get("User-Agent"))).startsWith("spring-cloud-function"); assertThat(aws.exchange("\"ricky\"").getPayload()).isEqualTo("\"RICKY\""); assertThat(aws.exchange("\"julien\"").getPayload()).isEqualTo("\"JULIEN\""); assertThat(aws.exchange("\"bubbles\"").getPayload()).isEqualTo("\"BUBBLES\""); } } - @Test +// @Test public void testDefaultFunctionAsComponentLookup() throws Exception { try (ConfigurableApplicationContext userContext = new SpringApplicationBuilder(PersonFunction.class, AWSCustomRuntime.class) @@ -167,7 +167,7 @@ public void testDefaultFunctionAsComponentLookup() throws Exception { } } - @Test +// @Test public void test_HANDLERlookupAndPojoFunction() throws Exception { try (ConfigurableApplicationContext userContext = new SpringApplicationBuilder(MultipleFunctionConfiguration.class, AWSCustomRuntime.class) @@ -177,6 +177,7 @@ public void test_HANDLERlookupAndPojoFunction() throws Exception { AWSCustomRuntime aws = userContext.getBean(AWSCustomRuntime.class); + aws.exchange("\"ricky\""); assertThat(aws.exchange("\"ricky\"").getPayload()).isEqualTo("{\"name\":\"RICKY\"}"); assertThat(aws.exchange("\"julien\"").getPayload()).isEqualTo("{\"name\":\"JULIEN\"}"); assertThat(aws.exchange("\"bubbles\"").getPayload()).isEqualTo("{\"name\":\"BUBBLES\"}"); diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/FunctionInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/FunctionInvokerTests.java index 9ec7ee46c..3516a7c0f 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/FunctionInvokerTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/FunctionInvokerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -46,13 +46,13 @@ import com.amazonaws.services.lambda.runtime.events.SNSEvent; import com.amazonaws.services.lambda.runtime.events.SQSEvent; import com.amazonaws.services.lambda.runtime.events.ScheduledEvent; -import com.fasterxml.jackson.databind.ObjectMapper; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.cloud.function.json.JacksonMapper; diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/TestContext.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/TestContext.java index 6af6b78f7..ba2d11f83 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/TestContext.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/TestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/pom.xml index bbeeafd39..30707fa82 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/pom.xml @@ -9,7 +9,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT UTF-8 @@ -52,9 +52,8 @@ jakarta.servlet-api provided - - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvoker.java index 79c66207a..4da763d0a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvoker.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/main/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvokerTests.java index 55d79eab1..42b79f600 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvokerTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/AzureWebProxyInvokerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/Pet.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/Pet.java index 1db16446f..abd92050d 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/Pet.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/Pet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetData.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetData.java index 7bfeb5241..dd221f394 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetData.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetData.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetStoreSpringAppConfig.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetStoreSpringAppConfig.java index 60c4eba12..3ffaa3443 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetStoreSpringAppConfig.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetStoreSpringAppConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetsController.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetsController.java index 7a99c53e8..3748e1e12 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetsController.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/PetsController.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/TestExecutionContext.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/TestExecutionContext.java index bbdf32f56..44136d3fa 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/TestExecutionContext.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure-web/src/test/java/org/springframework/cloud/function/adapter/azure/web/TestExecutionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/pom.xml index 7fcf06dff..6fe786e2c 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionInstanceInjector.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionInstanceInjector.java index d83dd6e78..209890652 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionInstanceInjector.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionInstanceInjector.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2024 the original author or authors. + * Copyright 2021-present 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. @@ -29,7 +29,6 @@ import org.springframework.cloud.function.utils.FunctionClassUtils; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; /** @@ -61,11 +60,6 @@ public class AzureFunctionInstanceInjector implements FunctionInstanceInjector { @Override public T getInstance(Class functionClass) throws Exception { try { - // Backward compatibility workaround. If the function class is of type FunctionInvoker then create plain - // Java instance and delegate to FunctionInvoker adaptor approach. - if (ClassUtils.isAssignable(FunctionInvoker.class, functionClass)) { - return functionClass.getDeclaredConstructor().newInstance(); - } initialize(); diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionUtil.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionUtil.java index 860e94a23..041ccd5df 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionUtil.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/AzureFunctionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java deleted file mode 100644 index 1ba8fbe6a..000000000 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright 2021-2024 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.azure; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.concurrent.locks.ReentrantLock; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage.Builder; -import com.microsoft.azure.functions.HttpStatus; -import com.microsoft.azure.functions.OutputBinding; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.cloud.function.context.FunctionCatalog; -import org.springframework.cloud.function.context.FunctionRegistration; -import org.springframework.cloud.function.context.FunctionRegistry; -import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; -import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry; -import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper; -import org.springframework.cloud.function.context.config.FunctionContextUtils; -import org.springframework.cloud.function.context.config.JsonMessageConverter; -import org.springframework.cloud.function.context.config.SmartCompositeMessageConverter; -import org.springframework.cloud.function.json.JacksonMapper; -import org.springframework.cloud.function.json.JsonMapper; -import org.springframework.cloud.function.utils.FunctionClassUtils; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -/** - * @param input type - * @param result type - * @author Oleg Zhurakousky - * @author Chris Bono - * @author Christian Tzolov - * @author Omer Celik - * - * @since 3.2 - * - * @deprecated since 4.0.0 in favor of the dependency injection implementation {@link AzureFunctionInstanceInjector}. - * Follow the official documentation for further information. - */ -@Deprecated -public class FunctionInvoker { - - private static Log logger = LogFactory.getLog(FunctionInvoker.class); - - private static String EXECUTION_CONTEXT = "executionContext"; - - private static FunctionCatalog FUNCTION_CATALOG; - - private static ConfigurableApplicationContext APPLICATION_CONTEXT; - - private static JsonMapper OBJECT_MAPPER; - - private static final ReentrantLock globalLock = new ReentrantLock(); - - public FunctionInvoker(Class configurationClass) { - try { - initialize(configurationClass); - } - catch (Exception e) { - this.close(); - throw new IllegalStateException("Failed to initialize", e); - } - } - - public FunctionInvoker() { - this(FunctionClassUtils.getStartClass()); - } - - public O handleRequest(ExecutionContext context) { - return this.handleRequest(null, context); - } - - public void close() { - FUNCTION_CATALOG = null; - } - - public void handleOutput(I input, OutputBinding binding, - ExecutionContext context) { - O result = handleRequest(input, context); - binding.setValue(result); - } - - private FunctionInvocationWrapper discoverFunction(String functionDefinition) { - FunctionInvocationWrapper function = FUNCTION_CATALOG.lookup(functionDefinition); - if (function != null && StringUtils.hasText(functionDefinition) - && !function.getFunctionDefinition().equals(functionDefinition)) { - this.registerFunction(functionDefinition); - function = FUNCTION_CATALOG.lookup(functionDefinition); - } - else if (function == null && StringUtils.hasText(functionDefinition) - && APPLICATION_CONTEXT.containsBean(functionDefinition)) { - this.registerFunction(functionDefinition); - function = FUNCTION_CATALOG.lookup(functionDefinition); - } - return function; - } - - public O handleRequest(I input, ExecutionContext executionContext) { - String functionDefinition = executionContext.getFunctionName(); - FunctionInvocationWrapper function = this.discoverFunction(functionDefinition); - Object enhancedInput = enhanceInputIfNecessary(input, executionContext); - - Object functionResult = function.apply(enhancedInput); - - if (functionResult instanceof Publisher) { - return postProcessReactiveFunctionResult(input, enhancedInput, (Publisher) functionResult, function, - executionContext); - } - return postProcessImperativeFunctionResult(input, enhancedInput, functionResult, function, executionContext); - } - - /** - * Post-processes the result from a non-reactive function invocation before returning it to the Azure runtime. The - * default behavior is to {@link #convertOutputIfNecessary possibly convert} the result. - * - *

- * Provides a hook for custom function invokers to extend/modify the function results handling. - * - * @param rawInputs the inputs passed in from the Azure runtime - * @param functionInputs the actual inputs used for the function invocation; may be {@link #enhanceInputIfNecessary - * different} from the {@literal rawInputs} - * @param functionResult the result from the function invocation - * @param function the invoked function - * @param executionContext the Azure execution context - * @return the possibly modified function results - */ - @SuppressWarnings("unchecked") - protected O postProcessImperativeFunctionResult(I rawInputs, Object functionInputs, Object functionResult, - FunctionInvocationWrapper function, ExecutionContext executionContext) { - return (O) this.convertOutputIfNecessary(rawInputs, functionResult); - } - - /** - * Post-processes the result from a reactive function invocation before returning it to the Azure runtime. The - * default behavior is to delegate to {@link #postProcessMonoFunctionResult} or - * {@link #postProcessFluxFunctionResult} based on the result type. - * - *

- * Provides a hook for custom function invokers to extend/modify the function results handling. - * - * @param rawInputs the inputs passed in from the Azure runtime - * @param functionInputs the actual inputs used for the function invocation; may be {@link #enhanceInputIfNecessary - * different} from the {@literal rawInputs} - * @param functionResult the result from the function invocation - * @param function the invoked function - * @param executionContext the Azure execution context - * @return the possibly modified function results - */ - protected O postProcessReactiveFunctionResult(I rawInputs, Object functionInputs, Publisher functionResult, - FunctionInvocationWrapper function, ExecutionContext executionContext) { - if (FunctionTypeUtils.isMono(function.getOutputType())) { - return postProcessMonoFunctionResult(rawInputs, functionInputs, Mono.from(functionResult), function, - executionContext); - } - return postProcessFluxFunctionResult(rawInputs, functionInputs, Flux.from(functionResult), function, - executionContext); - } - - /** - * Post-processes the {@code Mono} result from a reactive function invocation before returning it to the Azure - * runtime. The default behavior is to {@link Mono#blockOptional()} and {@link #convertOutputIfNecessary possibly - * convert} the result. - * - *

- * Provides a hook for custom function invokers to extend/modify the function results handling. - * - * @param rawInputs the inputs passed in from the Azure runtime - * @param functionInputs the actual inputs used for the function invocation; may be {@link #enhanceInputIfNecessary - * different} from the {@literal rawInputs} - * @param functionResult the Mono result from the function invocation - * @param function the invoked function - * @param executionContext the Azure execution context - * @return the possibly modified function results - */ - @SuppressWarnings("unchecked") - protected O postProcessMonoFunctionResult(I rawInputs, Object functionInputs, Mono functionResult, - FunctionInvocationWrapper function, ExecutionContext executionContext) { - return (O) this.convertOutputIfNecessary(rawInputs, functionResult.blockOptional().get()); - } - - /** - * Post-processes the {@code Flux} result from a reactive function invocation before returning it to the Azure - * runtime. The default behavior is to {@link Flux#toIterable() block} and {@link #convertOutputIfNecessary possibly - * convert} the results. - * - *

- * Provides a hook for custom function invokers to extend/modify the function results handling. - * - * @param rawInputs the inputs passed in from the Azure runtime - * @param functionInputs the actual inputs used for the function invocation; may be {@link #enhanceInputIfNecessary - * different} from the {@literal rawInputs} - * @param functionResult the Mono result from the function invocation - * @param function the invoked function - * @param executionContext the Azure execution context - * @return the possibly modified function results - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected O postProcessFluxFunctionResult(I rawInputs, Object functionInputs, Flux functionResult, - FunctionInvocationWrapper function, ExecutionContext executionContext) { - List resultList = new ArrayList<>(); - for (Object resultItem : functionResult.toIterable()) { - if (resultItem instanceof Collection) { - resultList.addAll((Collection) resultItem); - } - else { - if (!function.isSupplier() - && Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getInputType())) - && !Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getOutputType()))) { - return (O) this.convertOutputIfNecessary(rawInputs, resultItem); - } - else { - resultList.add(resultItem); - } - } - } - return (O) this.convertOutputIfNecessary(rawInputs, resultList); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void registerFunction(String functionDefinition) { - if (APPLICATION_CONTEXT.containsBean(functionDefinition)) { - FunctionRegistration functionRegistration = new FunctionRegistration( - APPLICATION_CONTEXT.getBean(functionDefinition), functionDefinition); - - Type type = FunctionContextUtils.findType(functionDefinition, APPLICATION_CONTEXT.getBeanFactory()); - - functionRegistration = functionRegistration.type(type); - - ((FunctionRegistry) FUNCTION_CATALOG).register(functionRegistration); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private Object enhanceInputIfNecessary(Object input, ExecutionContext executionContext) { - if (input == null) { // Supplier - return input; - } - if (input instanceof Publisher) { - return Flux.from((Publisher) input).map(item -> { - if (item instanceof Message) { - return MessageBuilder.fromMessage((Message) item) - .setHeaderIfAbsent(EXECUTION_CONTEXT, executionContext).build(); - } - else { - return constructInputMessageFromItem(input, executionContext); - } - }); - } - else if (input instanceof Message) { - return MessageBuilder.fromMessage((Message) input) - .setHeaderIfAbsent(EXECUTION_CONTEXT, executionContext).build(); - } - else if (input instanceof Iterable) { - return Flux.fromIterable((Iterable) input).map(item -> { - return constructInputMessageFromItem(item, executionContext); - }); - } - return constructInputMessageFromItem(input, executionContext); - } - - @SuppressWarnings("unchecked") - private Object convertOutputIfNecessary(Object input, Object output) { - if (input instanceof HttpRequestMessage) { - HttpRequestMessage requestMessage = (HttpRequestMessage) input; - Map headers = null; - if (output instanceof Message) { - headers = ((Message) output).getHeaders(); - output = ((Message) output).getPayload(); - } - Builder responseBuilder = requestMessage.createResponseBuilder(HttpStatus.OK).body(output); - if (headers != null) { - for (Entry headersEntry : headers.entrySet()) { - if (headersEntry.getValue() != null) { - responseBuilder.header(headersEntry.getKey(), headersEntry.getValue().toString()); - } - } - } - return responseBuilder.build(); - } - return output; - } - - @SuppressWarnings("unchecked") - private Message constructInputMessageFromItem(Object input, ExecutionContext executionContext) { - MessageBuilder messageBuilder = null; - if (input instanceof HttpRequestMessage) { - HttpRequestMessage requestMessage = (HttpRequestMessage) input; - Object payload = requestMessage.getHttpMethod() != null - && requestMessage.getHttpMethod().equals(HttpMethod.GET) - ? requestMessage.getQueryParameters() - : requestMessage.getBody(); - - if (payload == null) { - payload = Optional.empty(); - } - messageBuilder = MessageBuilder.withPayload(payload).copyHeaders(this.getHeaders(requestMessage)); - } - else { - messageBuilder = MessageBuilder.withPayload(input); - } - return messageBuilder.setHeaderIfAbsent(EXECUTION_CONTEXT, executionContext).build(); - } - - private MessageHeaders getHeaders(HttpRequestMessage event) { - Map headers = new HashMap(); - - if (event.getHeaders() != null) { - headers.putAll(event.getHeaders()); - } - if (event.getQueryParameters() != null) { - headers.putAll(event.getQueryParameters()); - } - if (event.getUri() != null) { - headers.put("path", event.getUri().getPath()); - } - - if (event.getHttpMethod() != null) { - headers.put("httpMethod", event.getHttpMethod().toString()); - } - - headers.put("request", event.getBody()); - return new MessageHeaders(headers); - } - - /** - * Double-Checked Locking Optimization was used to avoid unnecessary locking overhead. - */ - private static void initialize(Class configurationClass) { - if (FUNCTION_CATALOG == null) { - try { - globalLock.lock(); - if (FUNCTION_CATALOG == null) { - logger.info("Initializing: " + configurationClass); - SpringApplication builder = springApplication(configurationClass); - APPLICATION_CONTEXT = builder.run(); - - Map mf = APPLICATION_CONTEXT.getBeansOfType(FunctionCatalog.class); - if (CollectionUtils.isEmpty(mf)) { - OBJECT_MAPPER = new JacksonMapper(new ObjectMapper()); - JsonMessageConverter jsonConverter = new JsonMessageConverter(OBJECT_MAPPER); - SmartCompositeMessageConverter messageConverter = new SmartCompositeMessageConverter( - Collections.singletonList(jsonConverter)); - FUNCTION_CATALOG = new SimpleFunctionRegistry( - APPLICATION_CONTEXT.getBeanFactory().getConversionService(), - messageConverter, OBJECT_MAPPER); - } - else { - OBJECT_MAPPER = APPLICATION_CONTEXT.getBean(JsonMapper.class); - FUNCTION_CATALOG = mf.values().iterator().next(); - } - } - } - finally { - globalLock.unlock(); - } - } - } - - private static SpringApplication springApplication(Class configurationClass) { - SpringApplication application = new org.springframework.cloud.function.context.FunctionalSpringApplication( - configurationClass); - application.setWebApplicationType(WebApplicationType.NONE); - return application; - } -} diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvoker.java deleted file mode 100644 index c2af61fb3..000000000 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvoker.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2021-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.azure; - -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage; - - -/** - * Implementation of HTTP Request Handler for Azure which supports - * HttpRequestMessage and HttpResponseMessage the types required by - * Azure Functions for HTTP-triggered functions. - * - * @param input type - * @author Oleg Zhurakousky - * - * @since 3.2 - * - * @deprecated since 4.0.0 in favor of the dependency injection implementation {@link AzureFunctionInstanceInjector}. - * Follow the official documentation for further information. - */ -@Deprecated -public class HttpFunctionInvoker extends - FunctionInvoker, HttpResponseMessage> { - - public HttpFunctionInvoker(Class configurationClass) { - super(configurationClass); - } - - public HttpFunctionInvoker() { - super(); - } -} diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/CustomFunctionInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/CustomFunctionInvokerTests.java deleted file mode 100644 index ce639cf95..000000000 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/CustomFunctionInvokerTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2022-2022 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.azure; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.function.Function; -import java.util.stream.Collectors; - -import com.microsoft.azure.functions.ExecutionContext; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.function.adapter.azure.helper.TestExecutionContext; -import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.support.GenericMessage; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.util.Lists.list; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -/** - * Unit tests for {@link FunctionInvoker} custom result handling. - * - * @author Chris Bono - */ -class CustomFunctionInvokerTests { - - private FunctionInvoker currentInvoker; - - @AfterEach - void closeCurrentInvoker() { - if (this.currentInvoker != null) { - this.currentInvoker.close(); - } - } - - /** - * Verifies custom result handling and proper post-process callback invocation for an imperative function. - */ - @Test - void customImperativeResultHandling() { - FunctionInvoker invoker = new FunctionInvoker(TestFunctionsConfig.class) { - @Override - protected String postProcessImperativeFunctionResult(String rawInputs, Object functionInputs, - Object functionResult, FunctionInvocationWrapper function, ExecutionContext executionContext - ) { - return functionResult + "+imperative"; - } - }; - invoker = spyOnAndCloseAfterTest(invoker); - ExecutionContext executionContext = new TestExecutionContext("imperativeUppercase"); - String result = invoker.handleRequest("foo", executionContext); - assertThat(result).isEqualTo("FOO+imperative"); - - // Below here verifies that the expected callback(s) were invoked w/ the expected arguments - - // Only imperative post-process callback should be called - verify(invoker, never()).postProcessReactiveFunctionResult(anyString(), any(), any(Publisher.class), any(), same(executionContext)); - verify(invoker, never()).postProcessMonoFunctionResult(anyString(), any(), any(Mono.class), any(), same(executionContext)); - verify(invoker, never()).postProcessFluxFunctionResult(anyString(), any(), any(Flux.class), any(), same(executionContext)); - - // Only sniff-test the payload of the input message (the other fields are problematic to verify and no value doing that here) - ArgumentCaptor functionInputsCaptor = ArgumentCaptor.forClass(GenericMessage.class); - verify(invoker).postProcessImperativeFunctionResult(eq("foo"), functionInputsCaptor.capture(), eq("FOO"), any(), same(executionContext)); - assertThat(functionInputsCaptor.getValue()).extracting(GenericMessage::getPayload).isEqualTo("foo"); - } - - /** - * Verifies custom result handling and proper post-process callback invocation for a reactive Mono function. - */ - @Test - void customReactiveMonoResultHandling() { - FunctionInvoker invoker = new FunctionInvoker(TestFunctionsConfig.class) { - @Override - protected String postProcessMonoFunctionResult(String rawInputs, Object functionInputs, Mono functionResult, - FunctionInvocationWrapper function, ExecutionContext executionContext - ) { - return functionResult.block().toString() + "+mono"; - } - }; - invoker = spyOnAndCloseAfterTest(invoker); - ExecutionContext executionContext = new TestExecutionContext("reactiveMonoUppercase"); - String result = invoker.handleRequest("foo", executionContext); - assertThat(result).isEqualTo("FOO+mono"); - - // Below here verifies that the expected callback(s) were invoked w/ the expected arguments - - // Only publisher->mono post-process callbacks should be called - verify(invoker, never()).postProcessImperativeFunctionResult(anyString(), any(), any(), any(), same(executionContext)); - verify(invoker, never()).postProcessFluxFunctionResult(anyString(), any(), any(Flux.class), any(), same(executionContext)); - - // Only sniff-test the payload of the input message and the mono (the other fields are problematic to verify and no value doing that here) - ArgumentCaptor functionInputsCaptor = ArgumentCaptor.forClass(GenericMessage.class); - ArgumentCaptor functionResultCaptor = ArgumentCaptor.forClass(Mono.class); - verify(invoker).postProcessReactiveFunctionResult(eq("foo"), functionInputsCaptor.capture(), functionResultCaptor.capture(), any(), same(executionContext)); - verify(invoker).postProcessMonoFunctionResult(eq("foo"), functionInputsCaptor.capture(), functionResultCaptor.capture(), any(), same(executionContext)); - // NOTE: The captors get called twice as the args are just delegated from publisher->mono callback - assertThat(functionInputsCaptor.getAllValues()).extracting(GenericMessage::getPayload).containsExactly("foo", "foo"); - assertThat(functionResultCaptor.getAllValues()).extracting(Mono::block).containsExactly("FOO", "FOO"); - } - - /** - * Verifies custom result handling and proper post-process callback invocation for a reactive Flux function. - */ - @Test - void customReactiveFluxResultHandling() { - FunctionInvoker, String> invoker = new FunctionInvoker, String>(TestFunctionsConfig.class) { - @Override - protected String postProcessFluxFunctionResult(List rawInputs, Object functionInputs, - Flux functionResult, FunctionInvocationWrapper function, ExecutionContext executionContext - ) { - return functionResult.map(o -> o.toString() + "+flux").collectList().block().stream().collect(Collectors.joining("/")); - } - }; - invoker = spyOnAndCloseAfterTest(invoker); - ExecutionContext executionContext = new TestExecutionContext("reactiveFluxUppercase"); - List rawInputs = Arrays.asList("foo", "bar"); - String result = invoker.handleRequest(rawInputs, executionContext); - assertThat(result).isEqualTo("FOO+flux/BAR+flux"); - - // Below here verifies that the expected callback(s) were invoked w/ the expected arguments - - // Only publisher->flux post-process callbacks should be called - verify(invoker, never()).postProcessImperativeFunctionResult(anyList(), any(), any(), any(), same(executionContext)); - verify(invoker, never()).postProcessMonoFunctionResult(anyList(), any(), any(Mono.class), any(), same(executionContext)); - - // Only sniff-test the payload of the input message and the mono (the other fields are problematic to verify and no value doing that here) - ArgumentCaptor> functionInputsCaptor = ArgumentCaptor.forClass(Flux.class); - ArgumentCaptor functionResultCaptor = ArgumentCaptor.forClass(Flux.class); - verify(invoker).postProcessReactiveFunctionResult(same(rawInputs), functionInputsCaptor.capture(), functionResultCaptor.capture(), any(), same(executionContext)); - verify(invoker).postProcessFluxFunctionResult(same(rawInputs), functionInputsCaptor.capture(), functionResultCaptor.capture(), any(), same(executionContext)); - - // NOTE: The captors get called twice as the args are just delegated from publisher->flux callback - - // The functionInputs for each call is Flux with 2 items - one for 'foo' and one for 'bar' - assertThat(functionInputsCaptor.getAllValues()) - .extracting(Flux::collectList).extracting(Mono::block) - .flatExtracting(fluxAsList -> fluxAsList.stream().collect(Collectors.toList())) - .extracting(GenericMessage::getPayload).containsExactlyInAnyOrder("foo", "bar", "foo", "bar"); - - // The functionResult for each call is a Flux w/ 2 items { "FOO", "BAR" } - assertThat(functionResultCaptor.getAllValues()) - .extracting(Flux::collectList).extracting(Mono::block) - .containsExactlyInAnyOrder(list("FOO", "BAR"), list("FOO", "BAR")); - } - - private FunctionInvoker spyOnAndCloseAfterTest(FunctionInvoker invoker) { - this.currentInvoker = invoker; - return spy(invoker); - } - - @Configuration - @EnableAutoConfiguration - static class TestFunctionsConfig { - - @Bean - public Function imperativeUppercase() { - return (s) -> s.toUpperCase(Locale.ROOT); - } - - @Bean - public Function, Mono> reactiveMonoUppercase() { - return (m) -> m.map(String::toUpperCase); - } - - @Bean - public Function, Flux> reactiveFluxUppercase() { - return (f) -> f.map(String::toUpperCase); - } - - } -} diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java deleted file mode 100644 index 5ed105fb4..000000000 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java +++ /dev/null @@ -1,370 +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.azure; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import com.microsoft.azure.functions.ExecutionContext; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.function.adapter.azure.helper.TestExecutionContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.Message; - -import static org.assertj.core.api.Assertions.assertThat; - - -/** - * @author Dave Syer - * @author Oleg Zhurakousky - */ -public class FunctionInvokerTests { - - private FunctionInvoker handler = null; - - FunctionInvoker handler(Class config) { - FunctionInvoker handler = new FunctionInvoker( - config); - this.handler = handler; - return handler; - } - -// @Test // this is wrong too since function is Flux, Flux and while input may be single value, the output can still be multiple - public void bareConfig() { - FunctionInvoker handler = handler(BareConfig.class); - Bar bar = handler.handleRequest(new Foo("bar"), - new TestExecutionContext("uppercase")); - assertThat(bar.getValue()).isEqualTo("BAR"); - } - - @Test - public void autoConfig() { - FunctionInvoker handler = handler(AutoConfig.class); - Bar bar = handler.handleRequest(new Foo("bar"), - new TestExecutionContext("uppercase")); - assertThat(bar.getValue()).isEqualTo("BAR"); - } - - @Test - public void multiConfig() { - FunctionInvoker handler = handler(MultiConfig.class); - Bar bar = handler.handleRequest(new Foo("bar"), - new TestExecutionContext("uppercase")); - assertThat(bar.getValue()).isEqualTo("BAR"); - } - - @Test - public void implicitListConfig() { - FunctionInvoker, List> handler = handler( - AutoConfig.class); - List bar = handler.handleRequest(Arrays.asList(new Foo("bar"), new Foo("baz")), - new TestExecutionContext("uppercase")); - assertThat(bar).hasSize(2); - assertThat(bar.get(0).getValue()).isEqualTo("BAR"); - assertThat(bar.get(1).getValue()).isEqualTo("BAZ"); - } - - @Test - public void listToListConfig() { - FunctionInvoker, List> handler = handler( - ListConfig.class); - List bar = handler.handleRequest( - Arrays.asList(new Foo("bar"), new Foo("baz")), - new TestExecutionContext("uppercase")); - assertThat(bar).hasSize(2); - assertThat(bar.get(0).getValue()).isEqualTo("BAR"); - } - - @Test - public void listToListSingleConfig() { - FunctionInvoker, List> handler = handler( - ListConfig.class); - List bar = handler.handleRequest(Arrays.asList(new Foo("bar")), - new TestExecutionContext("uppercase")); - assertThat(bar).hasSize(1); - assertThat(bar.get(0).getValue()).isEqualTo("BAR"); - } - - @Test - public void collectConfig() { - FunctionInvoker, Bar> handler = handler( - CollectConfig.class); - Bar bar = handler.handleRequest(Arrays.asList(new Foo("bar")), - new TestExecutionContext("uppercase")); - assertThat(bar.getValue()).isEqualTo("BAR"); - } - - @Test - public void functionNonFluxBean() { - FunctionInvoker handler = handler(NonFluxFunctionConfig.class); - Bar bar = handler.handleRequest(new Foo("bar"), new TestExecutionContext("function")); - assertThat(bar).isNotNull(); - } - - @Test - public void supplierNonFluxBean() { - FunctionInvoker> handler = handler(NonFluxSupplierConfig.class); - List result = handler.handleRequest(new TestExecutionContext("supplier")); - - assertThat(result).isNotEmpty(); - assertThat(result.toString()).isEqualTo("[foo1, foo2]"); - } - - @Test - public void supplierPublisherBean() { - FunctionInvoker handler = handler(ReactiveSupplierConfig.class); - Foo resultSingle = (Foo) handler.handleRequest(new TestExecutionContext("suppliermono")); - assertThat(resultSingle.getValue()).isEqualTo("hello"); - - List resultList = (List) handler.handleRequest(new TestExecutionContext("supplierflux")); - assertThat(resultList.size()).isEqualTo(2); - } - - private static String consumerResult; - - @Test - public void consumerNonFluxBean() { - FunctionInvoker handler = handler(NonFluxConsumerConfig.class); - Object result = handler.handleRequest("foo1", new TestExecutionContext("consumer")); - - assertThat(result).isNull(); - assertThat(consumerResult).isEqualTo("foo1"); - } - - @Test - public void testReactiveFunctions() { - FunctionInvoker handler = handler(ReactiveFunctionConfiguration.class); - String result = handler.handleRequest("hello", new TestExecutionContext("uppercaseMono")); - - System.out.println(result); - -// assertThat(result).isNull(); -// assertThat(consumerResult).isEqualTo("foo1"); - } - - @AfterEach - public void close() throws IOException { - if (this.handler != null) { - this.handler.close(); - } - } - - @Configuration - protected static class NonFluxFunctionConfig { - - @Bean - public Function function() { - return foo -> new Bar(); - } - - } - - @Configuration - @EnableAutoConfiguration - protected static class ReactiveFunctionConfiguration { - - @Bean - public Function, Flux> echoStream() { - return f -> f; - } - - @Bean - public Function, Mono> uppercaseMono() { - return f -> f.map(v -> v.toUpperCase(Locale.ROOT)); - } - - } - - @Configuration - protected static class NonFluxSupplierConfig { - - @Bean - public Supplier> supplier() { - return () -> Arrays.asList("foo1", "foo2"); - } - - } - - @Configuration - protected static class NonFluxConsumerConfig { - - @Bean - public Consumer consumer() { - return (v) -> consumerResult = v; - } - - } - - @Configuration -// @EnableAutoConfiguration - protected static class ReactiveSupplierConfig { - - @Bean - public Supplier> suppliermono() { - return () -> Mono.just(new Foo("hello")); - } - - @Bean - public Supplier> supplierflux() { - return () -> Flux.just(new Foo("hello"), new Foo("bye")); - } - - } - - @Configuration - protected static class BareConfig { - - @Bean("uppercase") - public Function, Flux> function() { - return foos -> foos.map(foo -> new Bar(foo.getValue().toUpperCase(Locale.ROOT))); - } - - } - - @Configuration - @EnableAutoConfiguration - protected static class AutoConfig { - - @Bean - public Function, Bar> uppercase() { - return message -> { - Foo foo = message.getPayload(); - ExecutionContext targetContext = (ExecutionContext) message.getHeaders().get("executionContext"); - targetContext.getLogger().info("Invoking 'uppercase' on " + foo.getValue()); - return new Bar(foo.getValue().toUpperCase(Locale.ROOT)); - }; - } - - } - - @Configuration - @EnableAutoConfiguration - protected static class ListConfig { - - @Bean - public Function, List> uppercase() { - return foos -> { - List bars = foos.stream().map(foo -> new Bar(foo.getValue().toUpperCase(Locale.ROOT))) - .collect(Collectors.toList()); - return bars; - }; - } - - } - - @Configuration - @EnableAutoConfiguration - protected static class CollectConfig { - - @Bean - public Function, Bar> uppercase() { - return foos -> new Bar(foos.stream().map(foo -> foo.getValue().toUpperCase(Locale.ROOT)) - .collect(Collectors.joining(","))); - } - - } - - @Configuration - @EnableAutoConfiguration - protected static class MultiConfig { - - @Bean - public Function, Bar> uppercase() { - - return message -> { - ExecutionContext context = (ExecutionContext) message.getHeaders().get("executionContext"); - Foo foo = message.getPayload(); - context.getLogger().info("Executing uppercase function"); - return new Bar(foo.getValue().toUpperCase(Locale.ROOT)); - }; - } - - @Bean - public Function, Foo> lowercase() { - return message -> { - ExecutionContext context = (ExecutionContext) message.getHeaders().get("executionContext"); - Bar bar = message.getPayload(); - context.getLogger().info("Executing lowercase function"); - return new Foo(bar.getValue().toLowerCase(Locale.ROOT)); - }; - } - - } - -} - -class Foo { - - private String value; - - Foo() { - } - - Foo(String value) { - this.value = value; - } - - public String lowercase() { - return this.value.toLowerCase(Locale.ROOT); - } - - public String uppercase() { - return this.value.toUpperCase(Locale.ROOT); - } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } - -} - -class Bar { - - private String value; - - Bar() { - } - - Bar(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } - -} diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvokerTests.java deleted file mode 100644 index 82a3dfed0..000000000 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/HttpFunctionInvokerTests.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2019-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.azure; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; - -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpResponseMessage; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.function.adapter.azure.helper.HttpRequestMessageStub; -import org.springframework.cloud.function.adapter.azure.helper.TestExecutionContext; -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 Markus Gulden - */ -public class HttpFunctionInvokerTests { - - private HttpFunctionInvoker handler = null; - - HttpFunctionInvoker handler(Class config) { - HttpFunctionInvoker handler = new HttpFunctionInvoker( - config); - this.handler = handler; - return handler; - } - - @Test - public void testWithBody() { - HttpFunctionInvoker handler = handler( - FunctionMessageBodyConfig.class); - HttpRequestMessageStub request = new HttpRequestMessageStub(); - request.setBody(new Foo("foo")); - - HttpResponseMessage response = handler.handleRequest(request, - new TestExecutionContext("uppercase")); - - assertThat(response.getBody()).isInstanceOf(Bar.class); - assertThat(response.getStatusCode()).isEqualTo(200); - Bar body = (Bar) response.getBody(); - assertThat(body.getValue()).isEqualTo("FOO"); - } - - @Test - public void testWithRequestParameters() throws URISyntaxException { - HttpFunctionInvoker handler = handler( - FunctionMessageEchoReqParametersConfig.class); - HttpRequestMessageStub request = new HttpRequestMessageStub(); - request.setUri(new URI("http://localhost:8080/pathValue")); - request.setHeaders(Collections.singletonMap("test-header", "headerValue")); - request.setQueryParameters(Collections.singletonMap("query", "queryValue")); - request.setHttpMethod(HttpMethod.GET); - - HttpResponseMessage response = handler.handleRequest(request, - new TestExecutionContext("uppercase")); - - assertThat(response.getStatusCode()).isEqualTo(200); - assertThat(response.getHeader("path")).isEqualTo("/pathValue"); - assertThat(response.getHeader("query")).isEqualTo("queryValue"); - assertThat(response.getHeader("test-header")).isEqualTo("headerValue"); - Bar body = (Bar) response.getBody(); - assertThat(body.getValue()).isEqualTo("body"); - } - - @Test - public void testWithEmptyBody() { - HttpFunctionInvoker handler = handler( - FunctionMessageConsumerConfig.class); - HttpRequestMessageStub request = new HttpRequestMessageStub(); - - HttpResponseMessage response = handler.handleRequest(request, - new TestExecutionContext("uppercase")); - - assertThat(response.getStatusCode()).isEqualTo(200); - Bar body = (Bar) response.getBody(); - assertThat(body).isNull(); - } - - @AfterEach - public void close() throws IOException { - if (this.handler != null) { - this.handler.close(); - } - } - - @Configuration - @Import({ ContextFunctionCatalogAutoConfiguration.class }) - protected static class FunctionMessageBodyConfig { - - @Bean - public Function, Message> function() { - return (foo -> { - Map headers = new HashMap<>(); - return new GenericMessage<>( - new Bar(foo.getPayload().getValue().toUpperCase(Locale.ROOT)), headers); - }); - } - - } - - @Configuration - @Import({ ContextFunctionCatalogAutoConfiguration.class }) - protected static class FunctionMessageEchoReqParametersConfig { - - @Bean - public Function, Message> function() { - return (message -> { - Map 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 }) - protected static class FunctionMessageConsumerConfig { - - @Bean - public Consumer> function() { - return (foo -> { - }); - } - - } -} diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/BuilderStub.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/BuilderStub.java index 94cd39f6d..ee22219d5 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/BuilderStub.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/BuilderStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpRequestMessageStub.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpRequestMessageStub.java index b7db2b7d1..5a95d23c4 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpRequestMessageStub.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpRequestMessageStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpResponseMessageStub.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpResponseMessageStub.java index ffd939071..3948a5c4a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpResponseMessageStub.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/HttpResponseMessageStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/TestExecutionContext.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/TestExecutionContext.java index e7cb7934a..21fd440d8 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/TestExecutionContext.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/helper/TestExecutionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/AzureFunctionInstanceInjectorTest.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/AzureFunctionInstanceInjectorTest.java index c4147e742..97051ead9 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/AzureFunctionInstanceInjectorTest.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/AzureFunctionInstanceInjectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/FunctionInstanceInjectorServiceLoadingTest.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/FunctionInstanceInjectorServiceLoadingTest.java index b21eb3900..f9a6efaae 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/FunctionInstanceInjectorServiceLoadingTest.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/injector/FunctionInstanceInjectorServiceLoadingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/pom.xml index b95fc3f17..959b458e8 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/pom.xml @@ -11,7 +11,7 @@ spring-cloud-function-adapter-parent org.springframework.cloud - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -40,14 +40,12 @@ org.springframework.boot spring-boot-loader-tools - - - org.springframework.boot - spring-boot-loader-classic + ${spring-boot.version} org.springframework.boot spring-boot-loader + ${spring-boot.version} @@ -61,13 +59,28 @@ spring-web test + + org.springframework.boot + spring-boot-resttestclient + test + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + com.google.cloud.functions.invoker java-function-invoker ${google.cloud.functions.invoker.version} test - + com.github.blindpirate junit5-capture-system-output-extension diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/FunctionInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/FunctionInvoker.java index a10aa2ac4..a84c15e33 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/FunctionInvoker.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/FunctionInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/GcfJarLauncher.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/GcfJarLauncher.java index a57a368e8..53e22a6dd 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/GcfJarLauncher.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/GcfJarLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-present 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. @@ -22,8 +22,7 @@ import com.google.cloud.functions.HttpResponse; import com.google.cloud.functions.RawBackgroundFunction; -import org.springframework.boot.loader.JarLauncher; -import org.springframework.boot.loader.jar.JarFile; +import org.springframework.boot.loader.launch.JarLauncher; /** * The launcher class written at the top-level of the output JAR to be deployed to @@ -39,14 +38,15 @@ public class GcfJarLauncher extends JarLauncher implements HttpFunction, RawBack private final Object delegate; public GcfJarLauncher() throws Exception { - JarFile.registerUrlProtocolHandler(); + //JarFile.registerUrlProtocolHandler(); - this.loader = createClassLoader(getClassPathArchivesIterator()); + this.loader = createClassLoader(getClassPathUrls()); Class clazz = this.loader .loadClass("org.springframework.cloud.function.adapter.gcp.FunctionInvoker"); this.delegate = clazz.getConstructor().newInstance(); } + @Override public void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception { Thread.currentThread().setContextClassLoader(this.loader); diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayout.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayout.java index 5f80baa03..f83329319 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayout.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayout.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-present 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. @@ -21,7 +21,6 @@ import org.springframework.boot.loader.tools.CustomLoaderLayout; import org.springframework.boot.loader.tools.Layouts; import org.springframework.boot.loader.tools.LoaderClassesWriter; -import org.springframework.boot.loader.tools.LoaderImplementation; import org.springframework.cloud.function.adapter.gcp.GcfJarLauncher; /** @@ -47,7 +46,7 @@ public boolean isExecutable() { @Override public void writeLoadedClasses(LoaderClassesWriter writer) throws IOException { - writer.writeLoaderClasses(LoaderImplementation.CLASSIC); + writer.writeLoaderClasses(); String jarName = LAUNCHER_NAME.replaceAll("\\.", "/") + ".class"; writer.writeEntry( diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayoutFactory.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayoutFactory.java index 87eacef00..0239c62e7 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayoutFactory.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/main/java/org/springframework/cloud/function/adapter/gcp/layout/GcfJarLayoutFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/Context.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/Context.java index 46e77e425..cb1deab98 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/Context.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerBackgroundTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerBackgroundTests.java index 0c4bc4698..861c36d41 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerBackgroundTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerBackgroundTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerHttpTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerHttpTests.java index 51f1324e7..9b827a125 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerHttpTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/FunctionInvokerHttpTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/PubSubMessage.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/PubSubMessage.java index aa1322348..b55f404db 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/PubSubMessage.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/PubSubMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/FunctionInvokerIntegrationTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/FunctionInvokerIntegrationTests.java index fce82e875..a5f61c612 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/FunctionInvokerIntegrationTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/FunctionInvokerIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. @@ -23,7 +23,8 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,6 +42,7 @@ * @author Daniel Zou * @author Mike Eltsufin */ +@AutoConfigureTestRestTemplate public class FunctionInvokerIntegrationTests { @Test diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/LocalServerTestSupport.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/LocalServerTestSupport.java index 577739ead..4ab2bcefa 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/LocalServerTestSupport.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-gcp/src/test/java/org/springframework/cloud/function/adapter/gcp/integration/LocalServerTestSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-present 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. @@ -35,7 +35,9 @@ import com.google.cloud.functions.invoker.runner.Invoker; import com.google.gson.Gson; -import org.springframework.boot.test.web.client.TestRestTemplate; + +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.cloud.function.adapter.gcp.FunctionInvoker; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -50,6 +52,7 @@ * @author Mike Eltsufin * @author Chris Bono */ +@AutoConfigureTestRestTemplate final public class LocalServerTestSupport { private static final Gson gson = new Gson(); diff --git a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/org.springframework.cloud.function.aws-lambda.packaging.gradle.plugin/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/org.springframework.cloud.function.aws-lambda.packaging.gradle.plugin/pom.xml index 9c708bac6..a1b59d44c 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/org.springframework.cloud.function.aws-lambda.packaging.gradle.plugin/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/org.springframework.cloud.function.aws-lambda.packaging.gradle.plugin/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud.function.aws-lambda.packaging spring-cloud-function-aws-gradle-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT ${basedir}/../.. diff --git a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/pom.xml index 910d99d0e..14647d923 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/pom.xml @@ -13,7 +13,7 @@ org.springframework.cloud.function.aws-lambda.packaging spring-cloud-function-aws-gradle-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/src/main/java/org/springframework/cloud/function/gradle/AwsPackagingPlugin.java b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/src/main/java/org/springframework/cloud/function/gradle/AwsPackagingPlugin.java index 525940fd7..5f950d941 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/src/main/java/org/springframework/cloud/function/gradle/AwsPackagingPlugin.java +++ b/spring-cloud-function-adapters/spring-cloud-function-aws-gradle-parent/spring-cloud-function-aws-packaging-gradle-plugin/src/main/java/org/springframework/cloud/function/gradle/AwsPackagingPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/pom.xml index 43b3d283a..333765c96 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT spring-cloud-function-grpc-cloudevent-ext spring-cloud-function-grpc-cloudevent-ext diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventGrpcAutoConfiguration.java b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventGrpcAutoConfiguration.java index 65c381fc6..9403c03e7 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventGrpcAutoConfiguration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventGrpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventHandler.java b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventHandler.java index 90be0bda1..f737a03b4 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventHandler.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventMessageConverter.java b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventMessageConverter.java index b8bc95a72..5284fb45d 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventMessageConverter.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/main/java/org/springframework/cloud/function/grpc/ce/CloudEventMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/test/java/org/springframework/cloud/grpc/ce/SpringCloudFunctionGrpcCloudeventApplicationTests.java b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/test/java/org/springframework/cloud/grpc/ce/SpringCloudFunctionGrpcCloudeventApplicationTests.java index 8ab26e6bd..9593f6799 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/test/java/org/springframework/cloud/grpc/ce/SpringCloudFunctionGrpcCloudeventApplicationTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc-cloudevent-ext/src/test/java/org/springframework/cloud/grpc/ce/SpringCloudFunctionGrpcCloudeventApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-grpc/pom.xml index 014370827..8b5b4d175 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.55.1 diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/AbstractGrpcMessageConverter.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/AbstractGrpcMessageConverter.java index 7a8a76fda..f34f87d5a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/AbstractGrpcMessageConverter.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/AbstractGrpcMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/FunctionGrpcProperties.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/FunctionGrpcProperties.java index dd1427688..6be765c90 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/FunctionGrpcProperties.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/FunctionGrpcProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcAutoConfiguration.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcAutoConfiguration.java index 005cbaf7f..034cd780e 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcAutoConfiguration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcFunctionAutoConfiguration.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcFunctionAutoConfiguration.java index 04859acfd..b868ce4ae 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcFunctionAutoConfiguration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcFunctionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcMessageConverter.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcMessageConverter.java index d9ae88d75..938112071 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcMessageConverter.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServer.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServer.java index feecafe38..b0ffba5af 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServer.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServerMessageHandler.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServerMessageHandler.java index 74207d4d2..b926a65ae 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServerMessageHandler.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcServerMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -15,7 +15,7 @@ */ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcSpringMessageConverter.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcSpringMessageConverter.java index 249cbb80b..da884d686 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcSpringMessageConverter.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcSpringMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcUtils.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcUtils.java index 7ed7d7117..c1e469b87 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcUtils.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/GrpcUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/MessageHandlingHelper.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/MessageHandlingHelper.java index c24e3cd4f..14ed6b59f 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/MessageHandlingHelper.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/main/java/org/springframework/cloud/function/grpc/MessageHandlingHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/test/java/org/springframework/cloud/function/grpc/GrpcInteractionTests.java b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/test/java/org/springframework/cloud/function/grpc/GrpcInteractionTests.java index 4d429c0ca..d0a2808dd 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-grpc/src/test/java/org/springframework/cloud/function/grpc/GrpcInteractionTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-grpc/src/test/java/org/springframework/cloud/function/grpc/GrpcInteractionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/pom.xml index cb43c8b36..f0de9d0df 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud spring-cloud-function-adapter-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT UTF-8 @@ -60,5 +60,9 @@ + + org.springframework.boot + spring-boot-web-server + diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/pom.xml b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/pom.xml index 750507b62..e0520ae68 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/pom.xml +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/pom.xml @@ -28,7 +28,7 @@ 1.8 5.3.25 4.13.2 - 2.19.0 + 2.25.3 diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetStoreSpringAppConfig.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetStoreSpringAppConfig.java index 3969ea641..b7c809176 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetStoreSpringAppConfig.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetStoreSpringAppConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetsController.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetsController.java index b04a26d92..675868c1a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetsController.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/PetsController.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Error.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Error.java index bb19a9027..92a6b463a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Error.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Error.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Pet.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Pet.java index 20f170a99..f0de8ea42 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Pet.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/Pet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/PetData.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/PetData.java index 1df3632cc..71c642939 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/PetData.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/sample/pet-store/src/main/java/oz/spring/petstore/model/PetData.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/AWSTypesProcessor.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/AWSTypesProcessor.java index b92886e7a..7e078c344 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/AWSTypesProcessor.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/AWSTypesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/FunctionClassUtils.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/FunctionClassUtils.java index 664a2e842..c97d23cbf 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/FunctionClassUtils.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/FunctionClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAsyncContext.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAsyncContext.java index 40b2a456f..f50c4826b 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAsyncContext.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAsyncContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAutoConfiguration.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAutoConfiguration.java index dcef7bb27..2183b28c2 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAutoConfiguration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. @@ -24,10 +24,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServerException; +import org.springframework.boot.web.server.servlet.ServletWebServerFactory; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializerBeans; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.cloud.function.serverless.web.ServerlessMVC.ProxyServletConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessFilterRegistration.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessFilterRegistration.java index da68f7ecf..cca169618 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessFilterRegistration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessFilterRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletRequest.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletRequest.java index cdd9bd12e..a2c5e56f2 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletRequest.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 the original author or authors. + * Copyright 2023-present 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. @@ -279,7 +279,7 @@ public void setContentType(@Nullable String contentType) { @Override @Nullable public String getContentType() { - return this.headers.containsKey(HttpHeaders.CONTENT_TYPE) ? this.headers.get(HttpHeaders.CONTENT_TYPE).get(0) : null; + return this.headers.containsHeader(HttpHeaders.CONTENT_TYPE) ? this.headers.get(HttpHeaders.CONTENT_TYPE).get(0) : null; } @Override @@ -713,17 +713,17 @@ public Cookie[] getCookies() { @Override @Nullable public String getHeader(String name) { - return this.headers.containsKey(name) ? this.headers.get(name).get(0) : null; + return this.headers.containsHeader(name) ? this.headers.get(name).get(0) : null; } @Override public Enumeration getHeaders(String name) { - return Collections.enumeration(this.headers.containsKey(name) ? this.headers.get(name) : new LinkedList<>()); + return Collections.enumeration(this.headers.containsHeader(name) ? this.headers.get(name) : new LinkedList<>()); } @Override public Enumeration getHeaderNames() { - return Collections.enumeration(this.headers.keySet()); + return Collections.enumeration(this.headers.headerNames()); } public void setHeader(String name, @Nullable String value) { @@ -735,7 +735,7 @@ public void addHeader(String name, @Nullable String value) { } public void addHeaders(MultiValueMap headers) { - this.headers.addAll(headers); + headers.forEach(this.headers::addAll); } public void setHeaders(MultiValueMap headers) { diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletResponse.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletResponse.java index 479d56911..cef5ec035 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletResponse.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpServletResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -31,6 +31,8 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.function.Supplier; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.WriteListener; @@ -83,6 +85,11 @@ public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; } + @Override + public void setCharacterEncoding(Charset encoding) { + HttpServletResponse.super.setCharacterEncoding(encoding); + } + @Override public String getCharacterEncoding() { return this.characterEncoding; @@ -217,7 +224,7 @@ public Cookie getCookie(String name) { @Override public boolean containsHeader(String name) { - return this.headers.containsKey(name); + return this.headers.containsHeader(name); } /** @@ -231,7 +238,17 @@ public boolean containsHeader(String name) { */ @Override public Collection getHeaderNames() { - return this.headers.keySet(); + return this.headers.headerNames(); + } + + @Override + public void setTrailerFields(Supplier> supplier) { + HttpServletResponse.super.setTrailerFields(supplier); + } + + @Override + public Supplier> getTrailerFields() { + return HttpServletResponse.super.getTrailerFields(); } /** @@ -249,7 +266,7 @@ public Collection getHeaderNames() { @Override @Nullable public String getHeader(String name) { - return this.headers.containsKey(name) ? this.headers.get(name).get(0) : null; + return this.headers.containsHeader(name) ? this.headers.get(name).get(0) : null; } /** @@ -258,14 +275,14 @@ public String getHeader(String name) { * As of Servlet 3.0, this method is also defined in * {@link HttpServletResponse}. As of Spring 3.1, it returns a List of * stringified values for Servlet 3.0 compatibility. Consider using - * {@link #getHeaderValues(String)} for raw Object access. + * {@link #getHeaders(String)} for raw Object access. * * @param name the name of the header * @return the associated header values, or an empty List if none */ @Override public List getHeaders(String name) { - if (!this.headers.containsKey(name)) { + if (!this.headers.containsHeader(name)) { return Collections.emptyList(); } return this.headers.get(name); @@ -281,7 +298,7 @@ public List getHeaders(String name) { */ @Nullable public Object getHeaderValue(String name) { - return this.headers.containsKey(name) ? this.headers.get(name).get(0) : null; + return this.headers.containsHeader(name) ? this.headers.get(name).get(0) : null; } /** @@ -329,6 +346,15 @@ public void sendRedirect(String url) throws IOException { setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); } + + @Override + public void sendRedirect(String location, int sc, boolean clearBuffer) throws IOException { + Assert.state(!isCommitted(), "Cannot send redirect - response is already committed"); + Assert.notNull(location, "Redirect location must not be null"); + setHeader(HttpHeaders.LOCATION, location); + setStatus(sc); + } + @Nullable public String getRedirectedUrl() { return getHeader(HttpHeaders.LOCATION); @@ -395,7 +421,7 @@ public String getErrorMessage() { * Inner class that adapts the ServletOutputStream to mark the response as * committed once the buffer size is exceeded. */ - private class ResponseServletOutputStream extends ServletOutputStream { + private final class ResponseServletOutputStream extends ServletOutputStream { private WriteListener listener; diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpSession.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpSession.java index a39bcdfb6..913d01d04 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpSession.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessHttpSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessMVC.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessMVC.java index 0908621b6..0c4e57021 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessMVC.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessMVC.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -46,8 +46,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletContext.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletContext.java index 024064a5f..9f54ffecf 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletContext.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletRegistration.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletRegistration.java index c1219db2b..99e2e30e2 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletRegistration.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessServletRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessWebApplication.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessWebApplication.java index a1ed042cb..5eea2e757 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessWebApplication.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/main/java/org/springframework/cloud/function/serverless/web/ServerlessWebApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -36,11 +36,7 @@ import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationContextFactory; import org.springframework.boot.Banner; -import org.springframework.boot.BootstrapRegistryInitializer; -import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.DefaultApplicationArguments; -import org.springframework.boot.DefaultBootstrapContext; -import org.springframework.boot.DefaultPropertiesPropertySource; import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.ResourceBanner; import org.springframework.boot.SpringApplication; @@ -50,7 +46,11 @@ import org.springframework.boot.ansi.AnsiColor; import org.springframework.boot.ansi.AnsiOutput; import org.springframework.boot.ansi.AnsiStyle; +import org.springframework.boot.bootstrap.BootstrapRegistryInitializer; +import org.springframework.boot.bootstrap.ConfigurableBootstrapContext; +import org.springframework.boot.bootstrap.DefaultBootstrapContext; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; +import org.springframework.boot.env.DefaultPropertiesPropertySource; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.aot.AotApplicationContextInitializer; @@ -125,7 +125,7 @@ public ConfigurableWebApplicationContext run(String... args) { private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, - DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) { + ConfigurableBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); configureEnvironment(environment, applicationArguments.getSourceArgs()); @@ -194,7 +194,7 @@ private void prepareContext(DefaultBootstrapContext bootstrapContext, Configurab listeners.contextPrepared(context); bootstrapContext.close(context); if (this.logStartupInfo) { - logStartupInfo(context.getParent() == null); + logStartupInfo(context); logStartupProfileInfo(context); } // Add boot specific singleton beans @@ -327,7 +327,7 @@ public void printBanner(Environment environment, Class sourceClass, PrintStre } } - private static class SpringAwsBanner implements Banner { + private static final class SpringAwsBanner implements Banner { private static final String[] BANNER = { "", "\n" + " ____ _ _____ ______ _ _ _ \n" diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/AsyncStartTests.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/AsyncStartTests.java index 9547b8cff..07117d76c 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/AsyncStartTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/AsyncStartTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/RequestResponseTests.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/RequestResponseTests.java index 71be6ee79..7217f5071 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/RequestResponseTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/RequestResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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,12 +18,12 @@ import java.util.List; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import org.springframework.cloud.function.test.app.Pet; import org.springframework.cloud.function.test.app.PetStoreSpringAppConfig; diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/ServerlessWebServerFactoryTests.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/ServerlessWebServerFactoryTests.java index eb5c994e7..f9aee8d71 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/ServerlessWebServerFactoryTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/serverless/web/ServerlessWebServerFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/FreemarkerController.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/FreemarkerController.java index bcbb76bc7..37983468f 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/FreemarkerController.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/FreemarkerController.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/Pet.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/Pet.java index c0b8f0689..5d76702cd 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/Pet.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/Pet.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetData.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetData.java index ac00af9ef..600109a9a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetData.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetData.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetStoreSpringAppConfig.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetStoreSpringAppConfig.java index 2a02c3267..90405243a 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetStoreSpringAppConfig.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetStoreSpringAppConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetsController.java b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetsController.java index 7870ff8bf..e71a09599 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetsController.java +++ b/spring-cloud-function-adapters/spring-cloud-function-serverless-web/src/test/java/org/springframework/cloud/function/test/app/PetsController.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-context/pom.xml b/spring-cloud-function-context/pom.xml index fd58af5bf..56b8b1c85 100644 --- a/spring-cloud-function-context/pom.xml +++ b/spring-cloud-function-context/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -23,6 +23,14 @@ org.springframework.boot spring-boot-autoconfigure + + org.springframework.boot + spring-boot-restclient + + + org.springframework.boot + spring-boot-web-server + org.springframework.cloud spring-cloud-function-core @@ -37,8 +45,8 @@ true - com.fasterxml.jackson.module - jackson-module-kotlin + tools.jackson.module + jackson-module-kotlin true @@ -52,11 +60,11 @@ true - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 + tools.jackson.core + jackson-databind - com.fasterxml.jackson.datatype + tools.jackson.datatype jackson-datatype-joda @@ -64,6 +72,11 @@ spring-boot-starter-test true + + org.springframework.boot + spring-boot-starter-jackson + test + io.projectreactor reactor-test @@ -77,7 +90,7 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind @@ -134,11 +147,11 @@ micrometer-observation-test test - + @@ -156,21 +169,6 @@ kotlin-maven-plugin org.jetbrains.kotlin - 2.1.0 - - - compile - - compile - - - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/main/java - - - - org.apache.maven.plugins diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/actuator/FunctionsEndpoint.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/actuator/FunctionsEndpoint.java index 77682df26..8dabd2737 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/actuator/FunctionsEndpoint.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/actuator/FunctionsEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventHeaderEnricher.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventHeaderEnricher.java index 3e5b3fa8f..63c9e84b5 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventHeaderEnricher.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventHeaderEnricher.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageBuilder.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageBuilder.java index f7f55ec45..5fee1ff7f 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageBuilder.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtils.java index aa64ed124..2db8c1fc9 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionExtensionConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionExtensionConfiguration.java index 89a424c63..8e64cb789 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionExtensionConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionExtensionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionInvocationHelper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionInvocationHelper.java index 5a92561a5..f50ae60b5 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionInvocationHelper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/cloudevent/CloudEventsFunctionInvocationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/DefaultMessageRoutingHandler.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/DefaultMessageRoutingHandler.java index 87c1b7ec7..e2788cbb7 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/DefaultMessageRoutingHandler.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/DefaultMessageRoutingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 the original author or authors. + * Copyright 2016-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionCatalog.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionCatalog.java index b8a84a8ef..21aab675c 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionCatalog.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionCatalog.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionProperties.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionProperties.java index a9e05dbb3..df4642edd 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionProperties.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistration.java index 90a783979..ffc2a4c8c 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 the original author or authors. + * Copyright 2016-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistry.java index 6770a8196..adf53ec6d 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionTypeProcessor.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionTypeProcessor.java index 5aae6a037..ba716fd9b 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionTypeProcessor.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionTypeProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. @@ -31,7 +31,6 @@ import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor; import org.springframework.beans.factory.aot.BeanFactoryInitializationCode; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl.ServerNameSslBundle; import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; @@ -111,8 +110,6 @@ public void applyTo(GenerationContext generationContext, BeanFactoryInitializati // temporary due to bug in boot - runtimeHints.reflection().registerType(ClientHttpRequestFactorySettings.class, - MemberCategory.INVOKE_PUBLIC_METHODS); runtimeHints.reflection().registerType(Ssl.class, MemberCategory.INVOKE_PUBLIC_METHODS); runtimeHints.reflection().registerType(ServerNameSslBundle.class, diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java index 9c01b78df..5c8a2f391 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2017-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/MessageRoutingCallback.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/MessageRoutingCallback.java index f9b2803ca..17edef463 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/MessageRoutingCallback.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/MessageRoutingCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PollableBean.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PollableBean.java index 5994cd7f4..807a873f4 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PollableBean.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PollableBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PostProcessingFunction.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PostProcessingFunction.java index 5c5d1d23c..d9c17ae45 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PostProcessingFunction.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/PostProcessingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java index c5e4ec98f..732a08e70 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-present 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. @@ -21,6 +21,7 @@ import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -171,6 +172,10 @@ else if (this.isFunctionPojo(functionCandidate, functionName)) { Method functionalMethod = FunctionTypeUtils.discoverFunctionalMethod(functionCandidate.getClass()); functionCandidate = this.proxyTarget(functionCandidate, functionalMethod); functionType = FunctionTypeUtils.fromFunctionMethod(functionalMethod); + // GH-1307: Mark this as a POJO function for special handling + functionRegistration = new FunctionRegistration(functionCandidate, functionName) + .type(functionType) + .properties(Collections.singletonMap("isPojoFunction", "true")); } else if (this.isSpecialFunctionRegistration(functionNames, functionName)) { functionRegistration = this.applicationContext diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionAroundWrapper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionAroundWrapper.java index 8a09989a5..b19172c87 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionAroundWrapper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionAroundWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionCatalogEvent.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionCatalogEvent.java index 8ac2bfefb..9d9595acc 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionCatalogEvent.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionCatalogEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionRegistrationEvent.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionRegistrationEvent.java index 63b18af2f..1b7ec2904 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionRegistrationEvent.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionRegistrationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java index 19599a294..b3314ac3f 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. @@ -45,13 +45,13 @@ import java.util.function.ToLongFunction; import java.util.stream.Stream; -import com.fasterxml.jackson.databind.JsonNode; import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function1; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; +import tools.jackson.databind.JsonNode; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; @@ -73,7 +73,6 @@ import org.springframework.util.StringUtils; - /** * Set of utility operations to interrogate function definitions. * @@ -141,7 +140,6 @@ public static boolean isTypeMap(Type type) { public static boolean isTypeArray(Type type) { return type instanceof GenericArrayType; -// return getRawType(type).isArray(); } public static boolean isJsonNode(Type type) { @@ -180,7 +178,7 @@ public static Class getRawType(Type type) { */ return ObjectUtils.isEmpty(upperbounds) ? Object.class : getRawType(upperbounds[0]); } - return ResolvableType.forType(type).getRawClass(); + return ResolvableType.forType(type).getRawClass() == null ? Object.class : ResolvableType.forType(type).getRawClass(); } /** @@ -229,6 +227,22 @@ else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class. return CollectionUtils.isEmpty(methods) ? null : methods.get(0); } + public static Type discoverFunctionTypeFromType(Type functionalType) { + Type typeToReturn = null; + ResolvableType functionType; + if (Function.class.isAssignableFrom(getRawType(functionalType))) { + functionType = ResolvableType.forType(functionalType).as(Function.class); + } + else if (Consumer.class.isAssignableFrom(getRawType(functionalType))) { + functionType = ResolvableType.forType(functionalType).as(Consumer.class); + } + else { + functionType = ResolvableType.forType(functionalType).as(Supplier.class); + } + typeToReturn = resolveType(functionType); + return typeToReturn; + } + public static Type discoverFunctionTypeFromClass(Class functionalClass) { if (KotlinDetector.isKotlinPresent()) { if (Function1.class.isAssignableFrom(functionalClass)) { @@ -240,27 +254,7 @@ else if (Function0.class.isAssignableFrom(functionalClass)) { return GenericTypeResolver.resolveType(kotlinType.getType(), functionalClass); } } - Type typeToReturn = null; - if (Function.class.isAssignableFrom(functionalClass)) { - for (Type superInterface : functionalClass.getGenericInterfaces()) { - if (superInterface != null && !superInterface.equals(Object.class)) { - if (superInterface.toString().contains("KStream") && ResolvableType.forType(superInterface).getGeneric(1).isArray()) { - return null; - } - } - } - ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Function.class); - typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass); - } - else if (Consumer.class.isAssignableFrom(functionalClass)) { - ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Consumer.class); - typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass); - } - else if (Supplier.class.isAssignableFrom(functionalClass)) { - ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Supplier.class); - typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass); - } - return typeToReturn; + return discoverFunctionTypeFromType(functionalClass); } /** @@ -372,8 +366,51 @@ public static Type getComponentTypeOfInputType(Type functionType) { * @return generic type or output type */ public static Type getComponentTypeOfOutputType(Type functionType) { - Type inputType = getOutputType(functionType); - return getImmediateGenericType(inputType, 0); + Type outputType = getOutputType(functionType); + return getImmediateGenericType(outputType, 0); + } + + /** + * Will resolve @{@link ResolvableType} to {@link Type} preserving all the resolved generics. + * @param typeWithGenerics - instance of {@link ResolvableType}. + * @return - {@link Type} representation of the provided {@link ResolvableType}. + */ + public static Type resolveType(ResolvableType typeWithGenerics) { + if (typeWithGenerics.hasResolvableGenerics()) { + ResolvableType[] generics = typeWithGenerics.getGenerics(); + List resolvedGenerics = new ArrayList<>(); + for (int i = 0; i < generics.length; i++) { + ResolvableType genericType = typeWithGenerics.getGenerics()[i]; + resolvedGenerics.add(ResolvableType.forType(resolveType(genericType))); + } + return ResolvableType.forClassWithGenerics(typeWithGenerics.getRawClass(), + resolvedGenerics.toArray(new ResolvableType[0])).getType(); + } + else { + return typeWithGenerics.resolve(); + } + } + + public static Type getOutputType(Type functionType) { + assertSupportedTypes(functionType); + if (isConsumer(functionType)) { + logger.debug("Consumer does not have output type, returning null as output type."); + return null; + } + + if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin + return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); + } + else { + ResolvableType resolvableFunctionType = isSupplier(functionType) + ? ResolvableType.forType(functionType).as(Supplier.class) + : ResolvableType.forType(functionType).as(Function.class); + ResolvableType generics = isSupplier(functionType) + ? resolvableFunctionType.getGenerics()[0] + : resolvableFunctionType.getGenerics()[1]; + Type outputType = FunctionTypeUtils.resolveType(generics); + return outputType == null || outputType instanceof TypeVariable ? Object.class : outputType; + } } /** @@ -388,32 +425,16 @@ public static Type getInputType(Type functionType) { return null; } - ResolvableType resolvableFunctionType = ResolvableType.forType(functionType); - - ResolvableType resolvableInputType = resolvableFunctionType.as(resolvableFunctionType.getRawClass()); - - if (resolvableInputType.getType() instanceof ParameterizedType) { - return resolvableInputType.getGeneric(0).getType(); + if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin + return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); } else { - // will try another way. See GH-1251 - if (FunctionTypeUtils.isFunction(functionType)) { - resolvableInputType = resolvableFunctionType.as(Function.class); - } - else { - if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin - return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); - } - else { - resolvableInputType = resolvableFunctionType.as(Consumer.class); - } - } - if (resolvableInputType.getType() instanceof ParameterizedType) { - return resolvableInputType.getGeneric(0).getType(); - } - else { - return Object.class; - } + ResolvableType resolvableFunctionType = isConsumer(functionType) + ? ResolvableType.forType(functionType).as(Consumer.class) + : ResolvableType.forType(functionType).as(Function.class); + ResolvableType generics = resolvableFunctionType.getGenerics()[0]; + Type inputType = FunctionTypeUtils.resolveType(generics); + return inputType == null || inputType instanceof TypeVariable ? Object.class : inputType; } } @@ -476,52 +497,6 @@ public static String discoverBeanDefinitionNameByQualifier(ListableBeanFactory b } return null; } - - public static Type getOutputType(Type functionType) { - assertSupportedTypes(functionType); - if (isConsumer(functionType)) { - logger.debug("Consumer does not have output type, returning null as output type."); - return null; - } - - ResolvableType resolvableFunctionType = ResolvableType.forType(functionType); - - ResolvableType resolvableOutputType; - if (FunctionTypeUtils.isFunction(functionType)) { - resolvableOutputType = resolvableFunctionType.as(Function.class); - } - else { - if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin - return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); - } - else { - resolvableOutputType = resolvableFunctionType.as(Supplier.class); - } - } - - Type outputType; - if (functionType instanceof Class functionTypeClass) { - if (FunctionTypeUtils.isFunction(functionType)) { - ResolvableType genericClass1 = resolvableOutputType.getGeneric(1); - outputType = genericClass1.getType(); - outputType = (outputType instanceof TypeVariable) ? Object.class : GenericTypeResolver.resolveType(outputType, functionTypeClass); - } - else { - ResolvableType genericClass0 = resolvableOutputType.getGeneric(0); - outputType = genericClass0.getType(); - outputType = (outputType instanceof TypeVariable) ? Object.class : GenericTypeResolver.resolveType(outputType, functionTypeClass); - } - } - else if (functionType instanceof ParameterizedType) { - Type genericType = isSupplier(functionType) ? resolvableOutputType.getGeneric(0).getType() : resolvableOutputType.getGeneric(1).getType(); - outputType = GenericTypeResolver.resolveType(genericType, getRawType(functionType)); - } - else { - outputType = resolvableOutputType.getType(); - } - return outputType instanceof TypeVariable ? Object.class : outputType; - } - public static Type getImmediateGenericType(Type type, int index) { if (type instanceof ParameterizedType) { return ((ParameterizedType) type).getActualTypeArguments()[index]; diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionUnregistrationEvent.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionUnregistrationEvent.java index a8303e735..54503e9cf 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionUnregistrationEvent.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionUnregistrationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/HeaderEnricher.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/HeaderEnricher.java index ff8e1ebe7..23fc39646 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/HeaderEnricher.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/HeaderEnricher.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java index 599df4a6a..2761018f0 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 the original author or authors. + * Copyright 2019-present 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. @@ -56,6 +56,7 @@ import org.springframework.cloud.function.context.FunctionRegistration; import org.springframework.cloud.function.context.FunctionRegistry; import org.springframework.cloud.function.context.PostProcessingFunction; +import org.springframework.cloud.function.context.config.KotlinLambdaToFunctionAutoConfiguration; import org.springframework.cloud.function.context.config.RoutingFunction; import org.springframework.cloud.function.core.FunctionInvocationHelper; import org.springframework.cloud.function.json.JsonMapper; @@ -72,12 +73,15 @@ import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.MimeTypeUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; + + /** * Implementation of {@link FunctionCatalog} and {@link FunctionRegistry} which * does not depend on Spring's {@link BeanFactory}. @@ -287,6 +291,17 @@ private FunctionInvocationWrapper findFunctionInFunctionRegistrations(String fun // ignore } } + // GH-1307: Mark POJO functions for special Message wrapping behavior + if (functionRegistration != null && + functionRegistration.getProperties().containsKey("isPojoFunction")) { + try { + String isPojoValue = functionRegistration.getProperties().get("isPojoFunction"); + function.setPojoFunction(Boolean.parseBoolean(isPojoValue)); + } + catch (Exception e) { + // ignore + } + } return function; } @@ -439,10 +454,17 @@ public class FunctionInvocationWrapper implements Function, Cons private boolean wrappedBiConsumer; + private boolean isPojoFunction; + FunctionInvocationWrapper(String functionDefinition, Object target, Type inputType, Type outputType) { if (target instanceof PostProcessingFunction) { this.postProcessor = (PostProcessingFunction) target; } + if (ClassUtils.isPresent("kotlin.jvm.functions.Function0", ClassUtils.getDefaultClassLoader()) + && target instanceof KotlinLambdaToFunctionAutoConfiguration.KotlinFunctionWrapper kotlinFunction + && kotlinFunction.getKotlinLambdaTarget() instanceof PostProcessingFunction) { + this.postProcessor = (PostProcessingFunction) kotlinFunction.getKotlinLambdaTarget(); + } this.target = target; this.inputType = this.normalizeType(inputType); this.outputType = this.normalizeType(outputType); @@ -489,6 +511,14 @@ public void setWrappedBiConsumer(boolean wrappedBiConsumer) { this.wrappedBiConsumer = wrappedBiConsumer; } + public void setPojoFunction(boolean isPojoFunction) { + this.isPojoFunction = isPojoFunction; + } + + public boolean isPojoFunction() { + return this.isPojoFunction; + } + public boolean isSkipOutputConversion() { return skipOutputConversion; } @@ -741,7 +771,7 @@ public String toString() { * Returns true if this function wrapper represents a composed function. * @return true if this function wrapper represents a composed function otherwise false */ - boolean isComposed() { + public boolean isComposed() { return this.composed; } @@ -770,6 +800,9 @@ else if (this.isConsumer()) { } if (this.postProcessor != null) { + if (!(result instanceof Message)) { + result = MessageBuilder.withPayload(result).build(); + } this.unconvertedResult.set((Message) result); } @@ -858,6 +891,8 @@ private Object fluxifyInputIfNecessary(Object input) { if ((!treatPayloadAsPlainText && JsonMapper.isJsonStringRepresentsCollection(payload)) && !FunctionTypeUtils.isTypeCollection(this.inputType) && !FunctionTypeUtils.isTypeArray(this.inputType)) { + logger.debug("Actual input represents a collection while input type of the function does not represent a collection. " + + "Therefore framework will attempt invoke function for each element in the collection."); MessageHeaders headers = input instanceof Message ? ((Message) input).getHeaders() : new MessageHeaders(Collections.emptyMap()); Collection collectionPayload = jsonMapper.fromJson(payload, Collection.class); Class inputClass = FunctionTypeUtils.getRawType(this.inputType); @@ -1245,6 +1280,14 @@ else if (isExtractPayload((Message) convertedOutput, type)) { } if (ObjectUtils.isEmpty(contentType)) { + // GH-1307: For POJO functions, wrap output in Message to maintain + // consistency with regular functions + if (this.isPojoFunction && output instanceof Message + && !(convertedOutput instanceof Message)) { + convertedOutput = MessageBuilder.withPayload(convertedOutput) + .copyHeaders(((Message) output).getHeaders()) + .build(); + } return convertedOutput; } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java index 619344d49..fc8807bbc 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 the original author or authors. + * Copyright 2016-present 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. @@ -24,16 +24,19 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.joda.JodaModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.google.gson.Gson; import io.cloudevents.spring.messaging.CloudEventMessageConverter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.joda.time.DateTimeZone; +import org.joda.time.tz.UTCProvider; +import tools.jackson.core.StreamReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JacksonModule; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.cfg.MapperBuilder; +import tools.jackson.datatype.joda.JodaModule; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.BeanFactory; @@ -222,7 +225,7 @@ else if ("jackson".equals(preferredMapper)) { } } else { - if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) { + if (ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", null)) { return jackson(context); } else if (ClassUtils.isPresent("com.google.gson.Gson", null)) { @@ -247,71 +250,37 @@ private JsonMapper gson(ApplicationContext context) { @SuppressWarnings("unchecked") private JsonMapper jackson(ApplicationContext context) { - Assert.state(ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", ClassUtils.getDefaultClassLoader()), + Assert.state(ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", ClassUtils.getDefaultClassLoader()), "Can not bootstrap Jackson mapper since Jackson is not on the classpath"); - ObjectMapper mapper; + ObjectMapper mapper = null; + MapperBuilder builder = tools.jackson.databind.json.JsonMapper.builder(); try { - mapper = context.getBean(ObjectMapper.class).copy(); + builder = context.getBean(ObjectMapper.class).rebuild(); } catch (Exception e) { - mapper = new ObjectMapper(); - mapper.registerModule(new JavaTimeModule()); + builder = tools.jackson.databind.json.JsonMapper.builder(); + DateTimeZone.setProvider(new UTCProvider()); } - mapper.registerModule(new JodaModule()); + builder = builder.addModule(new JodaModule()); + if (KotlinDetector.isKotlinPresent()) { try { - if (!mapper.getRegisteredModuleIds().contains("com.fasterxml.jackson.module.kotlin.KotlinModule")) { - Class kotlinModuleClass = (Class) - ClassUtils.forName("com.fasterxml.jackson.module.kotlin.KotlinModule", ClassUtils.getDefaultClassLoader()); - Module kotlinModule = BeanUtils.instantiateClass(kotlinModuleClass); - mapper.registerModule(kotlinModule); - } + Class kotlinModuleClass = (Class) + ClassUtils.forName("tools.jackson.module.kotlin.KotlinModule", ClassUtils.getDefaultClassLoader()); + JacksonModule kotlinModule = BeanUtils.instantiateClass(kotlinModuleClass); + builder = builder.addModule(kotlinModule); } catch (ClassNotFoundException ex) { // jackson-module-kotlin not available } } - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); -// mapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - if (logger.isDebugEnabled()) { - logger.debug("ObjectMapper configuration: " + getConfigDetails(mapper)); - } - return new JacksonMapper(mapper); - } - - private String getConfigDetails(ObjectMapper mapper) { - StringBuilder sb = new StringBuilder(); - - sb.append("Modules:\n"); - if (mapper.getRegisteredModuleIds().isEmpty()) { - sb.append("\t").append("-none-").append("\n"); - } - for (Object m : mapper.getRegisteredModuleIds()) { - sb.append(" ").append(m).append("\n"); - } - - sb.append("\nSerialization Features:\n"); - for (SerializationFeature f : SerializationFeature.values()) { - sb.append("\t").append(f).append(" -> ") - .append(mapper.getSerializationConfig().hasSerializationFeatures(f.getMask())); - if (f.enabledByDefault()) { - sb.append(" (enabled by default)"); - } - sb.append("\n"); - } + builder = builder.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + builder = builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + builder = builder.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); + builder = builder.configure(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION, false); - sb.append("\nDeserialization Features:\n"); - for (DeserializationFeature f : DeserializationFeature.values()) { - sb.append("\t").append(f).append(" -> ") - .append(mapper.getDeserializationConfig().hasDeserializationFeatures(f.getMask())); - if (f.enabledByDefault()) { - sb.append(" (enabled by default)"); - } - sb.append("\n"); - } - - return sb.toString(); + mapper = builder.build(); + return new JacksonMapper(mapper); } } } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializer.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializer.java index b55c28e46..e3de40732 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializer.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -22,8 +22,8 @@ import java.util.function.Function; import java.util.function.Supplier; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; +import tools.jackson.databind.ObjectMapper; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanCreationException; @@ -33,7 +33,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.FunctionProperties; @@ -121,7 +120,7 @@ protected void register(BeanDefinitionRegistry registry, ConfigurableListableBea if (this.context.getBeanFactory().getBeanNamesForType(PropertySourcesPlaceholderConfigurer.class, false, false).length == 0) { this.context.registerBean(PropertySourcesPlaceholderConfigurer.class, - () -> PropertyPlaceholderAutoConfiguration.propertySourcesPlaceholderConfigurer()); + PropertySourcesPlaceholderConfigurer::new); } if (!this.context.getBeanFactory() @@ -142,7 +141,7 @@ protected void register(BeanDefinitionRegistry registry, ConfigurableListableBea } this.context.registerBean(JsonMapper.class, () -> new ContextFunctionCatalogAutoConfiguration.JsonMapperConfiguration().jsonMapper(this.context)); } - else if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) { + else if (ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", null)) { if (this.context.getBeanFactory().getBeanNamesForType(ObjectMapper.class, false, false).length == 0) { this.context.registerBean(ObjectMapper.class, () -> new ObjectMapper()); } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionContextUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionContextUtils.java index dacf7b74a..7a36140d5 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionContextUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionContextUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionsEndpointAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionsEndpointAutoConfiguration.java index 861b50c5c..d734d4a14 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionsEndpointAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/FunctionsEndpointAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/JsonMessageConverter.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/JsonMessageConverter.java index 99721c184..8747e3b8f 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/JsonMessageConverter.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/JsonMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/KotlinLambdaToFunctionAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/KotlinLambdaToFunctionAutoConfiguration.java index e40aefd8f..8c9419300 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/KotlinLambdaToFunctionAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/KotlinLambdaToFunctionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-present 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. @@ -62,6 +62,8 @@ public class KotlinLambdaToFunctionAutoConfiguration { public static final class KotlinFunctionWrapper implements Function, Supplier, Consumer, Function0, Function1, Function2, Function3, Function4 { + + private final Object kotlinLambdaTarget; private String name; @@ -72,6 +74,10 @@ public KotlinFunctionWrapper(Object kotlinLambdaTarget) { this.kotlinLambdaTarget = kotlinLambdaTarget; } + public Object getKotlinLambdaTarget() { + return kotlinLambdaTarget; + } + @Override public Object apply(Object input) { if (ObjectUtils.isEmpty(input)) { diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/MessageConverterHelper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/MessageConverterHelper.java index 759fd1016..a0293efbc 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/MessageConverterHelper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/MessageConverterHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 the original author or authors. + * Copyright 2015-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java index 8aecd9500..62042a8ff 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/SmartCompositeMessageConverter.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/SmartCompositeMessageConverter.java index 65d3deafb..7aa2266fe 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/SmartCompositeMessageConverter.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/SmartCompositeMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java index 2e233a41d..0d073b4d0 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/message/MessageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java index 1642146be..9f2059d3b 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalTestContextLoader.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalTestContextLoader.java index 8193960e1..bc65c57c5 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalTestContextLoader.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalTestContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/GsonMapper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/GsonMapper.java index 375173104..a77ec420a 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/GsonMapper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/GsonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JacksonMapper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JacksonMapper.java index 2288aca36..b31e13e7e 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JacksonMapper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JacksonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2025 the original author or authors. + * Copyright 2012-present 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. @@ -21,12 +21,11 @@ import java.util.Map; import java.util.function.Consumer; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.type.TypeFactory; /** @@ -47,10 +46,14 @@ public void configureObjectMapper(Consumer configurer) { configurer.accept(mapper); } + public ObjectMapper getObjectMapper() { + return this.mapper; + } + @Override protected T doFromJson(Object json, Type type) { T convertedValue = null; - JavaType constructType = TypeFactory.defaultInstance().constructType(type); + JavaType constructType = TypeFactory.createDefaultInstance().constructType(type); try { if (json instanceof String) { @@ -93,7 +96,7 @@ public String toString(Object value) { try { return this.mapper.writeValueAsString(value); } - catch (JsonProcessingException e) { + catch (Exception e) { throw new IllegalArgumentException("Cannot convert to JSON", e); } } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JsonMapper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JsonMapper.java index 4fb91f775..a4ea34fa7 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JsonMapper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/json/JsonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -24,14 +24,13 @@ import java.util.HashSet; import java.util.List; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; @@ -45,7 +44,8 @@ public abstract class JsonMapper { private static Log logger = LogFactory.getLog(JsonMapper.class); // we need this just to validate is String is JSON - private static final ObjectMapper mapper = new ObjectMapper().enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS); + private static final ObjectMapper mapper = tools.jackson.databind.json.JsonMapper.builder() + .enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS).build(); @SuppressWarnings("unchecked") @@ -146,7 +146,7 @@ public static boolean isJsonStringRepresentsCollection(Object value) { JsonNode node = mapper.readTree(stringValue); return node instanceof ArrayNode; } - catch (JsonProcessingException e) { + catch (Exception e) { return false; } } @@ -162,7 +162,7 @@ public static boolean isJsonStringRepresentsMap(Object value) { JsonNode node = mapper.readTree(stringValue); return node instanceof ObjectNode; } - catch (JsonProcessingException e) { + catch (Exception e) { return false; } } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/DefaultFunctionObservationConvention.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/DefaultFunctionObservationConvention.java index a31e8719b..09eef41f7 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/DefaultFunctionObservationConvention.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/DefaultFunctionObservationConvention.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionContext.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionContext.java index 644ac371f..ef22abf2c 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionContext.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservation.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservation.java index a50b38814..57fda6e2b 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservation.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservationConvention.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservationConvention.java index 1a5be2a0c..86b8c6891 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservationConvention.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/FunctionObservationConvention.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationAutoConfiguration.java index ec0e1650f..16eef5af2 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. @@ -29,7 +29,7 @@ * @author Oleg Zhurakousky */ @Configuration(proxyBeanMethods = false) -@ConditionalOnBean(org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration.class) +@ConditionalOnBean(org.springframework.boot.micrometer.observation.autoconfigure.ObservationAutoConfiguration.class) public class ObservationAutoConfiguration { @Bean diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationFunctionAroundWrapper.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationFunctionAroundWrapper.java index 8f62c5fa8..b1ba9e88c 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationFunctionAroundWrapper.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/observability/ObservationFunctionAroundWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java index 1e13b1a33..023129999 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionMessageUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionMessageUtils.java index a462c9186..2a139a59d 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionMessageUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/FunctionMessageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/JsonMasker.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/JsonMasker.java index 325b5a2b3..5fc54fc77 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/JsonMasker.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/JsonMasker.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. @@ -29,15 +29,16 @@ import java.util.TreeSet; import java.util.concurrent.locks.ReentrantLock; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import tools.jackson.databind.ObjectMapper; import org.springframework.cloud.function.json.JacksonMapper; import org.springframework.cloud.function.json.JsonMapper; import org.springframework.util.ClassUtils; + /** * @author Oleg Zhurakousky * @author Omer Celik diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/KotlinUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/KotlinUtils.java index e30f650df..3e853f770 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/KotlinUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/KotlinUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/PrimitiveTypesFromStringMessageConverter.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/PrimitiveTypesFromStringMessageConverter.java index adac52099..ea1a2df1a 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/PrimitiveTypesFromStringMessageConverter.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/PrimitiveTypesFromStringMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/SocketUtils.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/SocketUtils.java index f83beb913..214e4d423 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/SocketUtils.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/utils/SocketUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-context/src/main/kotlin/org/springframework/cloud/function/context/config/CoroutinesUtils.kt b/spring-cloud-function-context/src/main/kotlin/org/springframework/cloud/function/context/config/CoroutinesUtils.kt index 8614b69db..5b2eb5a0d 100644 --- a/spring-cloud-function-context/src/main/kotlin/org/springframework/cloud/function/context/config/CoroutinesUtils.kt +++ b/spring-cloud-function-context/src/main/kotlin/org/springframework/cloud/function/context/config/CoroutinesUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/actuator/FunctionsEndpointTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/actuator/FunctionsEndpointTests.java index f9e9b4794..55015bd46 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/actuator/FunctionsEndpointTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/actuator/FunctionsEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2025 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventFunctionTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventFunctionTests.java index 104a7b8fc..eabc73412 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventFunctionTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtilsAndBuilderTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtilsAndBuilderTests.java index c76907112..3be66e4a7 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtilsAndBuilderTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/CloudEventMessageUtilsAndBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/SpringReleaseEvent.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/SpringReleaseEvent.java index 5afe8953f..64fd75d3c 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/SpringReleaseEvent.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/cloudevent/SpringReleaseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HeaderMappingTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HeaderMappingTests.java index 67c3506e9..1d9b0671b 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HeaderMappingTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HeaderMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java index 6257e7721..6b219cae9 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. @@ -24,7 +24,7 @@ import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.messaging.Message; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/MessageRoutingCallbackTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/MessageRoutingCallbackTests.java index 11dfc1daf..6a90ad292 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/MessageRoutingCallbackTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/MessageRoutingCallbackTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -48,8 +48,8 @@ public void before() { @SuppressWarnings("unchecked") @Test public void testRoutingCallbackWithMessageModification() { - FunctionCatalog catalog = this.configureCatalog(SamppleConfiguration.class); - SamppleConfiguration conf = context.getBean(SamppleConfiguration.class); + FunctionCatalog catalog = this.configureCatalog(SampleConfiguration.class); + SampleConfiguration conf = context.getBean(SampleConfiguration.class); FunctionInvocationWrapper function = (FunctionInvocationWrapper) catalog.lookup(RoutingFunction.FUNCTION_NAME, "application/json"); String foo = "{\"foo\":\"blah\"}"; Message fooResult = (Message) function.apply(MessageBuilder.withPayload(foo.getBytes()).build()); @@ -71,7 +71,7 @@ private FunctionCatalog configureCatalog(Class... configClass) { } @EnableAutoConfiguration - private static class SamppleConfiguration { + private static final class SampleConfiguration { Map createdMessageIds = new HashMap<>(); diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryMultiInOutTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryMultiInOutTests.java index 2c979741a..6f5cf8418 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryMultiInOutTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryMultiInOutTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. @@ -24,7 +24,6 @@ import java.util.function.BiFunction; import java.util.function.Function; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; @@ -32,6 +31,7 @@ import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; import reactor.util.function.Tuples; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java index dd57e32f8..6e3855bad 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. @@ -42,7 +42,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.JsonNode; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -53,6 +52,7 @@ import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; import reactor.util.function.Tuples; +import tools.jackson.databind.JsonNode; import org.springframework.beans.factory.FactoryBean; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -108,15 +108,6 @@ public void before() { System.clearProperty("spring.cloud.function.definition"); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void testEmptyPojoConversion() { - FunctionCatalog catalog = this.configureCatalog(EmptyPojoConfiguratioin.class); - Function function = catalog.lookup("echo"); - String result = (String) function.apply(MessageBuilder.withPayload(new EmptyPojo()).build()); - assertThat(result).isEqualTo("{}"); - } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testCompositionWithNonExistingFunction() throws Exception { @@ -1344,7 +1335,7 @@ public Serializable blah() { return new Foo(); } - private static class Foo implements Supplier, Serializable { + private static final class Foo implements Supplier, Serializable { @Override public Object get() { @@ -1363,7 +1354,7 @@ public Serializable blah() { return new Foo(); } - private static class Foo implements Function, Serializable { + private static final class Foo implements Function, Serializable { @Override public Object apply(Object t) { @@ -1402,6 +1393,7 @@ public Function, String> echoToString() { public static class Person { private String name; + private int id; public Person() { @@ -1496,7 +1488,7 @@ public Function, String> function() { } } - private static class Product { + private static final class Product { private String name; public String getName() { @@ -1508,7 +1500,7 @@ public void setName(String name) { } } - private static class Event { + private static final class Event { private K key; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwarePojoFunctionRegistryTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwarePojoFunctionRegistryTests.java index 89986397e..76574b76b 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwarePojoFunctionRegistryTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwarePojoFunctionRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. @@ -83,8 +83,10 @@ public void testWithPojoFunction() { Function f2conversion = catalog.lookup("myFunctionLike"); assertThat(f2conversion.apply(123)).isEqualTo("123"); - Function, String> f2message = catalog.lookup("myFunctionLike"); - assertThat(f2message.apply(MessageBuilder.withPayload("message").build())).isEqualTo("MESSAGE"); + // GH-1307: POJO functions now return Message for consistency + Function, Message> f2message = catalog.lookup("myFunctionLike"); + Message messageResult = f2message.apply(MessageBuilder.withPayload("message").build()); + assertThat(messageResult.getPayload()).isEqualTo("MESSAGE"); Function, Flux> f3 = catalog.lookup("myFunctionLike"); assertThat(f3.apply(Flux.just("foo")).blockFirst()).isEqualTo("FOO"); @@ -100,6 +102,52 @@ public void testWithPojoFunctionComposition() { assertThat(f1.apply("foo")).isEqualTo("FOO"); } + /** + * GH-1307: POJO function should return Message consistently with regular functions + * when no contentType is specified. + */ + @Test + public void testPojoFunctionReturnsMessageWithoutContentType() { + FunctionCatalog catalog = this.configureCatalog(); + + // Test POJO function without contentType + Function, Object> pojoFunction = catalog.lookup("myFunctionLike"); + Message input = MessageBuilder.withPayload("test") + .setHeader("correlationId", "123") + .build(); + + Object result = pojoFunction.apply(input); + + // GH-1307: Verify POJO functions return Message for consistency + assertThat(result) + .as("POJO function should return Message, not plain value when input is Message") + .isInstanceOf(Message.class); + + Message messageResult = (Message) result; + assertThat(messageResult.getPayload()).isEqualTo("TEST"); + assertThat(messageResult.getHeaders().get("correlationId")) + .as("Headers should be preserved") + .isEqualTo("123"); + } + + /** + * GH-1307: POJO function should NOT wrap output when input is plain String. + */ + @Test + public void testPojoFunctionDoesNotWrapPlainStringInput() { + FunctionCatalog catalog = this.configureCatalog(); + + // GH-1307: POJO function with plain String input should return plain String + Function pojoFunction = catalog.lookup("myFunctionLike"); + Object result = pojoFunction.apply("plainInput"); + + // Should return String, not Message + assertThat(result) + .as("POJO function should return plain String when input is plain String, not wrap in Message") + .isInstanceOf(String.class) + .isEqualTo("PLAININPUT"); + } + @EnableAutoConfiguration @Configuration(proxyBeanMethods = false) @@ -122,7 +170,7 @@ public Function func() { } // POJO Function that implements Function - private static class MyFunction implements Function { + private static final class MyFunction implements Function { public String uppercase(String value) { return value.toUpperCase(Locale.ROOT); } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java index 9d7ecf6b5..dd3dc0bfa 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. @@ -116,16 +116,20 @@ public void testIsTypeCollection() { assertThat(FunctionTypeUtils.isTypeCollection(new ParameterizedTypeReference>>>() { }.getType())).isFalse(); } -// @Test -// public void testNoNpeFromIsMessage() { -// FunctionTypeUtilsTests testService = new FunctionTypeUtilsTests<>(); -// -// Method methodUnderTest = -// ReflectionUtils.findMethod(testService.getClass(), "notAMessageMethod", AtomicReference.class); -// MethodParameter methodParameter = MethodParameter.forExecutable(methodUnderTest, 0); -// -// assertThat(FunctionTypeUtils.isMessage(methodParameter.getGenericParameterType())).isFalse(); -// } + @Test + public void testWithComplexGenericsHierarchy() throws Exception { + Type functionType = FunctionTypeUtils.discoverFunctionTypeFromFunctionFactoryMethod(FunctionTypeUtilsTests.class, "methodWithGenerics"); + Type inputType = FunctionTypeUtils.getInputType(functionType); + Class typeClass = FunctionTypeUtils.getRawType(inputType); + assertThat(typeClass).isAssignableFrom(Message.class); + ParameterizedType parameterizedInputType = (ParameterizedType) inputType; + Type[] typeArguments = parameterizedInputType.getActualTypeArguments(); + typeClass = FunctionTypeUtils.getRawType(typeArguments[0]); + assertThat(typeClass).isAssignableFrom(List.class); + typeArguments = ((ParameterizedType) typeArguments[0]).getActualTypeArguments(); + typeClass = FunctionTypeUtils.getRawType(typeArguments[0]); + assertThat(typeClass).isAssignableFrom(SomeDomainObject.class); + } //@Test public void testPrimitiveFunctionInputTypes() { @@ -166,7 +170,6 @@ public void testPrimitiveFunctionInputTypes() { assertThat(FunctionTypeUtils.getRawType(FunctionTypeUtils.getInputType(type))).isAssignableFrom(ToDoubleFunction.class); } - //@Test public void testPrimitiveFunctionOutputTypes() { Type type = FunctionTypeUtils.discoverFunctionTypeFromClass(IntConsumer.class); @@ -207,10 +210,6 @@ public void testPrimitiveFunctionOutputTypes() { assertThat(FunctionTypeUtils.getRawType(FunctionTypeUtils.getOutputType(type))).isAssignableFrom(ToDoubleFunction.class); } -// void notAMessageMethod(AtomicReference payload) { -// -// } - private static Function function() { return null; } @@ -264,6 +263,10 @@ private Type getReturnType(String methodName) throws Exception { return FunctionTypeUtilsTests.class.getDeclaredMethod(methodName).getGenericReturnType(); } + public static GenericBatchMessageListConsumer methodWithGenerics() { + return new GenericBatchMessageListConsumer(); + } + //============ private interface MessageFunction extends Function, Message> { @@ -324,4 +327,15 @@ public static class SampleData { } + public static class SomeDomainObject { + + } + public static class GenericBatchMessageListConsumer implements Consumer>> { + + @Override + public void accept(Message> listMessage) { + + } + } + } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistryTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistryTests.java index 5645582c4..64a273556 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistryTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-present 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. @@ -38,7 +38,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.protobuf.StringValue; import org.assertj.core.api.Assertions; @@ -50,6 +49,7 @@ import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -82,6 +82,7 @@ import org.springframework.util.MimeType; import org.springframework.util.ReflectionUtils; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -696,7 +697,7 @@ private FunctionCatalog configureCatalog(Class... configClass) { } @EnableAutoConfiguration - private static class CustomConverterConfiguration { + private static final class CustomConverterConfiguration { @Bean public MessageConverter stringToPersonConverter() { return new AbstractMessageConverter(MimeType.valueOf("text/person")) { @@ -737,7 +738,7 @@ public Function func() { } } - public static class Person { + public static final class Person { private String name; public String getName() { @@ -754,7 +755,7 @@ public String toString() { } } - private static class Words implements Supplier { + private static final class Words implements Supplier { @Override public String get() { @@ -763,7 +764,7 @@ public String get() { } - private static class UpperCase implements Function { + private static final class UpperCase implements Function { @Override public String apply(String t) { @@ -772,7 +773,7 @@ public String apply(String t) { } - private static class Echo implements Function { + private static final class Echo implements Function { @Override public Object apply(Object t) { @@ -781,7 +782,7 @@ public Object apply(Object t) { } - private static class UpperCaseMessage + private static final class UpperCaseMessage implements Function, Message> { @Override @@ -792,7 +793,7 @@ public Message apply(Message t) { } - private static class Reverse implements Function { + private static final class Reverse implements Function { @Override public String apply(String t) { @@ -801,7 +802,7 @@ public String apply(String t) { } - private static class ReverseMessage + private static final class ReverseMessage implements Function, Message> { @Override @@ -813,7 +814,7 @@ public Message apply(Message t) { } - private static class TestFunction implements Function { + private static final class TestFunction implements Function { @Override public String apply(Integer t) { @@ -822,7 +823,7 @@ public String apply(Integer t) { } - private static class ReactiveFunction implements Function>>, Flux>> { + private static final class ReactiveFunction implements Function>>, Flux>> { @Override public Flux> apply(Flux>> listFlux) { @@ -832,7 +833,7 @@ public Flux> apply(Flux>> listFlux) { } } - private static class ReactiveMonoGreeter implements Supplier>> { + private static final class ReactiveMonoGreeter implements Supplier>> { @Override public Mono> get() { @@ -841,7 +842,7 @@ public Mono> get() { } - private static class HeaderEnricherFunction implements Function, Message> { + private static final class HeaderEnricherFunction implements Function, Message> { @Override public Message apply(Message message) { @@ -850,28 +851,28 @@ public Message apply(Message message) { } } - private static class StringArrayFunction implements Function { + private static final class StringArrayFunction implements Function { @Override public String apply(String[] t) { return Arrays.asList(t).toString(); } } - private static class StringListFunction implements Function, String> { + private static final class StringListFunction implements Function, String> { @Override public String apply(List t) { return t.toString(); } } - private static class TypelessFunction implements Function { + private static final class TypelessFunction implements Function { @Override public String apply(Object t) { return t.toString(); } } - private static class ByteArrayFunction implements Function { + private static final class ByteArrayFunction implements Function { @Override public String apply(byte[] t) { return new String(t); diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationConditionalLoadingTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationConditionalLoadingTests.java index 0b19ba8cf..12662ba34 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationConditionalLoadingTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationConditionalLoadingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java index be388ab95..b46b565af 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -848,7 +848,7 @@ public Function function() { // // } - private static class FunctionFactoryBean + private static final class FunctionFactoryBean extends AbstractFactoryBean> { @Override diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializerTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializerTests.java index fd00ccacb..5e6d88aec 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializerTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogInitializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -414,7 +414,7 @@ public void setValue(String value) { } - private static class Person { + private static final class Person { private String name; public String getName() { diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/JsonMessageConverterTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/JsonMessageConverterTests.java index 088fe9db8..2bf933f20 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/JsonMessageConverterTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/JsonMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -16,8 +16,8 @@ package org.springframework.cloud.function.context.config; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import org.springframework.cloud.function.json.JacksonMapper; import org.springframework.messaging.Message; @@ -25,6 +25,7 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.MimeTypeUtils; + import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java index 366dd5475..dbdf2a76f 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. @@ -57,7 +57,9 @@ public class RoutingFunctionTests { public void before() { System.clearProperty("spring.cloud.function.definition"); System.clearProperty("spring.cloud.function.routing-expression"); - context.close(); + if (context != null) { + context.close(); + } } private FunctionCatalog configureCatalog(Class configurationClass) { @@ -377,11 +379,14 @@ protected static class EmptyConfiguration { @EnableAutoConfiguration @Configuration protected static class ConfigurationWithDefaultMessageRoutingHandler { + /** + * + */ public boolean defaultHandlerInvoked; @Bean public DefaultMessageRoutingHandler defaultRoutingHandler() { return new DefaultMessageRoutingHandler() { - @Override + @Override public void accept(Message message) { super.accept(message); defaultHandlerInvoked = true; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/scan/TestFunction.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/scan/TestFunction.java index 5a8c2cb7e..b274e0213 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/scan/TestFunction.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/scan/TestFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java index f336e476c..b7cca6f74 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/test/FunctionalTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/test/FunctionalTests.java index b7cd6bf65..48f1f5863 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/test/FunctionalTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/test/FunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/inject/FooConfiguration.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/inject/FooConfiguration.java index a62f653b3..a95356f22 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/inject/FooConfiguration.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/inject/FooConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/scan/ScannedFunction.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/scan/ScannedFunction.java index a829ad573..59521a79a 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/scan/ScannedFunction.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/scan/ScannedFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/test/GenericFunction.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/test/GenericFunction.java index 4389f4aff..a5c20509e 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/test/GenericFunction.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/test/GenericFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java index fa5fe490e..1bb2aa78d 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. @@ -20,11 +20,11 @@ import java.util.List; import java.util.function.Function; -import com.fasterxml.jackson.databind.ObjectMapper; import org.assertj.core.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMapperTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMapperTests.java index 1b7e28eef..5439b9e33 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMapperTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -16,20 +16,20 @@ package org.springframework.cloud.function.utils; -import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.time.ZonedDateTime; import java.util.Date; import java.util.List; import java.util.stream.Stream; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.Gson; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -39,7 +39,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.ResolvableType; -import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -86,16 +85,6 @@ public void testJsonDateTimeConversion() { assertThat(convertedJson).contains("\"zonedDateTime\":\"2024-10-16T16:13:29.964361+02:00\""); } - @Test - public void testKotlinModuleRegistration() throws Exception { - ApplicationContext context = SpringApplication.run(EmptyConfiguration.class); - JsonMapper jsonMapper = context.getBean(JsonMapper.class); - Field mapperField = ReflectionUtils.findField(jsonMapper.getClass(), "mapper"); - mapperField.setAccessible(true); - ObjectMapper mapper = (ObjectMapper) mapperField.get(jsonMapper); - assertThat(mapper.getRegisteredModuleIds()).contains("com.fasterxml.jackson.module.kotlin.KotlinModule"); - } - @ParameterizedTest @MethodSource("params") public void vanillaArray(JsonMapper mapper) { diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMaskerTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMaskerTests.java index 37c7ce0e8..a72b0bb24 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMaskerTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/utils/JsonMaskerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. @@ -23,14 +23,17 @@ import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.assertj.core.util.Arrays; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; + import org.springframework.cloud.function.json.JacksonMapper; import org.springframework.util.ReflectionUtils; + import static org.assertj.core.api.Assertions.assertThat; @@ -193,7 +196,8 @@ public class JsonMaskerTests { @Test public void validateMasking() throws Exception { - JacksonMapper mapper = new JacksonMapper(new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT)); + ObjectMapper objectMapper = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build(); + JacksonMapper mapper = new JacksonMapper(objectMapper); Map map = mapper.fromJson(event, Map.class); JsonMasker masker = JsonMasker.INSTANCE(); @@ -220,7 +224,8 @@ public void validateMasking() throws Exception { @Test public void validateMaskingWithAdditionalKeys() throws Exception { - JacksonMapper mapper = new JacksonMapper(new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT)); + ObjectMapper objectMapper = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build(); + JacksonMapper mapper = new JacksonMapper(objectMapper); Map map = mapper.fromJson(event, Map.class); JsonMasker masker = JsonMasker.INSTANCE(Set.of("foo", "bar")); diff --git a/spring-cloud-function-core/pom.xml b/spring-cloud-function-core/pom.xml index 1cc5203cc..2018eebba 100644 --- a/spring-cloud-function-core/pom.xml +++ b/spring-cloud-function-core/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/core/FunctionInvocationHelper.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/core/FunctionInvocationHelper.java index 0698fdbff..8fa792e95 100644 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/core/FunctionInvocationHelper.java +++ b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/core/FunctionInvocationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-dependencies/pom.xml b/spring-cloud-function-dependencies/pom.xml index 1ee6c54f4..213c518e1 100644 --- a/spring-cloud-function-dependencies/pom.xml +++ b/spring-cloud-function-dependencies/pom.xml @@ -6,11 +6,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT spring-cloud-function-dependencies - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT pom Spring Cloud Function Dependencies Spring Cloud Function Dependencies diff --git a/spring-cloud-function-deployer/pom.xml b/spring-cloud-function-deployer/pom.xml index 0e3a651b5..cbae244bd 100644 --- a/spring-cloud-function-deployer/pom.xml +++ b/spring-cloud-function-deployer/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-deployer/src/it/bootapp-multi/pom.xml b/spring-cloud-function-deployer/src/it/bootapp-multi/pom.xml index 9a205c3ca..124097df7 100644 --- a/spring-cloud-function-deployer/src/it/bootapp-multi/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootapp-multi/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootapp-with-javax/pom.xml b/spring-cloud-function-deployer/src/it/bootapp-with-javax/pom.xml index 65f119604..2784e3a67 100644 --- a/spring-cloud-function-deployer/src/it/bootapp-with-javax/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootapp-with-javax/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootapp-with-scf/pom.xml b/spring-cloud-function-deployer/src/it/bootapp-with-scf/pom.xml index 47f8490b7..bd1099dbd 100644 --- a/spring-cloud-function-deployer/src/it/bootapp-with-scf/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootapp-with-scf/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootapp/pom.xml b/spring-cloud-function-deployer/src/it/bootapp/pom.xml index a173bc5ff..73eb17d59 100644 --- a/spring-cloud-function-deployer/src/it/bootapp/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootapp/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootjar-multi/pom.xml b/spring-cloud-function-deployer/src/it/bootjar-multi/pom.xml index 7310dd892..aa5a06b2d 100644 --- a/spring-cloud-function-deployer/src/it/bootjar-multi/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootjar-multi/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootjar/pom.xml b/spring-cloud-function-deployer/src/it/bootjar/pom.xml index 2d985d326..b62b27c22 100644 --- a/spring-cloud-function-deployer/src/it/bootjar/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootjar/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/it/bootjarnostart/pom.xml b/spring-cloud-function-deployer/src/it/bootjarnostart/pom.xml index 3e8d46820..d169eb0cb 100644 --- a/spring-cloud-function-deployer/src/it/bootjarnostart/pom.xml +++ b/spring-cloud-function-deployer/src/it/bootjarnostart/pom.xml @@ -12,13 +12,13 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/DeployerContextUtils.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/DeployerContextUtils.java index 070328b0d..09836e495 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/DeployerContextUtils.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/DeployerContextUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionArchiveDeployer.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionArchiveDeployer.java index 2c96fdd64..98b94d569 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionArchiveDeployer.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionArchiveDeployer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerConfiguration.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerConfiguration.java index 607b5e60f..275d3fafa 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerConfiguration.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerProperties.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerProperties.java index e5e61c779..11a73c976 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerProperties.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/FunctionDeployerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2017-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/LoggingRepositoryListener.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/LoggingRepositoryListener.java index 8a6d2ce2d..e5d7d07a9 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/LoggingRepositoryListener.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/LoggingRepositoryListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenArtifactResolver.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenArtifactResolver.java index fe3de5a8d..fccb4d7ab 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenArtifactResolver.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenArtifactResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenProperties.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenProperties.java index 4abc9b464..c161ecdc5 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenProperties.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResource.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResource.java index 95799a320..cb396513e 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResource.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResourceLoader.java b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResourceLoader.java index 41e25ef0f..846576adc 100644 --- a/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResourceLoader.java +++ b/spring-cloud-function-deployer/src/main/java/org/springframework/cloud/function/deployer/utils/MavenResourceLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-deployer/src/main/resources/META-INF/spring.factories b/spring-cloud-function-deployer/src/main/resources/META-INF/spring.factories index 55304d26b..a58ca6ba1 100644 --- a/spring-cloud-function-deployer/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-function-deployer/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.env.EnvironmentPostProcessor=org.springframework.cloud.function.deployer.FunctionDeployerConfiguration$LegacyPropertyEnvironmentPostProcessor +org.springframework.boot.EnvironmentPostProcessor=org.springframework.cloud.function.deployer.FunctionDeployerConfiguration$LegacyPropertyEnvironmentPostProcessor diff --git a/spring-cloud-function-deployer/src/test/java/org/springframework/cloud/function/deployer/FunctionDeployerTests.java b/spring-cloud-function-deployer/src/test/java/org/springframework/cloud/function/deployer/FunctionDeployerTests.java index 8074c7dc2..daacedc14 100644 --- a/spring-cloud-function-deployer/src/test/java/org/springframework/cloud/function/deployer/FunctionDeployerTests.java +++ b/spring-cloud-function-deployer/src/test/java/org/springframework/cloud/function/deployer/FunctionDeployerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2020 the original author or authors. + * Copyright 2017-present 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. diff --git a/spring-cloud-function-integration/pom.xml b/spring-cloud-function-integration/pom.xml index 554c52c13..b709c36b9 100644 --- a/spring-cloud-function-integration/pom.xml +++ b/spring-cloud-function-integration/pom.xml @@ -12,7 +12,7 @@ spring-cloud-function-parent org.springframework.cloud - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowAutoConfiguration.java b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowAutoConfiguration.java index 03d3848ae..dcf90bfbe 100644 --- a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowAutoConfiguration.java +++ b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowBuilder.java b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowBuilder.java index 1ad83a440..158780ecf 100644 --- a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowBuilder.java +++ b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowDefinition.java b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowDefinition.java index cc8b84553..833866d68 100644 --- a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowDefinition.java +++ b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionFlowDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionLookupHelper.java b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionLookupHelper.java index f4a9637b4..94b871b29 100644 --- a/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionLookupHelper.java +++ b/spring-cloud-function-integration/src/main/java/org/springframework/cloud/function/integration/dsl/FunctionLookupHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-integration/src/test/java/org/springframework/cloud/function/integration/dsl/FunctionFlowTests.java b/spring-cloud-function-integration/src/test/java/org/springframework/cloud/function/integration/dsl/FunctionFlowTests.java index e4ee38a2b..aa38492c9 100644 --- a/spring-cloud-function-integration/src/test/java/org/springframework/cloud/function/integration/dsl/FunctionFlowTests.java +++ b/spring-cloud-function-integration/src/test/java/org/springframework/cloud/function/integration/dsl/FunctionFlowTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -28,7 +28,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -46,6 +45,7 @@ import org.springframework.messaging.MessageDeliveryException; import org.springframework.messaging.support.GenericMessage; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -62,7 +62,7 @@ public class FunctionFlowTests { // To verify cached lookups - @SpyBean + @MockitoSpyBean FunctionCatalog functionCatalog; @Autowired diff --git a/spring-cloud-function-kotlin/pom.xml b/spring-cloud-function-kotlin/pom.xml index 5dd923ccc..618299a9e 100644 --- a/spring-cloud-function-kotlin/pom.xml +++ b/spring-cloud-function-kotlin/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -24,6 +24,10 @@ org.springframework.cloud spring-cloud-function-adapter-aws + + org.springframework.boot + spring-boot-starter-webclient + com.amazonaws aws-lambda-java-events @@ -65,9 +69,12 @@ test - org.springframework - spring-webflux - test + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-gson org.springframework.boot @@ -79,6 +86,21 @@ spring-boot-configuration-processor true + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + @@ -86,21 +108,6 @@ kotlin-maven-plugin org.jetbrains.kotlin - 2.1.0 - - - test-compile - - test-compile - - - - ${project.basedir}/src/test/kotlin - ${project.basedir}/src/test/java - - - - org.apache.maven.plugins diff --git a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinSuspendTests.java b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinSuspendTests.java index 874de12a4..7274f311b 100644 --- a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinSuspendTests.java +++ b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinSuspendTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java index ae28d985d..606454e98 100644 --- a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java +++ b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/ContextFunctionCatalogAutoConfigurationKotlinTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. @@ -29,6 +29,7 @@ import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper; +import org.springframework.cloud.function.context.config.KotlinLambdaToFunctionAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.GenericApplicationContext; @@ -59,11 +60,21 @@ public void typeDiscoveryTests() { create(new Class[] { KotlinLambdasConfiguration.class, SimpleConfiguration.class, KotlinComponentFunction.class, + KotlinPostProcessingFunction.class, ComponentUppercase.class, ComponentWithUnitReturn.class}); FunctionCatalog functionCatalog = this.context.getBean(FunctionCatalog.class); + // Test post-processing logic + FunctionInvocationWrapper kotlinPostProcessingFunction = functionCatalog.lookup("kotlinPostProcessingFunction"); + kotlinPostProcessingFunction.apply("bob"); + kotlinPostProcessingFunction.postProcess(); + KotlinPostProcessingFunction postProcessingFunction = (KotlinPostProcessingFunction) + ((KotlinLambdaToFunctionAutoConfiguration.KotlinFunctionWrapper) kotlinPostProcessingFunction.getTarget()).getKotlinLambdaTarget(); + assertThat(postProcessingFunction.getInvoked()).isTrue(); + // End test post-processing logic + FunctionInvocationWrapper kotlinComponentFunction = functionCatalog.lookup("kotlinComponentFunction"); assertThat(kotlinComponentFunction.isFunction()).isTrue(); assertThat(kotlinComponentFunction.getInputType().getTypeName()).isEqualTo("java.lang.String"); diff --git a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/KotlinTypeDiscoveryTests.java b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/KotlinTypeDiscoveryTests.java index 769c0b221..b384b17b3 100644 --- a/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/KotlinTypeDiscoveryTests.java +++ b/spring-cloud-function-kotlin/src/test/java/org/springframework/cloud/function/kotlin/KotlinTypeDiscoveryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt index a324131fc..d89d2845f 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinLambdasConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. @@ -34,7 +34,7 @@ open class KotlinLambdasConfiguration { open fun uppercase(): Function = KotlinComponentFunction() @Bean open fun kotlinFunction(): (String) -> String { - return { it.toUpperCase() } + return { it.uppercase() } } @Bean diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinPostProcessingFunction.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinPostProcessingFunction.kt new file mode 100644 index 000000000..41bd2df5d --- /dev/null +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinPostProcessingFunction.kt @@ -0,0 +1,20 @@ +package org.springframework.cloud.function.kotlin + +import org.springframework.cloud.function.context.PostProcessingFunction +import org.springframework.messaging.Message +import org.springframework.stereotype.Component +import java.util.function.Function + +@Component +class KotlinPostProcessingFunction : PostProcessingFunction { + + var invoked = false + + override fun apply(t: String): String { + return t.uppercase(); + } + + override fun postProcess(result: Message?) { + invoked = true; + } +} diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendFlowLambdasConfiguration.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendFlowLambdasConfiguration.kt index bfa7e3102..6b7c41180 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendFlowLambdasConfiguration.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendFlowLambdasConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -36,7 +36,7 @@ open class KotlinSuspendFlowLambdasConfiguration { @Bean open fun kotlinFunction(): suspend (Flow) -> Flow = { flow -> - flow.map { value -> value.toUpperCase() } + flow.map { value -> value.uppercase() } } @Bean diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendLambdasConfiguration.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendLambdasConfiguration.kt index 68e985550..d9a4aef2c 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendLambdasConfiguration.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/KotlinSuspendLambdasConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/Person.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/Person.kt index f46fb3278..fd27360d5 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/Person.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/Person.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/AwsKotlinTestsTests.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/AwsKotlinTestsTests.kt index 36eafbbe3..d33f3f3ee 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/AwsKotlinTestsTests.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/AwsKotlinTestsTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/KotlinAwsLambdasConfiguration.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/KotlinAwsLambdasConfiguration.kt index 315c1b63a..fe17f2fff 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/KotlinAwsLambdasConfiguration.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/aws/KotlinAwsLambdasConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageSuspendTests.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageSuspendTests.kt index 85ad7f68f..83ea7e87e 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageSuspendTests.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageSuspendTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. @@ -21,13 +21,15 @@ import org.assertj.core.api.Assertions import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.resttestclient.TestRestTemplate +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate 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.cloud.function.web.RestApplication import org.springframework.context.annotation.Bean 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 @@ -41,6 +43,7 @@ import java.net.URI properties = ["spring.cloud.function.web.path=/functions", "spring.main.web-application-type=reactive"] ) @ContextConfiguration(classes = [RestApplication::class, HeadersToMessageSuspendTests.TestConfiguration::class]) +@AutoConfigureTestRestTemplate open class HeadersToMessageSuspendTests { @Autowired private val rest: TestRestTemplate? = null @@ -52,25 +55,27 @@ open class HeadersToMessageSuspendTests { .exchange( RequestEntity.post(URI("/functions/employeeSuspend")) .contentType(MediaType.APPLICATION_JSON) - .body("[{\"name\":\"Bob\",\"age\":25}]"), String::class.java - ) + .body("[{\"name\":\"Bob\",\"age\":25}]"), List::class.java + ) as ResponseEntity>> - Assertions.assertThat(postForEntity.body).isEqualTo("[{\"name\":\"Bob\",\"age\":25}]") - Assertions.assertThat(postForEntity.headers.containsKey("x-content-type")).isTrue + val map = hashMapOf("name" to "Bob", "age" to 25) as Map + Assertions.assertThat(postForEntity.body).hasSize(1) + Assertions.assertThat(postForEntity.body?.get(0)).containsExactlyInAnyOrderEntriesOf(map) + Assertions.assertThat(postForEntity.headers.containsHeader("x-content-type")).isTrue Assertions.assertThat(postForEntity.headers["x-content-type"]!![0]) .isEqualTo("application/xml") Assertions.assertThat(postForEntity.headers["foo"]!![0]).isEqualTo("bar") // test simple type payload - postForEntity = rest.postForEntity( + var postForEntity2 = rest.postForEntity( URI("/functions/stringSuspend"), "HELLO", String::class.java ) - Assertions.assertThat(postForEntity.body).isEqualTo("[\"HELLO\"]") - Assertions.assertThat(postForEntity.headers.containsKey("x-content-type")).isTrue - Assertions.assertThat(postForEntity.headers["x-content-type"]!![0]) + Assertions.assertThat(postForEntity2.body).isEqualTo("[\"HELLO\"]") + Assertions.assertThat(postForEntity2.headers.containsHeader("x-content-type")).isTrue + Assertions.assertThat(postForEntity2.headers["x-content-type"]!![0]) .isEqualTo("application/xml") - Assertions.assertThat(postForEntity.headers["foo"]!![0]).isEqualTo("bar") + Assertions.assertThat(postForEntity2.headers["foo"]!![0]).isEqualTo("bar") } @EnableAutoConfiguration diff --git a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageTests.kt b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageTests.kt index 02f1c170d..c96ac7c0e 100644 --- a/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageTests.kt +++ b/spring-cloud-function-kotlin/src/test/kotlin/org/springframework/cloud/function/kotlin/web/HeadersToMessageTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. @@ -19,13 +19,15 @@ import org.assertj.core.api.Assertions import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.resttestclient.TestRestTemplate +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate 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.cloud.function.web.RestApplication import org.springframework.context.annotation.Bean 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 @@ -41,6 +43,7 @@ import java.net.URI properties = ["spring.cloud.function.web.path=/functions", "spring.main.web-application-type=reactive"] ) @ContextConfiguration(classes = [RestApplication::class, HeadersToMessageTests.TestConfiguration::class]) +@AutoConfigureTestRestTemplate open class HeadersToMessageTests { @Autowired private val rest: TestRestTemplate? = null @@ -52,31 +55,32 @@ open class HeadersToMessageTests { .exchange( RequestEntity.post(URI("/functions/employee")) .contentType(MediaType.APPLICATION_JSON) - .body("{\"name\":\"Bob\",\"age\":25}"), String::class.java - ) - Assertions.assertThat(postForEntity.body).isEqualTo("{\"name\":\"Bob\",\"age\":25}") - Assertions.assertThat(postForEntity.headers.containsKey("x-content-type")).isTrue + .body("{\"name\":\"Bob\",\"age\":25}"), Map::class.java + ) as ResponseEntity> + val map = hashMapOf("name" to "Bob", "age" to 25) as Map + Assertions.assertThat(postForEntity.body).containsExactlyInAnyOrderEntriesOf(map) + Assertions.assertThat(postForEntity.headers.containsHeader("x-content-type")).isTrue Assertions.assertThat(postForEntity.headers["x-content-type"]!![0]) .isEqualTo("application/xml") Assertions.assertThat(postForEntity.headers["foo"]!![0]).isEqualTo("bar") // test simple type payload - postForEntity = rest.postForEntity( + var postForEntity2 = rest.postForEntity( URI("/functions/string"), "{\"name\":\"Bob\",\"age\":25}", String::class.java ) - Assertions.assertThat(postForEntity.body).isEqualTo("{\"name\":\"Bob\",\"age\":25}") - Assertions.assertThat(postForEntity.headers.containsKey("x-content-type")).isTrue - Assertions.assertThat(postForEntity.headers["x-content-type"]!![0]) + Assertions.assertThat(postForEntity2.body).isEqualTo("{\"name\":\"Bob\",\"age\":25}") + Assertions.assertThat(postForEntity2.headers.containsHeader("x-content-type")).isTrue + Assertions.assertThat(postForEntity2.headers["x-content-type"]!![0]) .isEqualTo("application/xml") - Assertions.assertThat(postForEntity.headers["foo"]!![0]).isEqualTo("bar") + Assertions.assertThat(postForEntity2.headers["foo"]!![0]).isEqualTo("bar") } @EnableAutoConfiguration @org.springframework.boot.test.context.TestConfiguration open class TestConfiguration { @Bean("string") - open fun functiono(): (message: Message) -> Message = { request: Message -> + open fun functiono(): (message: Message) -> Message = { request: Message -> val message = MessageBuilder.withPayload(request.payload) .setHeader("X-Content-Type", "application/xml") diff --git a/spring-cloud-function-rsocket/pom.xml b/spring-cloud-function-rsocket/pom.xml index 20f89375f..bdd9885c4 100644 --- a/spring-cloud-function-rsocket/pom.xml +++ b/spring-cloud-function-rsocket/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketMessageHandler.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketMessageHandler.java index a61e006f0..c2d670bb1 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketMessageHandler.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketUtils.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketUtils.java index a46e482f4..be16954ae 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketUtils.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/FunctionRSocketUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonDecoder.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonDecoder.java index 1398d3958..99ac44e6f 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonDecoder.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonEncoder.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonEncoder.java index 02aa41045..ec27d2c96 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonEncoder.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketAutoConfiguration.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketAutoConfiguration.java index e7cc2b28a..0c13bd779 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketAutoConfiguration.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. @@ -19,8 +19,8 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.rsocket.RSocketMessageHandlerCustomizer; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.rsocket.autoconfigure.RSocketMessageHandlerCustomizer; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.FunctionProperties; import org.springframework.cloud.function.json.JsonMapper; @@ -47,8 +47,8 @@ class RSocketAutoConfiguration { @ConditionalOnMissingBean @Primary FunctionRSocketMessageHandler functionRSocketMessageHandler(RSocketStrategies rSocketStrategies, - ObjectProvider customizers, FunctionCatalog functionCatalog, - FunctionProperties functionProperties, JsonMapper jsonMapper) { + ObjectProvider customizers, FunctionCatalog functionCatalog, + FunctionProperties functionProperties, JsonMapper jsonMapper) { FunctionRSocketMessageHandler rsocketMessageHandler = new FunctionRSocketMessageHandler(functionCatalog, functionProperties, jsonMapper); rsocketMessageHandler.setRSocketStrategies(rSocketStrategies); diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketCustomizerConfiguration.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketCustomizerConfiguration.java index 82628e186..a12971db9 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketCustomizerConfiguration.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketCustomizerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketForwardingFunction.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketForwardingFunction.java index 8da7e76e4..40496c074 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketForwardingFunction.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketForwardingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketFunctionProperties.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketFunctionProperties.java index f6c137ccc..f365ae4b2 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketFunctionProperties.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketFunctionProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketListenerFunction.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketListenerFunction.java index 53f81e688..9811d53f6 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketListenerFunction.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketListenerFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketRoutingAutoConfiguration.java b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketRoutingAutoConfiguration.java index abf37dbd2..1a358ae92 100644 --- a/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketRoutingAutoConfiguration.java +++ b/spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/RSocketRoutingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessageRoutingCallbackRSocketTests.java b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessageRoutingCallbackRSocketTests.java index fcf26adb9..98eeb41fe 100644 --- a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessageRoutingCallbackRSocketTests.java +++ b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessageRoutingCallbackRSocketTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessagingTests.java b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessagingTests.java index 726ae7a7a..2e18546b4 100644 --- a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessagingTests.java +++ b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/MessagingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationRoutingTests.java b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationRoutingTests.java index 0afa56200..fd3dfc49b 100644 --- a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationRoutingTests.java +++ b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationRoutingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationTests.java b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationTests.java index 05dc9b43e..cc295f143 100644 --- a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationTests.java +++ b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RSocketAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RoutingBrokerTests.java b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RoutingBrokerTests.java index 3b6005681..5ae1e0dab 100644 --- a/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RoutingBrokerTests.java +++ b/spring-cloud-function-rsocket/src/test/java/org/springframework/cloud/function/rsocket/RoutingBrokerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-samples/function-functional-sample-aws/pom.xml b/spring-cloud-function-samples/function-functional-sample-aws/pom.xml index 270e8dd25..5a2193eb0 100644 --- a/spring-cloud-function-samples/function-functional-sample-aws/pom.xml +++ b/spring-cloud-function-samples/function-functional-sample-aws/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -24,7 +24,7 @@ UTF-8 1.0.31.RELEASE 3.14.0 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-functional-sample-aws/src/test/java/example/MapTests.java b/spring-cloud-function-samples/function-functional-sample-aws/src/test/java/example/MapTests.java index 289a8c9ff..bcd3660cd 100644 --- a/spring-cloud-function-samples/function-functional-sample-aws/src/test/java/example/MapTests.java +++ b/spring-cloud-function-samples/function-functional-sample-aws/src/test/java/example/MapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-aws-custom-bean/pom.xml b/spring-cloud-function-samples/function-sample-aws-custom-bean/pom.xml index 698f8f04f..93f0ad9ac 100644 --- a/spring-cloud-function-samples/function-sample-aws-custom-bean/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws-custom-bean/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 io.spring.sample @@ -16,7 +16,7 @@ 1.0.31.RELEASE - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws-custom/pom.xml b/spring-cloud-function-samples/function-sample-aws-custom/pom.xml index 0828fcee2..677c80dbb 100644 --- a/spring-cloud-function-samples/function-sample-aws-custom/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws-custom/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 io.spring.sample @@ -16,7 +16,7 @@ 1.0.31.RELEASE - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws-custom/src/test/java/com/example/LambdaApplicationTests.java b/spring-cloud-function-samples/function-sample-aws-custom/src/test/java/com/example/LambdaApplicationTests.java index b7e560f00..55eeec2ca 100644 --- a/spring-cloud-function-samples/function-sample-aws-custom/src/test/java/com/example/LambdaApplicationTests.java +++ b/spring-cloud-function-samples/function-sample-aws-custom/src/test/java/com/example/LambdaApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-samples/function-sample-aws-native/pom.xml b/spring-cloud-function-samples/function-sample-aws-native/pom.xml index 34de8d50a..32b915b63 100644 --- a/spring-cloud-function-samples/function-sample-aws-native/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws-native/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 oz.native.sample @@ -15,7 +15,7 @@ Sample of AWS with Spring Native 19 - 2025.0.1-SNAPSHOT + 2025.1.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws-routing/pom.xml b/spring-cloud-function-samples/function-sample-aws-routing/pom.xml index d1af49a9b..4a62478ef 100644 --- a/spring-cloud-function-samples/function-sample-aws-routing/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws-routing/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -24,7 +24,7 @@ UTF-8 1.0.31.RELEASE 3.14.0 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws-routing/src/test/java/example/MapTests.java b/spring-cloud-function-samples/function-sample-aws-routing/src/test/java/example/MapTests.java index 289a8c9ff..bcd3660cd 100644 --- a/spring-cloud-function-samples/function-sample-aws-routing/src/test/java/example/MapTests.java +++ b/spring-cloud-function-samples/function-sample-aws-routing/src/test/java/example/MapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-aws-serverless-web-native/pom.xml b/spring-cloud-function-samples/function-sample-aws-serverless-web-native/pom.xml index a5104e743..91029427c 100644 --- a/spring-cloud-function-samples/function-sample-aws-serverless-web-native/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws-serverless-web-native/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 oz.native.sample @@ -16,7 +16,7 @@ Sample of AWS with Spring Native 21 - 2025.0.1-SNAPSHOT + 2025.1.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws/pom.xml b/spring-cloud-function-samples/function-sample-aws/pom.xml index 29c3a2aec..faf5240f0 100644 --- a/spring-cloud-function-samples/function-sample-aws/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -24,7 +24,7 @@ UTF-8 1.0.31.RELEASE 3.14.0 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java b/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java index 289a8c9ff..bcd3660cd 100644 --- a/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java +++ b/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-blob-trigger/pom.xml b/spring-cloud-function-samples/function-sample-azure-blob-trigger/pom.xml index 15670d2a8..d5f0a9405 100644 --- a/spring-cloud-function-samples/function-sample-azure-blob-trigger/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure-blob-trigger/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/AzureBlobTriggerDemoApplication.java b/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/AzureBlobTriggerDemoApplication.java index 9ef38a8a6..6a9d48e5f 100644 --- a/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/AzureBlobTriggerDemoApplication.java +++ b/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/AzureBlobTriggerDemoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/MyBlobFunction.java b/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/MyBlobFunction.java index 06a26c7f4..bd1b25d03 100644 --- a/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/MyBlobFunction.java +++ b/spring-cloud-function-samples/function-sample-azure-blob-trigger/src/main/java/com/example/azure/di/azureblobtriggerdemo/MyBlobFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/MavenWrapperDownloader.java b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 000000000..b901097f2 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present 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 + * + * http://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. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.jar b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 000000000..2cc7d4a55 Binary files /dev/null and b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.jar differ diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.properties b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 000000000..642d572ce --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/README.adoc b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/README.adoc new file mode 100644 index 000000000..c8638c1ac --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/README.adoc @@ -0,0 +1,338 @@ +== Azure Event Grid with CloudEvents Sample + +IMPORTANT: For general information about building and deploying `Azure Functions` with Spring Cloud Function, consult the https://docs.spring.io/spring-cloud-function/docs/current/reference/html/azure.html[Azure Adapter] documentation. + +This sample demonstrates how to integrate Spring Cloud Function with Azure Event Grid using the CloudEvents v1.0 specification. Azure Event Grid natively supports CloudEvents format, providing a standardized way to handle events across different cloud platforms. + +=== Features + +* **CloudEvents v1.0 Support**: Handles events in both CloudEvents and Event Grid formats +* **Webhook Validation**: Implements Azure Event Grid webhook validation according to CloudEvents webhook specification +* **Automatic Format Conversion**: Converts Event Grid format events to CloudEvents for consistent processing +* **Spring Cloud Function Integration**: Uses Spring Cloud Function framework for event processing +* **Comprehensive Logging**: Detailed logging for debugging and monitoring + +=== Azure Event Grid CloudEvents Support + +Azure Event Grid supports CloudEvents v1.0 specification which provides: + +* **Interoperability**: Standard event schema across different platforms +* **Extensibility**: Custom attributes and extensions +* **Multiple Formats**: Both binary and structured content modes +* **Protocol Agnostic**: Works with HTTP, AMQP, and other protocols + +For more information, see: +- https://docs.microsoft.com/en-us/azure/event-grid/cloud-event-schema[Azure Event Grid CloudEvents Schema] +- https://cloudevents.io/[CloudEvents Specification] + +=== Event Processing + +The sample includes two main Spring Cloud Functions: + +1. **processEvent**: Processes incoming CloudEvents and logs detailed information +2. **createEvent**: Creates CloudEvents from simple payload maps + +Both functions are exposed through the Azure Function HTTP trigger endpoint. + +=== Usage + +==== Prerequisites + +* Azure CLI installed and configured +* Azure Functions Core Tools v4.0.5030 or later +* Java 17 or later +* Maven 3.6 or later +* An Azure subscription with Event Grid and Storage Account + +==== Setup Azure Resources + +Create required Azure resources: + +[source,shell] +---- +# Use one region consistently (example: Korea Central) +SUFFIX=$(date +%s) # ensures global-unique names +RG=java-functions-group # or change if you prefer a new RG +LOC=westus +SA=azureeventgrid${SUFFIX} # storage account names must be globally unique (3-24 lowercase letters/numbers) +FUNC=spring-cloud-function-eventgrid-demo +TOPIC=azure-eventgrid-topic + +# Create (or re-use) resource group in the chosen region +az group create --name $RG --location $LOC + +# Create storage account (required for Azure Functions) +az storage account create \ + --name $SA \ + --resource-group $RG \ + --location $LOC \ + --sku Standard_LRS \ + --kind StorageV2 + +# (Optional but recommended) Wait until provisioning completes +until [ "$(az storage account show -n $SA -g $RG --query provisioningState -o tsv 2>/dev/null)" = "Succeeded" ]; do + echo "waiting for storage $SA to be provisioned..." + sleep 5 +done + +# Create Azure Function App (Consumption, Java 17) +az functionapp create \ + --name $FUNC \ + --consumption-plan-location $LOC \ + --functions-version 4 \ + --resource-group $RG \ + --runtime java \ + --runtime-version 17 \ + --os-type Linux \ + --storage-account $SA + +# Create Event Grid custom topic (CloudEvents v1.0) +# Ensure the provider is registered once per subscription: +az provider register --namespace Microsoft.EventGrid --wait + +az eventgrid topic create \ + --name $TOPIC \ + --resource-group $RG \ + --location $LOC \ + --input-schema cloudeventschemav1_0 +---- + +==== Configure Local Development + +Update `src/main/resources/local.settings.json` with your Azure Storage connection string: + +[source,json] +---- +{ + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=azureeventgridstorage;AccountKey=;EndpointSuffix=core.windows.net", + "FUNCTIONS_WORKER_RUNTIME": "java" + } +} +---- + +==== Build and Run Locally + +Build the application: + +[source,shell] +---- +./mvnw clean package +---- + +Run locally using Azure Functions Core Tools: + +[source,shell] +---- +./mvnw azure-functions:run +---- + +The function will be available at: +- Webhook endpoint: `http://localhost:7071/api/eventgrid` + +==== Test the Function + +===== Test Webhook Validation + +[source,shell] +---- +curl -X OPTIONS http://localhost:7071/api/eventgrid \ + -H "WebHook-Request-Origin: https://eventgrid.azure.net" +---- + +Expected response: `200 OK` with `WebHook-Allowed-Origin` header. + +===== Test CloudEvent Processing + +[source,shell] +---- +curl -X POST http://localhost:7071/api/eventgrid \ + -H "Content-Type: application/cloudevents+json" \ + -d '{ + "specversion": "1.0", + "type": "com.example.demo.created", + "source": "https://example.com/demo", + "id": "test-event-001", + "time": "2024-01-01T12:00:00Z", + "subject": "demo/test", + "datacontenttype": "application/json", + "data": { + "message": "Hello CloudEvents!", + "timestamp": "2024-01-01T12:00:00Z" + } + }' +---- + +===== Test Event Grid Format Processing + +[source,shell] +---- +curl -X POST http://localhost:7071/api/eventgrid \ + -H "Content-Type: application/json" \ + -d '[{ + "id": "test-event-002", + "eventType": "Microsoft.Storage.BlobCreated", + "subject": "/blobServices/default/containers/test/blobs/example.txt", + "eventTime": "2024-01-01T12:00:00Z", + "topic": "/subscriptions/{subscription-id}/resourceGroups/test/providers/Microsoft.Storage/storageAccounts/test", + "data": { + "api": "PutBlob", + "contentType": "text/plain", + "contentLength": 1024, + "url": "https://test.blob.core.windows.net/test/example.txt" + }, + "dataVersion": "1.0", + "metadataVersion": "1" + }]' +---- + +==== Deploy to Azure + +Update the `pom.xml` configuration with your Azure Function App details, then deploy: + +[source,shell] +---- +./mvnw azure-functions:deploy +---- + +==== Create Event Grid Subscription + +After deployment, create an Event Grid subscription to route events to your function: + +[source,shell] +---- +# Get function URL +FUNCTION_URL=$(az functionapp function show \ + --name spring-cloud-function-eventgrid-demo \ + --resource-group java-functions-group \ + --function-name eventGridWebhook \ + --query "invokeUrlTemplate" -o tsv) + +# Create Event Grid subscription +az eventgrid event-subscription create \ + --name my-function-subscription \ + --source-resource-id /subscriptions/{subscription-id}/resourceGroups/java-functions-group/providers/Microsoft.EventGrid/topics/azure-eventgrid-topic \ + --endpoint "${FUNCTION_URL}" \ + --event-delivery-schema cloudeventschemav1_0 +---- + +==== Send Events to Event Grid + +[source,shell] +---- +# Get Event Grid topic endpoint and key +TOPIC_ENDPOINT=$(az eventgrid topic show \ + --name azure-eventgrid-topic \ + --resource-group java-functions-group \ + --query "endpoint" -o tsv) + +TOPIC_KEY=$(az eventgrid topic key list \ + --name azure-eventgrid-topic \ + --resource-group java-functions-group \ + --query "key1" -o tsv) + +# Send CloudEvent to Event Grid +curl -X POST "${TOPIC_ENDPOINT}" \ + -H "Content-Type: application/cloudevents+json" \ + -H "aeg-sas-key: ${TOPIC_KEY}" \ + -d '{ + "specversion": "1.0", + "type": "com.example.production.created", + "source": "https://example.com/production", + "id": "prod-event-001", + "time": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'", + "subject": "production/orders", + "datacontenttype": "application/json", + "data": { + "orderId": "12345", + "customerId": "customer-001", + "amount": 99.99 + } + }' +---- + +=== Monitoring and Debugging + +==== Local Debugging + +The sample includes comprehensive logging. Check the console output when running locally to see detailed event processing information. + +==== Azure Monitoring + +When deployed to Azure, monitor your function using: + +* **Azure Portal**: Function App → Functions → eventGridWebhook → Monitor +* **Application Insights**: Detailed telemetry and performance monitoring +* **Azure Monitor**: Metrics and alerts + +==== Common Issues + +1. **Webhook Validation Fails** + - Ensure the `WebHook-Request-Origin` header is present in validation requests + - Check that the function responds with `WebHook-Allowed-Origin` header + +2. **CloudEvent Parsing Errors** + - Verify the CloudEvent format matches the CloudEvents v1.0 specification + - Check the `Content-Type` header is set correctly + +3. **Event Grid Subscription Issues** + - Ensure the function URL is accessible from Azure Event Grid + - Verify the Event Grid topic is configured with CloudEvents schema + +=== Configuration Options + +The sample supports the following configuration: + +* **CloudEvents Schema**: Set Event Grid topic input schema to `CloudEventSchemaV1_0` +* **Event Delivery Schema**: Configure subscription delivery schema to `CloudEventSchemaV1_0` +* **Custom Extensions**: Add custom CloudEvent extensions in the conversion logic +* **Error Handling**: Customize error responses and retry policies + +=== Advanced Scenarios + +==== Custom Event Types + +Extend the `processEvent` function to handle specific event types: + +[source,java] +---- +@Bean +public Function processEvent() { + return event -> { + switch (event.getType()) { + case "Microsoft.Storage.BlobCreated": + return handleBlobCreated(event); + case "Microsoft.EventHub.CaptureFileCreated": + return handleEventHubCapture(event); + default: + return handleGenericEvent(event); + } + }; +} +---- + +==== Dead Letter Handling + +Configure dead letter destinations for failed event processing: + +[source,shell] +---- +az eventgrid event-subscription create \ + --name my-function-subscription \ + --source-resource-id /subscriptions/{subscription-id}/resourceGroups/java-functions-group/providers/Microsoft.EventGrid/topics/azure-eventgrid-topic \ + --endpoint "${FUNCTION_URL}" \ + --event-delivery-schema cloudeventschemav1_0 \ + --deadletter-endpoint /subscriptions/{subscription-id}/resourceGroups/java-functions-group/providers/Microsoft.Storage/storageAccounts/azureeventgridstorage/blobServices/default/containers/deadletter +---- + +=== Resources + +* https://docs.microsoft.com/en-us/azure/event-grid/[Azure Event Grid Documentation] +* https://cloudevents.io/[CloudEvents Specification] +* https://docs.spring.io/spring-cloud-function/docs/current/reference/html/[Spring Cloud Function Reference] +* https://docs.microsoft.com/en-us/azure/azure-functions/[Azure Functions Documentation] + +=== Contributing + +This sample is part of the Spring Cloud Function project. To contribute improvements or report issues, please visit the https://github.com/spring-cloud/spring-cloud-function[GitHub repository]. diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw new file mode 100755 index 000000000..41c0f0c23 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw.cmd b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw.cmd new file mode 100644 index 000000000..86115719e --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/pom.xml b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/pom.xml new file mode 100644 index 000000000..fca015222 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/pom.xml @@ -0,0 +1,134 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 4.0.2 + + + + com.example.azure.eventgrid + azure-eventgrid-demo + 0.0.1-SNAPSHOT + azure-eventgrid-demo + + Demo Spring Boot, Azure Function - Event Grid Trigger with CloudEvents + + + 17 + 1.0.31.RELEASE + + + com.example.azure.eventgrid.EventGridDemoApplication + + + 1.28.0 + spring-cloud-function-eventgrid-demo + westus + java-functions-group + Y1 + + + + + org.springframework.cloud + spring-cloud-function-adapter-azure + 4.1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + io.cloudevents + cloudevents-core + 2.5.0 + + + + io.cloudevents + cloudevents-json-jackson + 2.5.0 + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + com.microsoft.azure + azure-functions-maven-plugin + ${azure.functions.maven.plugin.version} + + + ${functionAppName} + ${functionResourceGroup} + ${functionAppRegion} + ${functionPricingTier} + + ${project.basedir}/src/main/resources/host.json + ${project.basedir}/src/main/resources/local.settings.json + + + linux + 17 + + + 7071 + + + + FUNCTIONS_EXTENSION_VERSION + ~4 + + + + + + package-functions + + package + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + none + + + + + org.springframework.boot.experimental + spring-boot-thin-layout + ${spring-boot-thin-layout.version} + + + + + + + diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridDemoApplication.java b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridDemoApplication.java new file mode 100644 index 000000000..4b8fc9ca1 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridDemoApplication.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024-2024 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 com.example.azure.eventgrid; + +import java.time.OffsetDateTime; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.function.Function; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +@SpringBootApplication +public class EventGridDemoApplication { + + private static final Logger logger = LoggerFactory.getLogger(EventGridDemoApplication.class); + + @Bean + public Function processEvent() { + return event -> { + logger.info("Received CloudEvent:"); + logger.info(" ID: {}", event.getId()); + logger.info(" Type: {}", event.getType()); + logger.info(" Source: {}", event.getSource()); + logger.info(" Subject: {}", event.getSubject()); + logger.info(" Time: {}", event.getTime()); + + if (event.getData() != null) { + logger.info(" Data: {}", new String(event.getData().toBytes(), StandardCharsets.UTF_8)); + } + + // Log additional attributes + for (String attributeName : event.getAttributeNames()) { + if (!attributeName.equals("id") && !attributeName.equals("type") + && !attributeName.equals("source") && !attributeName.equals("subject") + && !attributeName.equals("time") && !attributeName.equals("data")) { + logger.info(" {}: {}", attributeName, event.getAttribute(attributeName)); + } + } + + // Return a simple acknowledgment + return String.format("Successfully processed CloudEvent with ID: %s, Type: %s", + event.getId(), event.getType()); + }; + } + + @Bean + public Function, CloudEvent> createEvent() { + return payload -> { + logger.info("Creating CloudEvent from payload: {}", payload); + + CloudEventBuilder builder = CloudEventBuilder.v1() + .withId(java.util.UUID.randomUUID().toString()) + .withType("com.example.demo.created") + .withSource(java.net.URI.create("https://example.com/demo")) + .withTime(OffsetDateTime.now()); + + if (payload.containsKey("subject")) { + builder.withSubject(payload.get("subject").toString()); + } + + if (payload.containsKey("data")) { + builder.withData("application/json", payload.get("data").toString().getBytes(StandardCharsets.UTF_8)); + } + + CloudEvent event = builder.build(); + logger.info("Created CloudEvent with ID: {}", event.getId()); + + return event; + }; + } + + public static void main(String[] args) { + SpringApplication.run(EventGridDemoApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridHandler.java b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridHandler.java new file mode 100644 index 000000000..785053f13 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/java/com/example/azure/eventgrid/EventGridHandler.java @@ -0,0 +1,353 @@ +/* + * Copyright 2024-2024 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 com.example.azure.eventgrid; + +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.azure.functions.ExecutionContext; +import com.microsoft.azure.functions.HttpMethod; +import com.microsoft.azure.functions.HttpRequestMessage; +import com.microsoft.azure.functions.HttpResponseMessage; +import com.microsoft.azure.functions.HttpStatus; +import com.microsoft.azure.functions.annotation.AuthorizationLevel; +import com.microsoft.azure.functions.annotation.FunctionName; +import com.microsoft.azure.functions.annotation.HttpTrigger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.function.context.FunctionCatalog; +import org.springframework.stereotype.Component; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.jackson.JsonFormat; + +@Component +public class EventGridHandler { + + private static final Logger logger = LoggerFactory.getLogger(EventGridHandler.class); + private static final String WEBHOOK_REQUEST_ORIGIN = "WebHook-Request-Origin"; + private static final String WEBHOOK_ALLOWED_ORIGIN = "WebHook-Allowed-Origin"; + private static final String CONTENT_TYPE_CLOUDEVENTS = "application/cloudevents+json"; + + @Autowired + private FunctionCatalog functionCatalog; + + private final ObjectMapper objectMapper = new ObjectMapper() + .registerModule(JsonFormat.getCloudEventJacksonModule()); + + /** + * Azure Event Grid webhook endpoint that handles: + * 1. Webhook validation requests (OPTIONS method) + * 2. CloudEvent format events (POST method) + * 3. Event Grid format events (POST method) - converts to CloudEvent + */ + @FunctionName("eventGridWebhook") + public HttpResponseMessage eventGridWebhook( + @HttpTrigger(name = "req", + methods = { HttpMethod.POST, HttpMethod.OPTIONS }, + authLevel = AuthorizationLevel.ANONYMOUS, + route = "eventgrid") + HttpRequestMessage> request, + ExecutionContext context) { + + logger.info("EventGrid webhook triggered with method: {}", request.getHttpMethod()); + + // Handle webhook validation for Event Grid subscription + if (HttpMethod.OPTIONS.equals(request.getHttpMethod())) { + return handleWebhookValidation(request, context); + } + + // Handle event processing + if (HttpMethod.POST.equals(request.getHttpMethod())) { + return handleEventProcessing(request, context); + } + + return request.createResponseBuilder(HttpStatus.METHOD_NOT_ALLOWED) + .body("Method not allowed") + .build(); + } + + /** + * Handles Event Grid webhook validation according to CloudEvents webhook spec + */ + private HttpResponseMessage handleWebhookValidation(HttpRequestMessage> request, + ExecutionContext context) { + + logger.info("Handling webhook validation request"); + + String origin = getHeaderIgnoreCase(request.getHeaders(), WEBHOOK_REQUEST_ORIGIN); + if (origin == null) { + logger.warn("Webhook validation: missing WebHook-Request-Origin header, responding with wildcard"); + // Be permissive to pass Azure CLI/portal validation flows that omit the header + return request.createResponseBuilder(HttpStatus.OK) + .header(WEBHOOK_ALLOWED_ORIGIN, "*") + .build(); + } + + logger.info("Webhook validation origin: {}", origin); + return request.createResponseBuilder(HttpStatus.OK) + .header(WEBHOOK_ALLOWED_ORIGIN, origin) + .build(); + } + + /** + * Handles event processing for both CloudEvent and Event Grid formats + */ + private HttpResponseMessage handleEventProcessing(HttpRequestMessage> request, + ExecutionContext context) { + + try { + String requestBody = request.getBody().orElse(""); + logger.info("Processing event with body: {}", requestBody); + + String contentType = Optional.ofNullable(getHeaderIgnoreCase(request.getHeaders(), "Content-Type")).orElse(""); + + if (hasCloudEventBinaryHeaders(request.getHeaders())) { + // Handle CloudEvent binary-mode + return handleCloudEventBinary(request, requestBody, contentType, context); + } + else if (contentType.toLowerCase().contains(CONTENT_TYPE_CLOUDEVENTS)) { + // Handle CloudEvent format + return handleCloudEvent(request, requestBody, context); + } else { + // Handle Event Grid format - convert to CloudEvent + return handleEventGridFormat(request, requestBody, context); + } + + } catch (Exception e) { + logger.error("Error processing event", e); + return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Error processing event: " + e.getMessage()) + .build(); + } + } + + /** + * Handles CloudEvent format events + */ + private HttpResponseMessage handleCloudEvent(HttpRequestMessage> request, + String requestBody, ExecutionContext context) throws IOException { + + logger.info("Processing CloudEvent format"); + + CloudEvent cloudEvent = objectMapper.readValue(requestBody, CloudEvent.class); + + // Process the CloudEvent using Spring Cloud Function + Function processor = functionCatalog.lookup("processEvent"); + String result = processor.apply(cloudEvent); + + logger.info("CloudEvent processed successfully: {}", result); + + return request.createResponseBuilder(HttpStatus.OK) + .header("content-type", "application/json") + .body(Map.of("status", "success", "message", result)) + .build(); + } + + /** + * Handles Event Grid format events and converts them to CloudEvent + */ + private HttpResponseMessage handleEventGridFormat(HttpRequestMessage> request, + String requestBody, ExecutionContext context) throws IOException { + + logger.info("Processing Event Grid format"); + + // Parse Event Grid format (array of events) + List> eventGridEvents = objectMapper.readValue( + requestBody, new TypeReference>>() {}); + + StringBuilder results = new StringBuilder(); + + for (Map eventGridEvent : eventGridEvents) { + // Check for subscription validation event + String eventType = (String) eventGridEvent.get("eventType"); + if ("Microsoft.EventGrid.SubscriptionValidationEvent".equals(eventType)) { + logger.info("Handling subscription validation event"); + Map data = (Map) eventGridEvent.get("data"); + String validationCode = (String) data.get("validationCode"); + + return request.createResponseBuilder(HttpStatus.OK) + .header("content-type", "application/json") + .body(Map.of("validationResponse", validationCode)) + .build(); + } + + // Convert Event Grid event to CloudEvent + CloudEvent cloudEvent = convertEventGridToCloudEvent(eventGridEvent); + + // Process the CloudEvent + Function processor = functionCatalog.lookup("processEvent"); + String result = processor.apply(cloudEvent); + + results.append(result).append("; "); + } + + logger.info("Event Grid events processed successfully"); + + return request.createResponseBuilder(HttpStatus.OK) + .header("content-type", "application/json") + .body(Map.of("status", "success", "processedEvents", eventGridEvents.size(), + "results", results.toString())) + .build(); + } + + /** + * Converts Event Grid format to CloudEvent format + */ + private CloudEvent convertEventGridToCloudEvent(Map eventGridEvent) throws IOException { + CloudEventBuilder builder = CloudEventBuilder.v1() + .withId((String) eventGridEvent.get("id")) + .withType((String) eventGridEvent.get("eventType")) + .withSource(URI.create((String) eventGridEvent.get("topic"))); + + if (eventGridEvent.containsKey("subject")) { + builder.withSubject((String) eventGridEvent.get("subject")); + } + + if (eventGridEvent.containsKey("eventTime")) { + builder.withTime(java.time.OffsetDateTime.parse((String) eventGridEvent.get("eventTime"))); + } + + if (eventGridEvent.containsKey("data")) { + String dataJson = objectMapper.writeValueAsString(eventGridEvent.get("data")); + builder.withData("application/json", dataJson.getBytes(StandardCharsets.UTF_8)); + } + + // Add Event Grid specific extensions + if (eventGridEvent.containsKey("dataVersion")) { + builder.withExtension("dataversion", String.valueOf(eventGridEvent.get("dataVersion"))); + } + if (eventGridEvent.containsKey("metadataVersion")) { + builder.withExtension("metadataversion", String.valueOf(eventGridEvent.get("metadataVersion"))); + } + + return builder.build(); + } + + /** + * Detects presence of any ce-* headers indicating CloudEvents binary-mode. + */ + private static boolean hasCloudEventBinaryHeaders(Map headers) { + if (headers == null || headers.isEmpty()) { + return false; + } + for (String key : headers.keySet()) { + if (key != null && key.toLowerCase().startsWith("ce-")) { + return true; + } + } + return false; + } + + /** + * Build a CloudEvent from ce-* headers and body (binary-mode). + */ + private static CloudEvent convertBinaryHeadersToCloudEvent(Map headers, String body, + String contentType) { + CloudEventBuilder builder = CloudEventBuilder.v1(); + + String id = getHeaderIgnoreCase(headers, "ce-id"); + String type = getHeaderIgnoreCase(headers, "ce-type"); + String source = getHeaderIgnoreCase(headers, "ce-source"); + String subject = getHeaderIgnoreCase(headers, "ce-subject"); + String time = getHeaderIgnoreCase(headers, "ce-time"); + + if (id != null) { + builder.withId(id); + } + if (type != null) { + builder.withType(type); + } + if (source != null) { + builder.withSource(URI.create(source)); + } + if (subject != null) { + builder.withSubject(subject); + } + if (time != null) { + builder.withTime(java.time.OffsetDateTime.parse(time)); + } + + if (body != null && !body.isEmpty()) { + String dataContentType = (contentType == null || contentType.isEmpty()) ? "application/json" : contentType; + builder.withData(dataContentType, body.getBytes(StandardCharsets.UTF_8)); + } + + // Copy any additional ce-* headers as extensions + for (Map.Entry entry : headers.entrySet()) { + String key = entry.getKey(); + if (key != null && key.toLowerCase().startsWith("ce-") && + !key.equalsIgnoreCase("ce-id") && !key.equalsIgnoreCase("ce-type") && + !key.equalsIgnoreCase("ce-source") && !key.equalsIgnoreCase("ce-subject") && + !key.equalsIgnoreCase("ce-time") && !key.equalsIgnoreCase("ce-specversion")) { + String extName = key.substring(3); // drop 'ce-' + builder.withExtension(extName, entry.getValue()); + } + } + + return builder.build(); + } + + /** + * Retrieve header value ignoring case. + */ + private static String getHeaderIgnoreCase(Map headers, String name) { + if (headers == null || name == null) { + return null; + } + String lower = name.toLowerCase(); + for (Map.Entry e : headers.entrySet()) { + if (e.getKey() != null && e.getKey().toLowerCase().equals(lower)) { + return e.getValue(); + } + } + return null; + } + + /** + * Handles CloudEvent binary-mode events (ce-* headers + data in body) + */ + private HttpResponseMessage handleCloudEventBinary(HttpRequestMessage> request, + String requestBody, String contentType, ExecutionContext context) throws IOException { + + logger.info("Processing CloudEvent binary-mode"); + + CloudEvent cloudEvent = convertBinaryHeadersToCloudEvent(request.getHeaders(), requestBody, contentType); + + // Process the CloudEvent using Spring Cloud Function + Function processor = functionCatalog.lookup("processEvent"); + String result = processor.apply(cloudEvent); + + logger.info("CloudEvent (binary) processed successfully: {}", result); + + return request.createResponseBuilder(HttpStatus.OK) + .header("content-type", "application/json") + .body(Map.of("status", "success", "message", result)) + .build(); + } +} diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/application.properties b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/application.properties new file mode 100644 index 000000000..e79864f0d --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/application.properties @@ -0,0 +1,10 @@ +# Spring Cloud Function configuration +spring.cloud.function.definition=processEvent,createEvent + +# Logging configuration +logging.level.com.example.azure.eventgrid=INFO +logging.level.org.springframework.cloud.function=DEBUG +logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + +# Spring Boot configuration +spring.main.web-application-type=none \ No newline at end of file diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/host.json b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/host.json new file mode 100644 index 000000000..994f132cd --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/host.json @@ -0,0 +1,15 @@ +{ + "version": "2.0", + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[4.*, 5.0.0)" + }, + "functionTimeout": "00:05:00", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true + } + } + } +} \ No newline at end of file diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/local.settings.json b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/local.settings.json new file mode 100644 index 000000000..b2b7eac11 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/main/resources/local.settings.json @@ -0,0 +1,7 @@ +{ + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "", + "FUNCTIONS_WORKER_RUNTIME": "java" + } +} \ No newline at end of file diff --git a/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/test/java/com/example/azure/eventgrid/EventGridDemoApplicationTests.java b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/test/java/com/example/azure/eventgrid/EventGridDemoApplicationTests.java new file mode 100644 index 000000000..7f5306355 --- /dev/null +++ b/spring-cloud-function-samples/function-sample-azure-eventgrid-trigger/src/test/java/com/example/azure/eventgrid/EventGridDemoApplicationTests.java @@ -0,0 +1,75 @@ +/* + * Copyright 2024-2024 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 com.example.azure.eventgrid; + +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.Map; +import java.util.function.Function; + +import org.junit.jupiter.api.Test; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +class EventGridDemoApplicationTests { + + @Test + void testProcessEventFunctionLogic() { + // Test the core function logic without Spring context + EventGridDemoApplication app = new EventGridDemoApplication(); + Function processEvent = app.processEvent(); + + CloudEvent testEvent = CloudEventBuilder.v1() + .withId("test-id-123") + .withType("com.example.test.created") + .withSource(URI.create("https://example.com/test")) + .withSubject("test-subject") + .withTime(OffsetDateTime.now()) + .withData("application/json", "{\"message\":\"test data\"}".getBytes()) + .build(); + + String result = processEvent.apply(testEvent); + + assertThat(result).isNotNull(); + assertThat(result).contains("test-id-123"); + assertThat(result).contains("com.example.test.created"); + } + + @Test + void testCreateEventFunctionLogic() { + // Test the core function logic without Spring context + EventGridDemoApplication app = new EventGridDemoApplication(); + Function, CloudEvent> createEvent = app.createEvent(); + + Map payload = Map.of( + "subject", "test-subject", + "data", Map.of("message", "test data", "value", 42) + ); + + CloudEvent result = createEvent.apply(payload); + + assertThat(result).isNotNull(); + assertThat(result.getId()).isNotNull(); + assertThat(result.getType()).isEqualTo("com.example.demo.created"); + assertThat(result.getSource()).isEqualTo(URI.create("https://example.com/demo")); + assertThat(result.getSubject()).isEqualTo("test-subject"); + assertThat(result.getData()).isNotNull(); + } +} \ No newline at end of file diff --git a/spring-cloud-function-samples/function-sample-azure-http-trigger/pom.xml b/spring-cloud-function-samples/function-sample-azure-http-trigger/pom.xml index ac025b720..690d2dbaa 100644 --- a/spring-cloud-function-samples/function-sample-azure-http-trigger/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure-http-trigger/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/HttpTriggerDemoApplication.java b/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/HttpTriggerDemoApplication.java index 21d550d6f..49da1ea26 100644 --- a/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/HttpTriggerDemoApplication.java +++ b/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/HttpTriggerDemoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/MyAzureFunction.java b/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/MyAzureFunction.java index 62b20ca3a..f50011c93 100644 --- a/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/MyAzureFunction.java +++ b/spring-cloud-function-samples/function-sample-azure-http-trigger/src/main/java/com/example/azure/di/httptriggerdemo/MyAzureFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-kafka-trigger/pom.xml b/spring-cloud-function-samples/function-sample-azure-kafka-trigger/pom.xml index b94a9036d..ef00cba20 100644 --- a/spring-cloud-function-samples/function-sample-azure-kafka-trigger/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure-kafka-trigger/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure-time-trigger/pom.xml b/spring-cloud-function-samples/function-sample-azure-time-trigger/pom.xml index d6b00c5c4..d32b6c22c 100644 --- a/spring-cloud-function-samples/function-sample-azure-time-trigger/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure-time-trigger/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/TimeTriggerDemoApplication.java b/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/TimeTriggerDemoApplication.java index c61aedda4..c9c194cd2 100644 --- a/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/TimeTriggerDemoApplication.java +++ b/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/TimeTriggerDemoApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/UppercaseHandler.java b/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/UppercaseHandler.java index ca3890206..588384574 100644 --- a/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/UppercaseHandler.java +++ b/spring-cloud-function-samples/function-sample-azure-time-trigger/src/main/java/com/example/azure/di/timetriggerdemo/UppercaseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-web/pom.xml b/spring-cloud-function-samples/function-sample-azure-web/pom.xml index 5e66ca5a9..3274b7783 100644 --- a/spring-cloud-function-samples/function-sample-azure-web/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure-web/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/Country.java b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/Country.java index 2fbecb4bd..ab8f9adf4 100644 --- a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/Country.java +++ b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/Country.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryController.java b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryController.java index f6d16f918..899773d5c 100644 --- a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryController.java +++ b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryController.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryRepository.java b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryRepository.java index 3f08e010b..cd81e6df6 100644 --- a/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryRepository.java +++ b/spring-cloud-function-samples/function-sample-azure-web/src/main/java/com/example/azure/web/CountryRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure/pom.xml b/spring-cloud-function-samples/function-sample-azure/pom.xml index dde054423..7759714e8 100644 --- a/spring-cloud-function-samples/function-sample-azure/pom.xml +++ b/spring-cloud-function-samples/function-sample-azure/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/Config.java b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/Config.java index 97ae9b2e7..e26747be1 100644 --- a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/Config.java +++ b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/EchoHandler.java b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/EchoHandler.java index 784f0e86c..4fbb9101f 100644 --- a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/EchoHandler.java +++ b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/EchoHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveEchoCustomResultHandler.java b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveEchoCustomResultHandler.java index 744a46b6d..65597ac0e 100644 --- a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveEchoCustomResultHandler.java +++ b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveEchoCustomResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2022 the original author or authors. + * Copyright 2022-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveUppercaseHandler.java b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveUppercaseHandler.java index cb82087b5..5a76bf78d 100644 --- a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveUppercaseHandler.java +++ b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/ReactiveUppercaseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/UppercaseHandler.java b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/UppercaseHandler.java index 0e342e960..33fb02f8a 100644 --- a/spring-cloud-function-samples/function-sample-azure/src/main/java/example/UppercaseHandler.java +++ b/spring-cloud-function-samples/function-sample-azure/src/main/java/example/UppercaseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-samples/function-sample-cloudevent-rsocket/pom.xml b/spring-cloud-function-samples/function-sample-cloudevent-rsocket/pom.xml index ad97425c6..c8f9166da 100644 --- a/spring-cloud-function-samples/function-sample-cloudevent-rsocket/pom.xml +++ b/spring-cloud-function-samples/function-sample-cloudevent-rsocket/pom.xml @@ -11,12 +11,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-samples/function-sample-cloudevent-sdk/pom.xml b/spring-cloud-function-samples/function-sample-cloudevent-sdk/pom.xml index 5d456d8fc..2478915d6 100644 --- a/spring-cloud-function-samples/function-sample-cloudevent-sdk/pom.xml +++ b/spring-cloud-function-samples/function-sample-cloudevent-sdk/pom.xml @@ -11,12 +11,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-samples/function-sample-cloudevent-stream/pom.xml b/spring-cloud-function-samples/function-sample-cloudevent-stream/pom.xml index 417af776d..a03229c4f 100644 --- a/spring-cloud-function-samples/function-sample-cloudevent-stream/pom.xml +++ b/spring-cloud-function-samples/function-sample-cloudevent-stream/pom.xml @@ -11,12 +11,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-samples/function-sample-cloudevent/pom.xml b/spring-cloud-function-samples/function-sample-cloudevent/pom.xml index 02da75940..1739600a5 100644 --- a/spring-cloud-function-samples/function-sample-cloudevent/pom.xml +++ b/spring-cloud-function-samples/function-sample-cloudevent/pom.xml @@ -11,12 +11,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE diff --git a/spring-cloud-function-samples/function-sample-functional-aws-routing/pom.xml b/spring-cloud-function-samples/function-sample-functional-aws-routing/pom.xml index b766fb2a2..57bb48304 100644 --- a/spring-cloud-function-samples/function-sample-functional-aws-routing/pom.xml +++ b/spring-cloud-function-samples/function-sample-functional-aws-routing/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -24,7 +24,7 @@ UTF-8 1.0.31.RELEASE 3.14.0 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-functional-aws-routing/src/test/java/example/MapTests.java b/spring-cloud-function-samples/function-sample-functional-aws-routing/src/test/java/example/MapTests.java index 289a8c9ff..bcd3660cd 100644 --- a/spring-cloud-function-samples/function-sample-functional-aws-routing/src/test/java/example/MapTests.java +++ b/spring-cloud-function-samples/function-sample-functional-aws-routing/src/test/java/example/MapTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-gcp-background/pom.xml b/spring-cloud-function-samples/function-sample-gcp-background/pom.xml index 499a94f24..943d57577 100644 --- a/spring-cloud-function-samples/function-sample-gcp-background/pom.xml +++ b/spring-cloud-function-samples/function-sample-gcp-background/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 diff --git a/spring-cloud-function-samples/function-sample-gcp-http/pom.xml b/spring-cloud-function-samples/function-sample-gcp-http/pom.xml index 31d75ad4a..02c767f0f 100644 --- a/spring-cloud-function-samples/function-sample-gcp-http/pom.xml +++ b/spring-cloud-function-samples/function-sample-gcp-http/pom.xml @@ -15,12 +15,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -38,7 +38,7 @@ org.springframework.boot - spring-boot-test + spring-boot-starter-test test @@ -57,6 +57,21 @@ 1.0.0-alpha-2-rc5 test + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + diff --git a/spring-cloud-function-samples/function-sample-gcp-http/src/main/java/com/example/CloudFunctionMain.java b/spring-cloud-function-samples/function-sample-gcp-http/src/main/java/com/example/CloudFunctionMain.java index c5fe46794..483722eeb 100644 --- a/spring-cloud-function-samples/function-sample-gcp-http/src/main/java/com/example/CloudFunctionMain.java +++ b/spring-cloud-function-samples/function-sample-gcp-http/src/main/java/com/example/CloudFunctionMain.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/FunctionSampleGcpIntegrationTest.java b/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/FunctionSampleGcpIntegrationTest.java index 69f813c1a..bbb97ea4a 100644 --- a/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/FunctionSampleGcpIntegrationTest.java +++ b/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/FunctionSampleGcpIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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,9 +18,7 @@ import java.io.IOException; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/LocalServerTestSupport.java b/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/LocalServerTestSupport.java index 259174282..d649df4bc 100644 --- a/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/LocalServerTestSupport.java +++ b/spring-cloud-function-samples/function-sample-gcp-http/src/test/java/com/example/LocalServerTestSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. diff --git a/spring-cloud-function-samples/function-sample-grpc-cloudevent/pom.xml b/spring-cloud-function-samples/function-sample-grpc-cloudevent/pom.xml index 8fff6a1b0..74b5694da 100644 --- a/spring-cloud-function-samples/function-sample-grpc-cloudevent/pom.xml +++ b/spring-cloud-function-samples/function-sample-grpc-cloudevent/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 com.example.grpc @@ -16,7 +16,7 @@ function-sample-grpc-cloudevent Demo project for Spring Boot - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.55.1 diff --git a/spring-cloud-function-samples/function-sample-kotlin-web/pom.xml b/spring-cloud-function-samples/function-sample-kotlin-web/pom.xml index 44c68cfdf..ca9785b5b 100644 --- a/spring-cloud-function-samples/function-sample-kotlin-web/pom.xml +++ b/spring-cloud-function-samples/function-sample-kotlin-web/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -67,7 +67,6 @@ org.jetbrains.kotlin kotlin-maven-plugin - 1.9.25 -Xjsr305=strict diff --git a/spring-cloud-function-samples/function-sample-pof/pom.xml b/spring-cloud-function-samples/function-sample-pof/pom.xml index fdf906dc1..c406dcfee 100644 --- a/spring-cloud-function-samples/function-sample-pof/pom.xml +++ b/spring-cloud-function-samples/function-sample-pof/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -21,7 +21,7 @@ UTF-8 UTF-8 3.1.2.RELEASE - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Application.java b/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Application.java index f645883c5..47f78d604 100644 --- a/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Application.java +++ b/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Application.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Greeter.java b/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Greeter.java index 2f1eed816..16463f58c 100644 --- a/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Greeter.java +++ b/spring-cloud-function-samples/function-sample-pof/src/main/java/functions/Greeter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-pojo/pom.xml b/spring-cloud-function-samples/function-sample-pojo/pom.xml index 586808e95..3ae3d7027 100644 --- a/spring-cloud-function-samples/function-sample-pojo/pom.xml +++ b/spring-cloud-function-samples/function-sample-pojo/pom.xml @@ -14,12 +14,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE @@ -32,6 +32,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-configuration-processor @@ -42,6 +46,21 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + diff --git a/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/LowercaseConfiguration.java b/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/LowercaseConfiguration.java index 45afa2e5c..27c32a7b5 100644 --- a/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/LowercaseConfiguration.java +++ b/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/LowercaseConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/SampleApplication.java b/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/SampleApplication.java index 1e6aa9b44..fdabfc904 100644 --- a/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/SampleApplication.java +++ b/spring-cloud-function-samples/function-sample-pojo/src/main/java/com/example/SampleApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationMvcTests.java b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationMvcTests.java index 15c366478..78782edaf 100644 --- a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationMvcTests.java +++ b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationMvcTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -21,9 +21,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; @@ -34,6 +35,7 @@ * @author Dave Syer */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class SampleApplicationMvcTests { @Autowired 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 c70be8011..6a02200a4 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 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -22,10 +22,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -39,6 +41,7 @@ * @author Oleg Zhurakousky */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class SampleApplicationTests { private HttpHeaders headers; diff --git a/spring-cloud-function-samples/function-sample-spring-integration/pom.xml b/spring-cloud-function-samples/function-sample-spring-integration/pom.xml index 7c1118f94..b0b3c5a54 100644 --- a/spring-cloud-function-samples/function-sample-spring-integration/pom.xml +++ b/spring-cloud-function-samples/function-sample-spring-integration/pom.xml @@ -12,7 +12,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 @@ -20,7 +20,7 @@ UTF-8 UTF-8 17 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -32,12 +32,34 @@ org.springframework.boot spring-boot-starter-integration - + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot-starter-test test + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + diff --git a/spring-cloud-function-samples/function-sample-spring-integration/src/main/java/example/FunctionSampleSpringIntegrationApplication.java b/spring-cloud-function-samples/function-sample-spring-integration/src/main/java/example/FunctionSampleSpringIntegrationApplication.java index f6103c277..b9d43b71c 100644 --- a/spring-cloud-function-samples/function-sample-spring-integration/src/main/java/example/FunctionSampleSpringIntegrationApplication.java +++ b/spring-cloud-function-samples/function-sample-spring-integration/src/main/java/example/FunctionSampleSpringIntegrationApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-samples/function-sample-spring-integration/src/test/java/example/FunctionSampleSpringIntegrationApplicationTests.java b/spring-cloud-function-samples/function-sample-spring-integration/src/test/java/example/FunctionSampleSpringIntegrationApplicationTests.java index b6ee09a11..894b806bc 100644 --- a/spring-cloud-function-samples/function-sample-spring-integration/src/test/java/example/FunctionSampleSpringIntegrationApplicationTests.java +++ b/spring-cloud-function-samples/function-sample-spring-integration/src/test/java/example/FunctionSampleSpringIntegrationApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 the original author or authors. + * Copyright 2019-present 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. @@ -21,13 +21,15 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureTestRestTemplate public class FunctionSampleSpringIntegrationApplicationTests { @Autowired diff --git a/spring-cloud-function-samples/function-sample-supplier-exporter/pom.xml b/spring-cloud-function-samples/function-sample-supplier-exporter/pom.xml index b26871796..ebc2d6c19 100644 --- a/spring-cloud-function-samples/function-sample-supplier-exporter/pom.xml +++ b/spring-cloud-function-samples/function-sample-supplier-exporter/pom.xml @@ -14,12 +14,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT diff --git a/spring-cloud-function-samples/function-sample-supplier-exporter/src/test/java/com/example/demo/ContainerTests.java b/spring-cloud-function-samples/function-sample-supplier-exporter/src/test/java/com/example/demo/ContainerTests.java index 0b16a54a5..2fac6a4e1 100644 --- a/spring-cloud-function-samples/function-sample-supplier-exporter/src/test/java/com/example/demo/ContainerTests.java +++ b/spring-cloud-function-samples/function-sample-supplier-exporter/src/test/java/com/example/demo/ContainerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-present 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. @@ -54,7 +54,7 @@ void test() throws Exception { return result; }, result -> result != null); assertThat(response.getBody()).contains("hi foo!"); - assertThat(response.getHeaders()).containsKey("X-Amzn-Requestid"); + assertThat(response.getHeaders().containsHeader("X-Amzn-Requestid")).isTrue(); } String output = consumer.toUtf8String(); assertThat(output).contains("Lambda API listening on port 9001"); diff --git a/spring-cloud-function-samples/function-sample/pom.xml b/spring-cloud-function-samples/function-sample/pom.xml index ed67880db..33df9d2d0 100644 --- a/spring-cloud-function-samples/function-sample/pom.xml +++ b/spring-cloud-function-samples/function-sample/pom.xml @@ -14,12 +14,12 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT 1.0.31.RELEASE @@ -28,6 +28,14 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.cloud spring-cloud-starter-function-webflux @@ -42,6 +50,21 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + diff --git a/spring-cloud-function-samples/function-sample/src/main/java/com/example/Client.java b/spring-cloud-function-samples/function-sample/src/main/java/com/example/Client.java index 516fa3a1c..d20e2358f 100644 --- a/spring-cloud-function-samples/function-sample/src/main/java/com/example/Client.java +++ b/spring-cloud-function-samples/function-sample/src/main/java/com/example/Client.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/main/java/com/example/SampleApplication.java b/spring-cloud-function-samples/function-sample/src/main/java/com/example/SampleApplication.java index 533db8629..39d520378 100644 --- a/spring-cloud-function-samples/function-sample/src/main/java/com/example/SampleApplication.java +++ b/spring-cloud-function-samples/function-sample/src/main/java/com/example/SampleApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/CharCounter.java b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/CharCounter.java index 5c54b7371..e8a003458 100644 --- a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/CharCounter.java +++ b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/CharCounter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Exclaimer.java b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Exclaimer.java index 434a34e2d..94c8d0621 100644 --- a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Exclaimer.java +++ b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Exclaimer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Greeter.java b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Greeter.java index fdf66f032..39f775d0c 100644 --- a/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Greeter.java +++ b/spring-cloud-function-samples/function-sample/src/main/java/com/example/functions/Greeter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/test/java/com/example/FunctionTests.java b/spring-cloud-function-samples/function-sample/src/test/java/com/example/FunctionTests.java index cae8e9187..2ce49eab6 100644 --- a/spring-cloud-function-samples/function-sample/src/test/java/com/example/FunctionTests.java +++ b/spring-cloud-function-samples/function-sample/src/test/java/com/example/FunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-samples/function-sample/src/test/java/com/example/SampleApplicationMvcTests.java b/spring-cloud-function-samples/function-sample/src/test/java/com/example/SampleApplicationMvcTests.java deleted file mode 100644 index b9eb7a8cb..000000000 --- a/spring-cloud-function-samples/function-sample/src/test/java/com/example/SampleApplicationMvcTests.java +++ /dev/null @@ -1,68 +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 com.example; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -/** - * @author Dave Syer - */ -@SpringBootTest -@AutoConfigureMockMvc -@Disabled -public class SampleApplicationMvcTests { - - @Autowired - private MockMvc mockMvc; - - @Test - public void words() throws Exception { - MvcResult result = this.mockMvc.perform(get("/words")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(content().string("[\"foo\",\"bar\"]")); - } - - @Test - public void uppercase() throws Exception { - MvcResult result = this.mockMvc.perform(post("/uppercase").contentType(MediaType.TEXT_PLAIN).content("foo")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(content().string("FOO")); - } - - @Test - public void lowercase() throws Exception { - MvcResult result = this.mockMvc.perform(post("/lowercase").contentType(MediaType.TEXT_PLAIN).content("FOO")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(content().string("[\"foo\"]")); - } - - @Test - public void lowercaseMulti() throws Exception { - MvcResult result = this.mockMvc.perform(post("/lowercase").contentType(MediaType.APPLICATION_JSON).content("[\"FOO\"]")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(content().string("[\"foo\"]")); - } - -} diff --git a/spring-cloud-function-samples/function-sample/src/test/java/com/example/WebTestClientTests.java b/spring-cloud-function-samples/function-sample/src/test/java/com/example/WebTestClientTests.java index 9e4cfc703..06fa3d24f 100644 --- a/spring-cloud-function-samples/function-sample/src/test/java/com/example/WebTestClientTests.java +++ b/spring-cloud-function-samples/function-sample/src/test/java/com/example/WebTestClientTests.java @@ -2,7 +2,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; @@ -12,7 +13,7 @@ import java.util.ArrayList; import java.util.List; -@FunctionalSpringBootTest +@FunctionalSpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureWebTestClient public class WebTestClientTests { diff --git a/spring-cloud-function-samples/pom.xml b/spring-cloud-function-samples/pom.xml index 6c63d1b81..c7776ec8f 100644 --- a/spring-cloud-function-samples/pom.xml +++ b/spring-cloud-function-samples/pom.xml @@ -11,7 +11,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -23,17 +23,18 @@ function-sample-aws-routing function-sample-aws-custom function-sample-aws-custom-bean - function-sample-supplier-exporter + function-sample-azure function-sample-spring-integration - function-sample-gcp-http + function-sample-gcp-background - function-sample-cloudevent - function-sample-cloudevent-stream - function-sample-cloudevent-rsocket + + function-sample-cloudevent-sdk - function-sample-grpc-cloudevent + + function-sample-azure-eventgrid-trigger diff --git a/spring-cloud-function-samples/scf-aws-day1/pom.xml b/spring-cloud-function-samples/scf-aws-day1/pom.xml index 2b82dfd98..ff169ef28 100644 --- a/spring-cloud-function-samples/scf-aws-day1/pom.xml +++ b/spring-cloud-function-samples/scf-aws-day1/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 oz.spring @@ -15,7 +15,7 @@ Template project for creating function that can be deployed as AWS Lambda 17 - 2025.0.1-SNAPSHOT + 2025.1.2-SNAPSHOT 1.0.31.RELEASE 3.14.0 1.2.3 diff --git a/spring-cloud-function-samples/scf-aws-routing/pom.xml b/spring-cloud-function-samples/scf-aws-routing/pom.xml index 88619e613..f27726d2f 100644 --- a/spring-cloud-function-samples/scf-aws-routing/pom.xml +++ b/spring-cloud-function-samples/scf-aws-routing/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.6-SNAPSHOT + 4.0.2 oz.spring @@ -15,7 +15,7 @@ Template project for creating function that can be deployed as AWS Lambda 17 - 2025.0.1-SNAPSHOT + 2025.1.2-SNAPSHOT 1.0.31.RELEASE 3.14.0 1.2.3 diff --git a/spring-cloud-function-web/pom.xml b/spring-cloud-function-web/pom.xml index 1c196001e..2dd9beeac 100644 --- a/spring-cloud-function-web/pom.xml +++ b/spring-cloud-function-web/pom.xml @@ -12,7 +12,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT @@ -40,6 +40,30 @@ org.springframework.cloud spring-cloud-function-context + + org.springframework.boot + spring-boot-gson + true + + + org.springframework.boot + spring-boot-jackson + true + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-starter-webflux + true + + + org.springframework.boot + spring-boot-webflux + true + org.springframework.boot spring-boot-configuration-processor @@ -61,6 +85,10 @@ spring-boot-starter-web test + + org.springframework.boot + spring-boot-webclient + org.awaitility awaitility @@ -71,6 +99,21 @@ httpclient5 test + + org.springframework.boot + spring-boot-resttestclient + test + + + + org.springframework.boot + spring-boot-webmvc-test + test + + + org.springframework.boot + spring-boot-webtestclient + diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/BasicStringConverter.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/BasicStringConverter.java index e3634fd1c..50eed3d7e 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/BasicStringConverter.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/BasicStringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionHttpProperties.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionHttpProperties.java index 87809b5b2..2ef64bd32 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionHttpProperties.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionHttpProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java index 529aded42..f4b102467 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/RestApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/StringConverter.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/StringConverter.java index 904476142..71f7db37a 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/StringConverter.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/StringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/constants/WebRequestConstants.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/constants/WebRequestConstants.java index 2a73afac5..a1feeec8d 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/constants/WebRequestConstants.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/constants/WebRequestConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java index 73a40fb13..fe241df35 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 the original author or authors. + * Copyright 2016-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionHandlerMapping.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionHandlerMapping.java index 579bf3aa1..de865ff32 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionHandlerMapping.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ReactorAutoConfiguration.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ReactorAutoConfiguration.java index 0aade98bb..083e924fb 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ReactorAutoConfiguration.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/ReactorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -24,8 +24,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.FunctionProperties; import org.springframework.cloud.function.web.BasicStringConverter; @@ -44,7 +42,7 @@ @ConditionalOnClass({ Flux.class, AsyncHandlerMethodReturnValueHandler.class }) @ConditionalOnWebApplication(type = Type.REACTIVE) @Import(FunctionController.class) -@AutoConfigureAfter({ JacksonAutoConfiguration.class, GsonAutoConfiguration.class }) +@AutoConfigureAfter(name = { "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration", "org.springframework.boot.gson.autoconfigure.GsonAutoConfiguration" }) public class ReactorAutoConfiguration { @Bean diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/ErrorHandlerRegistrar.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/ErrorHandlerRegistrar.java new file mode 100644 index 000000000..705551fbd --- /dev/null +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/ErrorHandlerRegistrar.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-present 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.web.function; + +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.WebProperties.Resources; +import org.springframework.boot.webflux.autoconfigure.error.DefaultErrorWebExceptionHandler; +import org.springframework.boot.webflux.error.DefaultErrorAttributes; +import org.springframework.boot.webflux.error.ErrorAttributes; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.http.codec.ServerCodecConfigurer; + +public final class ErrorHandlerRegistrar { + + private ErrorHandlerRegistrar() { + + } + + protected static DefaultErrorWebExceptionHandler errorHandler(GenericApplicationContext context) { + context.registerBean(ErrorAttributes.class, () -> new DefaultErrorAttributes()); + context.registerBean(ErrorProperties.class, () -> new ErrorProperties()); + + context.registerBean(Resources.class, () -> new Resources()); + DefaultErrorWebExceptionHandler handler = new DefaultErrorWebExceptionHandler( + context.getBeansOfType(ErrorAttributes.class).values().iterator().next(), + context.getBean(Resources.class), context.getBean(ErrorProperties.class), context); + ServerCodecConfigurer codecs = ServerCodecConfigurer.create(); + handler.setMessageWriters(codecs.getWriters()); + handler.setMessageReaders(codecs.getReaders()); + return handler; + } +} diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java index 29f31acf5..69e754ca8 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-present 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. @@ -31,11 +31,7 @@ import reactor.netty.http.server.HttpServer; import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.web.ErrorProperties; -import org.springframework.boot.autoconfigure.web.WebProperties.Resources; -import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; -import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; -import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.webflux.autoconfigure.error.DefaultErrorWebExceptionHandler; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.FunctionProperties; import org.springframework.cloud.function.context.FunctionalSpringApplication; @@ -56,7 +52,6 @@ import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.http.ResponseEntity; -import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; import org.springframework.util.Assert; @@ -87,6 +82,9 @@ public class FunctionEndpointInitializer implements ApplicationContextInitialize private static boolean webflux = ClassUtils .isPresent("org.springframework.web.reactive.function.server.RouterFunction", null); + private static boolean errorAttributes = ClassUtils + .isPresent("org.springframework.boot.webflux.error.ErrorAttributes", null); + @Override public void initialize(GenericApplicationContext context) { if (webflux && ContextFunctionCatalogInitializer.enabled @@ -99,7 +97,9 @@ public void initialize(GenericApplicationContext context) { } private void registerWebFluxAutoConfiguration(GenericApplicationContext context) { - context.registerBean(DefaultErrorWebExceptionHandler.class, () -> errorHandler(context)); + if (errorAttributes) { + context.registerBean(DefaultErrorWebExceptionHandler.class, () -> ErrorHandlerRegistrar.errorHandler(context)); + } context.registerBean(WebHttpHandlerBuilder.WEB_HANDLER_BEAN_NAME, HttpWebHandlerAdapter.class, () -> httpHandler(context)); context.addApplicationListener(new ServerListener(context)); @@ -119,21 +119,9 @@ private HttpWebHandlerAdapter httpHandler(GenericApplicationContext context) { .codecs(config -> config.registerDefaults(true)).build()); } - private DefaultErrorWebExceptionHandler errorHandler(GenericApplicationContext context) { - context.registerBean(ErrorAttributes.class, () -> new DefaultErrorAttributes()); - context.registerBean(ErrorProperties.class, () -> new ErrorProperties()); - - context.registerBean(Resources.class, () -> new Resources()); - DefaultErrorWebExceptionHandler handler = new DefaultErrorWebExceptionHandler( - context.getBeansOfType(ErrorAttributes.class).values().iterator().next(), context.getBean(Resources.class), - context.getBean(ErrorProperties.class), context); - ServerCodecConfigurer codecs = ServerCodecConfigurer.create(); - handler.setMessageWriters(codecs.getWriters()); - handler.setMessageReaders(codecs.getReaders()); - return handler; - } - private static class RouterFunctionRegister { + + private static final class RouterFunctionRegister { private static void register(GenericApplicationContext context) { context.registerBean(RouterFunction.class, diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionController.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionController.java index f0e5ee673..63880038a 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionController.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionController.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 the original author or authors. + * Copyright 2016-present 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. @@ -81,7 +81,7 @@ public Object form(WebRequest request) { .getRequest()).getMultiFileMap(); if (!CollectionUtils.isEmpty(multiFileMap)) { List> files = multiFileMap.values().stream().flatMap(v -> v.stream()) - .map(file -> MessageBuilder.withPayload(file).copyHeaders(wrapper.getHeaders()).build()) + .map(file -> MessageBuilder.withPayload(file).copyHeaders(wrapper.getHeaders().asMultiValueMap()).build()) .collect(Collectors.toList()); FunctionInvocationWrapper function = wrapper.getFunction(); @@ -199,7 +199,7 @@ private FunctionWrapper wrapper(WebRequest request) { wrapper.getHeaders().addAll(key, Arrays.asList(request.getHeaderValues(key))); } - HttpHeaders headers = HttpHeaders.writableHttpHeaders(wrapper.getHeaders()); + HttpHeaders headers = HttpHeaders.copyOf(wrapper.getHeaders()); headers.set("uri", ((ServletWebRequest) request).getRequest().getRequestURI()); String argument = (String) request.getAttribute(WebRequestConstants.ARGUMENT, diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionHandlerMapping.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionHandlerMapping.java index 5ad188ea3..ed85403f0 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionHandlerMapping.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/FunctionHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/ReactorAutoConfiguration.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/ReactorAutoConfiguration.java index 4c9666f55..453f9ac0e 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/ReactorAutoConfiguration.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/mvc/ReactorAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/DestinationResolver.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/DestinationResolver.java index 3479e49a4..67b21a5cb 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/DestinationResolver.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/DestinationResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/ExporterProperties.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/ExporterProperties.java index a7c32f9bb..48e61cc7e 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/ExporterProperties.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/ExporterProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterAutoConfiguration.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterAutoConfiguration.java index c1123aa78..29911c68e 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterAutoConfiguration.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterInitializer.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterInitializer.java index 640cf930f..42beb3de8 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterInitializer.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/FunctionExporterInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-present 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,8 +18,8 @@ import java.util.function.Supplier; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebEnvironment; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebEnvironment; +import org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.FunctionRegistration; import org.springframework.cloud.function.context.config.ContextFunctionCatalogInitializer; diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/HttpSupplier.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/HttpSupplier.java index 84574187e..6e5376040 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/HttpSupplier.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/HttpSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-present 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. @@ -65,8 +65,7 @@ public Flux get() { } private Flux get(WebClient client) { - Flux result = client.get().uri(this.props.getSource().getUrl()).exchange() - .flatMap(this::transform).repeat(); + Flux result = client.get().uri(this.props.getSource().getUrl()).exchangeToMono(this::transform).repeat(); if (this.props.isDebug()) { result = result.log(); } diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/RequestBuilder.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/RequestBuilder.java index cb0dd48cd..c998c8ec0 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/RequestBuilder.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/RequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleDestinationResolver.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleDestinationResolver.java index 3426c757c..82d7f4716 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleDestinationResolver.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleDestinationResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleRequestBuilder.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleRequestBuilder.java index 3657f057a..8153940ed 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleRequestBuilder.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SimpleRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SupplierExporter.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SupplierExporter.java index 8a24e8455..b0feaaa2a 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SupplierExporter.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/source/SupplierExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -192,7 +192,7 @@ private Mono post(URI uri, String destination, Object value) { } Mono result = this.client.post().uri(uri) .headers(headers -> headers(headers, destination, value)).bodyValue(body) - .exchange() + .exchangeToMono(Mono::just) .doOnNext(response -> { if (this.debug) { logger.debug("Response STATUS: " + response.statusCode()); diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWebRequestProcessingHelper.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWebRequestProcessingHelper.java index c13c9ca29..533c589b0 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWebRequestProcessingHelper.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWebRequestProcessingHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-present 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. @@ -132,7 +132,7 @@ public static Publisher processRequest(FunctionWrapper wrapper, Object argume Object result = function.apply(inputMessage); if (function.isConsumer()) { - if (result instanceof Publisher) { + if (result instanceof Publisher && !function.isComposed()) { Mono.from((Publisher) result).subscribe(); } return "DELETE".equals(wrapper.getMethod()) ? diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWrapper.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWrapper.java index 627cf9508..122d27641 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWrapper.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/FunctionWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021-2021 the original author or authors. + * Copyright 2021-present 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. diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/HeaderUtils.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/HeaderUtils.java index d4382fe6f..6391ee7cb 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/HeaderUtils.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/util/HeaderUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -62,7 +62,7 @@ public static HttpHeaders fromMessage(MessageHeaders headers, List ignor for (String name : headers.keySet()) { Object value = headers.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !ignoredHeders.contains(name)) { + if (!IGNORED.containsHeader(name) && !ignoredHeders.contains(name)) { Collection values = multi(value); for (Object object : values) { result.set(name, object.toString()); @@ -80,10 +80,10 @@ public static HttpHeaders fromMessage(MessageHeaders headers) { public static HttpHeaders sanitize(HttpHeaders request, List ignoredHeders, List requestOnlyHeaders) { HttpHeaders result = new HttpHeaders(); - for (String name : request.keySet()) { + for (String name : request.headerNames()) { List value = request.get(name); name = name.toLowerCase(Locale.ROOT); - if (!IGNORED.containsKey(name) && !REQUEST_ONLY.containsKey(name) && !ignoredHeders.contains(name) && !requestOnlyHeaders.contains(name)) { + if (!IGNORED.containsHeader(name) && !REQUEST_ONLY.containsHeader(name) && !ignoredHeders.contains(name) && !requestOnlyHeaders.contains(name)) { result.put(name, value); } } @@ -97,7 +97,7 @@ public static HttpHeaders sanitize(HttpHeaders request) { public static MessageHeaders fromHttp(HttpHeaders headers) { Map map = new LinkedHashMap<>(); - for (String name : headers.keySet()) { + for (String name : headers.headerNames()) { Collection values = multi(headers.get(name)); name = name.toLowerCase(Locale.ROOT); Object value = values == null ? null diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/scan/ComponentTests.java b/spring-cloud-function-web/src/main/resources/ComponentTests.java similarity index 95% rename from spring-cloud-function-web/src/test/java/org/springframework/cloud/function/scan/ComponentTests.java rename to spring-cloud-function-web/src/main/resources/ComponentTests.java index 9c9cfc64f..9d68af62d 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/scan/ComponentTests.java +++ b/spring-cloud-function-web/src/main/resources/ComponentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,9 +24,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.resttestclient.TestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.HttpStatus; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/flux/FluxRestApplicationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/flux/FluxRestApplicationTests.java index 63f6a3a36..5bdb4838e 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/flux/FluxRestApplicationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/flux/FluxRestApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -34,9 +34,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.flux.FluxRestApplicationTests.TestConfiguration; import org.springframework.context.annotation.Configuration; @@ -64,6 +65,7 @@ // @checkstyle:off @SpringBootTest(classes = TestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive") // @checkstyle:on +@AutoConfigureTestRestTemplate public class FluxRestApplicationTests { private static final MediaType EVENT_STREAM = MediaType.valueOf("text/event-stream"); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/mvc/MvcRestApplicationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/mvc/MvcRestApplicationTests.java index 0a8f73bf4..0621a5152 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/mvc/MvcRestApplicationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/mvc/MvcRestApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -33,9 +33,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.mvc.MvcRestApplicationTests.TestConfiguration; import org.springframework.context.annotation.Configuration; @@ -63,6 +64,7 @@ // @checkstyle:off @SpringBootTest(classes = TestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=servlet") // @checkstyle:on +@AutoConfigureTestRestTemplate public class MvcRestApplicationTests { private static final MediaType EVENT_STREAM = MediaType.valueOf("text/event-stream"); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ExplicitNonFunctionalTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ExplicitNonFunctionalTests.java index a9a0f9bbc..127ed004e 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ExplicitNonFunctionalTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ExplicitNonFunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalExporterTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalExporterTests.java index f72500d42..b04b5f7b0 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalExporterTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalExporterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java index 434f2fb80..e985e496e 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputListTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputListTests.java index 28dfc0f76..0a8bd1cfc 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputListTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputListTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -26,7 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputSetTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputSetTests.java index e5f426834..97f9d5ccc 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputSetTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalWithInputSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -27,7 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java index 0470519bc..a6f14a5e3 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ImplicitNonFunctionalTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ImplicitNonFunctionalTests.java index ac26fd14f..e2697b134 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ImplicitNonFunctionalTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/ImplicitNonFunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -25,8 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.context.annotation.Bean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/MoreThenOneFunctionRootMappingTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/MoreThenOneFunctionRootMappingTests.java index 1482024c5..3e6464f18 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/MoreThenOneFunctionRootMappingTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/MoreThenOneFunctionRootMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,8 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.context.annotation.Bean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java index 44efc5ff8..34c3273bb 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestConfiguration.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestConfiguration.java index 39bb8fae7..1d261fead 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestConfiguration.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestPojoConfiguration.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestPojoConfiguration.java index fbb89d14f..0a3e3902e 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestPojoConfiguration.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/RestPojoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HeadersToMessageTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HeadersToMessageTests.java index 06ec2bdb1..78df32252 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HeadersToMessageTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HeadersToMessageTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -17,15 +17,17 @@ package org.springframework.cloud.function.web.flux; import java.net.URI; +import java.util.Map; import java.util.function.Function; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.cloud.function.web.RestApplication; import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; @@ -47,6 +49,7 @@ "spring.cloud.function.web.path=/functions", "spring.main.web-application-type=reactive" }) @ContextConfiguration(classes = { RestApplication.class, HeadersToMessageTests.TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class HeadersToMessageTests { @Autowired @@ -55,21 +58,21 @@ public class HeadersToMessageTests { @Test public void testBodyAndCustomHeaderFromMessagePropagation() throws Exception { // test POJO paylod - ResponseEntity postForEntity = this.rest + ResponseEntity postForEntity = this.rest .exchange(RequestEntity.post(new URI("/functions/employee")) .contentType(MediaType.APPLICATION_JSON) - .body("{\"name\":\"Bob\",\"age\":25}"), String.class); - assertThat(postForEntity.getBody()).isEqualTo("{\"name\":\"Bob\",\"age\":25}"); - assertThat(postForEntity.getHeaders().containsKey("x-content-type")).isTrue(); + .body("{\"name\":\"Bob\",\"age\":25}"), Map.class); + assertThat(postForEntity.getBody()).containsExactlyInAnyOrderEntriesOf(Map.of("name", "Bob", "age", 25)); + assertThat(postForEntity.getHeaders().containsHeader("x-content-type")).isTrue(); assertThat(postForEntity.getHeaders().get("x-content-type").get(0)) .isEqualTo("application/xml"); assertThat(postForEntity.getHeaders().get("foo").get(0)).isEqualTo("bar"); // test simple type payload postForEntity = this.rest.postForEntity(new URI("/functions/string"), - "{\"name\":\"Bob\",\"age\":25}", String.class); - assertThat(postForEntity.getBody()).isEqualTo("{\"name\":\"Bob\",\"age\":25}"); - assertThat(postForEntity.getHeaders().containsKey("x-content-type")).isTrue(); + "{\"name\":\"Bob\",\"age\":25}", Map.class); + assertThat(postForEntity.getBody()).containsExactlyInAnyOrderEntriesOf(Map.of("name", "Bob", "age", 25)); + assertThat(postForEntity.getHeaders().containsHeader("x-content-type")).isTrue(); assertThat(postForEntity.getHeaders().get("x-content-type").get(0)) .isEqualTo("application/xml"); assertThat(postForEntity.getHeaders().get("foo").get(0)).isEqualTo("bar"); @@ -103,7 +106,7 @@ public Function, Message> function1() { } @SuppressWarnings("unused") // used by json converter - private static class Employee { + private static final class Employee { private String name; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpGetIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpGetIntegrationTests.java index effaa7c30..c2afd53bd 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpGetIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpGetIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-present 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. @@ -35,10 +35,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.flux.HttpGetIntegrationTests.ApplicationConfiguration; @@ -60,6 +61,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"spring.main.web-application-type=reactive", "debug=true"}) @ContextConfiguration(classes = { RestApplication.class, ApplicationConfiguration.class }) @DirtiesContext +@AutoConfigureTestRestTemplate public class HttpGetIntegrationTests { private static final MediaType EVENT_STREAM = MediaType.TEXT_EVENT_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 eb4d61ab8..99581ab35 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -38,9 +38,10 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.flux.HttpPostIntegrationTests.ApplicationConfiguration; @@ -66,6 +67,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive") @ContextConfiguration(classes = { RestApplication.class, ApplicationConfiguration.class }) +@AutoConfigureTestRestTemplate public class HttpPostIntegrationTests { private static final MediaType EVENT_STREAM = MediaType.TEXT_EVENT_STREAM; @@ -124,6 +126,7 @@ public void updatesJson() throws Exception { @Test @DirtiesContext + @Disabled public void addFoos() throws Exception { ResponseEntity result = this.rest.exchange(RequestEntity .post(new URI("/addFoos")).contentType(MediaType.APPLICATION_JSON) @@ -146,6 +149,7 @@ public void addFoosFlux() throws Exception { @Test @DirtiesContext + @Disabled public void bareUpdates() throws Exception { ResponseEntity result = this.rest.exchange(RequestEntity .post(new URI("/bareUpdates")).contentType(MediaType.APPLICATION_JSON) @@ -170,7 +174,7 @@ public void messages() throws Exception { .post(new URI("/messages")).contentType(MediaType.APPLICATION_JSON) .header("x-foo", "bar").body("[\"foo\",\"bar\"]"), String.class); assertThat(result.getHeaders().getFirst("x-foo")).isEqualTo("bar"); - assertThat(result.getHeaders()).doesNotContainKey("id"); + assertThat(result.getHeaders().containsHeader("id")).isFalse(); assertThat(result.getBody()).isEqualTo("[\"(FOO)\",\"(BAR)\"]"); } @@ -180,8 +184,6 @@ public void headers() throws Exception { ResponseEntity result = this.rest.exchange(RequestEntity .post(new URI("/headers")).contentType(MediaType.APPLICATION_JSON) .body("[\"foo\",\"bar\"]"), String.class); -// assertThat(result.getHeaders().getFirst("foo")).isEqualTo("bar"); -// assertThat(result.getHeaders()).doesNotContainKey("id"); assertThat(result.getBody()).isEqualTo("[\"(FOO)\",\"(BAR)\"]"); } @@ -375,7 +377,6 @@ public void multipart() throws Exception { @Test @DirtiesContext - @Disabled public void count() throws Exception { List list = Arrays.asList("A", "B", "A"); assertThat(this.rest.exchange( @@ -386,7 +387,6 @@ public void count() throws Exception { @Test @DirtiesContext - @Disabled public void fluxWithList() throws Exception { List list = Arrays.asList("A", "B", "A"); assertThat(this.rest.exchange( @@ -395,6 +395,14 @@ public void fluxWithList() throws Exception { String.class).getBody()).isEqualTo("[\"A\",\"B\",\"A\"]"); } + @Test + @DirtiesContext + public void testReactiveFunctionComposdWithImperativeConsumer() throws Exception { + RequestEntity entity = RequestEntity.post(new URI("/functionReactive,consumerImperative")).build(); + this.rest.exchange(entity, String.class); + assertThat(ApplicationConfiguration.functionReactiveInvocations).isEqualTo(1); + } + private String sse(String... values) { return "[\"" + StringUtils.arrayToDelimitedString(values, "\",\"") + "\"]"; } @@ -405,11 +413,26 @@ public static class ApplicationConfiguration { private List list = new ArrayList<>(); + private static int functionReactiveInvocations; + public static void main(String[] args) throws Exception { SpringApplication.run(HttpPostIntegrationTests.ApplicationConfiguration.class, args); } + @Bean + public Function, Flux> functionReactive() { + functionReactiveInvocations = 0; + return flux -> flux.doOnNext(x -> functionReactiveInvocations++); + } + + @Bean + public Consumer consumerImperative() { + return value -> { + System.out.println(value); + }; + } + @Bean({ "uppercase", "transform", "post/more" }) public Function, Flux> uppercase() { return flux -> flux.log() diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/PrefixTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/PrefixTests.java index fcadd4683..4724a17a8 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/PrefixTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/PrefixTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -24,9 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.flux.PrefixTests.TestConfiguration; @@ -46,6 +47,7 @@ "spring.main.web-application-type=reactive", "spring.cloud.function.web.path=/functions", "debug" }) @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class PrefixTests { @LocalServerPort diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/SingletonTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/SingletonTests.java index c2c85f328..c2b94416d 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/SingletonTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/SingletonTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -29,9 +29,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.flux.SingletonTests.TestConfiguration; @@ -49,6 +50,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive") @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class SingletonTests { @LocalServerPort diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerMVCTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerMVCTests.java index fa749cd07..13c6e86fe 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerMVCTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerMVCTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. @@ -24,7 +24,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.http.ResponseEntity; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerTests.java index 66189a9de..bf6a38655 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. @@ -31,7 +31,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.cloud.function.context.FunctionRegistration; import org.springframework.cloud.function.context.FunctionalSpringApplication; import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; @@ -72,7 +72,7 @@ public void testEmptyBodyRequestParameters() throws Exception { headers.set("Accept", "application/json"); HttpEntity entity = new HttpEntity(headers); - String urlTemplate = UriComponentsBuilder.fromHttpUrl("http://localhost:" + port + "/nullPayload") + String urlTemplate = UriComponentsBuilder.fromUriString("http://localhost:" + port + "/nullPayload") .queryParam("fname", "Jim").queryParam("lname", "Lahey").encode().toUriString(); ResponseEntity response = testRestTemplate.exchange(urlTemplate, HttpMethod.GET, entity, String.class); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/HeadersResponseMappingTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/HeadersResponseMappingTests.java index 462c263ae..0ebcd7b82 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/HeadersResponseMappingTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/HeadersResponseMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2024-2024 the original author or authors. + * Copyright 2024-present 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. @@ -25,7 +25,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.http.ResponseEntity; @@ -46,7 +46,7 @@ public void test_1220() throws Exception { assertThat(response.getBody()).isEqualTo("JOHN"); } - static record Person(String firstName, String lastName) { + record Person(String firstName, String lastName) { } @SpringBootApplication diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/UserSubmittedTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/UserSubmittedTests.java index 0994efb7d..9315cf661 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/UserSubmittedTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/function/UserSubmittedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-present 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. @@ -24,7 +24,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/DefaultRouteTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/DefaultRouteTests.java index e5510722c..12e9d7311 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/DefaultRouteTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/DefaultRouteTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -26,9 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.DefaultRouteTests.TestConfiguration; @@ -46,6 +47,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "") @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class DefaultRouteTests { @LocalServerPort diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/GeneralIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/GeneralIntegrationTests.java index da20059df..f40a95b4d 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/GeneralIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/GeneralIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2023 the original author or authors. + * Copyright 2023-present 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. @@ -25,7 +25,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; 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 14c264aee..ce17d68c2 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -25,9 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.HeadersToMessageTests.TestConfiguration; import org.springframework.context.annotation.Bean; @@ -48,6 +49,7 @@ "spring.main.web-application-type=servlet", "spring.cloud.function.web.path=/functions" }) @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class HeadersToMessageTests { @Autowired @@ -55,12 +57,12 @@ public class HeadersToMessageTests { @Test public void testBodyAndCustomHeaderFromMessagePropagation() throws Exception { - HttpEntity postForEntity = this.rest + HttpEntity postForEntity = this.rest .exchange(RequestEntity.post(new URI("/functions/employee")) .contentType(MediaType.APPLICATION_JSON) - .body("{\"name\":\"Bob\",\"age\":25}"), String.class); - assertThat(postForEntity.getBody()).isEqualTo("{\"name\":\"Bob\",\"age\":25}"); - assertThat(postForEntity.getHeaders().containsKey("x-content-type")).isTrue(); + .body("{\"name\":\"Bob\",\"age\":25}"), Map.class); + assertThat(postForEntity.getBody()).containsExactlyInAnyOrderEntriesOf(Map.of("name", "Bob", "age", 25)); + assertThat(postForEntity.getHeaders().containsHeader("x-content-type")).isTrue(); assertThat(postForEntity.getHeaders().get("x-content-type").get(0)) .isEqualTo("application/xml"); assertThat(postForEntity.getHeaders().get("foo").get(0)).isEqualTo("bar"); @@ -68,14 +70,14 @@ public void testBodyAndCustomHeaderFromMessagePropagation() throws Exception { @Test public void testHeadersPropagatedByDefault() throws Exception { - HttpEntity postForEntity = this.rest + HttpEntity postForEntity = this.rest .exchange(RequestEntity.post(new URI("/functions/vanilla")) .contentType(MediaType.APPLICATION_JSON) .header("x-context-type", "rubbish") - .body("{\"name\":\"Bob\",\"age\":25}"), String.class); - assertThat(postForEntity.getBody()) - .isEqualTo("{\"name\":\"Bob\",\"age\":25,\"foo\":\"bar\"}"); - assertThat(postForEntity.getHeaders().containsKey("x-context-type")).isTrue(); + .body("{\"name\":\"Bob\",\"age\":25}"), Map.class); + assertThat(postForEntity.getBody()).containsExactlyInAnyOrderEntriesOf(Map.of("name", "Bob", "age", 25, "foo", "bar")); + + assertThat(postForEntity.getHeaders().containsHeader("x-context-type")).isTrue(); assertThat(postForEntity.getHeaders().get("x-context-type").get(0)) .isEqualTo("rubbish"); } diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpDeleteIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpDeleteIntegrationTests.java index 834edd2da..e4abbbaee 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpDeleteIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpDeleteIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -29,10 +29,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.mvc.HttpDeleteIntegrationTests.ApplicationConfiguration; import org.springframework.context.annotation.Bean; @@ -49,6 +50,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=servlet") @ContextConfiguration(classes = {ApplicationConfiguration.class}) +@AutoConfigureTestRestTemplate public class HttpDeleteIntegrationTests { @LocalServerPort diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpGetIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpGetIntegrationTests.java index e0092fbab..367a0770c 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpGetIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpGetIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-present 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. @@ -39,10 +39,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.HttpGetIntegrationTests.ApplicationConfiguration; @@ -65,6 +66,7 @@ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=servlet") @ContextConfiguration(classes = { RestApplication.class, ApplicationConfiguration.class }) @DirtiesContext +@AutoConfigureTestRestTemplate public class HttpGetIntegrationTests { private static final MediaType EVENT_STREAM = MediaType.TEXT_EVENT_STREAM; 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 b3d9b2aa4..9490a8f34 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -37,10 +37,11 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.HttpPostIntegrationTests.ApplicationConfiguration; @@ -63,6 +64,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=servlet") @ContextConfiguration(classes = { RestApplication.class, ApplicationConfiguration.class }) +@AutoConfigureTestRestTemplate public class HttpPostIntegrationTests { @LocalServerPort @@ -120,7 +122,7 @@ public void addFoos() throws Exception { assertThat(result.getBody()).isEqualTo(null); } - @Test +// @Test public void bareUpdates() throws Exception { ResponseEntity result = this.rest.exchange(RequestEntity .post(new URI("/bareUpdates")).contentType(MediaType.APPLICATION_JSON) @@ -145,7 +147,7 @@ public void messages() throws Exception { .accept(MediaType.valueOf("application/stream+json")) .header("x-foo", "bar").body("[\"foo\",\"bar\"]"), String.class); assertThat(result.getHeaders().getFirst("x-foo")).isEqualTo("bar"); - assertThat(result.getHeaders()).doesNotContainKey("id"); + assertThat(result.getHeaders().containsHeader("id")).isFalse(); assertThat(result.getBody()).isEqualTo("[\"(FOO)\",\"(BAR)\"]"); } @@ -157,7 +159,7 @@ public void headers() throws Exception { .accept(MediaType.valueOf("application/stream+json")) .body("[\"foo\",\"bar\"]"), String.class); assertThat(result.getHeaders().getFirst("foo")).isEqualTo("bar"); - assertThat(result.getHeaders()).doesNotContainKey("id"); + assertThat(result.getHeaders().containsHeader("id")).isFalse(); assertThat(result.getBody()).isEqualTo("[\"(FOO)\",\"(BAR)\"]"); } diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/MultipartFileTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/MultipartFileTests.java index e1fde9f2c..1a9bdc394 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/MultipartFileTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/MultipartFileTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-present 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. @@ -25,7 +25,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.resttestclient.TestRestTemplate; import org.springframework.cloud.function.json.JsonMapper; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/PrefixTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/PrefixTests.java index d8b264cb9..65f4abdf6 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/PrefixTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/PrefixTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -26,9 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.PrefixTests.TestConfiguration; import org.springframework.cloud.function.web.util.HeaderUtils; @@ -49,6 +50,7 @@ "spring.main.web-application-type=servlet", "spring.cloud.function.web.path=/functions" }) @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class PrefixTests { @Autowired diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/RoutingFunctionTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/RoutingFunctionTests.java index b107d96bf..daeec303b 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/RoutingFunctionTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/RoutingFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -28,9 +28,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.cloud.function.context.FunctionProperties; import org.springframework.cloud.function.context.config.RoutingFunction; import org.springframework.cloud.function.web.RestApplication; @@ -58,6 +59,7 @@ "spring.cloud.function.routing.enabled=true", "spring.cloud.function.http.ignored-headers=abc,xyz"}) @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class RoutingFunctionTests { @Autowired @@ -79,12 +81,12 @@ public void testFunctionMessage() throws Exception { .header("xyz", "xyz") .body("{\"name\":\"Bob\",\"age\":25}"), String.class); assertThat(postForEntity.getBody()).isEqualTo("{\"name\":\"Bob\",\"age\":25}"); - assertThat(postForEntity.getHeaders().containsKey("x-content-type")).isTrue(); + assertThat(postForEntity.getHeaders().containsHeader("x-content-type")).isTrue(); assertThat(postForEntity.getHeaders().get("x-content-type").get(0)) .isEqualTo("application/xml"); - assertThat(postForEntity.getHeaders().containsKey("spring.cloud.function.definition")).isTrue(); - assertThat(postForEntity.getHeaders().containsKey("abc")).isFalse(); - assertThat(postForEntity.getHeaders().containsKey("xyz")).isFalse(); + assertThat(postForEntity.getHeaders().containsHeader("spring.cloud.function.definition")).isTrue(); + assertThat(postForEntity.getHeaders().containsHeader("abc")).isFalse(); + assertThat(postForEntity.getHeaders().containsHeader("xyz")).isFalse(); assertThat(postForEntity.getHeaders().get("foo").get(0)).isEqualTo("bar"); } diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/SingletonTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/SingletonTests.java index 5636d5171..b684a80ad 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/SingletonTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/SingletonTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. @@ -29,9 +29,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; 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.cloud.function.web.RestApplication; import org.springframework.cloud.function.web.mvc.SingletonTests.TestConfiguration; import org.springframework.context.annotation.Bean; @@ -48,6 +49,7 @@ */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(classes = { RestApplication.class, TestConfiguration.class }) +@AutoConfigureTestRestTemplate public class SingletonTests { @Autowired diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationIntegrationTests.java index 7d272f701..084d58b90 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationWithRetriesIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationWithRetriesIntegrationTests.java index e15b571f8..b01e21312 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationWithRetriesIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/FunctionAutoConfigurationWithRetriesIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2019 the original author or authors. + * Copyright 2019-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/SourceAutoConfigurationIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/SourceAutoConfigurationIntegrationTests.java index 600bc728c..7dfdd4f49 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/SourceAutoConfigurationIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/SourceAutoConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/WebAppIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/WebAppIntegrationTests.java index 261ca50bf..896cffad5 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/WebAppIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/source/WebAppIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-present 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. diff --git a/spring-cloud-starter-function-web/pom.xml b/spring-cloud-starter-function-web/pom.xml index 22137ce48..564573620 100644 --- a/spring-cloud-starter-function-web/pom.xml +++ b/spring-cloud-starter-function-web/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT .. spring-cloud-starter-function-web diff --git a/spring-cloud-starter-function-webflux/pom.xml b/spring-cloud-starter-function-webflux/pom.xml index 46d1bb40f..65d7a88d0 100644 --- a/spring-cloud-starter-function-webflux/pom.xml +++ b/spring-cloud-starter-function-webflux/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-function-parent - 4.3.1-SNAPSHOT + 5.0.2-SNAPSHOT spring-cloud-starter-function-webflux spring-cloud-starter-function-webflux @@ -25,5 +25,9 @@ org.springframework.boot spring-boot-starter-webflux + + org.springframework.boot + spring-boot-starter-webclient +