cdevents / sdk-go Goto Github PK
View Code? Open in Web Editor NEWGo SDK for CDEvents
License: Apache License 2.0
Go SDK for CDEvents
License: Apache License 2.0
The SDK contains today a lot of boilerplate code which is copied over and over to various events to implement all the getter and setter methods. The initial version of the code was generated through a script which is not up to date now and cannot be used to update existing code either.
The objective of this work is to have repeatable code generation, so that when events schemas change, the code may be regenerated automatically. There are two possible levels of code generation, which can be dealt with in separate issues:
According to the CDEvents spec, the source
field in the context is of type URI-reference
.
The field is currently validated as a string
- we should add better validation, either through the schema or in the go code.
When generating go code, we should utilize what go provides out of the box, go generate
which looks to be unused. This is idiomatic to go
The benefit of using go generate is you can just call it from the root of the project or wherever and it'll generate the code rather than a specific scripting file
It will be great to have a constant with all the supported event types. I couldn't find one if that exists already. Right now I need to look into each event in order to see its type: https://github.com/cdevents/sdk-go/blob/main/pkg/api/artifactpackaged.go#L27
The use case that I am trying to cover is:
Having a const containing all the available CDEvents types can help also to keep track of the changes in the spec.
In the readme file the example of sending the event as a cloudevent is wrong as it cannot initialize 1 variables with 2 values. It is missing the reference to err.
Current:
ce := cdevents.AsCloudEvent(event)
Should be:
ce, err := cdevents.AsCloudEvent(event)
as per pkg/api/bindings.go line 153
// AsCloudEvent renders a CDEvent as a CloudEvent
func AsCloudEvent(event CDEventReader) (*cloudevents.Event, error) {
if event == nil {
return nil, fmt.Errorf("nil CDEvent cannot be rendered as CloudEvent")
}
// Validate the event
err := Validate(event)
if err != nil {
return nil, fmt.Errorf("cannot validate CDEvent %v", err)
}
ce := cloudevents.NewEvent()
ce.SetSource(event.GetSource())
ce.SetSubject(event.GetSubjectId())
ce.SetType(event.GetType().String())
err = ce.SetData(cloudevents.ApplicationJSON, event)
return &ce, err
}
According to the CDEvents spec, the CloudEvents id
field must match the CDEvents id
field. The AsCloudEvent
method should set the CloudEvents id
, but it does not today.
Currently we use the raw cloudevents client directly. This can pose many problems in the future
So instead we should wrap the client which mitigates the two problems listed above, and allows us to add custom patterns ourselves, e.g. hooks. Users should be able to provide their own client if they want, but we should always wrap the client for any SDK.
cc, err := cdevents.NewCDEventsClient(cdevents.WithPresendHook(func(client cdevents.Client) {
log.Println("Some fancy logging")
})
// and allowing users to pass in their own client
cc, err := cdevents.NewCDEventsClient(cdevents.CDEventsClientOptions.WithCloudEventsClient(cloudeventsClient))
This issue will most likely depend on some upstream discussion to be had about supporting links in SDKs in general.
Once high-level design of the API is done, we will track the implementation in the go SDK through this issue.
So this kind of depends on #92
But right now we have these if statements that do validation based on an if type check.
if t, ok := event.(SomeBusV5) {
}
However, if we add v6, v7, v8, this if statement will just keep growing. The handler pattern works really well here.
var defaultHandlers CDEventClientHandlers = NewCDEventClientHandlers()
.Add("v5-validation", SomeBusV5Validator)
// then when users create clients we can just inject the default handlers
func NewCDEventsClient(ctx context.Context, options ...CDEventClientOption) (*CDEventsClient, err) {
client := &CDEventsClient {
ClientHandlers: defaultHandlers,
}
return client
}
Hey there.
Doing up a simple example today poking around and im getting compilation error
Sample Code:
package main
import (
// For nice logging
log "github.com/sirupsen/logrus"
// Import CDEVENTS
"github.com/cdevents/sdk-go/pkg/api"
)
func main(){
// Create a BASE EVENT
event, err := cdevents.NewPipelineRunQueuedEvent()
if err != nil {
log.Fatalf("could not create a cdevent, %v", err)
}
// Set the required Context fields
event.SetSubjectId("PipelineRun")
event.SetSource("cdevent-caller-program")
// Set the required Subject Fields
event.SetSubjectPipelineName("PiplineRun-1")
event.SetSubjectUrl("https://somethingsomethingdarkside.com")
log.Infof("PRINT EVENT \n --> %v", event)
}
Currently, the code in README.md does not work for sending as a CloudEvent. I would like to mentor a beginner for this issue so please assign it to me. I have done an example process to get them used to git here they can follow: #33
We need to make the following changes..
go get github.com/cloudevents/sdk-go/v2
2 . line 64 - Change from Sent to Send so it's not in the past tense
c, err := cloudevents.NewClientHTTP()
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
if result := c.Send(ctx, *ce); cloudevents.IsUndelivered(result) {
log.Fatalf("failed to send, %v", result)
}
The CDEvents spec introduced changes about how the spec and messages are versioned, described in cdevents/spec#67.
Align the SDK accordingly to match the spec.
Using GitHub actions, setup a CI job to run unit tests against all PRs and one CI job for linting.
The repo includes a makefile with targets already defined for that:
$ make
Makefile all fmt get-fmt-deps importfmt lint test
In the current generated schema, type
is at the bottom of each schema, and we would like instead to move it to the top for readability.
Schemas are currently generated from the go structs.
Check if it's possible to change this in the code that generates the json schemas.
For instance:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cdevents.dev/draft/schema/artifact-packaged-event",
"properties": {
"context": { (...)
},
"subject": { (...)
},
"customData": { (...)
},
},
"additionalProperties": false,
"type": "object",
"required": [
"context",
"subject"
]
}
should be:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cdevents.dev/draft/schema/artifact-packaged-event",
"type": "object",
"properties": {
"context": { (...)
},
"subject": { (...)
},
"customData": { (...)
},
},
"additionalProperties": false,
"required": [
"context",
"subject"
]
}
The use case here is I want to map a CloudEvent with ce-type X to a CDEvent dev.cdevents.artifact.packaged.v1
, would it be worth to have a utility to create a CDEvent from a CloudEvent, where the target CDevent embeds the CloudEvent as data?
Is this covered already?
The SDK should be able to produce and consume events for different versions of CDEvents.
A released version of the SDK should be able to work with on released versions of the spec, but not -draft
events.
Hey there.
Apologies if this is a really "dumb" question and i have missed it somewhere.
From the Examples, i see that we wrap a cdevent in a Cloud Event e.g:
And on the receiver side, we have created our inbound received event using the Cloudevents.NewEventFromHTTPRequest to pass up to our handlers/functions - all fine and good.
However, in terms of "unwrapping" a CDevent that is passed, is there a helper function or should i just (de)serialize to JSON / struct from the CloudEvent Content (i.e. cloudevents.ApplicationJSON (which is just a map[string]string of the CDevent) parts that i need ?
cloudevents.event.GetData() and then bind to a CDevent Type?
Essentially, if i follow off the CloudEvents, i have come up with this Handler Function that 'snitches' the incoming CloudEvent Type and then uses it with the NewCDEvent function in the tools - it "works" in that i get my CDEvent stripped away from the CloudEvent Envelope, but im not sure its the best way (e.g. what happens if you decide to remove that NewCDEvent? - there doesnt seem to be a Generic CDEvent.New() that i could find?
This ends up with a raw object of type inbound of the same CDEvents Type (based of the "type" derived from the CloudEvent field (Type).
So again, working .. but seems a bit "ugly" to wrap - i suppose i could "cast", but that would be worse i think.
Cheers and thanks for any insights/input!
Z
Setters are not heavily used in Go, so we should revisit a more idiomatic approach either by setting things on the struct directly or using functions options which is pretty standard in Go
So instead of
event := cdevents.NewSomeCDEvent()
event.SetFoo("foo")
we'd have something more like
event := cdevents.NewSomeCDEvent(cdevent.SomeCDEventOptions.WithFields(func(e cdevents.SomeCDEvent) {
e.Foo = "foo"
})
// or
event := cdevents.NewSomeCDEvent(cdevent.SomeCDEventOptions.WithFoo("foo"))
Or a combination of the two. So is one better than the other? Not necessarily. But one is more idiomatic, and that's crucial for SDKs.
In the license file on line 189 the authors haven't been stated, this is a common thing that people miss when adding apache2 licenses.
I will create a PR to update it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.