|
1 | | - |
2 | 1 | # Java Function Invoker [](https://travis-ci.org/projectriff/java-function-invoker) |
3 | 2 |
|
4 | 3 | ## What It Does |
@@ -60,8 +59,37 @@ public class UppercaseApplication { |
60 | 59 | } |
61 | 60 | ``` |
62 | 61 |
|
| 62 | +#### Function detection |
| 63 | + |
| 64 | +Spring Cloud Function will attempt to detect the function from the function source. |
| 65 | +If you have a single function declared with `@Bean` in a Spring Boot app then that is the function that will be used. |
| 66 | +If you have multiple functions in the source then you have to specify which one you want using a handler (see the next section). |
| 67 | + |
| 68 | +If you have a Plain Java class with a function then you can provide a `Function-Class` entry in the JAR file manifest to indicate which function class to use. |
| 69 | +Here is an example of using a plug-in for Maven to add this information to the manifest: |
| 70 | + |
| 71 | +```xml |
| 72 | + <build> |
| 73 | + <plugins> |
| 74 | + <plugin> |
| 75 | + <groupId>org.apache.maven.plugins</groupId> |
| 76 | + <artifactId>maven-jar-plugin</artifactId> |
| 77 | + <version>3.0.2</version> |
| 78 | + <configuration> |
| 79 | + <archive> |
| 80 | + <manifestEntries> |
| 81 | + <Function-Class>functions.Greeter</Function-Class> |
| 82 | + </manifestEntries> |
| 83 | + </archive> |
| 84 | + </configuration> |
| 85 | + </plugin> |
| 86 | + </plugins> |
| 87 | + </build> |
| 88 | +``` |
| 89 | + |
63 | 90 | #### Function handler |
64 | 91 |
|
| 92 | +If your function can't be automatically detected then you need to provide a handler specification. |
65 | 93 | The simplest form of the handler is a bean name or a class name that can be instantiated (with a default constructor). |
66 | 94 | More complex creation scenarios can be handled by giving the handler in the form `<bean>[&main=<main>]` where |
67 | 95 |
|
@@ -115,12 +143,12 @@ eval $(minikube docker-env) |
115 | 143 | ``` |
116 | 144 |
|
117 | 145 | Now you can build and deploy your function from the base directory of your app source. You need to provide the `--handler` option (see above for different handler types). |
118 | | -To build a Boot app with a function bean, use: |
| 146 | +To build the `uppercase` sample Boot app that is using a function bean, use: |
119 | 147 |
|
120 | 148 | ```sh |
121 | | -riff function create java upper --handler upper --local-path . --image dev.local/upper:v1 |
| 149 | +riff function create java uppercase --handler uppercase --local-path . --image dev.local/uppercase:v1 |
122 | 150 | ``` |
123 | | -> NOTE: If your Spring Boot application contains a single function bean, then you can omit the `--handler` options since the invoker is able to automatically detect it. |
| 151 | +> NOTE: If your Spring Boot application contains a single function bean, then you can omit the `--handler` options since the invoker is able to automatically detect it. You can also omit the `--handler` if the JAR manifest has a `Function-Class` entry. |
124 | 152 |
|
125 | 153 | > NOTE: You need to provide a tag for the image to avoid Kubernetes trying to download the latest version of the image. |
126 | 154 | If the specified image tag already exists in the Docker daemon then Kubernetes will use it since `IfNotPresent` is the default pull policy. |
@@ -151,60 +179,50 @@ riff namespace init default --gcr gcr-storage-admin.json |
151 | 179 | ``` |
152 | 180 |
|
153 | 181 | You need to push your function source to a Git repo and provide the URL for the command that creates the function. |
| 182 | +Here we are using a [sample function from the riff samples](https://github.com/projectriff-samples/java-hello). |
154 | 183 |
|
155 | | -Now you can build and deploy your function from this Git repo. You need to provide the `--handler` option (see above for different handler types). To build a Boot app with a function bean, use: |
| 184 | +Now you can build and deploy your function from this Git repo. You need to provide the `--handler` option (see above for different handler types). |
| 185 | +To build with a plain Java function, you can use: |
156 | 186 |
|
157 | 187 | ```sh |
158 | 188 | export GCP_PROJECT=$(gcloud config get-value core/project) |
159 | | -export GIT_REPO=https://github.com/trisberg/upper.git |
160 | | -riff function create java upper --git-repo $GIT_REPO --handler upper --image gcr.io/$GCP_PROJECT/upper-new --verbose |
| 189 | +export GIT_REPO= https://github.com/projectriff-samples/java-hello.git |
| 190 | +riff function create java Hello --git-repo $GIT_REPO --handler functions.Hello --image gcr.io/$GCP_PROJECT/java-hello --verbose |
161 | 191 | ``` |
162 | | -> NOTE: If your Spring Boot application contains a single function bean, then you can omit the `--handler` options since the invoker is able to automatically detect it. It is possible to have multiple function beans in the same source repository and just refer to the one you want to use when creating the riff function using the `--handler` option. |
| 192 | +> NOTE: If your Spring Boot application contains a single function bean, then you can omit the `--handler` options since the invoker is able to automatically detect it. You can also omit the `--handler` if the JAR manifest has a `Function-Class` entry. |
| 193 | +
|
| 194 | +> NOTE: It is possible to have multiple function beans in the same source repository and just refer to the one you want to use when creating the riff function using the `--handler` option. |
163 | 195 |
|
164 | 196 | Once the function is up and running you can invoke it using: |
165 | 197 |
|
166 | 198 | ```sh |
167 | | -riff service invoke upper --text -- -w '\n' -d "hello world" |
| 199 | +riff service invoke hello --text -- -w '\n' -d "world" |
168 | 200 | ``` |
169 | 201 |
|
170 | 202 | To delete the function use: |
171 | 203 |
|
172 | 204 | ```sh |
173 | | -riff service delete upper |
| 205 | +riff service delete hello |
174 | 206 | ``` |
175 | 207 |
|
176 | 208 | ## How it Works |
177 | 209 |
|
178 | | -As long as the dependencies are included in the archive correctly, you |
179 | | -can supply a `Function` with a wide range of input and output |
180 | | -types. The input or output types can be plain JDK classes, or POJOs |
181 | | -defined in your archive, or `Message` (from `spring-messaging`) or |
182 | | -`Publisher` (from `reactive-streams`) or `Flux` or `Mono` (from |
183 | | -`reactor-core`). The `Message` type will give you access to header |
184 | | -metadata in the incoming and outgoing messages. If the input or output |
185 | | -is either a `Publisher` or a `Message` (or a `Publisher<Message>`) |
186 | | -then both input and output must be in the same form, with possibly |
187 | | -different payload types, obviously. POJOs are converted from incoming |
188 | | -messages assuming the payload is JSON ans using the GSON library. |
189 | | - |
190 | | -The invoker is a [Spring Boot](https://projects.spring.io/spring-boot) |
191 | | -application with a configuration key `function.uri` that can be used |
192 | | -to point to a `java.util.function.Function`. Because of the way Spring |
193 | | -Boot works you can use an environment variable `FUNCTION_URI` or a |
194 | | -System property `function.uri` or a command line argument |
195 | | -`--function.uri` (amongst other options). Its value points to a |
196 | | -classpath archive, which can be a jar file or a directory, together |
197 | | -with parameters: |
198 | | - |
199 | | -* `handler`: the class name of a `Function` to execute, or a bean name of a `Function`. Can also be a |
200 | | - comma, or pipe-separated list of functions, which are composed |
201 | | - together at runtime. |
202 | | -* `main`: (optional) the class name of a Spring `@Configuration` that |
203 | | - can be used to create a Spring application context, in which the |
204 | | - `handler` is defined. |
205 | | - |
206 | | -The jar archive can also be a comma-separated list of archive |
207 | | -locations, in case you need to compose things together. |
| 210 | +As long as the dependencies are included in the archive correctly, you can supply a `Function` with a wide range of input and output types. |
| 211 | +The input or output types can be plain JDK classes, or POJOs defined in your archive, or `Message` (from `spring-messaging`) or `Publisher` (from `reactive-streams`) or `Flux` or `Mono` (from `reactor-core`). |
| 212 | +The `Message` type will give you access to header metadata in the incoming and outgoing messages. |
| 213 | +If the input or output is either a `Publisher` or a `Message` (or a `Publisher<Message>`) then both input and output must be in the same form, with possibly different payload types, obviously. POJOs are converted from incoming messages assuming the payload is JSON and using the GSON library. |
| 214 | + |
| 215 | +The invoker is a [Spring Boot](https://projects.spring.io/spring-boot) application with a configuration key `function.uri` that can be used to point to a `java.util.function.Function`. |
| 216 | +Because of the way Spring Boot works you can use an environment variable `FUNCTION_URI` or a System property `function.uri` or a command line argument `--function.uri` (amongst other options). |
| 217 | +Its value points to a classpath archive, which can be a jar file or a directory, together with parameters: |
| 218 | + |
| 219 | +* `handler`: the class name of a `Function` to execute, or a bean name of a `Function`. Can also be a comma, or pipe-separated list of functions, which are composed together at runtime. |
| 220 | + |
| 221 | +* `main`: (optional) the class name of a Spring `@Configuration` that can be used to create a Spring application context, in which the `handler` is defined. |
| 222 | + |
| 223 | +The jar archive can also be a comma-separated list of archive locations, in case you need to compose things together. |
| 224 | + |
| 225 | +> NOTE: If your Spring Boot application contains a single function bean, then you can omit the `handler` and `main` parameters since the function can be automatically detected. You can also omit the the `handler` and `main` parameters if the JAR manifest has a `Function-Class` entry. |
208 | 226 |
|
209 | 227 | Examples: |
210 | 228 |
|
|
0 commit comments