Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<modules>
<module>kafka</module>
<module>restful-ws-quarkus</module>
<module>vertx</module>
</modules>

Expand Down
85 changes: 85 additions & 0 deletions examples/restful-ws-quarkus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Cloudevents Restful WS Quarkus example

This sample application has a `/users` REST endpoint in which you can manage the different users.
The way to create users is through CloudEvents. Here is an example POST:

```shell script
curl -v http://localhost:8080/users \
-H "Ce-Specversion: 1.0" \
-H "Ce-Type: User" \
-H "Ce-Source: io.cloudevents.examples/user" \
-H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f78" \
-H "Content-Type: application/json" \
-H "Ce-Subject: SUBJ-0001" \
-d @examples/user.json

> POST /users HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.69.1
> Accept: */*
> Ce-Specversion: 1.0
> Ce-Type: User
> Ce-Source: io.cloudevents.examples/user
> Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f78
> Content-Type: application/json
> Ce-Subject: SUBJ-0001
> Content-Length: 88

< HTTP/1.1 201 Created
< Content-Length: 0
< Location: http://localhost:8080/users
```

In order to also show how to create and send CloudEvents, generated events will be periodically sent
each 2 seconds through HTTP to the same endpoint using a REST client.

Check the following URL to view the existing users:

```shell script
$ curl http://localhost:8080/users
{
"user1": {
"username": "user1",
"firstName": "firstName1",
"lastName": "lastName1",
"age": 1
},
"user2": {
"username": "user2",
"firstName": "firstName2",
"lastName": "lastName2",
"age": 2
}
}
```

## Build and execution

This project uses Quarkus, the Supersonic Subatomic Java Framework.

If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .

### Running the application in dev mode

You can run your application in dev mode that enables live coding using:
```
mvn quarkus:dev
```

### Packaging and running the application

The application can be packaged using `mvn package`.
It produces the `cloudevents-restful-ws-quarkus-example-1.0-SNAPSHOT-runner.jar` file in the `/target` directory.
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/lib` directory.

The application is now runnable using `java -jar target/cloudevents-restful-ws-quarkus-example-1.0-SNAPSHOT-runner.jar`.

### Creating a native executable

You can create a native executable using: `mvn package -Pnative`.

Or, if you don't have GraalVM installed, you can run the native executable build in a container using: `mvn package -Pnative -Dquarkus.native.container-build=true`.

You can then execute your native executable with: `./target/cloudevents-restful-ws-quarkus-example-1.0-SNAPSHOT-runner`

If you want to learn more about building native executables, please consult https://quarkus.io/guides/building-native-image.
6 changes: 6 additions & 0 deletions examples/restful-ws-quarkus/examples/user.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"username": "jsmith",
"firstName": "John",
"lastName": "Smith",
"age": 37
}
118 changes: 118 additions & 0 deletions examples/restful-ws-quarkus/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parent>
<artifactId>cloudevents-examples</artifactId>
<groupId>io.cloudevents</groupId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudevents-restful-ws-quarkus-example</artifactId>
<properties>
<quarkus-plugin.version>1.7.1.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>1.7.1.Final</quarkus.platform.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client</artifactId>
</dependency>
<dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-http-restful-ws</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-json-jackson</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare</goal>
<goal>prepare-tests</goal>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.cloudevents.examples.quarkus.client;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.cloudevents.CloudEvent;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

@Path("/users")
@RegisterRestClient
public interface UserClient {

@POST
@Produces(MediaType.APPLICATION_JSON)
void emit(CloudEvent event);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.cloudevents.examples.quarkus.client;

import java.net.URI;
import java.time.Duration;
import java.util.UUID;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;

import io.cloudevents.CloudEvent;
import io.cloudevents.core.builder.CloudEventBuilder;
import io.cloudevents.examples.quarkus.model.User;
import io.quarkus.runtime.StartupEvent;
import io.smallrye.mutiny.Multi;
import io.vertx.core.json.Json;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ApplicationScoped
public class UserEventsGenerator {

private static final Logger LOGGER = LoggerFactory.getLogger(UserEventsGenerator.class);

@Inject
@RestClient
UserClient userClient;

public void init(@Observes StartupEvent startupEvent) {
Multi.createFrom().ticks().every(Duration.ofSeconds(2))
.onItem()
.transform(this::createEvent)
.subscribe()
.with(event -> {
LOGGER.info("try to emit user: {}", event.getId());
userClient.emit(event);
});
}

private CloudEvent createEvent(long id) {
return CloudEventBuilder.v1()
.withSource(URI.create("example"))
.withType("io.cloudevents.examples.quarkus.user")
.withId(UUID.randomUUID().toString())
.withDataContentType(MediaType.APPLICATION_JSON)
.withData(createUserAsByteArray(id))
.build();
}

private byte[] createUserAsByteArray(Long id) {
User user = new User()
.setAge(id.intValue())
.setUsername("user" + id)
.setFirstName("firstName" + id)
.setLastName("lastName" + id);
return Json.encode(user).getBytes();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.cloudevents.examples.quarkus.model;

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 +
'}';
}
}
Loading