Subscribing to Kafka events
With this tutorial, you can learn how to subscribe to Kafka events by using the IBM Cloud® Code Engine CLI.
Oftentimes in distributed environments you want your applications or jobs to react to messages (events) that are generated from other components, which are usually called event producers. With Code Engine, your applications or jobs can receive events of interest by subscribing to event producers. Event information is received as POST HTTP requests for applications and as environment variables for jobs.
The Kafka event producer watches for new messages to appear in a Kafka instance. When you create a Code Engine Kafka subscription for a set of topics, your app or job receives a separate event for each new message that appears in one of the topics.
While you can use any Kafka instance, the examples in this tutorial use the IBM® Event Streams for IBM Cloud® service. Event Streams is an IBM event streaming service for Kafka events. For more information about this service, see Event Streams documentation.
Before you begin
- Set up your Code Engine CLI environment.
- Set up your Event Streams CLI.
- Create and work with a project.
All Code Engine users are required to have a Pay-as-you-Go account. Tutorials might incur costs. Use the Cost Estimator to generate a cost estimate based on your projected usage. For more information, see Code Engine pricing.
Setting up the Kafka event producer
You can set up your Kafka message producer to send messages to Code Engine Kafka event subscriptions. Use your Code Engine Kafka event subscription to trigger applications or jobs when a Kafka message is received.
To get started, create an Event Streams service instance for your event streaming service. While you can use the console or the CLI, the following steps describe how to set up the Event Streams event producer with the CLI.
-
Create a service instance for Event Streams. The name of the Event Streams CLI service is
messagehub
. For this example, create an Event Streams service instance that is namedmyeventstream
.ibmcloud resource service-instance-create myeventstream messagehub lite us-south
-
Create a service key to provide credentials to your service instance.
ibmcloud resource service-key-create myeventstream-key Manager --instance-name myeventstream
Example output
Creating service key of service instance myeventstream under account <user_account>... OK Service key crn:v1:bluemix:public:messagehub:us-south:a/e43abfcbd191404cb17ef650e9681dd3:c0736069-3f4a-438a-b614-6846877d692d:resource-key:4c8edfdb-abcd-abcd-abcd-abcdabcdabcd was created. Name: myeventstream-key ID: crn:v1:bluemix:public:messagehub:us-south:a/e43abfcbd191404cb17ef650e9681dd3:c0736069-3f4a-438a-b614-6846877d692d:resource-key:4c8edfdb-abcd-abcd-abcd-abcdabcdabcd Created At: Mon Mar 21 18:36:09 UTC 2022 State: active Credentials: api_key: abcdeH9tu3qE5Sn8VbJfcDEWtjR_l0iPisB3abcdefgh apikey: abcdeH9tu3qE5Sn8VbJfcDEWtjR_l0iPisB3abcdefgh iam_apikey_description: Auto-generated for key crn:v1:bluemix:public:messagehub:us-south:a/e43abfcbd191404cb17ef650e9681dd3:c0736069-3f4a-438a-b614-6846877d692d:resource-key:4c8edfdb-abcd-abcd-abcd-abcdabcdabcd iam_apikey_name: myeventstream-key iam_role_crn: crn:v1:bluemix:public:iam::::serviceRole:Manager iam_serviceid_crn: crn:v1:bluemix:public:iam-identity::a/e43abfcbd191404cb17ef650e9681dd3::serviceid:ServiceId-3e99caa5-b174-4f04-9845-5c5d783b8bc7 instance_id: c0736069-3f4a-438a-b614-6846877d692d kafka_admin_url: https://abcdabcdabcdabcd.svc07.us-south.eventstreams.cloud.ibm.com kafka_brokers_sasl: [broker-1-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-2-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-5-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-3-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-4-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-0-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093] kafka_http_url: https://abcdabcdabcdabcd.svc07.us-south.eventstreams.cloud.ibm.com password: abcdeH9tu3qE5Sn8VbJfcDEWtjR_l0iPisB3abcdefgh user: token
Make note of the values for
user
,password
, andkafka-brokers_sasl
for your service key. You need this information when you set up your Code Engine Kafka subscription. The values forpassword
andapikey
are the same in the service key for your Event Streams service instance. You can also use theibmcloud resource service-key myeventstream-key
command to retrieve the service key information. -
Initialize the Event Streams plug-in relative to your Event Streams service instance.
ibmcloud es init --instance-name myeventstream
-
Create an Event Streams topic.
ibmcloud es topic-create kafka-topic1
Setting up a Code Engine sample app to produce Kafka messages
For this tutorial, set up a Code Engine application to act as an event producer of Kafka messages. The purpose of this kafka-sender-app
app is to connect to your Event Streams instance and to produce (send) Kafka messages to a receiver
of the messages (Kafka consumer). This app that produces events for Kafka messages uses the Code Engine Kafka sender sample app to send Kafka
messages. This sample sender image requires the BROKERS
environment variable and a secret that includes the password
credentials.
-
Create a secret with credentials that are required by the Code Engine Kafka samples. For example, create the
kafka-subscription-secret
secret, to contain the credentials that are required for both the Kafka sender sample app and the Kafka event subscription, which uses the Kafka receiver sample. These credentials are required for the sample Kafka sender app and the Code Engine Kafka event subscription to communicate with the service instance for Event Streams. While it not required that you create this secret before you create the Kafka sender app and the event subscription, this action simplifies the required steps.To create the
kafka-subscription-secret
secret, add a literal environment variable forpassword
, andusername
. For more information, see create a secret with the CLI.-
Specify the
username
key with the value ofuser
that is listed in the details of the service credentials in the Event Streams service instance. For the Event Streams service instance, this value istoken
. This key is required for authentication between the Code Engine Kafka event subscription and the Kafka message broker. -
Specify the
password
key with the value ofapikey
that is listed in the details of the service credentials in the Event Streams service instance. This key is required for the sender sample, and to enable communications between the Code Engine Kafka event subscription and the Kafka message broker.ibmcloud ce secret create --name kafka-subscription-secret --from-literal password=<value_of_apikey> --from-literal username=<value_of_user>
For example,
ibmcloud ce secret create --name kafka-subscription-secret --from-literal password=abcdeH9tu3qE5Sn8VbJfcDEWtjR_l0iPisB3abcdefgh --from-literal username=token
-
-
Create the
kafka-sender-app
with the following information.-
Specify the
--image
option to reference theicr.io/codeengine/kafka-sender
container image. This image is built fromsender.go
, which is available from the Samples for IBM Cloud Code Engine GitHub repo. This sample sender app requires thepassword
credentials that are stored in yourkafka-subscription-secret
, and it requires theBROKERS
environment variable. -
Specify the
--env-from-secret
option to reference the full secret,kafka-subscription-secret
, which contains thepassword
credentials. -
Specify the
--env
option to add a literal environment variable,BROKERS
, and provide the name of one of the brokers hosts listed in the details of the service credentials in the Event Streams service instance. However, if you want to specify more than one broker hostname, use the format--env BROKERS-broker1,broker2,broker3
. -
(optional) Specify the
--min-scale=1
option so that the app always has an instance that is running and does not scale to zero. Configuring the app to always have a running instance is useful when you view logs. If you are running in a production environment, consider the cost of keeping a running instance of your app or whether you want Code Engine to autoscale to zero. By default, the app scales to zero when not in use.ibmcloud ce app create --name kafka-sender-app --image icr.io/codeengine/kafka-sender --env-from-secret kafka-subscription-secret --env BROKERS=broker-4-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --min-scale 1
-
-
After you deploy this app, run the
app get
command to confirm that the app is inready
status.ibmcloud ce app get -n kafka-sender-app
You created the kafka-sender-app
app to produce Kafka messages for Code Engine event subscriptions, and you created the kafka-subscription-secret
secret that contains the required credentials.
Setting up a Code Engine Kafka subscription
For Code Engine to work with Kafka events, set up a Code Engine Kafka eventing subscription to connect to Kafka event brokers and listen for Kafka events. Also, set up a Code Engine app to act as the receiver of the Kafka events. The Kafka event subscription defines the relationship between the Kafka producer (sender) and consumer (receiver) of events.
The Code Engine Kafka event subscription connects to your Kafka message broker and sends HTTP Post requests for each incoming Kafka message to the receiver application. For more information about the information that is included with Kafka events, see HTTP headers and body information for events that are delivered to apps.
-
Create a Code Engine application to act as an event consumer of Kafka messages and receive the Kafka events. For example, create an application that is called
kafka-receiver-app
that uses theicr.io/codeengine/kafka-receiver
image. This image is built fromreceiver.go
, which is available from the Samples for IBM Cloud Code Engine GitHub repo. This sample does not require any environment variables. You can optionally specify the--min-scale=1
option, such that the app always has an instance that is running and does not scale to zero. Configuring the app to always have a running instance is useful when you view logs. If you are running in a production environment, consider the cost of keeping a running instance of your app or whether you want Code Engine to autoscale to zero. By default, the app scales to zero when not in use.ibmcloud ce app create -n kafka-receiver-app --image icr.io/codeengine/kafka-receiver --min-scale 1
By default, events are routed to the root URL of the destination application. You can send events to a different destination within the app by using the
--path
option. For example, if your subscription specifies--path /event
, the event is sent tohttps://<base application URL>/events
. -
After you deploy this app, run the
app get
command to confirm that the app is inready
status.ibmcloud ce app get -n kafka-receiver-app
-
Create a Code Engine Kafka event subscription for your Kafka events by using the
ibmcloud ce sub kafka create
command. Use thekafka-subscription-secret
secret that you previously created to access the message broker. Specify the broker information based on the service credentials information for your Kafka resource. For this example, you can obtain the broker information from the output of theibmcloud resource service-key myeventstream-key
command. Notice that you must specify a--broker
option for each broker for your topic. The--destination
option specifies the Code Engine resource that receives the events.ibmcloud ce sub kafka create --name mykafkasubscription --destination kafka-receiver-app --secret kafka-subscription-secret --topic kafka-topic1 --broker broker-3-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --broker broker-5-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --broker broker-0-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --broker broker-1-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --broker broker-4-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 --broker broker-2-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093
-
Display the details of the Kafka event subscription.
ibmcloud ce sub kafka get -n mykafkasubscription
Example output
Getting Kafka event subscription 'mykafkasubscription'... OK Name: mykafkasubscription [...] Destination Type: app Destination: kafka-receiver-app Brokers: broker-3-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-5-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-0-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-1-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-4-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 broker-2-abcdabcdabcdabcd.kafka.svc07.us-south.eventstreams.cloud.ibm.com:9093 Consumer Group: knative-kafka-source-a4072fe1-1dfa-4470-9d07-bf7a0ff8e340 Topics: kafka-topic1 Secret key reference (user): kafka-subscription-secret.username Secret key reference (password): kafka-subscription-secret.password Ready: true Conditions: Type OK Age Reason ConnectionEstablished true 24s InitialOffsetsCommitted true 24s Ready true 24s Scheduled true 24s SinkProvided true 24s Events: Type Reason Age Source Messages Normal FinalizerUpdate 26s kafkasource-controller Updated "mykafkasubscription" finalizers
Testing your subscription
Now that your Kafka event subscription, which references the kafka-receiver-app
application, is created, use the kafka-sender-app
to send message events to the receiver application.
-
Obtain the public URL of the destination app,
kafka-sender-app
by using theibmcloud ce app get
command with the--output url
option to find the URL of your app.ibmcloud ce app get -n kafka-sender-app --output url
Example output
https://kafka-sender-app.abcdabcdabc.us-south.codeengine.appdomain.cloud
-
Run the Kafka event producer app,
kafka-sender-app
to send events to the destination Code Engine application. Call thekafka-sender-app
application withcurl
and specify values for the topic and the number of messages. Use the output of theibmcloud ce app get
command to find the public URL of your app. Be sure to wrap the value to curl in quotation marks to ensure that it is treated as a single string. For example,curl "<public_URL_of_Kafka_sender_app>?topic=<your_topic_name>&num=<number_of_messages_to_produce>"
For example,
curl "https://kafka-sender-app.abcdabcdabc.us-south.codeengine.appdomain.cloud?topic=kafka-topic1&num=1"
-
View events in logs. When your Kafka event subscription is created with a broker, topics and an access secret that are valid, and you have a Kafka application that produces messages on that topic (such as
kafka-sender-app
), then you can see events in logs for your destination Code Engine application that receives Kafka messages, such askafka-receiver-app
. When you use the Kafka receiver app (icr.io/codeengine/kafka-receiver
), search forEvent data
in the logs for the receiver application to see the messages that are received.ibmcloud ce app logs -n kafka-receiver-app
Example output
Getting logs for all instances of application 'kafka-receiver-app'... OK kafka-receiver-app-00001-deployment-66976f7988-9xttm/user-container: 2022/03/31 22:19:45 Listening on port 8080 2022/03/31 22:19:46 ---------- 2022/03/31 22:19:46 Path: / 2022/03/31 22:19:46 Header: Accept-Encoding=[gzip] 2022/03/31 22:19:46 Header: Ce-Id=[partition:0/offset:167] 2022/03/31 22:19:46 Header: Ce-Source=[/apis/v1/namespaces/glxo4k7nj7d/kafkasources/mykafkasubscription#kafka-topic1] 2022/03/31 22:19:46 Header: Ce-Specversion=[1.0] 2022/03/31 22:19:46 Header: Ce-Subject=[partition:0#167] 2022/03/31 22:19:46 Header: Ce-Time=[2022-03-31T22:19:36.499Z] 2022/03/31 22:19:46 Header: Ce-Type=[dev.knative.kafka.event] 2022/03/31 22:19:46 Header: Content-Length=[8] 2022/03/31 22:19:46 Header: Forwarded=[for=172.30.208.213;proto=http, for=127.0.0.6] 2022/03/31 22:19:46 Header: K-Proxy-Request=[activator] 2022/03/31 22:19:46 Header: Traceparent=[00-b033708685c715a7c2384cdf05797785-65540b0937e9b0ce-00] 2022/03/31 22:19:46 Header: User-Agent=[Go-http-client/1.1] 2022/03/31 22:19:46 Header: X-B3-Parentspanid=[e1a785d7fdbead6c] 2022/03/31 22:19:46 Header: X-B3-Sampled=[1] 2022/03/31 22:19:46 Header: X-B3-Spanid=[abcde9901e6bf83f] 2022/03/31 22:19:46 Header: X-B3-Traceid=[abcde490a426573772fa0bf60caf5ddb] 2022/03/31 22:19:46 Header: X-Envoy-Attempt-Count=[1] 2022/03/31 22:19:46 Header: X-Forwarded-For=[172.30.208.213, 127.0.0.6, 127.0.0.6] 2022/03/31 22:19:46 Header: X-Forwarded-Proto=[http] 2022/03/31 22:19:46 Header: X-Request-Id=[abcdeb4e-c5ac-abcd-abcd-60e6278abcde] 2022/03/31 22:19:46 Event data: test1: 1
Note that log information for apps lasts for only one hour. For more information about viewing logs for apps (or jobs), see Viewing logs.
Updating your subscription
To update an event subscription with the CLI, use the ibmcloud ce subscription kafka update
command. The following example updates
the topic name.
ibmcloud ce sub kafka update -n mykafkasubscription --topic kafka-topic2
You can use the ibmcloud ce subscription kafka update
command to update the values for the Kafka subscription. However, you cannot
modify the value for the consumer group with this command. If you want to update the subscription to reference a different topic, make sure that the Kafka topic exists before you update the subscription.
Clean up for Kafka subscription tutorial
Ready to delete your Kafka subscription, the sending and receiving apps, and the secret? You can use the ibmcloud ce app delete
, the
ibmcloud ce sub kafka delete
, and the ibmcloud ce sub kafka delete
commands. You can optionally use the -f
option to force the delete of the component without confirmation.
When you delete the Kafka subscription, the delete does not delete the app that is referenced by the subscription.
To remove your subscription,
ibmcloud ce sub kafka delete --name mykafkasubscription -f
To remove your Kafka message-receiving application,
ibmcloud ce app delete --name kafka-receiver-app -f
Similarly, you can remove the kafka-sender-app
.
ibmcloud ce app delete --name kafka-sender-app -f
To remove the kafka-subscription-secret
,
ibmcloud ce secret delete --name kafka-subscription-secret -f
Ready to delete your service instance for Event Streams service instance? The --recursive
option specifies to remove all resources for the service instance, which includes the associated service key.
ibmcloud resource service-instance-delete myeventstream --recursive -f
Next steps
For more information about working with Kafka event subscriptions, see Working with the Kafka event producer.
Looking for more code examples? Check out the Samples for IBM Cloud Code Engine GitHub repo.