GH-731 Add support for SDK CloudEvent type

The type itself comes form cloud event sdk. And while s-c-function provides native support for cloud events, this is necessary for cases when user uses CloudEvent type in the signature of a function

Resolves #731
This commit is contained in:
Oleg Zhurakousky
2021-08-31 17:15:51 +02:00
parent 0e2663bd55
commit eccafd3278
9 changed files with 91 additions and 33 deletions

View File

@@ -25,8 +25,30 @@
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-api</artifactId>
<version>2.2.0</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,16 @@
package function.example;
import java.util.Map;
import java.util.function.Function;
import io.cloudevents.CloudEvent;
public class EchoCloudEventFunction implements Function<CloudEvent, CloudEvent> {
@Override
public CloudEvent apply(CloudEvent value) {
System.out.println("Received " + value);
return value;
}
}

View File

@@ -1,13 +0,0 @@
package function.example;
import java.util.function.Function;
public class UpperCaseFunction implements Function<String, String> {
@Override
public String apply(String value) {
System.out.println("Uppercasing " + value);
return value.toUpperCase();
}
}

View File

@@ -209,6 +209,7 @@ class FunctionArchiveDeployer extends JarLauncher {
private boolean shouldLoadViaDeployerLoader(String name) {
return name.startsWith("org.reactivestreams")
|| name.startsWith("reactor.")
|| name.startsWith("io.cloudevents")
|| name.startsWith("org.springframework.messaging.Message")
|| name.startsWith("org.springframework.messaging.converter.MessageConverter");
}
@@ -226,9 +227,6 @@ class FunctionArchiveDeployer extends JarLauncher {
else {
return null;
}
// return StringUtils.hasText(functionProperties.getFunctionClass())
// ? functionProperties.getFunctionClass().split(";")
// : new String[] {this.getArchive().getManifest().getMainAttributes().getValue("Function-Class")};
}
catch (Exception e) {
throw new IllegalStateException("Failed to discover function class name", e);

View File

@@ -33,10 +33,12 @@ import reactor.util.function.Tuples;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.deployer.resource.maven.MavenProperties;
import org.springframework.cloud.function.cloudevent.CloudEventMessageBuilder;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
@@ -107,20 +109,22 @@ public class FunctionDeployerTests {
public void testWithSimplestJar() throws Exception {
String[] args = new String[] {
"--spring.cloud.function.location=target/it/simplestjar/target/simplestjar-1.0.0.RELEASE.jar",
"--spring.cloud.function.function-class=function.example.UpperCaseFunction" };
"--spring.cloud.function.function-class=function.example.EchoCloudEventFunction" };
ApplicationContext context = SpringApplication.run(DeployerApplication.class, args);
FunctionCatalog catalog = context.getBean(FunctionCatalog.class);
Function<String, String> function = catalog.lookup("upperCaseFunction");
Function<Message<String>, Message<byte[]>> function = catalog.lookup("echoCloudEventFunction");
assertThat(function.apply("bob")).isEqualTo("BOB");
assertThat(function.apply("stacy")).isEqualTo("STACY");
String data = "{\"name\":\"Ricky\"}";
Message<String> inputMessage = CloudEventMessageBuilder
.withData(data)
.setId("123")
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
.setSource("https://spring.io/")
.setType("org.springframework")
.build();
Function<Flux<String>, Flux<String>> functionAsFlux = catalog.lookup("upperCaseFunction");
List<String> results = functionAsFlux.apply(Flux.just("bob", "stacy")).collectList().block();
assertThat(results.get(0)).isEqualTo("BOB");
assertThat(results.get(1)).isEqualTo("STACY");
assertThat(new String(function.apply(inputMessage).getPayload())).isEqualTo(data);
}
@Test
@@ -146,20 +150,28 @@ public class FunctionDeployerTests {
public void testWithSimplestJarExploaded() throws Exception {
String[] args = new String[] {
"--spring.cloud.function.location=target/it/simplestjar/target/classes",
"--spring.cloud.function.function-class=function.example.UpperCaseFunction" };
"--spring.cloud.function.function-class=function.example.EchoCloudEventFunction" };
ApplicationContext context = SpringApplication.run(DeployerApplication.class, args);
FunctionCatalog catalog = context.getBean(FunctionCatalog.class);
Function<String, String> function = catalog.lookup("upperCaseFunction");
Function<Message<String>, Message<byte[]>> function = catalog.lookup("echoCloudEventFunction");
assertThat(function.apply("bob")).isEqualTo("BOB");
assertThat(function.apply("stacy")).isEqualTo("STACY");
String data = "{\"name\":\"Ricky\"}";
Message<String> inputMessage = CloudEventMessageBuilder
.withData(data)
.setId("123")
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
.setSource("https://spring.io/")
.setType("org.springframework")
.build();
Function<Flux<String>, Flux<String>> functionAsFlux = catalog.lookup("upperCaseFunction");
assertThat(new String(function.apply(inputMessage).getPayload())).isEqualTo(data);
List<String> results = functionAsFlux.apply(Flux.just("bob", "stacy")).collectList().block();
assertThat(results.get(0)).isEqualTo("BOB");
assertThat(results.get(1)).isEqualTo("STACY");
Function<Flux<Message<String>>, Flux<Message<byte[]>>> functionAsFlux = catalog.lookup("echoCloudEventFunction");
List<Message<byte[]>> results = functionAsFlux.apply(Flux.just(inputMessage)).collectList().block();
assertThat(results.get(0).getPayload()).isEqualTo(data.getBytes());
//assertThat(results.get(1)).isEqualTo("STACY");
}
/*