Skip to content

Commit

Permalink
Upgrade cdevent's go-sdk version with v0.4.1 (#7)
Browse files Browse the repository at this point in the history
* update sdk version to v0.4.1
* update events-broker address to check ci error
* update testCase with correct event type
* adding failure check IsUndelivered for cloudevent
* update README

Signed-off-by: Jalander Ramagiri <[email protected]>
  • Loading branch information
rjalander authored Sep 25, 2024
1 parent 6d6c6c5 commit 39ad147
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 33 deletions.
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

A CDEvents Webhook Adapter can receive events via Webhooks and translate them into CDEvents,
with the help of various translators which supports publishing events via Webhooks.
The translated CDEvents can be sent to configured `messageBroker` URL

This adapter provides client and server implementation over an RPC connection and exposes an interface for plugin implementation,
Various translators can be developed as plugins using Hashicorp's [go-plugin](https://github.com/hashicorp/go-plugin/)
This adapter provides client and server implementation over an RPC connection and exposes an interface for plugin implementation,
````go
// EventTranslator is the interface that we're exposing as a plugin.
type EventTranslator interface {
TranslateEvent(event string, headers http.Header) (string, error)
}

````
Various translators can be developed as plugins by implementing this interface method and serve using Hashicorp's [go-plugin](https://github.com/hashicorp/go-plugin/?tab=readme-ov-file#usage)

## Translator's configuration
Once the plugin implemented [translator-plugins.yaml](./translator-plugins.yaml) needs an update with the details of Plugin name, pluginURL and messageBroker
````yaml
translator:
path: "./plugins"
plugins:
- name: "<pluginName>"
pluginURL: "<plugin's binary URL>"
messageBroker: "<message broker URL>"
````

`DOWNLOAD_PLUGIN` is an environment variable that can be set to `true` or `false` to download the plugin's binary from the translator's `pluginURL` when launching this adapter. Alternatively, the plugin's binary can also be downloaded manually and placed under the `./plugins` directory (create it if it does not exist).

## Plugins implemented using this adapter
| Plugin Name | Plugin Repo |
| :------------ |:-------------------|
| gerrit-translator-cdevents| https://github.com/cdevents/gerrit-translator |
| jira-translator-cdevents | https://github.com/cdevents/jira-translator |
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cdevents/webhook-adapter
go 1.22.0

require (
github.com/cdevents/sdk-go v0.3.2
github.com/cdevents/sdk-go v0.4.1
github.com/cloudevents/sdk-go/v2 v2.15.2
github.com/hashicorp/go-plugin v1.6.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -32,14 +32,14 @@ require (
github.com/oklog/run v1.0.0 // indirect
github.com/package-url/packageurl-go v0.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
)
18 changes: 10 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/cdevents/sdk-go v0.3.2 h1:E9spqXsOCqSDJgKff7IS2pFFx479fC9ocrfBwCZyXJM=
github.com/cdevents/sdk-go v0.3.2/go.mod h1:8bMgOeAIlKTnjGcafMRCKLatA1mEywd0LM6XqJ06eP8=
github.com/cdevents/sdk-go v0.4.1 h1:Cr/iH/I51Z+slxKRx9AV7stn6hr2pjRHQ5wpPJhRLTU=
github.com/cdevents/sdk-go v0.4.1/go.mod h1:3IhWLoY4vsyUEzv7XJbyr0BRQ0KPgvNx+wiD2hQGFNU=
github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc=
github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
Expand Down Expand Up @@ -72,8 +74,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand All @@ -92,8 +94,8 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
Expand All @@ -103,8 +105,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
Expand Down
16 changes: 9 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ func downloadPlugin(translatorPlugin cdevents.Plugin, pluginPath string, transla

func makeHandler(translatorPlugin cdevents.Plugin, pluginPath string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
log.Println("Received event payload : " + string(body))

client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: cdevents.Handshake,
Plugins: cdevents.PluginMap,
Expand Down Expand Up @@ -114,18 +121,13 @@ func makeHandler(translatorPlugin cdevents.Plugin, pluginPath string) http.Handl
http.Error(w, "Only POST requests are allowed", http.StatusMethodNotAllowed)
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
log.Println("Received event payload : " + string(body))

event, err := eventTranslator.TranslateEvent(string(body), r.Header)
log.Println("Event translated : " + event)
if err != nil {
http.Error(w, "Error translating event", http.StatusInternalServerError)
return
}
log.Println("Event translated : " + event)
err = cdevents.SendCDEvent(event, translatorPlugin.MessageBroker)
if err != nil {
http.Error(w, "Error sending CDEvent", http.StatusInternalServerError)
Expand Down
21 changes: 12 additions & 9 deletions pkg/cdevents/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import (
"context"
"errors"
"fmt"
cdeventssdk "github.com/cdevents/sdk-go/pkg/api"
cloudevents "github.com/cloudevents/sdk-go/v2"
"gopkg.in/yaml.v3"
"log"
"net/url"
"os"

cdevents "github.com/cdevents/sdk-go/pkg/api"
cdevents04 "github.com/cdevents/sdk-go/pkg/api/v04"
cloudevents "github.com/cloudevents/sdk-go/v2"
"gopkg.in/yaml.v3"
)

type Plugin struct {
Expand Down Expand Up @@ -73,12 +75,12 @@ func ValidateURL(URL string) (string, error) {

func SendCDEvent(event string, messageBrokerURL string) error {
fmt.Println("IN SendCDEvent with event " + event)
cdEvent, err := cdeventssdk.NewFromJsonString(event)
cdEvent, err := cdevents04.NewFromJsonString(event)
if err != nil {
log.Printf("failed to create CDEvent from Json string, %v", err)
return err
}
ce, err := cdeventssdk.AsCloudEvent(cdEvent)
ce, err := cdevents.AsCloudEvent(cdEvent)
if err != nil {
log.Printf("failed to create CDEvent as CloudEvent, %v", err)
return err
Expand All @@ -92,11 +94,12 @@ func SendCDEvent(event string, messageBrokerURL string) error {
log.Printf("failed to create client, %v", err)
return err
}
if result := c.Send(ctx, *ce); cloudevents.IsNACK(result) {
result := c.Send(ctx, *ce)
if cloudevents.IsNACK(result) || cloudevents.IsUndelivered(result) {
log.Printf("Failed to send CDEvent, %v", result)
return errors.New("failed to send CDEvent")
} else {
log.Println("Sent CDEvent to target message-broker URL")
return errors.New("failed to send CDEvent to target message-broker URL: " + messageBrokerURL)
}

log.Printf("Sent CDEvent to target message-broker URL: %v", result)
return nil
}
7 changes: 4 additions & 3 deletions pkg/cdevents/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ SPDX-License-Identifier: Apache-2.0
package cdevents

import (
"github.com/stretchr/testify/assert"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLoadTranslator_PluginsConfig(t *testing.T) {
Expand Down Expand Up @@ -78,9 +79,9 @@ func TestValidate_InValidURL(t *testing.T) {
}

func TestSendCDEvent(t *testing.T) {
eventToSend := "{\n \"context\": {\n \"version\": \"0.3.0\",\n \"id\": \"eb175ff7-2fda-44c5-bdb4-17b1c7342fc0\",\n \"source\": \"http://dev.cdevents\",\n \"type\": \"dev.cdevents.pipelinerun.finished.0.1.1\",\n \"timestamp\": \"2024-02-29T15:23:09Z\"\n },\n \"subject\": {\n \"id\": \"/dev/pipeline/run/subject\",\n \"source\": \"/dev/pipeline/run/subject\",\n \"type\": \"pipelineRun\",\n \"content\": {\n \"pipelineName\": \"Name-pipeline\",\n \"url\": \"http://dev/pipeline/url\",\n \"outcome\": \"success\",\n \"errors\": \"errors to place\"\n }\n },\n \"customData\": {\n },\n \"customDataContentType\": \"application/json\"\n}"
eventToSend := "{\n \"context\": {\n \"version\": \"0.3.0\",\n \"id\": \"eb175ff7-2fda-44c5-bdb4-17b1c7342fc0\",\n \"source\": \"http://dev.cdevents\",\n \"type\": \"dev.cdevents.pipelinerun.finished.0.2.0\",\n \"timestamp\": \"2024-02-29T15:23:09Z\"\n },\n \"subject\": {\n \"id\": \"/dev/pipeline/run/subject\",\n \"source\": \"/dev/pipeline/run/subject\",\n \"type\": \"pipelineRun\",\n \"content\": {\n \"pipelineName\": \"Name-pipeline\",\n \"url\": \"http://dev/pipeline/url\",\n \"outcome\": \"success\",\n \"errors\": \"errors to place\"\n }\n },\n \"customData\": {\n },\n \"customDataContentType\": \"application/json\"\n}"

err := SendCDEvent(eventToSend, "http://cdevents.message.com/default/events-broker")
err := SendCDEvent(eventToSend, "http://dummyAddress/default/events-broker")
assert.Error(t, err, "Expected an error")
assert.Contains(t, err.Error(), "failed to send CDEvent", "Expected log message not found")
}
3 changes: 3 additions & 0 deletions translator-plugins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ translator:
- name: "gerrit-translator-cdevents"
pluginURL: "http://github.com/cdevents/gerrit-translator-cdevents/gerrit-translator-cdevents-0.1.0"
messageBroker: "http://10.101.1.117:8010/default/events-broker"
- name: "jira-translator-cdevents"
pluginURL: "http://github.com/cdevents/jira-translator-cdevents/jira-translator-cdevents-0.1.0"
messageBroker: "http://10.101.1.117:8010/default/events-broker"
# - name: "github-translator-cdevents"
# pluginURL: "http://github.com/cdevents/github-translator-cdevents/github-translator-cdevents-0.1.0"
# messageBroker: "http://10.101.1.117:8010/default/events-broker"

0 comments on commit 39ad147

Please sign in to comment.