diff --git a/examples/pom.xml b/examples/pom.xml index 2863c129..2384b5e4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -18,6 +18,7 @@ restful-ws-quarkus vertx basic-http + restful-ws-spring-boot diff --git a/examples/restful-ws-spring-boot/README.md b/examples/restful-ws-spring-boot/README.md new file mode 100644 index 00000000..df59a9ee --- /dev/null +++ b/examples/restful-ws-spring-boot/README.md @@ -0,0 +1,21 @@ +## CloudEvents Restful WS + Spring Boot + Jersey example + +This sample shows how to create a Spring Boot application that accepts CloudEvents and replies with CloudEvents. + +To run it: + +```shell +mvn spring-boot:run +``` + +You can try sending a request using `curl`: + +```shell +curl -X POST -v -d '{"username": "slinkydeveloper", "firstName": "Francesco", "lastName": "Guardiani", "age": 23}' \ ~ + -H'Content-type: application/json' \ + -H'Ce-id: 1' \ + -H'Ce-source: cloud-event-example' \ + -H'Ce-type: happybirthday.myapplication' \ + -H'Ce-specversion: 1.0' \ + http://localhost:8080/happy_birthday +``` diff --git a/examples/restful-ws-spring-boot/pom.xml b/examples/restful-ws-spring-boot/pom.xml new file mode 100644 index 00000000..ee62fba0 --- /dev/null +++ b/examples/restful-ws-spring-boot/pom.xml @@ -0,0 +1,65 @@ + + + + cloudevents-examples + io.cloudevents + 2.0.0-SNAPSHOT + + 4.0.0 + + cloudevents-spring-boot-example + + + 2.3.2.RELEASE + 5.2.8.RELEASE + + + + + + org.springframework + spring-framework-bom + ${spring.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-jersey + ${spring-boot.version} + + + io.cloudevents + cloudevents-core + ${project.version} + + + + io.cloudevents + cloudevents-json-jackson + ${project.version} + + + io.cloudevents + cloudevents-http-restful-ws + ${project.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + + diff --git a/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/Application.java b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/Application.java new file mode 100644 index 00000000..6d075421 --- /dev/null +++ b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/Application.java @@ -0,0 +1,31 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.cloudevents.examples.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/JerseyConfiguration.java b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/JerseyConfiguration.java new file mode 100644 index 00000000..9f1ae948 --- /dev/null +++ b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/JerseyConfiguration.java @@ -0,0 +1,33 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.cloudevents.examples.springboot; + +import io.cloudevents.http.restful.ws.CloudEventsProvider; +import org.glassfish.jersey.server.ResourceConfig; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JerseyConfiguration extends ResourceConfig { + + public JerseyConfiguration() { + // Configure Jersey to load the CloudEventsProvider (which serializes/deserializes CloudEvents) + // and our resource + registerClasses(CloudEventsProvider.class, MainResource.class); + } + +} diff --git a/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/MainResource.java b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/MainResource.java new file mode 100644 index 00000000..d82f033e --- /dev/null +++ b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/MainResource.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.cloudevents.examples.springboot; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; +import io.cloudevents.core.data.PojoCloudEventData; +import io.cloudevents.jackson.PojoCloudEventDataMapper; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import static io.cloudevents.core.CloudEventUtils.mapData; + +@Path("/") +public class MainResource { + + public static final String HAPPY_BIRTHDAY_EVENT_TYPE = "happybirthday.myapplication"; + + @Autowired + ObjectMapper objectMapper; + + @POST + @Path("happy_birthday") + public Response handleHappyBirthdayEvent(CloudEvent inputEvent) { + if (!inputEvent.getType().equals(HAPPY_BIRTHDAY_EVENT_TYPE)) { + return Response.status(Response.Status.BAD_REQUEST) + .type(MediaType.TEXT_PLAIN) + .entity("Event type should be \"" + HAPPY_BIRTHDAY_EVENT_TYPE + "\" but is \"" + inputEvent.getType() + "\"") + .build(); + } + + PojoCloudEventData cloudEventData = mapData(inputEvent, PojoCloudEventDataMapper.from(objectMapper, User.class)); + + if (cloudEventData == null) { + return Response.status(Response.Status.BAD_REQUEST) + .type(MediaType.TEXT_PLAIN) + .entity("Event should contain the user") + .build(); + } + + User user = cloudEventData.getValue(); + user.setAge(user.getAge() + 1); + + CloudEvent outputEvent = CloudEventBuilder.from(inputEvent) + .withData(PojoCloudEventData.wrap(user, objectMapper::writeValueAsBytes)) + .build(); + + return Response.ok(outputEvent).build(); + } +} diff --git a/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/User.java b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/User.java new file mode 100644 index 00000000..f06d6763 --- /dev/null +++ b/examples/restful-ws-spring-boot/src/main/java/io/cloudevents/examples/springboot/User.java @@ -0,0 +1,72 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.cloudevents.examples.springboot; + +public class User { + + private String username; + private String firstName; + private String lastName; + private Integer age; + + public String getUsername() { + return username; + } + + public User setUsername(String username) { + this.username = username; + return this; + } + + public String getFirstName() { + return firstName; + } + + public User setFirstName(String firstName) { + this.firstName = firstName; + return this; + } + + public String getLastName() { + return lastName; + } + + public User setLastName(String lastName) { + this.lastName = lastName; + return this; + } + + public Integer getAge() { + return age; + } + + public User setAge(Integer age) { + this.age = age; + return this; + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", age=" + age + + '}'; + } +}