GH-422 Formalize Cloud Event conversion strategy to consistently handle binary-mode and structured-mode cloud events

Moved CloudEvent related artifacts to ‘cloud events’ package with hopes to eventually donating it to CNCF SDK
Created CloudEventUtils identifying necessary constants and utility methods
This commit is contained in:
Oleg Zhurakousky
2020-11-12 15:13:35 +01:00
parent daa3c27226
commit a26ad928f6
14 changed files with 703 additions and 95 deletions

View File

@@ -38,7 +38,24 @@ provides a good example on how to accomplish this.
### Function as a REST endpoint
Given that SCF allows function to be exposed as REST endpoints, you can post cloud event to any of the
functions by using function name as path (e.g., `localhost:8080/<function_name>`)
functions by using function name as path (e.g., `localhost:8080/<function_name>`).
Just add this to your dependency
[source, xml]
----
<!-- REST - only needed if you intend to invoke via HTTP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.1.0-SNAPSHOT</version>
</dependency>
<!-- end REST -->
----
Here is an example of curl command posting a cloud event in binary-mode:

View File

@@ -2,28 +2,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.spring.sample</groupId>
<artifactId>function-sample-cloudevent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>function-sample-cloudevent</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0-RC1</version>
<relativePath/>
</parent>
<properties>
<java.version>8</java.version>
<java.version>1.8</java.version>
<spring-cloud-function.version>3.1.0-SNAPSHOT</spring-cloud-function.version>
<wrapper.version>1.0.21.RELEASE</wrapper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- REST - only needed if you intend to invoke via HTTP -->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -32,7 +31,7 @@
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.1.0-SNAPSHOT</version>
<!-- <version>3.1.0-SNAPSHOT</version> -->
</dependency>
<!-- end REST -->
@@ -59,8 +58,7 @@
<!-- <version>3.1.0-SNAPSHOT</version> -->
<!-- </dependency> -->
<!-- end Kafka -->
<dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
@@ -73,13 +71,112 @@
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-dependencies</artifactId>
<version>${spring-cloud-function.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Tests.java</include>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.function.context.config.CloudEventJsonMessageConverter;
import org.springframework.cloud.function.cloudevent.CloudEventJsonMessageConverter;
import org.springframework.cloud.function.json.JsonMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -39,7 +39,9 @@ import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.AbstractMessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.util.MimeType;
import org.springframework.util.SocketUtils;
/**
@@ -190,12 +192,12 @@ public class CloudeventDemoApplicationRESTTests {
RequestEntity<String> re = new RequestEntity<>(payload, headers, HttpMethod.POST, this.constructURI("/asStringMessage"));
ResponseEntity<String> response = testRestTemplate.exchange(re, String.class);
assertThat(response.getBody()).isEqualTo(payload);
assertThat(response.getBody()).isEqualTo("{\"version\":\"1.0\",\"releaseName\":\"Spring Framework\",\"releaseDate\":\"24-03-2004\"}");
re = new RequestEntity<>(payload, headers, HttpMethod.POST, this.constructURI("/asString"));
response = testRestTemplate.exchange(re, String.class);
assertThat(response.getBody()).isEqualTo(payload);
assertThat(response.getBody()).isEqualTo("{\"version\":\"1.0\",\"releaseName\":\"Spring Framework\",\"releaseDate\":\"24-03-2004\"}");
}
@@ -207,10 +209,10 @@ public class CloudeventDemoApplicationRESTTests {
}
}
public static class FooBarToCloudEventMessageConverter extends CloudEventJsonMessageConverter {
public static class FooBarToCloudEventMessageConverter extends AbstractMessageConverter {
public FooBarToCloudEventMessageConverter(JsonMapper jsonMapper) {
super(jsonMapper);
super(new MimeType("foo", "bar"));
}
@Override