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
97 changes: 57 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,95 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.cloudevents/cloudevents-parent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.cloudevents/cloudevents-parent)
[![Javadocs](http://www.javadoc.io/badge/io.cloudevents/cloudevents-core.svg?color=green)](http://www.javadoc.io/doc/io.cloudevents/cloudevents-core)

A Java API for the [CloudEvents specification](https://github.com/cloudevents/spec)
A Java API for the
[CloudEvents specification](https://github.com/cloudevents/spec)

Look at https://cloudevents.github.io/sdk-java/ for more documentation.

## Status

This SDK is considered **work in progress**. The community is working hard to bring you a new major version of the SDK with major enhancements both to APIs and to implementation.
This SDK is considered **work in progress**. The community is working hard to
bring you a new major version of the SDK with major enhancements both to APIs
and to implementation.

If you want to know more about v1 of this SDK, check out the [v1 readme](https://github.com/cloudevents/sdk-java/tree/1.x)
If you want to know more about v1 of this SDK, check out the
[v1 readme](https://github.com/cloudevents/sdk-java/tree/1.x)

Stay tuned!

Supported features of the specification:

| | [v0.3](https://github.com/cloudevents/spec/tree/v0.3) | [v1.0](https://github.com/cloudevents/spec/tree/v1.0) |
| :---------------------------: | :----------------------------------------------------------------------------: | :---------------------------------------------------------------------------------: |
| CloudEvents Core | :heavy_check_mark: | :heavy_check_mark: |
| AMQP Protocol Binding | :x: | :x: |
| AVRO Event Format | :x: | :x: |
| HTTP Protocol Binding | :heavy_check_mark: | :heavy_check_mark: |
| - [Vert.x](http/vertx) | :heavy_check_mark: | :heavy_check_mark: |
| - [Jakarta Restful WS](http/restful-ws) | :heavy_check_mark: | :heavy_check_mark: |
| JSON Event Format | :heavy_check_mark: | :heavy_check_mark: |
| - [Jackson](formats/json-jackson) | :heavy_check_mark: | :heavy_check_mark: |
| [Kafka Protocol Binding](kafka) | :heavy_check_mark: | :heavy_check_mark: |
| MQTT Protocol Binding | :x: | :x: |
| NATS Protocol Binding | :x: | :x: |
| Web hook | :x: | :x: |
| | [v0.3](https://github.com/cloudevents/spec/tree/v0.3) | [v1.0](https://github.com/cloudevents/spec/tree/v1.0) |
| :-------------------------------------: | :---------------------------------------------------: | :---------------------------------------------------: |
| CloudEvents Core | :heavy_check_mark: | :heavy_check_mark: |
| AMQP Protocol Binding | :x: | :x: |
| - [Proton](amqp) | :heavy_check_mark: | :heavy_check_mark: |
| AVRO Event Format | :x: | :x: |
| HTTP Protocol Binding | :heavy_check_mark: | :heavy_check_mark: |
| - [Vert.x](http/vertx) | :heavy_check_mark: | :heavy_check_mark: |
| - [Jakarta Restful WS](http/restful-ws) | :heavy_check_mark: | :heavy_check_mark: |
| - [Basic](http/basic) | :heavy_check_mark: | :heavy_check_mark: |
| JSON Event Format | :heavy_check_mark: | :heavy_check_mark: |
| - [Jackson](formats/json-jackson) | :heavy_check_mark: | :heavy_check_mark: |
| [Kafka Protocol Binding](kafka) | :heavy_check_mark: | :heavy_check_mark: |
| MQTT Protocol Binding | :x: | :x: |
| NATS Protocol Binding | :x: | :x: |
| Web hook | :x: | :x: |

## Motivation

The [CloudEvents specification](https://github.com/cloudevents/spec) is a vendor-neutral specification for defining the format of event data that is being exchanged between different cloud systems. The specification basically defines an abstract envelope for any event data payload, without knowing specific implementation details of the actual underlying event.
The current version of the spec is at `1.0` and it describes a simple event format, which was demonstrated at [KubeCon 2018](https://youtu.be/TZPPjAv12KU) using different _Serverless platforms_, such as [Apache Openwhisk](https://github.com/apache/incubator-openwhisk).
The [CloudEvents specification](https://github.com/cloudevents/spec) is a
vendor-neutral specification for defining the format of event data that is being
exchanged between different cloud systems. The specification basically defines
an abstract envelope for any event data payload, without knowing specific
implementation details of the actual underlying event. The current version of
the spec is at `1.0` and it describes a simple event format, which was
demonstrated at [KubeCon 2018](https://youtu.be/TZPPjAv12KU) using different
_Serverless platforms_, such as
[Apache Openwhisk](https://github.com/apache/incubator-openwhisk).

## Documentation

Documentation is available at https://cloudevents.github.io/sdk-java/

Javadocs are available on [javadoc.io](https://www.javadoc.io):

* [cloudevents-api](https://www.javadoc.io/doc/io.cloudevents/cloudevents-api)
* [cloudevents-core](https://www.javadoc.io/doc/io.cloudevents/cloudevents-core)
* [cloudevents-json-jackson](https://www.javadoc.io/doc/io.cloudevents/cloudevents-json-jackson)
* [cloudevents-http-basic](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-basic)
* [cloudevents-http-restful-ws](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-restful-ws)
* [cloudevents-http-vertx](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-vertx)
* [cloudevents-kafka](https://www.javadoc.io/doc/io.cloudevents/cloudevents-kafka)
- [cloudevents-api](https://www.javadoc.io/doc/io.cloudevents/cloudevents-api)
- [cloudevents-core](https://www.javadoc.io/doc/io.cloudevents/cloudevents-core)
- [cloudevents-json-jackson](https://www.javadoc.io/doc/io.cloudevents/cloudevents-json-jackson)
- [cloudevents-http-basic](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-basic)
- [cloudevents-http-restful-ws](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-restful-ws)
- [cloudevents-http-vertx](https://www.javadoc.io/doc/io.cloudevents/cloudevents-http-vertx)
- [cloudevents-kafka](https://www.javadoc.io/doc/io.cloudevents/cloudevents-kafka)

You can check out the examples in the [examples](examples) directory.

## Used By

| [Occurrent](https://occurrent.org) | [Knative Eventing](https://github.com/knative-sandbox/eventing-kafka-broker) |
|-------------|-------------|
| [Occurrent](https://occurrent.org) | [Knative Eventing](https://github.com/knative-sandbox/eventing-kafka-broker) |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <a href="https://occurrent.org"><img src="https://raw.githubusercontent.com/johanhaleby/occurrent/master/occurrent-logo-196x196.png" width="98" height="98" alt="Occurrent" title="Occurrent - Event Sourcing Utilities for the JVM"></img></a> | <a href="https://github.com/knative-sandbox/eventing-kafka-broker"><img src="https://cloudevents.io/img/logos/integrations/knative.png" height="98"></img></a> |

## Community

- There are bi-weekly calls immediately following the [Serverless/CloudEvents
call](https://github.com/cloudevents/spec#meeting-time) at
9am PT (US Pacific). Which means they will typically start at 10am PT, but
if the other call ends early then the SDK call will start early as well.
See the [CloudEvents meeting minutes](https://docs.google.com/document/d/1OVF68rpuPK5shIHILK9JOqlZBbfe91RNzQ7u_P7YCDE/edit#)
to determine which week will have the call.
- Slack: #cloudeventssdk channel under
[CNCF's Slack workspace](https://slack.cncf.io/).
- Email: https://lists.cncf.io/g/cncf-cloudevents-sdk
- Contact for additional information: Francesco Guardiani (`@slinkydeveloper` on slack), Fabio José (`@fabiojose` on slack).
- There are bi-weekly calls immediately following the
[Serverless/CloudEvents call](https://github.com/cloudevents/spec#meeting-time)
at 9am PT (US Pacific). Which means they will typically start at 10am PT,
but if the other call ends early then the SDK call will start early as well.
See the
[CloudEvents meeting minutes](https://docs.google.com/document/d/1OVF68rpuPK5shIHILK9JOqlZBbfe91RNzQ7u_P7YCDE/edit#)
to determine which week will have the call.
- Slack: #cloudeventssdk channel under
[CNCF's Slack workspace](https://slack.cncf.io/).
- Email: https://lists.cncf.io/g/cncf-cloudevents-sdk
- Contact for additional information: Francesco Guardiani (`@slinkydeveloper`
on slack), Fabio José (`@fabiojose` on slack).

Each SDK may have its own unique processes, tooling and guidelines, common
governance related material can be found in the
[CloudEvents `community`](https://github.com/cloudevents/spec/tree/master/community)
directory. In particular, in there you will find information concerning
how SDK projects are
directory. In particular, in there you will find information concerning how SDK
projects are
[managed](https://github.com/cloudevents/spec/blob/master/community/SDK-GOVERNANCE.md),
[guidelines](https://github.com/cloudevents/spec/blob/master/community/SDK-maintainer-guidelines.md)
for how PR reviews and approval, and our
Expand Down
20 changes: 20 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# CloudEvents sdk-java examples

This directory includes some examples on how to use CloudEvents sdk-java:

- [amqp-proton](amqp-proton) shows how to use the module
`cloudevents-amqp-proton` to send and receive CloudEvents using AMQP 1.0.
- [kafka](kafka) shows how to use the module `cloudevents-kafka` to produce
and consume CloudEvents on Kafka topics.
- [restful-ws-quarkus](restful-ws-quarkus) shows how to use the module
`cloudevents-http-restful-ws` with Quarkus to receive and send CloudEvents
through HTTP.
- [restful-ws-spring-boot](restful-ws-spring-boot) shows how to use the module
`cloudevents-http-restful-ws` with Spring Boot and Jersey to receive and
send CloudEvents through HTTP.
- [vertx](vertx) shows how to use the module `cloudevents-http-vertx` to
receive and send CloudEvents through HTTP using `vertx-web-client` and
`vertx-core`.
- [basic-http](basic-http) shows how to use the module
`cloudevents-http-basic` to send and receive CloudEvents using `JDK`'s
`HttpServer`, `HttpURLConnection` and Jetty.
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
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 com.fasterxml.jackson.databind.ObjectMapper;
import io.cloudevents.CloudEvent;
import io.cloudevents.CloudEventData;
import io.cloudevents.core.builder.CloudEventBuilder;
import io.cloudevents.core.data.PojoCloudEventData;
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;

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

@ApplicationScoped
public class UserEventsGenerator {

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

@Inject
ObjectMapper mapper;

@Inject
@RestClient
UserClient userClient;
Expand All @@ -44,16 +49,16 @@ private CloudEvent createEvent(long id) {
.withType("io.cloudevents.examples.quarkus.user")
.withId(UUID.randomUUID().toString())
.withDataContentType(MediaType.APPLICATION_JSON)
.withData(createUserAsByteArray(id))
.withData(createUser(id))
.build();
}

private byte[] createUserAsByteArray(Long id) {
private CloudEventData createUser(Long id) {
User user = new User()
.setAge(id.intValue())
.setUsername("user" + id)
.setFirstName("firstName" + id)
.setLastName("lastName" + id);
return Json.encode(user).getBytes();
return PojoCloudEventData.wrap(user, mapper::writeValueAsBytes);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.cloudevents.examples.quarkus.resources;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.cloudevents.CloudEvent;
import io.cloudevents.examples.quarkus.model.User;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.Json;
import io.cloudevents.jackson.PojoCloudEventDataMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
Expand All @@ -22,6 +23,9 @@ public class UserResource {

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

@Inject
ObjectMapper mapper;

@Context
UriInfo uriInfo;

Expand All @@ -46,7 +50,10 @@ public Response create(CloudEvent event) {
if (event == null || event.getData() == null) {
throw new BadRequestException("Invalid data received. Null or empty event");
}
User user = Json.decodeValue(Buffer.buffer(event.getData().toBytes()), User.class);
User user = PojoCloudEventDataMapper
.from(mapper, User.class)
.map(event.getData())
.getValue();
if (users.containsKey(user.getUsername())) {
throw new BadRequestException("Username already exists: " + user.getUsername());
}
Expand Down