Skip to content

Commit

Permalink
Restful-ws jakarta ee9 namespace support (cloudevents#469)
Browse files Browse the repository at this point in the history
* Replace javax restful-ws namespace usage with jakarata in own module
* Add microprofile with openliberty example using new jar
* Update gitignore to cover all copied directories
* Update Jersey Version to support jakarta.* namespace packages
* Port jersey integration tests from javax.* to jakarta.*
* Undo changes to existing integration test package names
* Add Integration test for Microprofile/Liberty for Jee9 package
* Add documentation for new Jakarta package

Signed-off-by: alex-butcher <[email protected]>
(cherry picked from commit f08a099)
  • Loading branch information
abutch3r authored and RobpMobX committed Apr 28, 2023
1 parent 62e9f22 commit 9eead70
Show file tree
Hide file tree
Showing 27 changed files with 1,655 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ _site/

# MacOS
*.DS_Store
/http/restful-ws-jakarta/src/main/*

137 changes: 137 additions & 0 deletions docs/http-jakarta-restful-ws-jakarta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
title: CloudEvents HTTP Jakarta EE 9+ - Jakarta RESTful Web Services
nav_order: 5
---

# HTTP Protocol Binding for Jakarta EE 9+ - Jakarta RESTful Web Services

[![Javadocs](https://www.javadoc.io/badge/io.cloudevents/cloudevents-http-restful-ws.svg?color=green)](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-restful-ws)

For Maven based projects, use the following to configure the CloudEvents Jakarta
RESTful Web Services Binding for Jakarta EE 9+:

```xml
<dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-http-restful-ws-jakarta</artifactId>
<version>2.5.0-SNAPSHOT</version>
</dependency>
```

This integration is tested with Jersey (Requires JDK11 or higher), RestEasy & Microprofile Liberty.

#### * Before using this package ensure your web framework does support the `jakarta.*` namespace.

## Receiving CloudEvents

You need to configure the `CloudEventsProvider` to enable
marshalling/unmarshalling of CloudEvents.

Below is a sample on how to read and write CloudEvents:

```java
import io.cloudevents.CloudEvent;
import io.cloudevents.core.builder.CloudEventBuilder;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;

@Path("/")
public class EventReceiverResource {



@GET
@Path("getMinEvent")
public CloudEvent getMinEvent() {
return CloudEventBuilder.v1()
.withId("hello")
.withType("example.vertx")
.withSource(URI.create("http://localhost"))
.build();
}

// Return the CloudEvent using the HTTP binding structured encoding
@GET
@Path("getStructuredEvent")
@StructuredEncoding("application/cloudevents+csv")
public CloudEvent getStructuredEvent() {
return CloudEventBuilder.v1()
.withId("hello")
.withType("example.vertx")
.withSource(URI.create("http://localhost"))
.build();
}

@POST
@Path("postEventWithoutBody")
public Response postEvent(CloudEvent inputEvent) {
// Handle the event
return Response.ok().build();
}
}
```

## Sending CloudEvents

You need to configure the `CloudEventsProvider` to enable
marshalling/unmarshalling of CloudEvents.

Below is a sample on how to use the client to send a CloudEvent:

```java
import io.cloudevents.CloudEvent;
import io.cloudevents.http.restful.ws.CloudEventsProvider;

import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;

public class CloudEventSender {

public Response sendEvent(WebTarget target, CloudEvent event) {
return target
.path("postEvent")
.request()
.buildPost(Entity.entity(event, CloudEventsProvider.CLOUDEVENT_TYPE))
.invoke();
}

public Response sendEventAsStructured(WebTarget target, CloudEvent event) {
return target
.path("postEvent")
.request()
.buildPost(Entity.entity(event, "application/cloudevents+json"))
.invoke();
}

public CloudEvent getEvent(WebTarget target) {
Response response = target
.path("getEvent")
.request()
.buildGet()
.invoke();

return response.readEntity(CloudEvent.class);
}
}
```

## Migrating EE 8 applications to EE 9+
The main change between Jakarta EE 8 and Jakarta EE 9 and future versions is the changing of the `javax.` to `jakarta.` namespaces used by key packages such as `jakarta.ws.rs-api` which provides the restful-ws API.

This change largely impacts only `import` statements it does filter down to dependencies such as this.

### Application migration
For application migration we would recommend reviewing materials available from https://jakarta.ee/resources/#documentation as a starting point.

### CloudEvents Dependency
To migrate to use EE 9+ supported package - replace `cloudevents-http-restful-ws` with `cloudevents-http-restful-ws-jakarta` and ensure the version is a minimum of `2.5.0-SNAPSHOT`

## Examples

- [Microprofile and Liberty](https://github.com/cloudevents/sdk-java/tree/master/examples/restful-ws-micropofile-liberty)

4 changes: 2 additions & 2 deletions docs/http-jakarta-restful-ws.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ title: CloudEvents HTTP Jakarta RESTful Web Services
nav_order: 5
---

# HTTP Protocol Binding for Jakarta RESTful Web Services
# HTTP Protocol Binding for Jakarta EE8 - RESTful Web Services

[![Javadocs](http://www.javadoc.io/badge/io.cloudevents/cloudevents-http-restful-ws.svg?color=green)](http://www.javadoc.io/doc/io.cloudevents/cloudevents-http-restful-ws)

For Maven based projects, use the following to configure the CloudEvents Jakarta
RESTful Web Services Binding:
RESTful Web Services Binding for Jakarta EE 8:

```xml
<dependency>
Expand Down
8 changes: 6 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ receive CloudEvents, check out the dedicated pages:

- [AMQP using Proton](amqp-proton.md)
- [HTTP using Vert.x](http-vertx.md)
- [HTTP using Jakarta Restful WS](http-jakarta-restful-ws.md)
- [HTTP using Jakarta EE 8 - Jakarta Restful WS](http-jakarta-restful-ws.md)
- [HTTP using Jakarta EE 9+ - Jakarta Restful WS](http-jakarta-restful-ws-jakarta.md)
- [HTTP using Spring](spring.md)
- [HTTP using Jackson](json-jackson.md)
- [Kafka](kafka.md)
Expand Down Expand Up @@ -98,7 +99,9 @@ a different feature from the different sub specs of
- [`cloudevents-http-vertx`] Implementation of [HTTP Protocol Binding] with
[Vert.x Core](https://vertx.io/)
- [`cloudevents-http-restful-ws`] Implementation of [HTTP Protocol Binding]
for [Jakarta Restful WS](https://jakarta.ee/specifications/restful-ws/)
for [Jakarta EE 8 Restful WS](https://jakarta.ee/specifications/restful-ws/2.1/)
- [`cloudevents-http-restful-ws-jakarta`] Implementation of [HTTP Protocol Binding]
for [Jakarta EE 9+ Restful WS](https://jakarta.ee/specifications/restful-ws/)
- [`cloudevents-http-basic`] Generic implementation of [HTTP Protocol
Binding], primarily intended for integrators
- [`cloudevents-kafka`] Implementation of [Kafka Protocol Binding]
Expand All @@ -123,6 +126,7 @@ You can look at the latest published artifacts on
[`cloudevents-http-vertx`]: https://github.com/cloudevents/sdk-java/tree/master/http/vertx
[`cloudevents-http-basic`]: https://github.com/cloudevents/sdk-java/tree/master/http/basic
[`cloudevents-http-restful-ws`]: https://github.com/cloudevents/sdk-java/tree/master/http/restful-ws
[`cloudevents-http-restful-ws-jakarta`]: https://github.com/cloudevents/sdk-java/tree/master/http/restful-ws-jakarta
[`cloudevents-kafka`]: https://github.com/cloudevents/sdk-java/tree/master/kafka
[`cloudevents-amqp-proton`]: https://github.com/cloudevents/sdk-java/tree/master/amqp
[`cloudevents-spring`]: https://github.com/cloudevents/sdk-java/tree/master/spring
Expand Down
1 change: 1 addition & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<modules>
<module>kafka</module>
<module>restful-ws-quarkus</module>
<module>restful-ws-microprofile-liberty</module>
<module>vertx</module>
<module>basic-http</module>
<module>restful-ws-spring-boot</module>
Expand Down
140 changes: 140 additions & 0 deletions examples/restful-ws-microprofile-liberty/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Cloudevents Restful WS Microprofile Example

This project uses Microprofile 5.0 with OpenLiberty

If you would like to know more about Microprofile go to https://microprofile.io

This Example uses Jakarta EE9 features as such the top level namespace of the `ws-api` packages has changed from `javax` to `jakarta` and uses the `cloudevents-http-restful-ws-jakarta` artifact.

## Build and Execution

### Running the application in dev mode

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

### Packaging and running the application

To Package and run as a minimum jar without a full OpenLiberty server
```
mvn liberty:package -Drunnable=mvn liberty:package -Dinclude=runnable
```

### Making requests against the server

This sample application has a `/events` RESTful endpoint on the application `cloudevents-restful-ws-microprofile-example
the base application is available at `http://localhost:9080/cloudevents-restful-ws-microprofile-example/`

There are three operations that can be performed:
#### GET /events
Returns a Cloud event with a payload containing a message

```shell
curl -v http://localhost:9080/cloudevents-restful-ws-microprofile-example/events

* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> GET /cloudevents-restful-ws-microprofile-example/events HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.83.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 no-content
< Ce-Id: hello
< Ce-Source: http://localhost
< Ce-Specversion: 1.0
< Ce-Type: example.http
< Content-Type: application/json
< Content-Language: en-GB
< Content-Length: 64
< Date: Wed, 17 Aug 2022 14:01:50 GMT
<
{"message":"Welcome to this Cloudevents + Microprofile example"}
```
#### POST /events
POST a Cloudevent with a payload that is printed out in the server logs
```shell
curl -v http://localhost:9080/cloudevents-restful-ws-microprofile-example/events \
-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 "hello"

* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> POST /cloudevents-restful-ws-microprofile-example/events HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.83.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: 5
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 204 No Content
< Content-Language: en-GB
< Content-Length: 0
< Date: Thu, 18 Aug 2022 13:33:03 GMT
<
* Connection #0 to host localhost left intact
```
Server log statement
```
[INFO] Received request providing a event with body hello
[INFO] CloudEvent{id='536808d3-88be-4077-9d7a-a3f162705f78', source=io.cloudevents.examples/user, type='User', datacontenttype='application/json', subject='SUBJ-0001', data=BytesCloudEventData{value=[104, 101, 108, 108, 111]}, extensions={}}
```
#### POST /events/echo
POST a Cloudevent with a payload and have it echoed back as a Cloudevent
```shell
curl -v http://localhost:9080/cloudevents-restful-ws-microprofile-example/events/echo \
-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 "hello"

* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> POST /cloudevents-restful-ws-microprofile-example/rest/events/echo HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.83.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: 5
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Ce-Id: echo
< Ce-Source: http://localhost
< Ce-Specversion: 1.0
< Ce-Type: echo.http
< Content-Type: application/json
< Content-Language: en-GB
< Content-Length: 17
< Date: Wed, 17 Aug 2022 12:57:59 GMT
<
{"echo": "hello"}* Connection #0 to host localhost left intact
```
Loading

0 comments on commit 9eead70

Please sign in to comment.