### Get Dependencies with Go Source: https://github.com/cloudevents/sdk-go/blob/main/samples/http/receiver-gin/README.md Run this command in the samples directory to fetch necessary Go dependencies. ```shell cd samples/ go get ``` -------------------------------- ### Run Kafka Cluster with Docker Source: https://github.com/cloudevents/sdk-go/blob/main/samples/kafka/README.md Use this command to start a Kafka cluster using Docker. Ensure Docker is installed and running. ```bash docker run --rm --net=host -e ADV_HOST=localhost -e SAMPLEDATA=0 lensesio/fast-data-dev ``` -------------------------------- ### Run the Gin Receiver App Source: https://github.com/cloudevents/sdk-go/blob/main/samples/http/receiver-gin/README.md Execute this command to start the Gin web server for receiving CloudEvents. ```shell go run main.go ``` -------------------------------- ### Run MQTT Broker with Docker Source: https://github.com/cloudevents/sdk-go/blob/main/samples/mqtt/README.md Use this command to start a Mosquitto MQTT broker using Docker. It maps port 1883 and runs without authentication. ```bash docker run -it --rm --name mosquitto -p 1883:1883 eclipse-mosquitto:2.0 mosquitto -c /mosquitto-no-auth.conf ``` -------------------------------- ### Run Confluent Kafka Locally with Docker Source: https://github.com/cloudevents/sdk-go/blob/main/samples/kafka_confluent/README.md Use this command to start a local Kafka cluster using Docker. Ensure Docker is installed and running. ```bash docker run --rm --net=host confluentinc/confluent-local ``` -------------------------------- ### CloudEvent Log Output Example Source: https://github.com/cloudevents/sdk-go/blob/main/samples/http/receiver-gin/README.md This shows the expected log output after a CloudEvent is successfully received and processed by the Gin receiver. ```shell Got an Event: Context Attributes, specversion: 1.0 type: dev.tekton.event.pipelinerun.started.v1 source: /apis/namespaces/dimitar/clone-build-n4qhgl subject: clone-build-n4qhgl id: e7d95c20-6eb4-4614-946d-27b0ce41c7ff datacontenttype: application/json Data, { "pipelineRun": { "metadata": { "name": "clone-build-n4qhgl", "namespace": "dimitar", "uid": "44ef2940-b2d9-4ecb-ad12-808a69972f02", ..... } [GIN] 2023/02/13 - 14:16:51 | 200 | 639.6µs | 127.0.0.1 | POST "/" ``` -------------------------------- ### Add SDK as Dependency Source: https://github.com/cloudevents/sdk-go/blob/main/README.md Add the CloudEvents Go SDK v2 module as a dependency to your project using go get. ```console go get github.com/cloudevents/sdk-go/v2 ``` -------------------------------- ### Receive CloudEvents via HTTP Source: https://github.com/cloudevents/sdk-go/blob/main/README.md Start an HTTP receiver to listen for incoming CloudEvents. The provided callback function will process each received event. ```go func receive(event cloudevents.Event) { // do something with event. fmt.Printf("%s", event) } func main() { // The default client is HTTP. c, err := cloudevents.NewClientHTTP() if err != nil { log.Fatalf("failed to create client, %v", err) } if err = c.StartReceiver(context.Background(), receive); err != nil { log.Fatalf("failed to start receiver: %v", err) } } ``` -------------------------------- ### Receive CloudEvents via HTTP Source: https://github.com/cloudevents/sdk-go/blob/main/docs/index.md Start an HTTP receiver to listen for incoming CloudEvents. Define a callback function to process received events. ```go func receive(event cloudevents.Event) { // do something with event. fmt.Printf("%s", event) } func main() { // The default client is HTTP. c, err := cloudevents.NewClientHTTP() if err != nil { log.Fatalf("failed to create client, %v", err) } log.Fatal(c.StartReceiver(context.Background(), receive)); } ``` -------------------------------- ### Regenerate Parser with ANTLR4 Source: https://github.com/cloudevents/sdk-go/blob/main/sql/v2/README.md Command to regenerate the parser using ANTLR4. Ensure ANTLR4 is installed and specify the correct version, language, package, output directory, and visitor pattern. ```shell antlr4 -v 4.10.1 -Dlanguage=Go -package gen -o gen -visitor -no-listener CESQLParser.g4 ``` -------------------------------- ### Build Benchmark Application Source: https://github.com/cloudevents/sdk-go/blob/main/test/benchmark/e2e/http/README.md Compile the benchmark application using the Go build tool. ```shell go build main.go ``` -------------------------------- ### Import SDK Source: https://github.com/cloudevents/sdk-go/blob/main/docs/index.md Import the CloudEvents Go SDK package into your Go code. ```go import cloudevents "github.com/cloudevents/sdk-go/v2" ``` -------------------------------- ### Run All Benchmark Tests Source: https://github.com/cloudevents/sdk-go/blob/main/test/benchmark/e2e/http/README.md Execute all defined benchmark tests and redirect output to CSV files for analysis. ```shell ./main --bench=baseline > baseline.csv && ./main --bench=receiver-sender > receiver-sender.csv && ./main --bench=client > client.csv ``` -------------------------------- ### Update Sample Dependencies (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Manually update sample dependencies after all core SDK and protocol releases are published. This ensures samples use the latest released versions. ```shell tag=v2.1.0 pushd sample/stan go mod edit -dropreplace github.com/cloudevents/sdk-go/protocol/stan/v2 go get -d github.com/cloudevents/sdk-go/protocol/stan/v2@$tag go mod edit -dropreplace github.com/cloudevents/sdk-go/v2 go get -d github.com/cloudevents/sdk-go/v2@$tag popd ``` -------------------------------- ### Tag Protocol Release (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Tag each protocol with a new version tag. This allows go modules to correctly reference the released protocol version. ```shell tag=protocol/stan/v2.1.0 pushd protocol/stan/v2 git tag $tag git push origin $tag popd ``` -------------------------------- ### Clone Repository and Add Upstream Source: https://github.com/cloudevents/sdk-go/blob/main/pr_guidelines.md Clone the repository and add the upstream remote for tracking changes. ```console git clone https://github.com/mygithuborg/sdk-go.git cd sdk-go git remote add upstream https://github.com/cloudevents/sdk-go.git ``` -------------------------------- ### Create Release Branch (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Manually create a branch for v2.x releases. This follows a similar pattern to the automated branch creation. ```shell branch=release-2.1 git checkout -b $branch git push -u origin $branch ``` -------------------------------- ### Add SDK Dependency Source: https://github.com/cloudevents/sdk-go/blob/main/docs/index.md Add the CloudEvents Go SDK as a project dependency using go mod. ```bash % go get github.com/cloudevents/sdk-go/v2@latest ``` -------------------------------- ### Tag New Branch (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Tag the newly created branch with the appropriate release version. This tag is used for versioning and referencing the release. ```shell tag=v2.4.1 git tag $tag git push origin $tag ``` -------------------------------- ### Create Instrumented CloudEvents HTTP Client Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Use this helper method to create a fully instrumented HTTP client for CloudEvents. It automatically handles span generation for outgoing and incoming requests with default attribute configurations. ```go import ( "context" otelObs "github.com/cloudevents/sdk-go/observability/opentelemetry/v2/client" cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/cloudevents/sdk-go/v2/client" cehttp "github.com/cloudevents/sdk-go/v2/protocol/http" ) // you can pass the http/client options as usual c, _ := otelObs.NewClientHTTP([]cehttp.Option{}, []client.Option{}) ``` -------------------------------- ### Basic OTelObservabilityService Configuration Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Configure the CloudEvents client to use the OTelObservabilityService for generating spans. This provides basic observability with default span names and attributes. ```go c, err := cloudevents.NewClient(p, client.WithObservabilityService(otelObs.NewOTelObservabilityService())) ``` -------------------------------- ### Configure HTTP Client with OpenTelemetry Auto-Instrumentation Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Configure the CloudEvents HTTP client with OpenTelemetry's auto-instrumentation for outgoing and incoming requests. This ensures spans are generated and trace context is propagated. ```go p, err := cloudevents.NewHTTP( cloudevents.WithRoundTripper(otelhttp.NewTransport(http.DefaultTransport)), cloudevents.WithMiddleware(func(next http.Handler) http.Handler { return otelhttp.NewHandler(next, "receive") }), ) ``` -------------------------------- ### Custom OTelObservabilityService Configuration Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Configure the OTelObservabilityService with custom span names and attributes. The nameFormatter and attributesGetter functions are called on each span creation; avoid heavy processing within them. ```go nameFormatter := func(e *cloudevents.Event) string { return "my.custom.name." + e.Context.GetType() } attributesGetter := func(*cloudevents.Event) []attribute.KeyValue { return []attribute.KeyValue{ attribute.String("my-attr", "some-value"), } } // create the obs service with custom span names and attributes os := otelObs.NewOTelObservabilityService( otelObs.WithSpanNameFormatter(nameFormatter), otelObs.WithSpanAttributesGetter(attributesGetter), ) c, err := cloudevents.NewClient(p, client.WithObservabilityService(os)) ``` -------------------------------- ### Tag Sub-module Release (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Manually tag each sub-module for release. This is an alternative to using the tag-release.sh script for individual sub-module releases. ```shell tag=protocol/stan-v2.1.0 git tag $tag git push origin $tag popd ``` -------------------------------- ### Add and Use User-Defined Function in CloudEvents Expression Source: https://github.com/cloudevents/sdk-go/blob/main/sql/v2/README.md Demonstrates how to define a custom function (e.g., HASPREFIX) and register it with the CloudEvents Expression Language runtime. This allows using custom logic within parsed expressions. ```go import ( cesql "github.com/cloudevents/sdk-go/sql/v2" cefn "github.com/cloudevents/sdk-go/sql/v2/function" cesqlparser "github.com/cloudevents/sdk-go/sql/v2/parser" ceruntime "github.com/cloudevents/sdk-go/sql/v2/runtime" cloudevents "github.com/cloudevents/sdk-go/v2" ) // Create a test event event := cloudevents.NewEvent() event.SetID("aaaa-bbbb-dddd") event.SetSource("https://my-source") event.SetType("dev.tekton.event") // Create and add a new user defined function var HasPrefixFunction cesql.Function = cefn.NewFunction( "HASPREFIX", []cesql.Type{cesql.StringType, cesql.StringType}, nil, func(event cloudevents.Event, i []interface{}) (interface{}, error) { str := i[0].(string) prefix := i[1].(string) return strings.HasPrefix(str, prefix), nil }, ) err := ceruntime.AddFunction(HasPrefixFunction) // parse the expression expression, err := cesqlparser.Parse("HASPREFIX(type, 'dev.tekton.event')") if err != nil { fmt.Println("parser err: ", err) os.Exit(1) } // Evalute the expression with the test event res, err := expression.Evaluate(event) if res.(bool) { fmt.Println("Event type has the prefix") } else { fmt.Println("Event type doesn't have the prefix") } ``` -------------------------------- ### Send a CloudEvent via cURL Source: https://github.com/cloudevents/sdk-go/blob/main/samples/http/receiver-gin/README.md Use this cURL command to send a sample CloudEvent to the running Gin receiver. Ensure 'event.json' contains the event payload. ```shell curl -v \ -H "Ce-Id: e7d95c20-6eb4-4614-946d-27b0ce41c7ff" \ -H "Ce-Source: /apis/namespaces/dimitar/clone-build-n4qhgl" \ -H "Ce-Subject: clone-build-n4qhgl" \ -H "Ce-Specversion: 1.0" \ -H "Ce-Type: dev.tekton.event.pipelinerun.started.v1" \ -H "Content-Type: application/json" \ -d @event.json http://localhost:8080 ``` -------------------------------- ### Plot Benchmark Results with Gnuplot Source: https://github.com/cloudevents/sdk-go/blob/main/test/benchmark/e2e/http/README.md Use gnuplot to visualize benchmark results, specifically plotting parallelism against nanoseconds per operation for a given payload size. ```shell gnuplot -c plot_parallelism_ns.gnuplot ``` ```shell gnuplot -c plot_parallelism_ns.gnuplot 16 ``` -------------------------------- ### Update Branch with Main Source: https://github.com/cloudevents/sdk-go/blob/main/pr_guidelines.md Fetch upstream changes and rebase your current branch onto the upstream main branch to incorporate the latest updates and resolve conflicts. ```console git fetch upstream git rebase upstream/main ``` -------------------------------- ### Update Protocol Dependencies (Manual v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Manually update protocol dependencies to use the new release tag instead of a replace directive. This ensures that the protocol uses the correct version of the core SDK. ```shell tag=v2.1.0 pushd protocol/stan/v2 go mod edit -dropreplace github.com/cloudevents/sdk-go/v2 go get -d github.com/cloudevents/sdk-go/v2@$tag popd ``` -------------------------------- ### Create CloudEvent from HTTP Request Source: https://github.com/cloudevents/sdk-go/blob/main/docs/index.md Parse an incoming HTTP request to create a CloudEvent object. Handle potential parsing errors and return an appropriate HTTP error response. ```go func handler(w http.ResponseWriter, r *http.Request) { event, err := cloudevents.NewEventFromHTTPRequest(r) if err != nil { log.Print("failed to parse CloudEvent from request: %v", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) } w.Write([]byte(*event.String())) } ``` -------------------------------- ### Create CloudEvent from HTTP Request Source: https://github.com/cloudevents/sdk-go/blob/main/README.md Parse an incoming HTTP request to create a CloudEvent object. Handles potential parsing errors by returning an HTTP error. ```go func handler(w http.ResponseWriter, r *http.Request) { event, err := cloudevents.NewEventFromHTTPRequest(r) if err != nil { log.Printf("failed to parse CloudEvent from request: %v", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) } w.Write([]byte(event.String())) log.Println(event.String()) } ``` -------------------------------- ### Set Event Extension Source: https://github.com/cloudevents/sdk-go/blob/main/docs/event_data_structure.md Use EventContextWriter to set a custom extension attribute on an event. Ensure the event object is initialized. ```go ev := cloudevents.NewEvent() err := ev.Context.SetExtension("aaa", "hello_world") ``` -------------------------------- ### Inject Trace Context into CloudEvent for Queue Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Injects the current trace context into a CloudEvent as a DistributedTracingExtension before sending it to a queue. Assumes the context is already instrumented. ```go func sendEventToQueue(ctx context.Context, event cloudevents.Event) { // assuming this function is properly instrumented, // the ctx contains the current span // Before sending the event to the queue // we can inject the tracecontext into the event as a DistributedTracingExtension otelObs.InjectDistributedTracingExtension(ctx, event) } ``` -------------------------------- ### Sign Git Commits Source: https://github.com/cloudevents/sdk-go/blob/main/CONTRIBUTING.md Ensure your Git commits are signed off to verify your contribution. This requires your Git user.name and user.email to be configured. ```console git commit --signoff ``` -------------------------------- ### Create Release Branch (v2.+) Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Create a new branch for v2.x releases. This branch is used by the GitHub Actions release workflow. ```shell branch=release-v2.1 git checkout -b $branch git push -u origin $branch ``` -------------------------------- ### Create Feature Branch Source: https://github.com/cloudevents/sdk-go/blob/main/pr_guidelines.md Fetch upstream changes, reset the local main branch, and create a new branch for your work. Use issue numbers in branch names for organization. ```console git fetch upstream git reset --hard upstream/main git checkout -b 486-fix-if-present-validation ``` -------------------------------- ### Send CloudEvent via HTTP Source: https://github.com/cloudevents/sdk-go/blob/main/README.md Send a CloudEvent using the HTTP client. Ensure the target URI is correctly set and handle potential sending errors. ```go func main() { c, err := cloudevents.NewClientHTTP() if err != nil { log.Fatalf("failed to create client, %v", err) } // Create an Event. event := cloudevents.NewEvent() event.SetSource("example/uri") event.SetType("example.type") event.SetData(cloudevents.ApplicationJSON, map[string]string{"hello": "world"}) // Set a target. ctx := cloudevents.ContextWithTarget(context.Background(), "http://localhost:8080/") // Send that Event. if result := c.Send(ctx, event); cloudevents.IsUndelivered(result) { log.Fatalf("failed to send, %v", result) } else { log.Printf("sent: %v", event) log.Printf("result: %v", result) } } ``` -------------------------------- ### Send CloudEvent via HTTP Source: https://github.com/cloudevents/sdk-go/blob/main/docs/index.md Send a CloudEvent using the HTTP protocol binding. Ensure the target URL is correctly set and handle potential errors during sending. ```go func main() { c, err := cloudevents.NewClientHTTP() if err != nil { log.Fatalf("failed to create client, %v", err) } // Create an Event. event := cloudevents.NewEvent() event.SetSource("example/uri") event.SetType("example.type") event.SetData(cloudevents.ApplicationJSON, map[string]string{"hello": "world"}) // Set a target. ctx := cloudevents.ContextWithTarget(context.Background(), "http://localhost:8080/") // Send that Event. if result := c.Send(ctx, event); !cloudevents.IsACK(result) { log.Fatalf("failed to send, %v", result) } } ``` -------------------------------- ### Reverse 'dropreplace' Command Source: https://github.com/cloudevents/sdk-go/blob/main/RELEASING.md Reverses the 'dropreplace' command in go.mod files, useful for reverting changes or testing local modifications. ```shell go mod edit -replace github.com/cloudevents/sdk-go/v2=../../../v2 ``` -------------------------------- ### CloudEventCarrier: Inject and Read Trace Parent/State Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Demonstrates using CloudEventCarrier to inject trace context from a Go context into the carrier and then accessing the raw traceparent and tracestate values. This carrier implements the OpenTelemetry TextMapCarrier interface. ```go type MyEvent struct { TraceParent string `json:"traceparent,omitempty"` TraceState string `json:"tracestate,omitempty"` } func injectAndReadTraceParentAndState(ctx context.Context, e cloudevents.Event) { me := MyEvent{} // the propagator from OpenTelemetry prop := propagation.TraceContext{} carrier := otelObs.NewCloudEventCarrier() // Injects (writes) the tracecontext into the NewCloudEventCarrier // Doing so, will set the DistributedTracingExtension fields prop.Inject(ctx, carrier) // Here then we have the "raw" access to the tracecontext data // https://www.w3.org/TR/trace-context/ // e.g. 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01 me.TraceParent = carrier.Extension.TraceParent // e.g. congo=t61rcWkgMzE me.TraceState = carrier.Extension.TraceState } ``` -------------------------------- ### Extract Trace Context from CloudEvent in Background Process Source: https://github.com/cloudevents/sdk-go/blob/main/observability/opentelemetry/v2/README.md Extracts trace context from a CloudEvent in a background process where a traditional context is not available. Re-creates a context with the extracted trace information to continue the trace. ```go func handleEvent(e cloudevents.Event) { // here in our long-running process, we don't have a "context" // if we have the tracecontext in the event, we can // re-create the context with it and continue the trace: ctx := otelObs.ExtractDistributedTracingExtension(context.Background(), e) // ctx now has the tracecontext from the moment when the event was sent. // All subsequent requests made with this context will be part of the trace. c, _ := otelObs.NewClientHTTP([]cehttp.Option{}, []client.Option{}) ctx = cloudevents.ContextWithTarget(ctx, "my-other-cloudevents-app") c.Send(ctx, e) } ``` -------------------------------- ### Set Event Source Attribute Source: https://github.com/cloudevents/sdk-go/blob/main/docs/event_data_structure.md Use EventContextWriter to set the source attribute of an event. Ensure the event object is initialized. ```go ev := cloudevents.NewEvent() err := ev.Context.SetSource("http://localhost") ``` -------------------------------- ### Force Push Changes Source: https://github.com/cloudevents/sdk-go/blob/main/pr_guidelines.md Force push your updated branch to your origin fork after rebasing or making significant changes. This is necessary if you have already pushed commits. ```console git push -f origin 486-fix-if-present-validation ``` -------------------------------- ### Interactive Rebase for Clean Commits Source: https://github.com/cloudevents/sdk-go/blob/main/pr_guidelines.md Use an interactive rebase to clean up your commit history, such as squashing or fixing typos, before force pushing. Follow git instructions for rewriting history. ```console git commit -m "fixup: fix typo" git rebase -i upstream/main # follow git instructions ``` -------------------------------- ### Apply ANTLR4 Workaround with sed Source: https://github.com/cloudevents/sdk-go/blob/main/sql/v2/README.md A sed command to apply a workaround for an ANTLR4 issue related to integer overflow on 32-bit platforms. This command modifies the generated Go parser file. ```shell sed -i 's/(1<