├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE.txt ├── README.md ├── THIRD_PARTY_LICENSES.txt ├── api ├── pom.xml └── src │ ├── main │ ├── api │ │ └── snapshot.sigfile │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── api │ │ ├── FnConfiguration.java │ │ ├── FnFeature.java │ │ ├── FnFeatures.java │ │ ├── FunctionInvoker.java │ │ ├── Headers.java │ │ ├── InputBinding.java │ │ ├── InputCoercion.java │ │ ├── InputEvent.java │ │ ├── InvocationContext.java │ │ ├── InvocationListener.java │ │ ├── MethodWrapper.java │ │ ├── OutputBinding.java │ │ ├── OutputCoercion.java │ │ ├── OutputEvent.java │ │ ├── QueryParameters.java │ │ ├── RuntimeContext.java │ │ ├── RuntimeFeature.java │ │ ├── TypeWrapper.java │ │ ├── exception │ │ ├── FunctionConfigurationException.java │ │ ├── FunctionInputHandlingException.java │ │ ├── FunctionLoadException.java │ │ └── FunctionOutputHandlingException.java │ │ ├── httpgateway │ │ └── HTTPGatewayContext.java │ │ └── tracing │ │ └── TracingContext.java │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ └── api │ └── HeadersTest.java ├── bin └── scripts │ └── migration │ ├── flag │ └── migrate_to_maven_central.sh ├── build_in_docker.sh ├── docs ├── DataBinding.md ├── ExtendingDataBinding.md ├── FAQ.md ├── FnFlowsAdvancedTopics.md ├── FnFlowsUserGuide.md ├── FunctionConfiguration.md ├── HTTPGatewayFunctions.md ├── SpringCloudFunctionSupport.md └── TestingFunctions.md ├── examples ├── README.md ├── async-thumbnails │ ├── .gitignore │ ├── README.md │ ├── func.yaml │ ├── pom.xml │ ├── run.sh │ ├── setup │ │ ├── resize128 │ │ │ ├── Dockerfile │ │ │ └── func.yaml │ │ ├── resize256 │ │ │ ├── Dockerfile │ │ │ └── func.yaml │ │ ├── resize512 │ │ │ ├── Dockerfile │ │ │ └── func.yaml │ │ └── setup.sh │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── fnproject │ │ │ │ └── fn │ │ │ │ └── examples │ │ │ │ └── ThumbnailsFunction.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── examples │ │ │ └── ThumbnailsFunctionTest.java │ └── test-image.png ├── gradle-build │ ├── .dockerignore │ ├── Dockerfile │ ├── README.md │ ├── build.gradle │ ├── func.yaml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── fn │ │ │ └── HelloFunction.java │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── fn │ │ └── HelloFunctionTest.java ├── pom.xml ├── qr-code │ ├── .gitignore │ ├── README.md │ ├── example.html │ ├── func.yaml │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── examples │ │ │ └── QRGen.java │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── examples │ │ │ └── QRGenTest.java │ │ └── resources │ │ ├── qr-code-number-0-12345-67890.png │ │ ├── qr-code-text-hello-world.jpg │ │ └── qr-code-text-hello-world.png ├── regex-query │ ├── README.md │ ├── func.yaml │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── examples │ │ │ ├── Match.java │ │ │ ├── Query.java │ │ │ ├── RegexQuery.java │ │ │ └── Response.java │ │ └── test │ │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── examples │ │ └── RegexQueryTests.java └── string-reverse │ ├── README.md │ ├── func.yaml │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── com │ │ └── example │ │ └── fn │ │ └── StringReverse.java │ └── test │ └── java │ └── com │ └── example │ └── fn │ └── testing │ └── StringReverseTest.java ├── experimental-native-image-support ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── nativeimagesupport │ │ │ └── JacksonFeature.java │ └── resources │ │ └── META-INF │ │ └── native-image │ │ └── com.fnproject.fn │ │ └── nativeimagesupport │ │ ├── jersey-support │ │ ├── reflect-config.json │ │ └── resource-config.json │ │ └── oci-client-support │ │ ├── reflect-config.json │ │ └── resource-config.json │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ └── nativeimagesupport │ └── JacksonFeatureTest.java ├── flow-api ├── pom.xml └── src │ ├── main │ ├── api │ │ └── snapshot.sigfile │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── api │ │ └── flow │ │ ├── Flow.java │ │ ├── FlowCompletionException.java │ │ ├── FlowFuture.java │ │ ├── Flows.java │ │ ├── FunctionInvocationException.java │ │ ├── FunctionInvokeFailedException.java │ │ ├── FunctionTimeoutException.java │ │ ├── HttpMethod.java │ │ ├── HttpRequest.java │ │ ├── HttpResponse.java │ │ ├── InvalidStageResponseException.java │ │ ├── LambdaSerializationException.java │ │ ├── PlatformException.java │ │ ├── ResultSerializationException.java │ │ ├── StageInvokeFailedException.java │ │ ├── StageLostException.java │ │ ├── StageTimeoutException.java │ │ ├── WrappedFunctionException.java │ │ └── package-info.java │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ └── api │ └── flow │ └── FlowsTest.java ├── flow-runtime ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── runtime │ │ └── flow │ │ ├── APIModel.java │ │ ├── BlobResponse.java │ │ ├── BlobStoreClient.java │ │ ├── CodeLocation.java │ │ ├── CompleterClient.java │ │ ├── CompleterClientFactory.java │ │ ├── CompletionId.java │ │ ├── DefaultHttpResponse.java │ │ ├── EntityReader.java │ │ ├── FlowContinuationInvoker.java │ │ ├── FlowFeature.java │ │ ├── FlowFutureSource.java │ │ ├── FlowId.java │ │ ├── FlowRuntimeGlobals.java │ │ ├── HttpClient.java │ │ ├── JsonInvoke.java │ │ ├── RemoteBlobStoreClient.java │ │ ├── RemoteFlow.java │ │ └── RemoteFlowApiClient.java │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ ├── runtime │ └── flow │ │ ├── FlowsContinuationInvokerTest.java │ │ ├── RemoteFlowApiClientTest.java │ │ └── TestBlobStore.java │ └── testing │ └── flowtestfns │ └── FnFlowsFunction.java ├── flow-testing ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── testing │ │ └── flow │ │ ├── FlowTesting.java │ │ ├── FnFunctionStubBuilder.java │ │ ├── InMemCompleter.java │ │ └── ResultException.java │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ └── testing │ ├── flow │ ├── FnTestingRuleFlowsTest.java │ ├── IntegrationTest.java │ ├── MultipleEventsTest.java │ └── WhenCompleteTest.java │ └── flowtestfns │ └── ExerciseEverything.java ├── fn-spring-cloud-function ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── fnproject │ │ └── springframework │ │ └── function │ │ ├── SimpleTypeWrapper.java │ │ ├── SpringCloudFunctionFeature.java │ │ ├── SpringCloudFunctionInvoker.java │ │ ├── SpringCloudFunctionLoader.java │ │ ├── exception │ │ └── SpringCloudFunctionNotFoundException.java │ │ └── functions │ │ ├── SpringCloudConsumer.java │ │ ├── SpringCloudFunction.java │ │ ├── SpringCloudMethod.java │ │ └── SpringCloudSupplier.java │ └── test │ └── java │ └── com │ └── fnproject │ └── springframework │ └── function │ ├── SpringCloudFunctionInvokerIntegrationTest.java │ ├── SpringCloudFunctionInvokerTest.java │ ├── SpringCloudFunctionLoaderTest.java │ └── testfns │ ├── EmptyFunctionConfig.java │ └── FunctionConfig.java ├── graalvm.version ├── infra └── update │ └── functions │ └── Jenkinsfile ├── pom.xml ├── release.version ├── runtime ├── README.md ├── pom.xml ├── smith.yaml └── src │ ├── main │ ├── c │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── Dockerfile-buildimage │ │ ├── README.md │ │ ├── buildit.sh │ │ ├── rebuild_so.sh │ │ └── unix_socket.c │ ├── java-filtered │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── runtime │ │ │ └── Version.java │ ├── java │ │ └── com │ │ │ └── fnproject │ │ │ └── fn │ │ │ └── runtime │ │ │ ├── DefaultMethodWrapper.java │ │ │ ├── EntryPoint.java │ │ │ ├── EventCodec.java │ │ │ ├── FunctionConfigurer.java │ │ │ ├── FunctionInvocationCallback.java │ │ │ ├── FunctionInvocationContext.java │ │ │ ├── FunctionLoader.java │ │ │ ├── FunctionRuntimeContext.java │ │ │ ├── HTTPStreamCodec.java │ │ │ ├── MethodFunctionInvoker.java │ │ │ ├── MethodTypeWrapper.java │ │ │ ├── PrimitiveTypeResolver.java │ │ │ ├── ReadOnceInputEvent.java │ │ │ ├── coercion │ │ │ ├── ByteArrayCoercion.java │ │ │ ├── ContextCoercion.java │ │ │ ├── InputEventCoercion.java │ │ │ ├── OutputEventCoercion.java │ │ │ ├── StringCoercion.java │ │ │ ├── VoidCoercion.java │ │ │ └── jackson │ │ │ │ └── JacksonCoercion.java │ │ │ ├── exception │ │ │ ├── FunctionClassInstantiationException.java │ │ │ ├── FunctionIOException.java │ │ │ ├── FunctionInitializationException.java │ │ │ ├── InternalFunctionInvocationException.java │ │ │ ├── InvalidEntryPointException.java │ │ │ ├── InvalidFunctionDefinitionException.java │ │ │ └── PlatformCommunicationException.java │ │ │ ├── httpgateway │ │ │ ├── FunctionHTTPGatewayContext.java │ │ │ ├── QueryParametersImpl.java │ │ │ └── QueryParametersParser.java │ │ │ ├── ntv │ │ │ ├── UnixServerSocket.java │ │ │ ├── UnixSocket.java │ │ │ ├── UnixSocketException.java │ │ │ └── UnixSocketNative.java │ │ │ └── tracing │ │ │ └── OCITracingContext.java │ └── resources │ │ └── META-INF │ │ └── native-image │ │ └── com.fnproject.fn │ │ └── runtime │ │ └── jni-config.json │ └── test │ └── java │ ├── com │ └── fnproject │ │ └── fn │ │ └── runtime │ │ ├── ConfigurationMethodsTest.java │ │ ├── DataBindingTest.java │ │ ├── EndToEndInvokeTest.java │ │ ├── ErrorMessagesTest.java │ │ ├── FnTestHarness.java │ │ ├── FunctionConstructionTest.java │ │ ├── HTTPStreamCodecTest.java │ │ ├── HeaderBuilder.java │ │ ├── JacksonCoercionTest.java │ │ ├── MethodWrapperTests.java │ │ ├── QueryParametersParserTest.java │ │ ├── httpgateway │ │ └── FunctionHTTPGatewayContextTest.java │ │ ├── ntv │ │ ├── UnixSocketNativeTest.java │ │ └── UnixSocketTest.java │ │ ├── testfns │ │ ├── Animal.java │ │ ├── BadTestFnDuplicateMethods.java │ │ ├── CustomDataBindingFnInputOutput.java │ │ ├── CustomDataBindingFnWithAnnotation.java │ │ ├── CustomDataBindingFnWithAnnotationAndConfig.java │ │ ├── CustomDataBindingFnWithConfig.java │ │ ├── CustomDataBindingFnWithDudCoercion.java │ │ ├── CustomDataBindingFnWithMultipleCoercions.java │ │ ├── CustomDataBindingFnWithNoUserCoercions.java │ │ ├── CustomOutputDataBindingFnWithAnnotation.java │ │ ├── CustomOutputDataBindingFnWithConfig.java │ │ ├── CustomOutputDataBindingFnWithDudCoercion.java │ │ ├── CustomOutputDataBindingFnWithMultipleCoercions.java │ │ ├── CustomOutputDataBindingFnWithNoUserCoercions.java │ │ ├── ErrorMessages.java │ │ ├── TestFn.java │ │ ├── TestFnConstructors.java │ │ ├── TestFnWithConfigurationMethods.java │ │ └── coercions │ │ │ ├── DudCoercion.java │ │ │ ├── StringReversalCoercion.java │ │ │ └── StringUpperCaseCoercion.java │ │ └── tracing │ │ └── OCITracingContextTest.java │ └── not │ └── in │ └── com │ └── fnproject │ └── fn │ └── StacktraceFilteringTestFunctions.java ├── settings-deploy.xml ├── testing-core ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── fnproject │ └── fn │ └── testing │ ├── FnEventBuilder.java │ ├── FnHttpEventBuilder.java │ ├── FnResult.java │ ├── FnTestingClassLoader.java │ ├── FunctionError.java │ ├── HeaderWriter.java │ └── PlatformError.java ├── testing-junit4 ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── fnproject │ │ └── fn │ │ └── testing │ │ ├── FnEventBuilderJUnit4.java │ │ ├── FnTestingRule.java │ │ └── FnTestingRuleFeature.java │ └── test │ └── java │ └── com │ └── fnproject │ └── fn │ └── testing │ └── FnTestingRuleTest.java └── testing └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | .DS_Store 4 | */dependency-reduced-pom.xml 5 | target/ 6 | rpm-package/ 7 | *.log 8 | \#* 9 | .\#* 10 | logs/ 11 | /headrevtag.txt 12 | *.bak 13 | *.versionsBackup 14 | .gradle 15 | examples/gradle-build/build 16 | **/*.classpath 17 | **/*.project 18 | **/*.settings 19 | 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Fn Java FDK 2 | 3 | We welcome all contributions! 4 | 5 | ## How to contribute 6 | * Fork the repo. 7 | * Fix an issue. Or create an issue and fix it. 8 | * Create a pull request. Reference the issue that you are fixing. 9 | * Your branch will be built by our CI system. Make sure that this build passes. 10 | * Be ready to respond to comments and questions from the community. 11 | * Good job! Thanks for being awesome! 12 | 13 | ## Tips for a swift merge 14 | * Make sure your branch has no conflicts with master. Rebase often. 15 | * Ensure that you have updated any JavaDoc or user/technical docs in `/docs`. 16 | * Don't make breaking changes to the public APIs. 17 | * Write tests - especially for public APIs. 18 | * Make sure that changes to `api` are backwards compatible with `runtime` and vice-versa. 19 | 20 | ## Note for mac users 21 | #### If you run into build failures, try the steps below: 22 | * Install `cmake`, if you don't have it already by running `brew install cmake` 23 | * Go to `fdk-java/runtime/src/main/c` folder and run `./buildit.sh` 24 | 25 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Fn Project 2 | ============ 3 | 4 | Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | ========================================================================== 19 | Third Party Dependencies 20 | ========================================================================== 21 | 22 | This project includes or depends on code from third party projects. 23 | Attributions are contained in THIRD_PARTY_LICENSES.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CircleCI](https://circleci.com/gh/fnproject/fdk-java.svg?style=svg&circle-token=348bec5610c34421f6c436ab8f6a18e153cb1c01)](https://circleci.com/gh/fnproject/fdk-java) 2 | 3 | # Function Development Kit for Java (FDK for Java) 4 | 5 | The Function Development Kit for Java makes it easy to build and deploy Java functions to Fn with full support for Java 11+ as the default out of the box. 6 | 7 | Some of the FDK for Java features include: 8 | 9 | - Parsing input and writing output 10 | - Flexible data binding to Java objects 11 | - Function testing using JUnit rules 12 | - And more! 13 | 14 | ## Learn about the Fn Project 15 | 16 | New to Fn Project? If you want to learn more about using the Fn Project to power your next project, start with the [official documentation](https://github.com/fnproject/docs). 17 | 18 | ## Using the Function Development Kit for Java 19 | 20 | For detailed instructions on using the FDK to build and deploy Java functions to Fn, please see the official FDK developer guide in our docs repo here: https://github.com/fnproject/docs/blob/master/fdks/fdk-java/README.md. 21 | 22 | ## Contributing to the Function Development Kit for Java 23 | 24 | Please see [CONTRIBUTING.md](CONTRIBUTING.md). 25 | 26 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/FnFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.lang.annotation.*; 20 | 21 | /** 22 | * Annotation to be used in user function classes to enable runtime-wide feature. 23 | * 24 | * Runtime features are initialized at the point that the function class is loaded but prior to the call chain. 25 | */ 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target(ElementType.TYPE) 28 | @Repeatable(FnFeatures.class) 29 | public @interface FnFeature { 30 | /** 31 | * The feature class to load this must have a zero-arg public constructor 32 | * @return feature class 33 | */ 34 | Class value(); 35 | } 36 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/FnFeatures.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Annotation to be used in user function classes to enable runtime-wide feature. 26 | * 27 | * Runtime features are initialized at the point that the function class is loaded but prior to the call chain. 28 | */ 29 | @Retention(RetentionPolicy.RUNTIME) 30 | @Target(ElementType.TYPE) 31 | public @interface FnFeatures { 32 | FnFeature[] value(); 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/FunctionInvoker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.util.Optional; 20 | 21 | /** 22 | * Handles the invocation of a given function call 23 | */ 24 | public interface FunctionInvoker { 25 | /** 26 | * Phase determines a loose ordering for invocation handler processing 27 | * this should be used with {@link RuntimeContext#addInvoker(FunctionInvoker, Phase)} to add new invoke handlers to a runtime 28 | */ 29 | enum Phase { 30 | /** 31 | * The Pre-Call phase runs before the main function call, all {@link FunctionInvoker} handlers added at this phase are tried prior to calling the {@link Phase#Call} phase 32 | * This phase is typically used for handlers that /may/ intercept the request based on request attributes 33 | */ 34 | PreCall, 35 | /** 36 | * The Call Phase indicates invokers that should handle call values - typically a given runtime will only be handled by one of these 37 | */ 38 | Call 39 | } 40 | 41 | /** 42 | * Optionally handles an invocation chain for this function 43 | *

44 | * If the invoker returns an empty option then no action has been taken and another invoker may attempt to tryInvoke 45 | *

46 | * In particular this means that implementations must not read the input event body until they are committed to handling this event. 47 | * 48 | * A RuntimeException thrown by the implementation will cause the entire function invocation to fail. 49 | * 50 | * @param ctx the context for a single invocation 51 | * @param evt the incoming event 52 | * @return a optional output event if the invoker handled the event. 53 | */ 54 | Optional tryInvoke(InvocationContext ctx, InputEvent evt); 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/InputBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Annotation to be used on a parameter of the user function. 26 | * 27 | * The annotation must have a 'coercion' argument which specifies the 28 | * {@link InputCoercion} class to use to perform the input binding. 29 | */ 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.PARAMETER) 32 | public @interface InputBinding { 33 | /** 34 | * Which coercion class to use for processing an InputEvent into 35 | * the type required by the function parameter. 36 | * 37 | * @return the{@link InputCoercion} class used to perform the input binding 38 | */ 39 | Class coercion(); 40 | } 41 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/InputCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.util.Optional; 20 | 21 | /** 22 | * Handles the coercion of an input event to a parameter 23 | */ 24 | public interface InputCoercion { 25 | /** 26 | * Handle coercion for a function parameter 27 | *

28 | * Coercions may choose to act on a parameter, in which case they should return a fulfilled option) or may 29 | * ignore parameters (allowing other coercions to act on the parameter) 30 | *

31 | * When a coercion ignores a parameter it must not consume the input stream of the event. 32 | *

33 | * If a coercion throws a RuntimeException, no further coercions will be tried and the function invocation will fail. 34 | * 35 | * @param currentContext the invocation context for this event - this links to the {@link RuntimeContext} and method and class 36 | * @param arg the parameter index for the argument being extracted 37 | * @param input the input event 38 | * @param methodWrapper the method which the parameter is for 39 | * @return the result of the coercion, if it succeeded 40 | */ 41 | Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper methodWrapper); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/InputEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.io.Closeable; 20 | import java.io.InputStream; 21 | import java.time.Instant; 22 | import java.util.function.Function; 23 | 24 | public interface InputEvent extends Closeable { 25 | 26 | /** 27 | * Consume the body associated with this event 28 | *

29 | * This may only be done once per request. 30 | * 31 | * @param dest a function to send the body to - this does not need to close the incoming stream 32 | * @param An optional return type 33 | * @return the new 34 | */ 35 | T consumeBody(Function dest); 36 | 37 | 38 | 39 | /** 40 | * return the current call ID for this event 41 | * @return a call ID 42 | */ 43 | String getCallID(); 44 | 45 | 46 | /** 47 | * The deadline by which this event should be processed - this is information and is intended to help you determine how long you should spend processing your event - if you exceed this deadline Fn will terminate your container. 48 | * 49 | * @return a deadline relative to the current system clock that the event must be processed by 50 | */ 51 | Instant getDeadline(); 52 | 53 | 54 | /** 55 | * The HTTP headers on the request 56 | * 57 | * @return an immutable map of headers 58 | */ 59 | Headers getHeaders(); 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/InvocationListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.util.EventListener; 20 | 21 | /** 22 | * Listener that will be notified in the event that a function invocation executes successfully or fails. 23 | * error. Instances of InvocationListener should be registered with {@link InvocationContext}. 24 | */ 25 | public interface InvocationListener extends EventListener { 26 | 27 | /** 28 | * Notifies this InvocationListener that a function invocation has executed successfully. 29 | */ 30 | void onSuccess(); 31 | 32 | /** 33 | * Notifies this InvocationListener that a function invocation has failed during its execution. 34 | */ 35 | void onFailure(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/OutputBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Annotation to be used on the method of the user function. 26 | *

27 | * The annotation must have a 'coercion' argument which specifies the 28 | * {@link OutputCoercion} class to use to perform the output binding. 29 | */ 30 | @Retention(RetentionPolicy.RUNTIME) 31 | @Target(ElementType.METHOD) 32 | public @interface OutputBinding { 33 | /** 34 | * @return Which coercion class to use for processing the return type of the user function into an OutputEvent. 35 | */ 36 | Class coercion(); 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/OutputCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.util.Optional; 20 | 21 | 22 | /** 23 | * Handles the coercion of a function's return value to an {@link OutputEvent} 24 | */ 25 | public interface OutputCoercion { 26 | 27 | /** 28 | * Handle coercion for a function parameter 29 | *

30 | * Coercions may choose to act on a parameter, in which case they should return a fulfilled option) or may 31 | * ignore parameters (allowing other coercions to act on the parameter) 32 | *

33 | * When a coercion ignores a parameter it must not consume the input stream of the event. 34 | *

35 | * If a coercion throws a RuntimeException, no further coercions will be tried and the function invocation will fail. 36 | * 37 | * @param currentContext the invocation context for this event - this links to the {@link RuntimeContext} and method and class 38 | * @param method the method which was invoked 39 | * @param value The object which the method returned 40 | * @return the result of the coercion, if it succeeded 41 | */ 42 | Optional wrapFunctionResult(InvocationContext currentContext, MethodWrapper method, Object value); 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/QueryParameters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | import java.util.Optional; 22 | 23 | /** 24 | * Wrapper for query parameters map parsed from the URL of a function invocation. 25 | */ 26 | public interface QueryParameters { 27 | /** 28 | * Find the first entry for {@code key} if it exists otherwise returns {@code Optional.empty} 29 | * 30 | * @param key the header entry key (e.g. {@code Accept} in {@code Accept: text/html} 31 | * @return the first entry for {@code key} if it was present in the URL otherwise {@code Optional.empty}. 32 | * @throws NullPointerException if {@code key} is null. 33 | */ 34 | Optional get(String key); 35 | 36 | /** 37 | * Find the list of entries for a specific key. Returns {@code Optional.empty}. Useful when multiple values are 38 | * passed. e.g. this method returns {@code ["val1", "val2", "val3]} for the key {@code param} in the URL 39 | * {@code http://example.com?param=val1&param=val2&param=val3} 40 | * 41 | * @param key the header entry key (e.g. {@code Accept} in {@code Accept: text/html} 42 | * @return the list of entries for the key if present otherwise the empty list 43 | * if not present. If the key was present without a value, it returns 44 | * a list with a single element, the empty string. 45 | * @throws NullPointerException if {@code key} is null. 46 | */ 47 | List getValues(String key); 48 | 49 | /** 50 | * @return a copy of the underlying map storing all query parameters 51 | */ 52 | Map> getAll(); 53 | } 54 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/RuntimeFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | /** 20 | * RuntimeFeatures are classes that configure the Fn Runtime prior to startup and can be loaded by annotating the function class with a {@link FnFeature} annotation 21 | * Created on 10/09/2018. 22 | *

23 | * (c) 2018 Oracle Corporation 24 | */ 25 | public interface RuntimeFeature { 26 | 27 | /** 28 | * Initialize the runtime context for this function 29 | * 30 | * @param context a runtime context to initalize 31 | */ 32 | void initialize(RuntimeContext context); 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/TypeWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | /** 20 | * Interface representing type information about a possibly-generic type. 21 | */ 22 | public interface TypeWrapper { 23 | 24 | /** 25 | * Unlike {@link java.lang.reflect.Method}, types (such as parameter types, or return types) are 26 | * resolved to a reified type even if they are generic, providing reification is possible. 27 | * 28 | * For example, take the following classes: 29 | *

{@code
30 |      * class GenericParent {
31 |      *   public void someMethod(T t) { // do something with t }
32 |      * }
33 |      *
34 |      * class ConcreteClass extends GenericParent { }
35 |      * }
36 | * 37 | * A {@link TypeWrapper} representing the first argument of {@code someMethod} would return {@code String.class} 38 | * instead of {@code Object.class} 39 | * 40 | * @return Reified type 41 | */ 42 | Class getParameterClass(); 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/exception/FunctionConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.exception; 18 | 19 | /** 20 | * The function class's configuration methods could not be invoked. 21 | */ 22 | public class FunctionConfigurationException extends FunctionLoadException { 23 | 24 | public FunctionConfigurationException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | public FunctionConfigurationException(String message) { 29 | super(message); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/exception/FunctionInputHandlingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.exception; 18 | 19 | /** 20 | * This used to wrap any exception thrown by an {@link com.fnproject.fn.api.InputCoercion}. It is 21 | * also thrown if no {@link com.fnproject.fn.api.InputCoercion} is applicable to a parameter of the user function. 22 | * 23 | * This indicates that the input was not appropriate to this function. 24 | */ 25 | public class FunctionInputHandlingException extends RuntimeException { 26 | public FunctionInputHandlingException(String s, Throwable t) { 27 | super(s,t); 28 | } 29 | 30 | public FunctionInputHandlingException(String s) { 31 | super(s); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/exception/FunctionLoadException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.exception; 18 | 19 | /** 20 | * an exception relating to loading the users code into runtime 21 | * see children for specific cases 22 | */ 23 | public abstract class FunctionLoadException extends RuntimeException { 24 | 25 | public FunctionLoadException(String message, Throwable cause) { 26 | super(message, cause); 27 | } 28 | 29 | public FunctionLoadException(String msg) { 30 | super(msg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /api/src/main/java/com/fnproject/fn/api/exception/FunctionOutputHandlingException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.exception; 18 | 19 | /** 20 | * This used to wrap any exception thrown by an {@link com.fnproject.fn.api.OutputCoercion}. It is 21 | * also thrown if no {@link com.fnproject.fn.api.OutputCoercion} is applicable to the object returned by the function. 22 | */ 23 | public class FunctionOutputHandlingException extends RuntimeException { 24 | public FunctionOutputHandlingException(String s, Exception e) { 25 | super(s,e); 26 | } 27 | 28 | public FunctionOutputHandlingException(String s) { 29 | super(s); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /api/src/test/java/com/fnproject/fn/api/HeadersTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | /** 24 | * Created on 10/09/2018. 25 | *

26 | * (c) 2018 Oracle Corporation 27 | */ 28 | public class HeadersTest { 29 | 30 | @Test 31 | public void shouldCanonicalizeHeaders(){ 32 | for (String[] v : new String[][] { 33 | {"",""}, 34 | {"a","A"}, 35 | {"fn-ID-","Fn-Id-"}, 36 | {"myHeader-VaLue","Myheader-Value"}, 37 | {" Not a Header "," Not a Header "}, 38 | {"-","-"}, 39 | {"--","--"}, 40 | {"a-","A-"}, 41 | {"-a","-A"} 42 | }){ 43 | assertThat(Headers.canonicalKey(v[0])).isEqualTo(v[1]); 44 | } 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /bin/scripts/migration/flag: -------------------------------------------------------------------------------- 1 | 0 0 -------------------------------------------------------------------------------- /build_in_docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | docker run --rm --name compile -v "$(pwd)":/usr/src/mymaven -w /usr/src/mymaven svenruppert/maven-3.5-jdk-08 mvn clean install 19 | -------------------------------------------------------------------------------- /docs/HTTPGatewayFunctions.md: -------------------------------------------------------------------------------- 1 | # Accessing HTTP Information From Functions 2 | 3 | Functions can be used to handle events, RPC calls or HTTP requests. When you are writing a function that handles an HTTP request you frequently need access to the HTTP headers of the incoming request or need to set HTTP headers or the status code on the outbound respsonse. 4 | 5 | 6 | In Fn for Java, when your function is being served by an HTTP trigger (or another compatible HTTP gateway) you can get access to both the incoming request headers for your function by adding a 'com.fnproject.fn.api.httpgateway.HTTPGatewayContext' parameter to your function's parameters. 7 | 8 | 9 | Using this allows you to : 10 | 11 | * Read incoming headers 12 | * Access the method and request URL for the trigger 13 | * Write outbound headers to the response 14 | * Set the status code of the response 15 | 16 | 17 | For example this function reads a request header the method and request URL, sets an response header and sets the response status code to perform an HTTP redirect. 18 | 19 | ```java 20 | package com.fnproject.fn.examples; 21 | import com.fnproject.fn.api.httpgateway.HTTPGatewayContext; 22 | 23 | 24 | public class RedirectFunction { 25 | 26 | public void redirect(HTTPGatewayContext hctx) { 27 | System.err.println("Request URL is:" + hctx.getRequestURL()); 28 | System.err.println("Trace ID" + hctx.getHeaders().get("My-Trace-ID").orElse("N/A")); 29 | 30 | hctx.setResponseHeader("Location","http://example.com"); 31 | hctx.setStatusCode(302); 32 | 33 | } 34 | } 35 | 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/SpringCloudFunctionSupport.md: -------------------------------------------------------------------------------- 1 | # Spring Cloud Functions with Fn 2 | 3 | [Spring cloud function](https://github.com/spring-cloud/spring-cloud-function) 4 | is a [Spring](https://spring.io/) project for building Java functions with the 5 | (optional) support of the spring framework. 6 | 7 | We support execution of Spring cloud functions through the 8 | `SpringCloudFunctionInvoker` which manages the discovery and invocation of your 9 | functions. 10 | 11 | ## Tutorial 12 | 13 | The minimal necessary function you must provide is: 14 | 15 | ```yaml 16 | cmd: com.example.fn.FunctionConfig::handleRequest 17 | ``` 18 | 19 | ```java 20 | package com.example.fn; 21 | 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.context.annotation.Import; 24 | 25 | 26 | @Configuration 27 | @Import(ContextFunctionCatalogAutoConfiguration.class) 28 | public class FunctionConfig { 29 | public static String consumedValue; 30 | public static String suppliedValue = "Hello"; 31 | 32 | @FnConfiguration 33 | public static void configure(RuntimeContext ctx) { 34 | ctx.setInvoker(new SpringCloudFunctionInvoker(FunctionConfig.class)); 35 | } 36 | 37 | 38 | // Blank entrypoint necessary to load the FunctionConfig class, this isn't invoked 39 | public void handleRequest() { } 40 | 41 | @Bean 42 | public Function upperCase(){ 43 | return String::toUpperCase; 44 | } 45 | } 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Fn Java FDK Example Projects 2 | 3 | In this directory you will find some example projects demonstrating different 4 | features of the Fn Java FDK: 5 | 6 | * Plain java code support (`string-reverse`) 7 | * Functional testing of your functions (`regex-query` and `qr-code`) 8 | * Built-in JSON coercion (`regex-query`) 9 | * [InputEvent and OutputEvent](/docs/DataBinding.md) handling (`qr-code`) 10 | 11 | ## (1) [String reverse](string-reverse/README.md) 12 | 13 | This function takes a string and returns the reverse of the string. 14 | The Fn Java FDK handles marshalling data into your 15 | functions without the function having any knowledge of the FDK API. 16 | 17 | ## (2) Regex query 18 | 19 | This function takes a JSON object containing a `text` field and a `regex` 20 | field and return a JSON object with a list of matches in the `matches` 21 | field. It demonstrates the builtin JSON support of the fn Java 22 | wrapper (provided through Jackson) and how the platform handles serialization 23 | of POJO return values. 24 | 25 | ## (3) QR Code gen 26 | 27 | This function parses the query parameters of a GET request (through the 28 | `InputEvent` passed into the function) to generate a QR code. It demonstrates 29 | the `InputEvent` and `OutputEvent` interfaces which provide low level 30 | access to data entering the `fn` Java FDK. 31 | 32 | ## (4) Asynchronous thumbnails generation 33 | 34 | This example showcases the Fn Flow asynchronous execution API, by 35 | creating a workflow that takes an image and asynchronously generates three 36 | thumbnails for it, then uploads them to an object storage. 37 | 38 | ## (5) Gradle build 39 | This shows how to use Gradle to build functions using the Java FDK. 40 | -------------------------------------------------------------------------------- /examples/async-thumbnails/.gitignore: -------------------------------------------------------------------------------- 1 | storage-upload 2 | -------------------------------------------------------------------------------- /examples/async-thumbnails/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | schema_version: 20180708 18 | name: async-thumbnails 19 | version: 0.0.8 20 | runtime: java 21 | cmd: com.fnproject.fn.examples.ThumbnailsFunction::handleRequest 22 | format: http-stream 23 | timeout: 120 24 | triggers: 25 | - name: async-thumbnails 26 | type: http 27 | source: /async-thumbnails 28 | -------------------------------------------------------------------------------- /examples/async-thumbnails/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -e 19 | 20 | fn --verbose deploy --app myapp --local 21 | 22 | 23 | echo "Calling function" 24 | curl -v -X POST --data-binary @test-image.png -H "Content-type: application/octet-stream" "http://localhost:8080/t/myapp/async-thumbnails" 25 | 26 | echo "Contents of bucket" 27 | mc ls -r example-storage-server 28 | echo "Sleeping for 5 seconds to allow flows to complete" 29 | sleep 5 30 | echo "Contents of bucket" 31 | mc ls -r example-storage-server 32 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize128/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM debian 18 | RUN apt-get update 19 | RUN apt-get install -y imagemagick 20 | ENTRYPOINT ["convert", "-", "-resize", "128x128", "-"] 21 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize128/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | schema_version: 20180708 18 | name: resize128 19 | version: 0.0.5 20 | entrypoint: convert - -resize 128x128 - 21 | format: default 22 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize256/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM debian 18 | RUN apt-get update 19 | RUN apt-get install -y imagemagick 20 | ENTRYPOINT ["convert", "-", "-resize", "256x256", "-"] 21 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize256/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | schema_version: 20180708 18 | name: resize256 19 | version: 0.0.5 20 | entrypoint: convert - -resize 256x256 - 21 | format: default 22 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize512/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM debian 18 | RUN apt-get update 19 | RUN apt-get install -y imagemagick 20 | ENTRYPOINT ["convert", "-", "-resize", "512x512", "-"] 21 | -------------------------------------------------------------------------------- /examples/async-thumbnails/setup/resize512/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | schema_version: 20180708 18 | name: resize512 19 | version: 0.0.8 20 | entrypoint: convert - -resize 512x512 - 21 | format: default 22 | -------------------------------------------------------------------------------- /examples/async-thumbnails/test-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnproject/fdk-java/16b41eb74002f443672de3b9c3a9445fe730bf58/examples/async-thumbnails/test-image.png -------------------------------------------------------------------------------- /examples/gradle-build/.dockerignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | .git 4 | build -------------------------------------------------------------------------------- /examples/gradle-build/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM gradle:4.5.1-jdk8 as build-stage 18 | WORKDIR /function 19 | # needed for gradle? 20 | USER root 21 | ENV GRADLE_USER_HOME /function/.gradle 22 | 23 | # Code build 24 | # Copy any build files into the build container and build 25 | COPY *.gradle /function/ 26 | RUN ["gradle", "-s", "--no-daemon","--console","plain","cacheDeps"] 27 | 28 | # Copies build source into build container 29 | COPY src /function/src 30 | 31 | RUN ["gradle", "-s", "--no-daemon","--console","plain","build"] 32 | # Container build 33 | FROM fnproject/fn-java-fdk:1.0.56 34 | WORKDIR /function 35 | COPY --from=build-stage /function/build/libs/*.jar /function/build/deps/*.jar /function/app/ 36 | CMD ["com.example.fn.HelloFunction::handleRequest"] 37 | -------------------------------------------------------------------------------- /examples/gradle-build/README.md: -------------------------------------------------------------------------------- 1 | # Fn Gradle + Java fdk example 2 | 3 | Fn uses Maven by default for builds. This is an example that uses Fn's `docker` runtime format to build a Java function using the [Fn Java FDK](https://github.com/fnproject/fdk-java). 4 | 5 | The example consists of a `Dockerfile` that builds the function using gradle and copies the function's dependencies to `build/deps` and a func.yaml that uses that `Dockerfile` to build the function. 6 | 7 | Note that fdk.versions are hard-coded in this example, you may need to update them manually to more recent version. 8 | 9 | Key points: 10 | 11 | * [Dockerfile](Dockerfile) - contains the containerised docker build (based on dockerhub library/gradle images) and image build - this includes the gradle invocation 12 | * The `cacheDeps` task in `build.gradle` is invoked within the Dockerfile - The task pulls down dependencies into the container gradle cache to speed up docker builds. 13 | * The `copyDeps` task in `build.gradle` copies the functions compile deps 14 | * This uses JDK 8 by default - you can change this to Java 11 by changing : `FROM gradle:4.5.1-jdk8 as build-stage` to `FROM gradle:4.5.1-jre11 as build-stage` and `FROM fnproject/fn-java-fdk:1.0.85` to `FROM fnproject/fn-java-fdk:jre11-1.0.85` -------------------------------------------------------------------------------- /examples/gradle-build/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'java' 18 | 19 | ext { 20 | fdkVersion = '1.0.56' 21 | } 22 | 23 | repositories { 24 | mavenCentral() 25 | maven { 26 | url 'https://dl.bintray.com/fnproject/fnproject' 27 | } 28 | } 29 | 30 | dependencies { 31 | runtime "com.fnproject.fn:api:$fdkVersion" 32 | // runtime "com.fnproject.fn:runtime:$fdkVersion" // this is optional and included with its deps in the base image to reduce layer size 33 | 34 | testCompile "junit:junit:4.12" 35 | testCompile "com.fnproject.fn:testing:$fdkVersion" 36 | } 37 | 38 | task cacheDeps(type: Exec) { 39 | configurations.testRuntime.files 40 | commandLine 'echo', 'Downloaded all dependencies' 41 | } 42 | 43 | task copyDeps(type: Copy) { 44 | from configurations.compile 45 | into "${project.buildDir}/deps" 46 | } 47 | 48 | build.dependsOn copyDeps 49 | -------------------------------------------------------------------------------- /examples/gradle-build/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | name: gradle_build 18 | version: 0.0.3 19 | runtime: docker 20 | format: http 21 | -------------------------------------------------------------------------------- /examples/gradle-build/src/main/java/com/example/fn/HelloFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.fn; 18 | 19 | public class HelloFunction { 20 | 21 | public String handleRequest(String input) { 22 | String name = (input == null || input.isEmpty()) ? "world" : input; 23 | return "Hello, " + name + "!"; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /examples/gradle-build/src/test/java/com/example/fn/HelloFunctionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.fn; 18 | 19 | import static org.junit.Assert.*; 20 | 21 | public class HelloFunctionTest { 22 | 23 | @Rule 24 | public final FnTestingRule testing = FnTestingRule.createDefault(); 25 | 26 | @Test 27 | public void shouldReturnGreeting() { 28 | testing.givenEvent().enqueue(); 29 | testing.thenRun(HelloFunction.class, "handleRequest"); 30 | 31 | FnResult result = testing.getOnlyResult(); 32 | assertEquals("Hello, world!", result.getBodyAsString()); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 23 | 4.0.0 24 | pom 25 | fdk-examples 26 | com.fnproject.fn.examples 27 | 28 | 29 | fdk 30 | com.fnproject.fn 31 | 1.0.0-SNAPSHOT 32 | 33 | 34 | 35 | string-reverse 36 | regex-query 37 | 40 | async-thumbnails 41 | 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-deploy-plugin 48 | 49 | true 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/qr-code/.gitignore: -------------------------------------------------------------------------------- 1 | /data/ 2 | -------------------------------------------------------------------------------- /examples/qr-code/example.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/qr-code/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | name: fn-example/qr-code-gen 18 | version: 0.0.1 19 | runtime: java 20 | cmd: com.fnproject.fn.examples.QRGen::create 21 | format: http 22 | timeout: 30 23 | path: /qr 24 | -------------------------------------------------------------------------------- /examples/qr-code/src/test/resources/qr-code-number-0-12345-67890.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnproject/fdk-java/16b41eb74002f443672de3b9c3a9445fe730bf58/examples/qr-code/src/test/resources/qr-code-number-0-12345-67890.png -------------------------------------------------------------------------------- /examples/qr-code/src/test/resources/qr-code-text-hello-world.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnproject/fdk-java/16b41eb74002f443672de3b9c3a9445fe730bf58/examples/qr-code/src/test/resources/qr-code-text-hello-world.jpg -------------------------------------------------------------------------------- /examples/qr-code/src/test/resources/qr-code-text-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnproject/fdk-java/16b41eb74002f443672de3b9c3a9445fe730bf58/examples/qr-code/src/test/resources/qr-code-text-hello-world.png -------------------------------------------------------------------------------- /examples/regex-query/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | name: fn-example/regex-query 18 | version: 0.0.1 19 | runtime: java 20 | timeout: 30 21 | format: http 22 | cmd: com.fnproject.fn.examples.RegexQuery::query 23 | path: /query 24 | -------------------------------------------------------------------------------- /examples/regex-query/src/main/java/com/fnproject/fn/examples/Match.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.examples; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class Match { 23 | public final int start; 24 | public final int end; 25 | public final String match; 26 | 27 | @JsonCreator 28 | public Match(@JsonProperty("start") int start, @JsonProperty("end") int end, @JsonProperty("match") String match) { 29 | this.start = start; 30 | this.end = end; 31 | this.match = match; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/regex-query/src/main/java/com/fnproject/fn/examples/Query.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.examples; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class Query { 23 | public final String regex; 24 | public final String text; 25 | 26 | @JsonCreator 27 | public Query(@JsonProperty("regex") String regex, @JsonProperty("text") String text) { 28 | this.regex = regex; 29 | this.text = text; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/regex-query/src/main/java/com/fnproject/fn/examples/RegexQuery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.examples; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.regex.Matcher; 22 | import java.util.regex.Pattern; 23 | 24 | public class RegexQuery { 25 | public Response query(Query query) { 26 | return new Response(query.regex, query.text, getMatches(query)); 27 | } 28 | 29 | private List getMatches(Query query) { 30 | Pattern pattern = Pattern.compile(query.regex); 31 | Matcher matcher = pattern.matcher(query.text); 32 | List matches = new ArrayList<>(); 33 | while (matcher.find()) { 34 | matches.add(new Match(matcher.start(), matcher.end(), query.text.substring(matcher.start(), matcher.end()))); 35 | } 36 | return matches; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/regex-query/src/main/java/com/fnproject/fn/examples/Response.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.examples; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | import java.util.List; 23 | 24 | public class Response { 25 | public final String regex; 26 | public final String text; 27 | public final List matches; 28 | 29 | @JsonCreator 30 | public Response(@JsonProperty("regex") String regex, @JsonProperty("text") String text, @JsonProperty("matches") List matches) { 31 | this.regex = regex; 32 | this.text = text; 33 | this.matches = matches; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/string-reverse/README.md: -------------------------------------------------------------------------------- 1 | # Example Java Function: String Reverse 2 | 3 | This example provides an HTTP trigger endpoint for reversing strings. 4 | 5 | ```bash 6 | $ curl -d "Hello World" http://localhost:8080/t/string-reverse-app/string-reverse 7 | dlroW olleH 8 | ``` 9 | 10 | 11 | ## Demonstrated FDK features 12 | 13 | This example uses **none** of the Fn Java FDK features, in fact it doesn't have 14 | any dependency on the Fn Java FDK. It is just plain old Java code. 15 | 16 | ## Step by step 17 | 18 | Ensure you have the Fn server running to host your 19 | function and provide the HTTP endpoint that invokes it: 20 | 21 | (1) Start the server 22 | 23 | ```sh 24 | $ fn start 25 | ``` 26 | 27 | (2) Create an app for the function 28 | 29 | ```sh 30 | $ fn create app string-reverse-app 31 | ``` 32 | 33 | (3) Deploy the function to your app from the `string-reverse` directory. 34 | 35 | ```sh 36 | fn deploy --app string-reverse-app --local 37 | ``` 38 | 39 | (4) Invoke the function and reverse the string. 40 | 41 | ```sh 42 | echo "Hello World" | fn invoke string-reverse-app string-reverse 43 | dlroW olleH 44 | ``` 45 | 46 | (5) Invoke the function using curl and a trigger to reverse a string. 47 | 48 | ```bash 49 | $ curl -d "Hello World" http://localhost:8080/t/string-reverse-app/string-reverse 50 | dlroW olleH 51 | ``` 52 | 53 | 54 | ## Code walkthrough 55 | 56 | The entrypoint to the function is specified in `func.yaml` in the `cmd` key. 57 | It is set this to `com.example.fn.StringReverse::reverse`. The whole class 58 | `StringReverse` is shown below: 59 | 60 | 61 | ```java 62 | package com.example.fn; 63 | 64 | public class StringReverse { 65 | public String reverse(String str) { 66 | return new StringBuilder(str).reverse().toString(); 67 | } 68 | } 69 | ``` 70 | 71 | As you can see, this is plain java with no references to the Fn API. The 72 | Fn Java FDK handles the marshalling of the HTTP body into the `str` 73 | parameter as well as the marshalling of the returned reversed string into the HTTP 74 | response body (see [Data Binding](/docs/DataBinding.md) for more 75 | information on how marshalling is performed). 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/string-reverse/func.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | schema_version: 20180708 18 | name: string-reverse 19 | version: 0.0.2 20 | runtime: java 21 | build_image: fnproject/fn-java-fdk-build:jdk11-1.0.87 22 | run_image: fnproject/fn-java-fdk:jre11-1.0.87 23 | cmd: com.example.fn.StringReverse::reverse 24 | triggers: 25 | - name: string-reverse 26 | type: http 27 | source: /string-reverse 28 | -------------------------------------------------------------------------------- /examples/string-reverse/src/main/java/com/example/fn/StringReverse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.fn; 18 | 19 | public class StringReverse { 20 | public String reverse(String str) { 21 | return new StringBuilder(str).reverse().toString(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/string-reverse/src/test/java/com/example/fn/testing/StringReverseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.fn.testing; 18 | 19 | import com.example.fn.StringReverse; 20 | import org.junit.Test; 21 | 22 | import static junit.framework.TestCase.assertEquals; 23 | 24 | public class StringReverseTest { 25 | private StringReverse stringReverse = new StringReverse(); 26 | 27 | @Test 28 | public void reverseEmptyString() { 29 | assertEquals("", reverse("")); 30 | } 31 | 32 | @Test 33 | public void reverseOfSingleCharacter() { 34 | assertEquals("a", reverse("a")); 35 | } 36 | 37 | @Test 38 | public void reverseHelloIsOlleh() { 39 | assertEquals("olleh", reverse("hello")); 40 | } 41 | 42 | private String reverse(String str) { 43 | return stringReverse.reverse(str); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /experimental-native-image-support/README.md: -------------------------------------------------------------------------------- 1 | # Experimental support tools for functions native images 2 | 3 | This is an optional module that can be added to native-image builds that resolves some common issues related to 4 | native-image handling in oracle functions. 5 | 6 | This library is _experimental_ - it may change in behaviour and may not work in many cases. 7 | 8 | Currently, this contains graal native-image configuration files which enable common use cases for : 9 | 10 | * Oracle Cloud Infrastructure java client support in native images 11 | * Graal native reflection config for general Jersey client support (specifically tested for the OCI client use case, may work in other cases) 12 | * Graal native reflection config for BouncyCastle crypto in native images 13 | 14 | It also includes : 15 | 16 | * A dynamic graal-native feature which automatically adds classes referenced in Jackson-databind annotations - this removes the need to have to manually add model classes that are referenced via Jackson annotations like `@JsonSubTypes.Type` `@JsonDeserlize` etc. 17 | 18 | # Enabling the feature in a native build: 19 | 20 | Generate a native build function (replace 1.0.121 with the appropriate fdk-java version): 21 | 22 | ``` 23 | fn init --init-image fnproject/fn-java-native-init:jdk11-1.0.121 graalfn 24 | ``` 25 | 26 | Edit your pom file and add this library as a dependency: 27 | 28 | ```xml 29 | 30 | com.fnproject.fn 31 | experimental-native-image-support 32 | ${fdk.version} 33 | runtime 34 | 35 | ``` 36 | 37 | Edit the generated `Dockerfile` and add the following to enable the feature: 38 | 39 | ``` 40 | --features=com.fnproject.fn.nativeimagesupport.JacksonFeature \ 41 | ``` 42 | You may also need to add the following flags if they are not already set: 43 | ``` 44 | --allow-incomplete-classpath \ 45 | --enable-all-security-services \ 46 | --enable-url-protocols=https \ 47 | --report-unsupported-elements-at-runtime \ 48 | ``` 49 | 50 | You may see "WARNING:..." messages during the build, these are expected and should not cause issues. 51 | -------------------------------------------------------------------------------- /experimental-native-image-support/src/main/resources/META-INF/native-image/com.fnproject.fn/nativeimagesupport/jersey-support/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | {"pattern":"\\QMETA-INF/services/.*\\E"} 5 | ]} 6 | } 7 | -------------------------------------------------------------------------------- /experimental-native-image-support/src/main/resources/META-INF/native-image/com.fnproject.fn/nativeimagesupport/oci-client-support/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | {"pattern":"\\Qcom/oracle/bmc/sdk.properties\\E"} 5 | ]} 6 | } 7 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/FlowCompletionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | 20 | /** 21 | * Exception thrown when a blocking operation on a flow fails - this corresponds to a 22 | * {@link java.util.concurrent.CompletionException} in {@link java.util.concurrent.CompletableFuture} calls 23 | */ 24 | public class FlowCompletionException extends RuntimeException { 25 | 26 | /** 27 | * If an exception was raised from within a stage, this will be the wrapped cause. 28 | * @param t The user exception 29 | */ 30 | public FlowCompletionException(Throwable t) { 31 | super(t); 32 | } 33 | 34 | public FlowCompletionException(String message) { 35 | super(message); 36 | } 37 | 38 | public FlowCompletionException(String message, Throwable t) { 39 | super(message, t); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/FunctionInvocationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when an external function invocation returns a failure. 21 | * 22 | * This includes when the function returns a result but has a non-successful HTTP error status 23 | * 24 | */ 25 | public class FunctionInvocationException extends RuntimeException { 26 | private final HttpResponse functionResponse; 27 | 28 | public FunctionInvocationException(HttpResponse functionResponse) { 29 | super(new String(functionResponse.getBodyAsBytes())); 30 | this.functionResponse = functionResponse; 31 | } 32 | 33 | /** 34 | * The HTTP details returned from the function invocation 35 | * @return an http response from the an external function 36 | */ 37 | public HttpResponse getFunctionResponse() { 38 | return functionResponse; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/FunctionInvokeFailedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a function call failed within the fn platform - the function may or may not have been invoked and 21 | * that invocation may or may not have completed. 22 | */ 23 | public class FunctionInvokeFailedException extends PlatformException { 24 | public FunctionInvokeFailedException(String reason) { super(reason); } 25 | } 26 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/FunctionTimeoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a function execution exceeds its configured timeout. 21 | * 22 | * When this exception is raised the fn server has terminated the container hosting the function. 23 | */ 24 | public class FunctionTimeoutException extends PlatformException { 25 | public FunctionTimeoutException(String reason) { super(reason); } 26 | } 27 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Enum representing the different HTTP types that can be used to invoke an external function 21 | * 22 | * @see Flow#invokeFunction 23 | */ 24 | public enum HttpMethod { 25 | GET("GET"), 26 | HEAD("HEAD"), 27 | POST("POST"), 28 | PUT("PUT"), 29 | DELETE("DELETE"), 30 | OPTIONS("OPTIONS"), 31 | PATCH("PATCH"); 32 | 33 | private final String verb; 34 | 35 | HttpMethod(String verb) { 36 | this.verb = verb; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return this.verb; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/HttpRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | import com.fnproject.fn.api.Headers; 20 | 21 | /** 22 | * An abstract HTTP request details (without location) 23 | */ 24 | public interface HttpRequest { 25 | /** 26 | * Return the HTTP method used to supply this value 27 | * 28 | * @return the HTTP method 29 | */ 30 | HttpMethod getMethod(); 31 | 32 | /** 33 | * Return the headers on the HTTP request 34 | * 35 | * @return the headers 36 | */ 37 | Headers getHeaders(); 38 | 39 | /** 40 | * Returns the body of the request as a byte array 41 | * 42 | * @return the function request body 43 | */ 44 | byte[] getBodyAsBytes(); 45 | } 46 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/HttpResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | import com.fnproject.fn.api.Headers; 20 | 21 | /** 22 | * A FunctionResponse represents the HTTP response from an external function invocation 23 | * (e.g. execute by {@code rt.invokeFunction(id, data)} 24 | */ 25 | public interface HttpResponse { 26 | /** 27 | * Return the HTTP status code of the function response 28 | * 29 | * @return the HTTP status code 30 | */ 31 | int getStatusCode(); 32 | 33 | /** 34 | * Return the headers on the HTTP function response 35 | * 36 | * @return the headers 37 | */ 38 | Headers getHeaders(); 39 | 40 | /** 41 | * Returns the body of the function result as a byte array 42 | * 43 | * @return the function response body 44 | */ 45 | byte[] getBodyAsBytes(); 46 | } 47 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/InvalidStageResponseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a completion stage responds with an incompatible datum type for its corresponding completion 21 | * graph stage. 22 | */ 23 | public class InvalidStageResponseException extends PlatformException { 24 | public InvalidStageResponseException(String reason) { super(reason); } 25 | } 26 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/LambdaSerializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a lambda or any referenced objects fail to be serialized. 21 | * The cause will typically be a {@link java.io.NotSerializableException} or other {@link java.io.IOException} detailing what could not be serialized 22 | */ 23 | public class LambdaSerializationException extends FlowCompletionException { 24 | public LambdaSerializationException(String message) { 25 | super(message); 26 | } 27 | 28 | public LambdaSerializationException(String message, Exception e) { 29 | super(message, e); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/PlatformException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when the completion facility fails to operate on a completion graph 21 | */ 22 | public class PlatformException extends FlowCompletionException { 23 | public PlatformException(Throwable t) { 24 | super(t); 25 | } 26 | public PlatformException(String message) { 27 | super(message); 28 | } 29 | public PlatformException(String message, Throwable t) { 30 | super(message, t); 31 | } 32 | 33 | /** 34 | * These are manufactured exceptions that arise outside the current runtime; therefore, 35 | * the notion of an embedded stack trace is meaningless. 36 | * 37 | * @return this 38 | */ 39 | @Override 40 | public synchronized Throwable fillInStackTrace() { 41 | return this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/ResultSerializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a result returned by a completion stage fails to be serialized. 21 | */ 22 | public class ResultSerializationException extends FlowCompletionException { 23 | public ResultSerializationException(String message, Throwable e) { 24 | super(message, e); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/StageInvokeFailedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a a completion stage invocation failed within Fn - the stage may or may not have been invoked 21 | * and that invocation may or may not have completed. 22 | */ 23 | public class StageInvokeFailedException extends PlatformException { 24 | public StageInvokeFailedException(String reason) { super(reason); } 25 | } 26 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/StageLostException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a stage failed after an internal error in the flow server, the stage may or may not have been 21 | * invoked and that invocation may or may not have completed. 22 | */ 23 | public class StageLostException extends PlatformException { 24 | public StageLostException(String reason) { super(reason); } 25 | } 26 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/StageTimeoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | /** 20 | * Exception thrown when a completion stage function execution exceeds it configured timeout - 21 | * the stage may or may not have completed normally. 22 | * 23 | * When this exception is raised the fn server has terminated the container hosting the function. 24 | */ 25 | public class StageTimeoutException extends PlatformException { 26 | public StageTimeoutException(String reason) { super(reason); } 27 | } 28 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/WrappedFunctionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * Wrapped exception where the root cause of a function failure was not serializable. 23 | * 24 | * This exposes the type of the original exception via {@link #getOriginalExceptionType()} and preserves the original exception stacktrace. 25 | * 26 | */ 27 | public final class WrappedFunctionException extends RuntimeException implements Serializable { 28 | private final Class originalExceptionType; 29 | 30 | public WrappedFunctionException(Throwable cause){ 31 | super(cause.getMessage()); 32 | this.setStackTrace(cause.getStackTrace()); 33 | this.originalExceptionType = cause.getClass(); 34 | } 35 | 36 | /** 37 | * Exposes the type of the original error 38 | * @return the class of the opriginal exception type; 39 | */ 40 | public Class getOriginalExceptionType() { 41 | return originalExceptionType; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /flow-api/src/main/java/com/fnproject/fn/api/flow/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * SDK for creating and running asynchronous processes from within fn for Java. 19 | */ 20 | package com.fnproject.fn.api.flow; 21 | -------------------------------------------------------------------------------- /flow-api/src/test/java/com/fnproject/fn/api/flow/FlowsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.api.flow; 18 | 19 | import org.junit.Test; 20 | 21 | import java.lang.reflect.Modifier; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | public class FlowsTest { 27 | public FlowsTest() { 28 | } 29 | 30 | /** People shall not be allowed to create subclasses of {@code Flow}: 31 | *

32 |     * static class MyFlows extends Flows {
33 |     * }
34 |     * 
35 | */ 36 | @Test 37 | public void dontSubclassFlows() { 38 | assertTrue("Flows is final", Modifier.isFinal(Flows.class.getModifiers())); 39 | assertEquals("No visible constructors", 0, Flows.class.getConstructors().length); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/BlobResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import com.fasterxml.jackson.annotation.JsonProperty; 20 | 21 | public class BlobResponse { 22 | @JsonProperty("blob_id") 23 | public String blobId; 24 | 25 | @JsonProperty("length") 26 | public Long blobLength; 27 | 28 | @JsonProperty("content_type") 29 | public String contentType; 30 | } 31 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/BlobStoreClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import java.io.InputStream; 20 | import java.util.function.Function; 21 | 22 | public interface BlobStoreClient { 23 | 24 | 25 | BlobResponse writeBlob(String prefix, byte[] bytes, String contentType); 26 | 27 | T readBlob(String prefix, String blobId, Function reader, String expectedContentType); 28 | } 29 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/CompleterClientFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import java.io.Serializable; 20 | 21 | public interface CompleterClientFactory extends Serializable { 22 | CompleterClient getCompleterClient(); 23 | 24 | BlobStoreClient getBlobStoreClient(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/CompletionId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import java.io.Serializable; 20 | import java.util.Objects; 21 | 22 | /** 23 | * Value type for a completion ID 24 | */ 25 | public final class CompletionId implements Serializable { 26 | private final String id; 27 | 28 | public CompletionId(String id) { 29 | this.id = Objects.requireNonNull(id); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object o) { 34 | if (this == o) return true; 35 | if (o == null || getClass() != o.getClass()) return false; 36 | CompletionId that = (CompletionId) o; 37 | return Objects.equals(id, that.id); 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return Objects.hash(id); 43 | } 44 | 45 | public String getId() { 46 | return id; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "#" + getId(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/DefaultHttpResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import com.fnproject.fn.api.Headers; 20 | import com.fnproject.fn.api.flow.HttpResponse; 21 | 22 | import java.util.Objects; 23 | 24 | /** 25 | * Created on 27/11/2017. 26 | *

27 | * (c) 2017 Oracle Corporation 28 | */ 29 | public class DefaultHttpResponse implements HttpResponse { 30 | 31 | 32 | private final int statusCode; 33 | private final Headers headers; 34 | private final byte[] body; 35 | 36 | public DefaultHttpResponse(int statusCode, Headers headers, byte[] body) { 37 | this.statusCode = statusCode; 38 | this.headers = Objects.requireNonNull(headers); 39 | this.body = Objects.requireNonNull(body); 40 | } 41 | 42 | @Override 43 | public int getStatusCode() { 44 | return statusCode; 45 | } 46 | 47 | @Override 48 | public Headers getHeaders() { 49 | return headers; 50 | } 51 | 52 | @Override 53 | public byte[] getBodyAsBytes() { 54 | return body; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/EntityReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import java.io.InputStream; 20 | import java.util.Map; 21 | import java.util.Optional; 22 | 23 | /** 24 | * Both an HTTP response and an individual part of a multipart MIME stream are constituted of 25 | * a set of headers together with the body stream. This interface abstracts the access to those parts. 26 | */ 27 | interface EntityReader { 28 | String getHeaderElement(String h, String e); 29 | 30 | Optional getHeaderValue(String header); 31 | 32 | InputStream getContentStream(); 33 | 34 | Map getHeaders(); 35 | } 36 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/FlowFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import com.fnproject.fn.api.FunctionInvoker; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.api.RuntimeFeature; 22 | 23 | /** 24 | * 25 | * The flow feature enables the Flow Client SDK and runtime behaviour in a Java function in order to use Flow in a function you must add the following to the function class: 26 | * 27 | * 28 | * 29 | * import com.fnproject.fn.api.FnFeature; 30 | * import com.fnproject.fn.runtime.flow.FlowFeature; 31 | * 32 | * {@literal @}FnFeature(FlowFeature.class) 33 | * public class MyFunction { 34 | * 35 | * 36 | * public void myFunction(String input){ 37 | * Flows.currentFlow().... 38 | * 39 | * } 40 | * } 41 | * 42 | * 43 | * 44 | * Created on 10/09/2018. 45 | *

46 | * (c) 2018 Oracle Corporation 47 | */ 48 | public class FlowFeature implements RuntimeFeature { 49 | @Override 50 | public void initialize(RuntimeContext context){ 51 | FunctionInvoker invoker = new FlowContinuationInvoker(); 52 | context.addInvoker(invoker,FunctionInvoker.Phase.PreCall); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/FlowFutureSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import com.fnproject.fn.api.flow.FlowFuture; 20 | 21 | /** 22 | * Created on 27/11/2017. 23 | *

24 | * (c) 2017 Oracle Corporation 25 | */ 26 | public interface FlowFutureSource { 27 | FlowFuture createFlowFuture(CompletionId completionId); 28 | } 29 | -------------------------------------------------------------------------------- /flow-runtime/src/main/java/com/fnproject/fn/runtime/flow/FlowId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.flow; 18 | 19 | import java.io.Serializable; 20 | import java.util.Objects; 21 | 22 | /** 23 | * Flow Identifier 24 | *

25 | * This may be serialized within the runtime class 26 | */ 27 | public final class FlowId implements Serializable { 28 | private final String id; 29 | 30 | public FlowId(String id) { 31 | this.id = Objects.requireNonNull(id); 32 | } 33 | 34 | @Override 35 | public boolean equals(Object o) { 36 | if (this == o) return true; 37 | if (o == null || getClass() != o.getClass()) return false; 38 | FlowId flowId = (FlowId) o; 39 | return Objects.equals(id, flowId.id); 40 | } 41 | 42 | @Override 43 | public int hashCode() { 44 | return Objects.hash(id); 45 | } 46 | 47 | public String getId() { 48 | return id; 49 | } 50 | 51 | public String toString() { 52 | return "flow." + getId(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow-runtime/src/test/java/com/fnproject/fn/testing/flowtestfns/FnFlowsFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing.flowtestfns; 18 | 19 | import com.fnproject.fn.api.FnFeature; 20 | import com.fnproject.fn.api.flow.Flow; 21 | import com.fnproject.fn.api.flow.Flows; 22 | import com.fnproject.fn.runtime.flow.FlowFeature; 23 | 24 | import java.io.Serializable; 25 | 26 | @FnFeature(FlowFeature.class) 27 | public class FnFlowsFunction implements Serializable { 28 | 29 | public static void usingFlows() { 30 | Flows.currentFlow(); 31 | } 32 | 33 | public static void notUsingFlows() { 34 | } 35 | 36 | public static void supply() { 37 | Flow fl = Flows.currentFlow(); 38 | fl.supply(() -> 3); 39 | } 40 | 41 | public static void accessRuntimeMultipleTimes() { 42 | Flows.currentFlow(); 43 | Flows.currentFlow(); 44 | } 45 | 46 | public static Integer supplyAndGetResult() { 47 | Flow fl = Flows.currentFlow(); 48 | Integer res = fl.supply(() -> 3).get(); 49 | 50 | return res; 51 | } 52 | 53 | public static void createFlowAndThenFail() { 54 | Flow fl = Flows.currentFlow(); 55 | throw new NullPointerException(fl.toString()); 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /flow-testing/src/main/java/com/fnproject/fn/testing/flow/ResultException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing.flow; 18 | 19 | import com.fnproject.fn.runtime.flow.APIModel; 20 | 21 | class ResultException extends RuntimeException { 22 | private final APIModel.Datum datum; 23 | 24 | ResultException(APIModel.Datum datum) { 25 | this.datum = datum; 26 | } 27 | 28 | APIModel.CompletionResult toResult() { 29 | return APIModel.CompletionResult.failure(datum); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-testing/src/test/java/com/fnproject/fn/testing/flow/IntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing.flow; 18 | 19 | import com.fnproject.fn.testing.FnTestingRule; 20 | import com.fnproject.fn.testing.FunctionError; 21 | import com.fnproject.fn.testing.flowtestfns.ExerciseEverything; 22 | import org.assertj.core.api.Assertions; 23 | import org.junit.Rule; 24 | import org.junit.Test; 25 | 26 | public class IntegrationTest { 27 | 28 | @Rule 29 | public FnTestingRule fn = FnTestingRule.createDefault(); 30 | 31 | public FlowTesting flow = FlowTesting.create(fn); 32 | 33 | @Test 34 | public void runIntegrationTests() { 35 | 36 | flow.givenFn("testFunctionNonExistant") 37 | .withFunctionError() 38 | 39 | .givenFn("testFunction") 40 | .withAction((body) -> { 41 | if (new String(body).equals("PASS")) { 42 | return "okay".getBytes(); 43 | } else { 44 | throw new FunctionError("failed as demanded"); 45 | } 46 | }); 47 | 48 | fn 49 | .givenEvent() 50 | .withBody("") // or "1,5,6,32" to select a set of tests individually 51 | .enqueue() 52 | 53 | .thenRun(ExerciseEverything.class, "handleRequest"); 54 | 55 | Assertions.assertThat(fn.getResults().get(0).getBodyAsString()) 56 | .endsWith("Everything worked\n"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flow-testing/src/test/java/com/fnproject/fn/testing/flow/WhenCompleteTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing.flow; 18 | 19 | import com.fnproject.fn.api.FnFeature; 20 | import com.fnproject.fn.api.flow.Flows; 21 | import com.fnproject.fn.runtime.flow.FlowFeature; 22 | import com.fnproject.fn.testing.FnTestingRule; 23 | import org.assertj.core.api.Assertions; 24 | import org.junit.Rule; 25 | import org.junit.Test; 26 | 27 | import java.util.concurrent.atomic.AtomicInteger; 28 | 29 | public class WhenCompleteTest { 30 | @Rule 31 | public FnTestingRule fn = FnTestingRule.createDefault(); 32 | private FlowTesting flow = FlowTesting.create(fn); 33 | 34 | public static AtomicInteger cas = new AtomicInteger(0); 35 | 36 | 37 | @FnFeature(FlowFeature.class) 38 | public static class TestFn { 39 | public void handleRequest() { 40 | Flows.currentFlow().completedValue(1) 41 | .whenComplete((v, e) -> WhenCompleteTest.cas.compareAndSet(0, 1)) 42 | .thenRun(() -> WhenCompleteTest.cas.compareAndSet(1, 2)); 43 | } 44 | } 45 | 46 | @Test 47 | public void OverlappingFlowInvocationsShouldWork() { 48 | fn.addSharedClass(WhenCompleteTest.class); 49 | 50 | cas.set(0); 51 | 52 | fn.givenEvent().enqueue(); 53 | 54 | fn.thenRun(TestFn.class, "handleRequest"); 55 | 56 | Assertions.assertThat(cas.get()).isEqualTo(2); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/SimpleTypeWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function; 18 | 19 | import com.fnproject.fn.api.TypeWrapper; 20 | 21 | /** 22 | * Implementation of @{@link TypeWrapper} which stores the type 23 | * passed in directly. 24 | */ 25 | public class SimpleTypeWrapper implements TypeWrapper { 26 | private final Class cls; 27 | 28 | public SimpleTypeWrapper(Class cls) { 29 | this.cls = cls; 30 | } 31 | 32 | @Override 33 | public Class getParameterClass() { 34 | return cls; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/SpringCloudFunctionFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function; 18 | 19 | import com.fnproject.fn.api.FunctionInvoker; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.api.RuntimeFeature; 22 | 23 | /** 24 | * 25 | * The SpringCloudFunctionFeature enables a function to be run with a spring cloud function configuration 26 | * 27 | * Created on 10/09/2018. 28 | *

29 | * (c) 2018 Oracle Corporation 30 | */ 31 | public class SpringCloudFunctionFeature implements RuntimeFeature { 32 | 33 | @Override 34 | public void initialize(RuntimeContext ctx) { 35 | ctx.addInvoker(new SpringCloudFunctionInvoker(ctx.getMethod().getTargetClass()),FunctionInvoker.Phase.Call); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/exception/SpringCloudFunctionNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function.exception; 18 | 19 | import com.fnproject.fn.api.exception.FunctionLoadException; 20 | 21 | /** 22 | * Spring Cloud Function integration attempts to find the right Bean to use 23 | * as the function entrypoint. This exception is thrown when that fails. 24 | */ 25 | public class SpringCloudFunctionNotFoundException extends FunctionLoadException { 26 | 27 | public SpringCloudFunctionNotFoundException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public SpringCloudFunctionNotFoundException(String msg) { 32 | super(msg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/functions/SpringCloudConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function.functions; 18 | 19 | import com.fnproject.fn.api.TypeWrapper; 20 | import com.fnproject.springframework.function.SimpleTypeWrapper; 21 | import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry; 22 | import reactor.core.publisher.Flux; 23 | 24 | import java.util.function.Consumer; 25 | 26 | /** 27 | * {@link SpringCloudMethod} representing a {@link Consumer} 28 | */ 29 | public class SpringCloudConsumer extends SpringCloudMethod { 30 | private Consumer> consumer; 31 | 32 | public SpringCloudConsumer(Consumer> consumer, SimpleFunctionRegistry registry) { 33 | super(registry); 34 | this.consumer = consumer; 35 | } 36 | 37 | @Override 38 | protected String getMethodName() { 39 | return "accept"; 40 | } 41 | 42 | @Override 43 | protected Object getFunction() { 44 | return consumer; 45 | } 46 | 47 | @Override 48 | public TypeWrapper getReturnType() { 49 | return new SimpleTypeWrapper(Void.class); 50 | } 51 | @Override 52 | public Flux invoke(Flux arg) { 53 | consumer.accept(arg); 54 | return Flux.empty(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/functions/SpringCloudFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function.functions; 18 | 19 | import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry; 20 | import reactor.core.publisher.Flux; 21 | 22 | import java.util.function.Function; 23 | 24 | /** 25 | * {@link SpringCloudMethod} representing a {@link Function} 26 | */ 27 | public class SpringCloudFunction extends SpringCloudMethod { 28 | private Function, Flux> function; 29 | 30 | public SpringCloudFunction(Function, Flux> function, SimpleFunctionRegistry registry) { 31 | super(registry); 32 | this.function = function; 33 | } 34 | 35 | @Override 36 | protected String getMethodName() { 37 | return "apply"; 38 | } 39 | 40 | @Override 41 | protected Object getFunction() { 42 | return function; 43 | } 44 | 45 | @Override 46 | public Flux invoke(Flux arg) { 47 | return function.apply(arg); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/main/java/com/fnproject/springframework/function/functions/SpringCloudSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function.functions; 18 | 19 | import com.fnproject.fn.api.TypeWrapper; 20 | import com.fnproject.springframework.function.SimpleTypeWrapper; 21 | import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry; 22 | import reactor.core.publisher.Flux; 23 | 24 | import java.util.function.Supplier; 25 | 26 | /** 27 | * {@link SpringCloudMethod} representing a {@link Supplier} 28 | */ 29 | public class SpringCloudSupplier extends SpringCloudMethod { 30 | private Supplier> supplier; 31 | 32 | public SpringCloudSupplier(Supplier> supplier, SimpleFunctionRegistry registry) { 33 | super(registry); 34 | this.supplier = supplier; 35 | } 36 | 37 | @Override 38 | protected String getMethodName() { 39 | return "get"; 40 | } 41 | 42 | @Override 43 | protected Object getFunction() { 44 | return supplier; 45 | } 46 | 47 | @Override 48 | public TypeWrapper getParamType(int i) { 49 | return new SimpleTypeWrapper(Void.class); 50 | } 51 | 52 | @Override 53 | public Flux invoke(Flux arg) { 54 | return supplier.get(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /fn-spring-cloud-function/src/test/java/com/fnproject/springframework/function/testfns/EmptyFunctionConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.springframework.function.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.FnFeature; 21 | import com.fnproject.fn.api.FunctionInvoker; 22 | import com.fnproject.fn.api.RuntimeContext; 23 | import com.fnproject.springframework.function.SpringCloudFunctionFeature; 24 | import com.fnproject.springframework.function.SpringCloudFunctionInvoker; 25 | import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.Import; 28 | 29 | @Configuration 30 | @Import(ContextFunctionCatalogAutoConfiguration.class) 31 | @FnFeature(SpringCloudFunctionFeature.class) 32 | public class EmptyFunctionConfig { 33 | 34 | public void handleRequest() { 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /graalvm.version: -------------------------------------------------------------------------------- 1 | 21.0.0.2 2 | -------------------------------------------------------------------------------- /infra/update/functions/Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | pipeline { 18 | agent any 19 | parameters { 20 | string(name: 'IMAGE', defaultValue: 'registry.oracledx.com/skeppare/functions-service:latest', description: 'Which image to use (full repository:tag, e.g. fnproject/fnserver:latest)') 21 | string(name: 'SOURCE_REPO', defaultValue: 'git@github.com:fnproject/fn.git', description: 'Which git repo to use to build the CLI tool') 22 | string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: 'Which git repo branch to use to build the CLI tool') 23 | } 24 | stages { 25 | stage('Update functions deployment image') { 26 | steps { 27 | sh ". /home/mjg/proxy ; kubectl set image deployment/fn-service fn-service=${params.IMAGE}" 28 | } 29 | } 30 | stage('Update fn cli tool') { 31 | steps { 32 | dir('cli') { 33 | git url: "${params.SOURCE_REPO}", branch: "${params.SOURCE_BRANCH}" 34 | sh 'docker run --rm -v "$PWD":/go/src/github.com/fnproject/fn -v /usr/local/bin:/go/bin -w /go/src/github.com/fnproject/fn/cli golang:1.8 go build -o /go/bin/fn' 35 | } 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /release.version: -------------------------------------------------------------------------------- 1 | 1.0.209 2 | -------------------------------------------------------------------------------- /runtime/README.md: -------------------------------------------------------------------------------- 1 | # Building and releasing a new fn-java-fdk base image 2 | 3 | ## Pre-requisites 4 | 1. Maven. 5 | 2. [Smith](https://github.com/oracle/smith). 6 | 3. Docker. 7 | 8 | ## Build and publish to Docker Hub 9 | 10 | Note: smith needs to be run on Linux. 11 | 12 | ```sh 13 | mvn clean package 14 | smith 15 | smith upload -r https://:@registry-1.docker.io/fnproject/fn-java-fdk:micro-jrebase 16 | docker build . -t fnproject/fn-java-fdk 17 | docker push fnproject/fn-java-fdk 18 | ``` 19 | -------------------------------------------------------------------------------- /runtime/smith.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | package: https://registry-1.docker.io/library/openjdk:8-slim 18 | type: oci 19 | paths: 20 | - /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so 21 | - /usr/lib/x86_64-linux-gnu/libstdc++.so.6 22 | - /lib/x86_64-linux-gnu/libm.so.6 23 | - /lib/x86_64-linux-gnu/libdl.so.2 24 | - /lib/x86_64-linux-gnu/libpthread.so.0 25 | - /lib/x86_64-linux-gnu/libc.so.6 26 | - /lib/x86_64-linux-gnu/libgcc_s.so.1 27 | - /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 28 | - /usr/lib/jvm/java-8-openjdk-amd64/jre/lib 29 | # add monotonic clock 30 | - /lib/x86_64-linux-gnu/librt.so.1 31 | cmd: 32 | - /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 33 | - "-cp" 34 | - "/read/app/*:/read/runtime/*" 35 | - "com.fnproject.fn.runtime.EntryPoint" 36 | -------------------------------------------------------------------------------- /runtime/src/main/c/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | libfnunixsocket.so 3 | libfnunixsocket.dylib 4 | cmake-build-debug 5 | -------------------------------------------------------------------------------- /runtime/src/main/c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(fnunixsocket) 3 | set(CMAKE_BUILD_TYPE Release) 4 | set(JAVA_AWT_LIBRARY NotNeeded) 5 | set(JAVA_JVM_LIBRARY NotNeeded) 6 | set(JAVA_AWT_INCLUDE_PATH NotNeeded) 7 | find_package(JNI REQUIRED) 8 | include_directories(${JNI_INCLUDE_DIRS}) 9 | set(CMAKE_C_STANDARD 11) 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") 11 | 12 | 13 | add_library(fnunixsocket SHARED unix_socket.c) 14 | -------------------------------------------------------------------------------- /runtime/src/main/c/Dockerfile-buildimage: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FROM iad.ocir.io/oraclefunctionsdevelopm/oraclelinux:7.5 18 | 19 | RUN rm -rf /var/cache/yum/* 20 | RUN yum install -y gcc cmake java-1.8.0-openjdk-devel make 21 | RUN yum install -y gcc-c++ 22 | 23 | RUN mkdir /build 24 | WORKDIR /build 25 | 26 | -------------------------------------------------------------------------------- /runtime/src/main/c/README.md: -------------------------------------------------------------------------------- 1 | # Native components for Fn unix socket protocol 2 | 3 | This is a very simple JNI binding to expose unix sockets to the Fn runtime 4 | 5 | ## Building 6 | 7 | you can rebuild a linux version (for the FDK itself) of the JNI library using `./rebuild_so.sh` this runs `buildit.sh` in a suitable docker container 8 | 9 | For testing on a mac you can also compile locally by running `buildit.sh`, you will need at least: 10 | 11 | * XCode compiler toolchain 12 | * cmake 13 | * make 14 | * a JDK installed (for cmake JNI) 15 | 16 | 17 | Current issues: 18 | * This is using old-style JNI array passing which is slow - it should be using native buffers 19 | * Doesn't support non-blocking operations, specifically reads and writes which will block indefinitely -------------------------------------------------------------------------------- /runtime/src/main/c/buildit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -e 19 | 20 | src_dir=$(pwd) 21 | build_dir=${src_dir}/build/$(uname -s| tr '[:upper:]' '[:lower:]') 22 | mkdir -p ${build_dir} 23 | ( 24 | cd ${build_dir} 25 | cmake ${src_dir} 26 | 27 | make 28 | ) 29 | mv ${build_dir}/libfnunixsocket.* ${src_dir} -------------------------------------------------------------------------------- /runtime/src/main/c/rebuild_so.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | mydir=$(cd "$(dirname "$0")"; pwd) 19 | cd ${mydir} 20 | 21 | set -e 22 | 23 | docker build -t fdk_c_build -f Dockerfile-buildimage . 24 | 25 | docker run -v $(pwd):/build fdk_c_build ./buildit.sh 26 | 27 | if [ $(uname -m) == "x86_64" ] 28 | then 29 | mkdir amd64 30 | cp libfnunixsocket.so amd64 31 | else 32 | mkdir arm64 33 | cp libfnunixsocket.so arm64 34 | fi 35 | -------------------------------------------------------------------------------- /runtime/src/main/java-filtered/com/fnproject/fn/runtime/Version.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | /** 20 | * This uses maven-resource filtering rather than conventional manifest versioning as it's more robust against resource changes than using standard META-INF/MANIFEST.MF 21 | * versioning. For native image functions this negates the need for extra configuration to include manifest resources. 22 | * 23 | * Created on 18/02/2020. 24 | *

25 | * 26 | * (c) 2020 Oracle Corporation 27 | */ 28 | public class Version { 29 | public static final String FDK_VERSION="${project.version}"; 30 | } 31 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/DefaultMethodWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | import com.fnproject.fn.api.MethodWrapper; 20 | import com.fnproject.fn.api.TypeWrapper; 21 | 22 | import java.lang.reflect.Method; 23 | import java.util.Arrays; 24 | 25 | /** 26 | * Wrapper class around {@link java.lang.reflect.Method} to provide type 27 | * resolution for methods with generic arguments 28 | */ 29 | public class DefaultMethodWrapper implements MethodWrapper { 30 | private final Class srcClass; 31 | private final Method srcMethod; 32 | 33 | DefaultMethodWrapper(Class srcClass, Method srcMethod) { 34 | this.srcClass = srcClass; 35 | this.srcMethod = srcMethod; 36 | } 37 | 38 | DefaultMethodWrapper(Class srcClass, String srcMethod) { 39 | this(srcClass, Arrays.stream(srcClass.getMethods()) 40 | .filter((m) -> m.getName().equals(srcMethod)) 41 | .findFirst() 42 | .orElseThrow(() -> new RuntimeException(new NoSuchMethodException(srcClass.getCanonicalName() + "::" + srcMethod)))); 43 | } 44 | 45 | 46 | @Override 47 | public Class getTargetClass() { 48 | return srcClass; 49 | } 50 | 51 | @Override 52 | public Method getTargetMethod() { 53 | return srcMethod; 54 | } 55 | 56 | @Override 57 | public TypeWrapper getParamType(int index) { 58 | return MethodTypeWrapper.fromParameter(this, index); 59 | } 60 | 61 | @Override 62 | public TypeWrapper getReturnType() { 63 | return MethodTypeWrapper.fromReturnType(this); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return getLongName(); 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/EventCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | import com.fnproject.fn.api.InputEvent; 20 | import com.fnproject.fn.api.OutputEvent; 21 | 22 | /** 23 | * Event Codec - deals with different calling conventions between fn and the function docker container 24 | */ 25 | public interface EventCodec { 26 | 27 | /** 28 | * Handler handles function content based on codec events 29 | *

30 | * A handler should generally deal with all exceptions (except errors) and convert them into appropriate OutputEvents 31 | */ 32 | interface Handler { 33 | /** 34 | * Handle a function input event and generate a response 35 | * 36 | * @param event the event to handle 37 | * @return an output event indicating the result of calling a function or an error 38 | */ 39 | OutputEvent handle(InputEvent event); 40 | } 41 | 42 | /** 43 | * Run Codec should continuously run the function event loop until either the FDK should exit normally (returning normally) or an error occurred. 44 | *

45 | * Codec should invoke the handler for each received event 46 | * 47 | * @param h the handler to run 48 | */ 49 | void runCodec(Handler h); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/FunctionInvocationCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | public interface FunctionInvocationCallback { 20 | void fireOnSuccessfulInvocation(); 21 | 22 | void fireOnFailedInvocation(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/MethodTypeWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | import com.fnproject.fn.api.MethodWrapper; 20 | import com.fnproject.fn.api.TypeWrapper; 21 | import net.jodah.typetools.TypeResolver; 22 | 23 | import java.lang.reflect.ParameterizedType; 24 | import java.lang.reflect.Type; 25 | 26 | public final class MethodTypeWrapper implements TypeWrapper { 27 | private final Class parameterClass; 28 | 29 | private MethodTypeWrapper(Class parameterClass) { 30 | this.parameterClass = parameterClass; 31 | } 32 | 33 | @Override 34 | public Class getParameterClass() { 35 | return parameterClass; 36 | } 37 | 38 | static Class resolveType(Type type, MethodWrapper src) { 39 | if (type instanceof Class) { 40 | return PrimitiveTypeResolver.resolve((Class) type); 41 | } else if (type instanceof ParameterizedType) { 42 | return (Class) ((ParameterizedType) type).getRawType(); 43 | } 44 | Class resolvedType = TypeResolver.resolveRawArgument(type, src.getTargetClass()); 45 | if (resolvedType == TypeResolver.Unknown.class) { 46 | // TODO: Decide what exception to throw here 47 | throw new RuntimeException("Cannot infer type of method parameter"); 48 | } else { 49 | return resolvedType; 50 | } 51 | } 52 | 53 | public static TypeWrapper fromParameter(MethodWrapper method, int paramIndex) { 54 | return new MethodTypeWrapper(resolveType(method.getTargetMethod().getGenericParameterTypes()[paramIndex], method)); 55 | } 56 | 57 | public static TypeWrapper fromReturnType(MethodWrapper method) { 58 | return new MethodTypeWrapper(resolveType(method.getTargetMethod().getGenericReturnType(), method)); 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/PrimitiveTypeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | public class PrimitiveTypeResolver { 23 | private static final Map, Class> boxedTypes = new HashMap<>(); 24 | static { 25 | boxedTypes.put(void.class, Void.class); 26 | boxedTypes.put(boolean.class, Boolean.class); 27 | boxedTypes.put(byte.class, Byte.class); 28 | boxedTypes.put(char.class, Character.class); 29 | boxedTypes.put(short.class, Short.class); 30 | boxedTypes.put(int.class, Integer.class); 31 | boxedTypes.put(long.class, Long.class); 32 | boxedTypes.put(float.class, Float.class); 33 | boxedTypes.put(double.class, Double.class); 34 | } 35 | 36 | /** 37 | * Resolves cls from a possibly primitive class to a boxed type otherwise just returns cls 38 | */ 39 | public static Class resolve(Class cls) { 40 | if (cls.isPrimitive()) { 41 | return boxedTypes.get(cls); 42 | } 43 | return cls; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/coercion/ContextCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.coercion; 18 | 19 | import com.fnproject.fn.api.*; 20 | import com.fnproject.fn.api.httpgateway.HTTPGatewayContext; 21 | import com.fnproject.fn.api.tracing.TracingContext; 22 | import com.fnproject.fn.runtime.httpgateway.FunctionHTTPGatewayContext; 23 | import com.fnproject.fn.runtime.tracing.OCITracingContext; 24 | 25 | import java.util.Optional; 26 | 27 | /** 28 | * Handles coercion to build in context objects ({@link RuntimeContext}, {@link InvocationContext} , {@link HTTPGatewayContext}) 29 | */ 30 | public class ContextCoercion implements InputCoercion { 31 | 32 | @Override 33 | public Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper method) { 34 | Class paramClass = method.getParamType(arg).getParameterClass(); 35 | 36 | if (paramClass.equals(RuntimeContext.class)) { 37 | return Optional.of(currentContext.getRuntimeContext()); 38 | } else if (paramClass.equals(InvocationContext.class)) { 39 | return Optional.of(currentContext); 40 | } else if (paramClass.equals(HTTPGatewayContext.class)) { 41 | return Optional.of(new FunctionHTTPGatewayContext(currentContext)); 42 | } else if (paramClass.equals(TracingContext.class)) { 43 | return Optional.of(new OCITracingContext(currentContext, currentContext.getRuntimeContext())); 44 | } else { 45 | return Optional.empty(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/coercion/InputEventCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.coercion; 18 | 19 | 20 | import com.fnproject.fn.api.InputCoercion; 21 | import com.fnproject.fn.api.InputEvent; 22 | import com.fnproject.fn.api.InvocationContext; 23 | import com.fnproject.fn.api.MethodWrapper; 24 | 25 | import java.util.Optional; 26 | 27 | public class InputEventCoercion implements InputCoercion { 28 | 29 | @Override 30 | public Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper method) { 31 | if (method.getParamType(arg).getParameterClass().equals(InputEvent.class)) { 32 | return Optional.of(input); 33 | } else { 34 | return Optional.empty(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/coercion/OutputEventCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.coercion; 18 | 19 | import com.fnproject.fn.api.InvocationContext; 20 | import com.fnproject.fn.api.MethodWrapper; 21 | import com.fnproject.fn.api.OutputCoercion; 22 | import com.fnproject.fn.api.OutputEvent; 23 | 24 | import java.util.Optional; 25 | 26 | public class OutputEventCoercion implements OutputCoercion { 27 | @Override 28 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 29 | if (method.getReturnType().getParameterClass().equals(OutputEvent.class)) { 30 | return Optional.of((OutputEvent) value); 31 | } else { 32 | return Optional.empty(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/coercion/StringCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.coercion; 18 | 19 | import com.fnproject.fn.api.*; 20 | import org.apache.commons.io.IOUtils; 21 | 22 | import java.io.IOException; 23 | import java.nio.charset.StandardCharsets; 24 | import java.util.Optional; 25 | 26 | public class StringCoercion implements InputCoercion, OutputCoercion { 27 | @Override 28 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 29 | if (method.getReturnType().getParameterClass().equals(String.class)) { 30 | return Optional.of(OutputEvent.fromBytes(((String) value).getBytes(), OutputEvent.Status.Success, "text/plain")); 31 | } else { 32 | return Optional.empty(); 33 | } 34 | } 35 | 36 | @Override 37 | public Optional tryCoerceParam(InvocationContext currentContext, int param, InputEvent input, MethodWrapper method) { 38 | if (method.getParamType(param).getParameterClass().equals(String.class)) { 39 | return Optional.of( 40 | input.consumeBody(is -> { 41 | try { 42 | return IOUtils.toString(is, StandardCharsets.UTF_8); 43 | } catch (IOException e) { 44 | throw new RuntimeException("Error reading input as string"); 45 | } 46 | })); 47 | } else { 48 | return Optional.empty(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/coercion/VoidCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.coercion; 18 | 19 | import com.fnproject.fn.api.InvocationContext; 20 | import com.fnproject.fn.api.MethodWrapper; 21 | import com.fnproject.fn.api.OutputCoercion; 22 | import com.fnproject.fn.api.OutputEvent; 23 | 24 | import java.util.Optional; 25 | 26 | public class VoidCoercion implements OutputCoercion { 27 | @Override 28 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 29 | if (method.getReturnType().getParameterClass().equals(Void.class)) { 30 | return Optional.of(OutputEvent.emptyResult(OutputEvent.Status.Success)); 31 | } else { 32 | return Optional.empty(); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/FunctionClassInstantiationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | import com.fnproject.fn.api.exception.FunctionLoadException; 20 | 21 | public class FunctionClassInstantiationException extends FunctionLoadException { 22 | public FunctionClassInstantiationException(String message, Throwable cause) { 23 | super(message, cause); 24 | } 25 | 26 | public FunctionClassInstantiationException(String s) { 27 | super(s); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/FunctionIOException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | /** 20 | * The FDK experienced a terminal issue communicating with the platform 21 | */ 22 | public final class FunctionIOException extends RuntimeException { 23 | 24 | 25 | /** 26 | * create a function invocation exception 27 | * 28 | * @param message private message for this exception - 29 | * @param target the underlying user exception that triggered this failure 30 | */ 31 | public FunctionIOException(String message, Throwable target) { 32 | super(message, target); 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/FunctionInitializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | /** 20 | * The FDK was not able to start up 21 | */ 22 | public final class FunctionInitializationException extends RuntimeException { 23 | 24 | 25 | /** 26 | * create a function invocation exception 27 | * 28 | * @param message private message for this exception - 29 | * @param target the underlying user exception that triggered this failure 30 | */ 31 | public FunctionInitializationException(String message, Throwable target) { 32 | super(message, target); 33 | } 34 | 35 | 36 | public FunctionInitializationException(String message) { 37 | super(message); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/InvalidEntryPointException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | import com.fnproject.fn.api.exception.FunctionLoadException; 20 | 21 | /** 22 | * The function entry point spec was malformed. 23 | */ 24 | public class InvalidEntryPointException extends FunctionLoadException { 25 | public InvalidEntryPointException(String msg) { 26 | super(msg); 27 | } 28 | 29 | public InvalidEntryPointException(String msg, Throwable e) { 30 | super(msg, e); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/InvalidFunctionDefinitionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | import com.fnproject.fn.api.exception.FunctionLoadException; 20 | 21 | /** 22 | * the function definition passed was invalid (e.g. class or method did not exist in jar, or method did not match required signature) 23 | */ 24 | public class InvalidFunctionDefinitionException extends FunctionLoadException { 25 | 26 | public InvalidFunctionDefinitionException(String message, Throwable cause) { 27 | super(message, cause); 28 | } 29 | 30 | public InvalidFunctionDefinitionException(String message) { 31 | super(message); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/exception/PlatformCommunicationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.exception; 18 | 19 | /** 20 | * An error occurred in the 21 | */ 22 | public class PlatformCommunicationException extends RuntimeException { 23 | public PlatformCommunicationException(String message) { 24 | super(message); 25 | } 26 | 27 | public PlatformCommunicationException(String message, Exception e) { 28 | super(message, e); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/httpgateway/QueryParametersImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.httpgateway; 18 | 19 | import com.fnproject.fn.api.QueryParameters; 20 | 21 | import java.io.Serializable; 22 | import java.util.*; 23 | 24 | public class QueryParametersImpl implements QueryParameters, Serializable { 25 | private final Map> params; 26 | 27 | public QueryParametersImpl() { 28 | this.params = new HashMap<>(); 29 | } 30 | 31 | public QueryParametersImpl(Map> params) { 32 | this.params = Objects.requireNonNull(params); 33 | } 34 | 35 | public Optional get(String key) { 36 | Objects.requireNonNull(key); 37 | return Optional.of(getValues(key)) 38 | .filter((values) -> values.size() > 0) 39 | .flatMap((values) -> Optional.ofNullable(values.get(0))); 40 | } 41 | 42 | public List getValues(String key) { 43 | Objects.requireNonNull(key); 44 | List values = this.params.get(key); 45 | if (values == null) { 46 | return Collections.emptyList(); 47 | } 48 | return values; 49 | } 50 | 51 | public int size() { 52 | return params.size(); 53 | } 54 | 55 | @Override 56 | public Map> getAll() { 57 | return new HashMap<>(params); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/ntv/UnixServerSocket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.ntv; 18 | 19 | import java.io.Closeable; 20 | import java.io.IOException; 21 | import java.net.SocketException; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | /** 25 | * Created on 12/09/2018. 26 | *

27 | * (c) 2018 Oracle Corporation 28 | */ 29 | public class UnixServerSocket implements Closeable { 30 | private final int fd; 31 | private final AtomicBoolean closed = new AtomicBoolean(); 32 | 33 | private UnixServerSocket(int fd) { 34 | this.fd = fd; 35 | } 36 | 37 | 38 | public static UnixServerSocket listen(String fileName, int backlog) throws IOException { 39 | int fd = UnixSocketNative.socket(); 40 | 41 | try { 42 | UnixSocketNative.bind(fd, fileName); 43 | } catch (UnixSocketException e) { 44 | UnixSocketNative.close(fd); 45 | throw e; 46 | } 47 | 48 | 49 | try { 50 | UnixSocketNative.listen(fd, backlog); 51 | } catch (UnixSocketException e) { 52 | UnixSocketNative.close(fd); 53 | throw e; 54 | } 55 | return new UnixServerSocket(fd); 56 | 57 | } 58 | 59 | @Override 60 | public void close() throws IOException { 61 | if (closed.compareAndSet(false,true)) { 62 | UnixSocketNative.close(fd); 63 | } 64 | } 65 | 66 | public UnixSocket accept(long timeoutMillis) throws IOException { 67 | if (closed.get()) { 68 | throw new SocketException("accept on closed socket"); 69 | } 70 | int newFd = UnixSocketNative.accept(fd, timeoutMillis); 71 | if (newFd == 0) { 72 | return null; 73 | } 74 | return new UnixSocket(newFd); 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /runtime/src/main/java/com/fnproject/fn/runtime/ntv/UnixSocketException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.ntv; 18 | 19 | import java.net.SocketException; 20 | 21 | /** 22 | * Created on 12/09/2018. 23 | *

24 | * (c) 2018 Oracle Corporation 25 | */ 26 | public class UnixSocketException extends SocketException { 27 | public UnixSocketException(String message, String detail) { 28 | super(message + ":" + detail); 29 | } 30 | 31 | public UnixSocketException(String message) { 32 | super(message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime/src/main/resources/META-INF/native-image/com.fnproject.fn/runtime/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name" : "com.fnproject.fn.runtime.ntv.UnixSocketNative", 4 | "methods" : [ 5 | { "name" : "socket" }, 6 | { "name" : "bind" }, 7 | { "name" : "connect" }, 8 | { "name" : "listen" }, 9 | { "name" : "accept" }, 10 | { "name" : "recv" }, 11 | { "name" : "send" }, 12 | { "name" : "close" }, 13 | { "name" : "setSendTimeout" }, 14 | { "name" : "getSendTimeout" }, 15 | { "name" : "setRecvTimeout" }, 16 | { "name" : "getRecvTimeout" }, 17 | { "name" : "setSendBufSize" }, 18 | { "name" : "setRecvBufSize" }, 19 | { "name" : "shutdown"} 20 | ] 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/HeaderBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime; 18 | 19 | import com.fnproject.fn.api.Headers; 20 | 21 | import java.util.AbstractMap; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | class HeaderBuilder { 27 | static Map.Entry> headerEntry(String key, String... values) { 28 | return new AbstractMap.SimpleEntry<>(Headers.canonicalKey(key), Arrays.asList(values)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/Animal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | 22 | public class Animal { 23 | private String name; 24 | private int age; 25 | 26 | @JsonCreator 27 | public Animal(@JsonProperty("name") String name, 28 | @JsonProperty("age") int age) { 29 | this.name = name; 30 | this.age = age; 31 | } 32 | 33 | public int getAge() { 34 | return age; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/BadTestFnDuplicateMethods.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | /** 20 | * Test function class for e2e tests 21 | */ 22 | public class BadTestFnDuplicateMethods { 23 | public void fn(String string){} 24 | public void fn(int integer){} 25 | } 26 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnInputOutput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringUpperCaseCoercion; 23 | 24 | public class CustomDataBindingFnInputOutput { 25 | 26 | @FnConfiguration 27 | public static void configure(RuntimeContext ctx){ 28 | ctx.addInputCoercion(new StringUpperCaseCoercion()); 29 | ctx.addOutputCoercion(new StringReversalCoercion()); 30 | } 31 | 32 | public String echo(String s){ 33 | return s; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithAnnotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.InputBinding; 20 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 21 | 22 | public class CustomDataBindingFnWithAnnotation { 23 | 24 | public String echo(@InputBinding(coercion=StringReversalCoercion.class) String s){ 25 | return s; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithAnnotationAndConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.InputBinding; 21 | import com.fnproject.fn.api.RuntimeContext; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 23 | import com.fnproject.fn.runtime.testfns.coercions.StringUpperCaseCoercion; 24 | 25 | public class CustomDataBindingFnWithAnnotationAndConfig { 26 | @FnConfiguration 27 | public static void inputConfig(RuntimeContext ctx){ 28 | ctx.addInputCoercion(new StringReversalCoercion()); 29 | } 30 | 31 | public String echo(@InputBinding(coercion=StringUpperCaseCoercion.class) String s){ 32 | return s; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 22 | 23 | public class CustomDataBindingFnWithConfig { 24 | 25 | @FnConfiguration 26 | public static void inputConfig(RuntimeContext ctx){ 27 | ctx.addInputCoercion(new StringReversalCoercion()); 28 | } 29 | 30 | public String echo(String s){ 31 | return s; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithDudCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.DudCoercion; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 23 | 24 | public class CustomDataBindingFnWithDudCoercion { 25 | @FnConfiguration 26 | public static void inputConfig(RuntimeContext ctx){ 27 | ctx.addInputCoercion(new DudCoercion()); 28 | ctx.addInputCoercion(new StringReversalCoercion()); 29 | } 30 | 31 | public String echo(String s){ 32 | return s; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithMultipleCoercions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringUpperCaseCoercion; 23 | 24 | public class CustomDataBindingFnWithMultipleCoercions { 25 | 26 | @FnConfiguration 27 | public static void inputConfig(RuntimeContext ctx){ 28 | ctx.addInputCoercion(new StringUpperCaseCoercion()); 29 | ctx.addInputCoercion(new StringReversalCoercion()); 30 | } 31 | 32 | public String echo(String s){ 33 | return s; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomDataBindingFnWithNoUserCoercions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | 22 | public class CustomDataBindingFnWithNoUserCoercions { 23 | 24 | @FnConfiguration 25 | public static void inputConfig(RuntimeContext ctx){ 26 | } 27 | 28 | public String echo(String s){ 29 | return s; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomOutputDataBindingFnWithAnnotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.OutputBinding; 20 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 21 | 22 | public class CustomOutputDataBindingFnWithAnnotation { 23 | 24 | @OutputBinding(coercion=StringReversalCoercion.class) 25 | public String echo(String s){ return s; } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomOutputDataBindingFnWithConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 22 | 23 | 24 | public class CustomOutputDataBindingFnWithConfig { 25 | @FnConfiguration 26 | public static void outputConfig(RuntimeContext ctx){ 27 | ctx.addOutputCoercion(new StringReversalCoercion()); 28 | } 29 | 30 | public String echo(String s){ return s; } 31 | } 32 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomOutputDataBindingFnWithDudCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.DudCoercion; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 23 | 24 | public class CustomOutputDataBindingFnWithDudCoercion { 25 | @FnConfiguration 26 | public static void outputConfig(RuntimeContext ctx){ 27 | ctx.addOutputCoercion(new DudCoercion()); 28 | ctx.addOutputCoercion(new StringReversalCoercion()); 29 | } 30 | 31 | public String echo(String s){ return s; } 32 | } 33 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomOutputDataBindingFnWithMultipleCoercions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | import com.fnproject.fn.runtime.testfns.coercions.StringReversalCoercion; 22 | import com.fnproject.fn.runtime.testfns.coercions.StringUpperCaseCoercion; 23 | 24 | public class CustomOutputDataBindingFnWithMultipleCoercions { 25 | 26 | @FnConfiguration 27 | public static void outputConfig(RuntimeContext ctx){ 28 | ctx.addOutputCoercion(new StringUpperCaseCoercion()); 29 | ctx.addOutputCoercion(new StringReversalCoercion()); 30 | } 31 | 32 | public String echo(String s){ return s; } 33 | } 34 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/CustomOutputDataBindingFnWithNoUserCoercions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | import com.fnproject.fn.api.FnConfiguration; 20 | import com.fnproject.fn.api.RuntimeContext; 21 | 22 | public class CustomOutputDataBindingFnWithNoUserCoercions { 23 | 24 | @FnConfiguration 25 | public static void outputConfig(RuntimeContext ctx){ 26 | } 27 | 28 | public String echo(String s){ return s; } 29 | } 30 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/ErrorMessages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns; 18 | 19 | public class ErrorMessages { 20 | 21 | public class NoMethodsClass { 22 | } 23 | 24 | public class OneMethodClass { 25 | public String theMethod(String x){ 26 | return x; 27 | } 28 | } 29 | 30 | public static class OtherMethodsClass { 31 | public String takesAnInteger(Integer x){ 32 | return "It was " + x; 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/coercions/DudCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns.coercions; 18 | 19 | import com.fnproject.fn.api.*; 20 | 21 | import java.util.Optional; 22 | 23 | public class DudCoercion implements InputCoercion, OutputCoercion { 24 | 25 | @Override 26 | public Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper methodWrapper) { 27 | return Optional.empty(); 28 | } 29 | 30 | @Override 31 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 32 | return Optional.empty(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/coercions/StringReversalCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns.coercions; 18 | 19 | import com.fnproject.fn.api.*; 20 | import org.apache.commons.io.IOUtils; 21 | 22 | import java.io.IOException; 23 | import java.nio.charset.StandardCharsets; 24 | import java.util.Optional; 25 | 26 | public class StringReversalCoercion implements InputCoercion, OutputCoercion { 27 | @Override 28 | public Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper methodWrapper) { 29 | return Optional.of( 30 | input.consumeBody(is -> { 31 | try { 32 | return new StringBuffer(IOUtils.toString(is, StandardCharsets.UTF_8)).reverse().toString(); 33 | } catch (IOException e) { 34 | return null; // Tests will fail if we end up here 35 | } 36 | }) 37 | ); 38 | } 39 | 40 | @Override 41 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 42 | if (ctx.getRuntimeContext().getMethod().getTargetMethod().getReturnType().equals(String.class)) { 43 | try { 44 | String reversedOutput = new StringBuffer((String) value).reverse().toString(); 45 | return Optional.of(OutputEvent.fromBytes(reversedOutput.getBytes(), OutputEvent.Status.Success, "text/plain")); 46 | } catch (ClassCastException e) { 47 | return Optional.empty(); 48 | } 49 | } else { 50 | return Optional.empty(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /runtime/src/test/java/com/fnproject/fn/runtime/testfns/coercions/StringUpperCaseCoercion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.runtime.testfns.coercions; 18 | 19 | import com.fnproject.fn.api.*; 20 | import org.apache.commons.io.IOUtils; 21 | 22 | import java.io.IOException; 23 | import java.nio.charset.StandardCharsets; 24 | import java.util.Optional; 25 | 26 | public class StringUpperCaseCoercion implements InputCoercion, OutputCoercion { 27 | 28 | @Override 29 | public Optional tryCoerceParam(InvocationContext currentContext, int arg, InputEvent input, MethodWrapper methodWrapper) { 30 | return Optional.of( 31 | input.consumeBody(is -> { 32 | try { 33 | return IOUtils.toString(is, StandardCharsets.UTF_8).toUpperCase(); 34 | } catch (IOException e) { 35 | return null; // Tests will fail if we end up here 36 | } 37 | }) 38 | ); 39 | } 40 | 41 | @Override 42 | public Optional wrapFunctionResult(InvocationContext ctx, MethodWrapper method, Object value) { 43 | if (ctx.getRuntimeContext().getMethod().getTargetMethod().getReturnType().equals(String.class)) { 44 | try { 45 | String capitalizedOutput = ((String) value).toUpperCase(); 46 | return Optional.of(OutputEvent.fromBytes(capitalizedOutput.getBytes(), OutputEvent.Status.Success, "text/plain")); 47 | } catch (ClassCastException e) { 48 | return Optional.empty(); 49 | } 50 | } else { 51 | return Optional.empty(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /settings-deploy.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 23 | 24 | 25 | bmcs-faas-snapshot-repo 26 | ${bmcs-faas-snapshot-repo.username} 27 | ${bmcs-faas-snapshot-repo.password} 28 | 29 | 30 | fnproject-release-repo 31 | ${fnproject-release-repo.username} 32 | ${fnproject-release-repo.password} 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /testing-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 23 | 24 | fdk 25 | com.fnproject.fn 26 | 1.0.0-SNAPSHOT 27 | 28 | 4.0.0 29 | 30 | testing-core 31 | 32 | 33 | 34 | com.fnproject.fn 35 | runtime 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-javadoc-plugin 44 | 45 | 46 | attach-javadocs 47 | 48 | jar 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /testing-core/src/main/java/com/fnproject/fn/testing/FnResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | import com.fnproject.fn.api.OutputEvent; 20 | 21 | /** 22 | * A simple abstraction over {@link OutputEvent} that buffers the response body 23 | */ 24 | public interface FnResult extends OutputEvent { 25 | /** 26 | * Returns the body of the function result as a byte array 27 | * 28 | * @return the function response body 29 | */ 30 | byte[] getBodyAsBytes(); 31 | 32 | /** 33 | * Returns the body of the function response as a string 34 | * 35 | * @return a function response body 36 | */ 37 | String getBodyAsString(); 38 | 39 | 40 | /** 41 | * Determine if the status code corresponds to a successful invocation 42 | * 43 | * @return true if the status code indicates success 44 | */ 45 | default boolean isSuccess() { 46 | return getStatus() == Status.Success; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /testing-core/src/main/java/com/fnproject/fn/testing/FunctionError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | /** 20 | * An Exception that can be used in invocations of stubbed external functions to signal the failure of the external 21 | * function due to a simulated error case of the function itself 22 | */ 23 | public class FunctionError extends Exception { 24 | public FunctionError() { 25 | } 26 | 27 | public FunctionError(String s) { 28 | super(s); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testing-core/src/main/java/com/fnproject/fn/testing/HeaderWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | import java.io.IOException; 20 | import java.io.OutputStream; 21 | 22 | class HeaderWriter { 23 | final OutputStream os; 24 | 25 | HeaderWriter(OutputStream os) { 26 | this.os = os; 27 | } 28 | 29 | void writeHeader(String key, String value) throws IOException { 30 | os.write((key + ": " + value + "\r\n").getBytes("ISO-8859-1")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /testing-core/src/main/java/com/fnproject/fn/testing/PlatformError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | /** 20 | * An Exception that can be used in invocations of stubbed external functions to signal the failure of the external 21 | * function due to a simulated infrastructure error in the Oracle Functions platform 22 | */ 23 | public class PlatformError extends Exception { 24 | public PlatformError() { 25 | } 26 | 27 | public PlatformError(String s) { 28 | super(s); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testing-junit4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 23 | 24 | fdk 25 | com.fnproject.fn 26 | 1.0.0-SNAPSHOT 27 | 28 | 4.0.0 29 | 30 | testing-junit4 31 | 32 | 33 | 34 | com.fnproject.fn 35 | testing-core 36 | 37 | 38 | com.fnproject.fn 39 | runtime 40 | 41 | 42 | 43 | junit 44 | junit 45 | compile 46 | 47 | 48 | org.assertj 49 | assertj-core 50 | test 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-javadoc-plugin 59 | 60 | 61 | attach-javadocs 62 | 63 | jar 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /testing-junit4/src/main/java/com/fnproject/fn/testing/FnEventBuilderJUnit4.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | public interface FnEventBuilderJUnit4 extends FnEventBuilder { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /testing-junit4/src/main/java/com/fnproject/fn/testing/FnTestingRuleFeature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.fnproject.fn.testing; 18 | 19 | import java.io.PrintStream; 20 | 21 | /** 22 | * Created on 07/09/2018. 23 | *

24 | * (c) 2018 Oracle Corporation 25 | */ 26 | public interface FnTestingRuleFeature { 27 | 28 | /** 29 | * Prepares a test 30 | * @param functionClassLoader 31 | * @param stderr 32 | * @param cls 33 | * @param method 34 | */ 35 | void prepareTest(ClassLoader functionClassLoader, PrintStream stderr, String cls, String method); 36 | 37 | 38 | void prepareFunctionClassLoader(FnTestingClassLoader cl); 39 | 40 | 41 | void afterTestComplete(); 42 | } 43 | -------------------------------------------------------------------------------- /testing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 23 | 24 | fdk 25 | com.fnproject.fn 26 | 1.0.0-SNAPSHOT 27 | 28 | 4.0.0 29 | 30 | testing 31 | 32 | 33 | 34 | com.fnproject.fn 35 | runtime 36 | 37 | 38 | com.fnproject.fn 39 | testing-core 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-javadoc-plugin 48 | 49 | 50 | attach-javadocs 51 | 52 | jar 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | --------------------------------------------------------------------------------