This document explains how to make use of the notification queue API to obtain the notifications for a given build and use the notification data to obtain invocation events from the event store API. To do so, the EngFlow API is used as external dependency (see WORKSPACE).
The first argument you must have to execute the client is the cluster grpc endpoint
you want to listen to.
The second argument is the queue name. As in this example we are interested in
getting lifecycle events from the cluster, we pull from the queue called lifecycle-events.
--notification_queue_endpoint=CLUSTER_URLthe URL of the cluster gRPC server. Must start withgrpc://orgrpcs://--queue_name=eventstore/lifecycle-eventsholds the name of the queue to listen
Next, you must provide authentication information so the client can establish a connection to the EngFlow cluster, unless the cluster is totally open. As for today, two authentication methods are available; certificates or authentication tokens. These arguments are optional and if they are not given but are required by the cluster, the connection is rejected.
In the first case you should have valid credentials in .crt and .key files. Add
the full path of your certificate files into the following options
--tls_certificate=certificate file containing your public keyholds the path of the crt file to access the cluster. Only needed forgrpcs://connections--tls_key=/path/to/your/file containing your private keyholds the path of the key file used to access the cluster. Only needed forgrpcs://connections
Run the client using
bazel run //java/com/engflow/notificationqueue:client -- \
'--notification_queue_endpoint=grpcs://example.cluster.engflow.com' '--queue_name=eventstore/lifecycle-events' \
'--tls_certificate=example_client.crt' '--tls_key=example_client.key'In the second authentication case you should count with a valid token. On EngFlow clusters you may get a new access token by
accessing the cluster's UI under the tab Getting Started. To execute the client against your cluster, add the argument
--token=your-long-JWT-tokenholds the authentication token. Needed for bothgrpc://andgrpcs://connections
Run the client using
bazel run //java/com/engflow/notificationqueue:client -- \
'--notification_queue_endpoint=grpcs://$CLUSTER.cluster.engflow.com' '--queue_name=eventstore/lifecycle-events' \
'--token=DKiJ3eic9l150dDmzdMsaiu0K5boBle0UlkCefbgwzBE7G7FItgi2AOFpz6pkcMUFV3SkpAGikMckcaQhTTKUmGeZKpLh9gT6vTsi0v'One useful use case for the notification and event store APIs is forwarding the
received data to external servers, for instance another build event store or result store sever.
The current client example implements communication
with a demo grpc stub. To do so, the client uses Request and Response
abstractions provided by a server proto definition.
To execute a client that forwards information to an external server you add the flag
--forward. Let us first execute a demonstration server that will receive the data from
the client. To execute the server run
bazel run //java/com/engflow/notificationqueue/demoserver:serverThis will start the demo server listening at localhost:50051. Now you can start the client with a given
authentication method and the forwarding endpoint
bazel run //java/com/engflow/notificationqueue:client -- \
'--notification_queue_endpoint=grpcs://example.cluster.engflow.com' '--queue_name=eventstore/lifecycle-events' \
'--tls_certificate=example_client.crt' '--tls_key=example_client.key' '--forward=grpc://localhost:50051'You may now build any targets on the cluster. Open your favorite foo project and build it using
the runtime flags remote_cache and bes_backend arguments like this
bazel build //... '--remote_cache=grpcs://example.cluster.engflow.com' '--bes_backend=grpcs://example.cluster.engflow.com'You should see a series of notifications like this one
{
type_url: "type.googleapis.com/engflow.eventstore.v1.BuildLifecycleEventNotification"
value: "\n\adefault\022$9608f439-4c3e-4909-8a0c-f78810322b6b\"\021command_name=test\"\021protocol_name=BEP\"0user_keyword=engflow:CiCdPipelineName=post-merge\"7user_keyword=engflow:CiCdJobName=ci-runners-test-matrix\"\'user_keyword=engflow:Requester=anfelbar\"%user_keyword=engflow:StreamSource=BES\"/user_keyword=engflow:StreamType=ClientBEPStream\272\006&\n$5173658c-4595-4978-8db0-2942b1e7ca13"
}The last value contains the uuid for one invocation. From the previous example the invocation uuid is 5173658c-4595-4978-8db0-2942b1e7ca13.
Using this uuid and the EventStore stub we get invocation data (see getInvocations code in Client.java):
Invocation: continuation_token: "CiQwNzBkMjViZi0zZWFjLTRlYTYtODVhOC00ZjA2NDMxNjU2NTcQAA=="
event {
stream_id {
build_id: "3a38c04f-233d-465f-a91d-f328c21ab832"
invocation_id: "070d25bf-3eac-4ea6-85a8-4f0643165657"
}
service_level: INTERACTIVE
notification_keywords: "command_name=test"
notification_keywords: "protocol_name=BEP"
notification_keywords: "user_keyword=engflow:CiCdPipelineName=post-merge"
notification_keywords: "user_keyword=engflow:CiCdJobName=runners-matrix"
notification_keywords: "user_keyword=engflow:Requester=userxyz"
notification_keywords: "user_keyword=engflow:StreamSource=BES"
notification_keywords: "user_keyword=engflow:StreamType=ClientBEPStream"
build_event {
event_time {
seconds: 1752547458
nanos: 781000000
}
invocation_attempt_started {
attempt_number: 1
}
}
}