Exercise 08 - Create a CloudEvent programmatically and publish it to AEM
Now that we are familiar with what a CloudEvent is, what a CloudEvent message looks like, and the different Event Formats available, let’s see how we can create one programmatically and publish it to a topic in AEM. By the end of this exercise, we will achieve a communication scenario like the one below.
Creating a CloudEvent using Node.js and publishing it to AEM
CloudEvents SDK
There are language-specific SDKs that can be used to create a message that complies with the CloudEvents standard. Below’s a list of the different languages that an SDK is available for:
Using an SDK allows us to easily create a CloudEvent message and ensure that it follows the guidelines defined in the standard. As an example, below we are using the Python SDK to create the CloudEvent message for the Ticket Website that we’ve seen as an example previously.
from cloudevents.http import CloudEvent
from cloudevents.conversion import to_binary
import requests
ticket_id = "VPHAH0OC"
# Create a CloudEvent
attributes = {
"specversion": "1.0",
"type": "itelo.tms.ticket.v1.Ticket.Purchased.v1",
"source": "https://tms-prod.itelo-entertainment.com/tickets",
"subject": ticket_id,
"datacontenttype": "application/json",
}
data = {
"ID": ticket_id,
"Customer": {
"Name": "John Doe",
"Email": "john.doe@gmail.com"
},
"CustomerAddress": {
"Street": "123 Main St",
"City": "Anytown",
"State": "CA",
"Postcode": "12345",
"Country": "USA"
},
"TicketType": {
"ID": 1,
"Description": "General Admission",
},
"DeliverTicketsByMail": true,
"NumberOfTickets": 2,
}
event = CloudEvent(attributes, data)
# Creates the HTTP request representation of the CloudEvent in binary content mode
headers, body = to_binary(event)
print(body)
You might have noticed that in the script above, we didn’t include the id
and time
attributes in the CloudEvent message. This is because the SDK will automatically generate these attributes for us. If you want to set these attributes manually, you can do so by adding them to the attributes
dictionary.
Create a CloudEvent in Node.js
We will now create a CloudEvent message programmatically using the CloudEvents SDK available for Node.js. We will use the same example as before, the ticket website that generates an event after a customer purchases a ticket.
👉 Open the CodeJam repository in SAP Business Application Studio
Open project in SAP Business Application Studio
To ensure that you are running the latest version of the repository, you can run the following commands in the terminal, from within the
/home/user/projects/event-driven-integrations-codejam
folder, to pull the latest changes:git pull origin main
.
👉 Open the terminal, navigate to the exercise folder and install the dependencies
cd exercises/08-cloudevents-sdk/code
npm install
In this folder, we have a few files that we need to get familiar with:
package.json
: Contains the dependencies of our simple application..env.sample
: Contains the environment variables that we need to set.app.js
: At the moment, the file is mostly empty. We are importing the CloudEvents SDK dependencies, loading some environment variables, and importing a module that is responsible for sending the CloudEvent message to a topic in SAP Integration Suite, advanced event mesh. This is the file that we will be working on.emitter.js
: This file contains the code that sends the CloudEvent message to the topic in SAP Integration Suite, advanced event mesh. It uses the REST API available in AEM to send a message to a topic.
👉 Make a copy of the .env.sample
file and name it .env
. Place it in the same folder as where the .env.sample
file resides.
- Replace the placeholder values with the credentials available in the Cluster Manager >
EU-North-Broker
>Connect
tab >REST
collapsible section (ensure that you selectProtocol
in theView by
dropdown). - Replace the [your-sap-community-username] placeholder with your SAP Community username in the topic.
EU-North-Broker REST API details
👉 Open the file emitter.js
and get familiar with it.
Although we don’t need to change anything in this file, it is highly recommended to get familiar with it, so that you can see how the message is sent to the topic.
👉 Open the file app.js
and get familiar with it.
Notice the different sections in the file. We will be adding code to the Define the CloudEvent contents
, Create a CloudEvent
, and Send the CloudEvent
sections.
👉 Add the code below in the Define the CloudEvent contents
section of the app.js
file:
const ticketId = "VPHAH0OC";
const type = "itelo.tms.ticket.v1.Ticket.Purchased.v1";
const source = "https://tms-prod.itelo-entertainment.com/tickets";
const datacontenttype = "application/json";
const sapcommunityid = "[your-sap-community-username]";
var data = {
"ID": ticketId,
"Customer": {
"Name": "John Doe",
"Email": "john.doe@gmail.com"
},
"CustomerAddress": {
"Street": "123 Main St",
"City": "Anytown",
"State": "CA",
"Postcode": "12345",
"Country": "USA"
},
"TicketType": {
"ID": 1,
"Description": "General Admission",
},
"DeliverTicketsByMail": true,
"NumberOfTickets": 2
};
Here we are defining the attributes and data that will be part of the CloudEvent message. We are using the same example as before, the ticket website that generates an event after a customer purchases a ticket. Note: Remember to update the sapcommunityid
with your SAP Community username.
👉 Add the following code in the Create a CloudEvent
section:
const emit = emitterFor(sendProcessedMessageToTopic, { mode: Mode.STRUCTURED });
// Create a new CloudEvent
const ce = new CloudEvent({ type, source, datacontenttype, data, sapcommunityid });
The emitterFor
function is part of the CloudEvents SDK and it is used to inform how we can send the CloudEvent message to the topic. The Mode.STRUCTURED
parameter specifies that the CloudEvent message will be sent in structured mode. Once the emitter function is ready, we create a new CloudEvent by passing the attributes and data that we defined earlier.
👉 Add the following code in the Send the CloudEvent
section:
console.log(ce);
emit(ce);
Finally, we will print the CloudEvent message to the console and send it.
👉 Save the file and run the script by running on terminal
node app.js
If everything went well, you should see the CloudEvent message printed in the console.
Output of program app.js
[!CAUTION] Note: If you see an error message, make sure that you have set the environment variables correctly in the
.env
file. Also, a solution for this exercise is available in the.sap/code/08-cloudevents-sdk
folder.
[!TIP] 💡 You can subscribe to the
codejam/edi/ce/[your-sap-community-username]/nodejs
topic, via theTry Me!
page, to see the CloudEvent message being published.
Summary
In this exercise, we learned how to create a CloudEvent message programmatically using the CloudEvents SDK for Node.js. We didn’t only create a CloudEvent message for the Ticket Website example that we’ve seen previously but we also published it to a topic in AEM.
Further Study
If you finish earlier than your fellow participants, you might like to ponder these questions. There isn’t always a single correct answer and there are no prizes - they’re just to give you something else to think about.
- Is it possible to batch CloudEvents in a single JSON document?
⇟ Hint 🔦
Check out the CloudEvents primer - [https://github.com/cloudevents/spec/blob/main/cloudevents/primer.md](https://github.com/cloudevents/spec/blob/main/cloudevents/primer.md) Batching multiple events into a single API call is natively supported by some protocols. To aid interoperability, it is left up to the protocols if and how batching is implemented. Details may be found in the protocol binding or the protocol specification. - Can you think of other scenarios where using an SDK to process a CloudEvent message would be beneficial?
- In our code, we specified the encoding Mode as
Structured
. What other modes are available? What if you send a message with a different mode? Can you spot the differences in the consumer UI?
Next
Continue to 👉 Exercise 09 - Forward messages in Queue to REST Consumer