diff --git a/examples/v1alpha1/taskruns/cloud-event.yaml b/examples/v1alpha1/taskruns/cloud-event.yaml index 006c3a94ca7..04e2745ff11 100644 --- a/examples/v1alpha1/taskruns/cloud-event.yaml +++ b/examples/v1alpha1/taskruns/cloud-event.yaml @@ -38,9 +38,7 @@ spec: with open("content.txt", mode="wb") as f: f.write(content) self.send_response(200) - self.send_header('Content-type', 'text/html') self.end_headers() - self.wfile.write(b'

POST!

') def do_GET(self): with open("content.txt", mode="rb") as f: diff --git a/go.mod b/go.mod index 5caa606503b..286cf97f6fa 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cloud.google.com/go v0.47.0 // indirect contrib.go.opencensus.io/exporter/stackdriver v0.12.8 // indirect github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher v0.0.0-20191203181535-308b93ad1f39 - github.com/cloudevents/sdk-go v1.0.0 + github.com/cloudevents/sdk-go/v2 v2.0.0-preview6 github.com/ghodss/yaml v1.0.0 github.com/go-openapi/spec v0.19.4 // indirect github.com/gogo/protobuf v1.3.1 // indirect @@ -14,6 +14,7 @@ require ( github.com/google/go-cmp v0.4.0 github.com/google/go-containerregistry v0.0.0-20200115214256-379933c9c22b github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.1 github.com/googleapis/gnostic v0.3.1 // indirect github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/golang-lru v0.5.3 @@ -36,14 +37,12 @@ require ( go.uber.org/multierr v1.4.0 // indirect go.uber.org/zap v1.13.0 golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect - golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/tools v0.0.0-20200214144324-88be01311a71 // indirect gomodules.xyz/jsonpatch/v2 v2.1.0 // indirect google.golang.org/appengine v1.6.5 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect k8s.io/api v0.17.3 k8s.io/apiextensions-apiserver v0.17.3 // indirect k8s.io/apimachinery v0.17.3 @@ -52,7 +51,6 @@ require ( k8s.io/gengo v0.0.0-20191108084044-e500ee069b5c // indirect k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a knative.dev/caching v0.0.0-20200116200605-67bca2c83dfa - knative.dev/eventing-contrib v0.11.2 knative.dev/pkg v0.0.0-20200227193851-2fe8db300072 ) diff --git a/go.sum b/go.sum index ac4c488ba2f..3546e06712e 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,10 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudevents/sdk-go v1.0.0 h1:gS5I0s2qPmdc4GBPlUmzZU7RH30BaiOdcRJ1RkXnPrc= -github.com/cloudevents/sdk-go v1.0.0/go.mod h1:3TkmM0cFqkhCHOq5JzzRU/RxRkwzoS8TZ+G448qVTog= +github.com/cloudevents/sdk-go v1.1.2 h1:mg/7d+BzubBPrPpH1bdeF85BQZYV85j7Ljqat3+m+qE= +github.com/cloudevents/sdk-go v1.1.2/go.mod h1:ss+jWJ88wypiewnPEzChSBzTYXGpdcILoN9YHk8uhTQ= +github.com/cloudevents/sdk-go/v2 v2.0.0-preview6 h1:IYRl0IoWKRZE+1f9Zlm8qtc6zKg/wq4k7TKBDbIq1rg= +github.com/cloudevents/sdk-go/v2 v2.0.0-preview6/go.mod h1:zbpxUOAoR8b4Shvo1GyHbcL/S/hgr1WJ3rNuMUgrlh0= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -377,11 +379,15 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk= +github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -543,6 +549,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tektoncd/plumbing v0.0.0-20200217163359-cd0db6e567d2 h1:BksmpUwtap3THXJ8Z4KGcotsvpRdFQKySjDHgtc22lA= github.com/tektoncd/plumbing v0.0.0-20200217163359-cd0db6e567d2/go.mod h1:QZHgU07PRBTRF6N57w4+ApRu8OgfYLFNqCDlfEZaD9Y= github.com/tektoncd/plumbing/pipelinerun-logs v0.0.0-20191206114338-712d544c2c21/go.mod h1:S62EUWtqmejjJgUMOGB1CCCHRp6C706laH06BoALkzU= @@ -550,6 +558,7 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238 h1:o+AFkRxPBxf23y/mH9RM5doyTxQHRFpq6psWi7012X0= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= @@ -606,6 +615,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -876,8 +887,6 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCui k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= knative.dev/caching v0.0.0-20200116200605-67bca2c83dfa h1:mxrur6DsVK8uIjhIq7c1OMls4YjBcRlyvnh3Vx13a0M= knative.dev/caching v0.0.0-20200116200605-67bca2c83dfa/go.mod h1:dHXFU6CGlLlbzaWc32g80cR92iuBSpsslDNBWI8C7eg= -knative.dev/eventing-contrib v0.11.2 h1:xncT+JrokPG+hPUFJwue8ubPpzmziV9GUIZqYt01JDo= -knative.dev/eventing-contrib v0.11.2/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g= knative.dev/pkg v0.0.0-20200227193851-2fe8db300072 h1:ZituYY5obt+2k4JRN5hNmtX00KXDBXGMohS6n2xf250= knative.dev/pkg v0.0.0-20200227193851-2fe8db300072/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= diff --git a/pkg/reconciler/taskrun/resources/cloudevent/cloud_event_controller.go b/pkg/reconciler/taskrun/resources/cloudevent/cloud_event_controller.go index e83de23b616..9849d152950 100644 --- a/pkg/reconciler/taskrun/resources/cloudevent/cloud_event_controller.go +++ b/pkg/reconciler/taskrun/resources/cloudevent/cloud_event_controller.go @@ -17,8 +17,10 @@ limitations under the License. package cloudevent import ( + "context" "time" + cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/hashicorp/go-multierror" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" @@ -67,6 +69,15 @@ func cloudEventDeliveryFromTargets(targets []string) []v1alpha1.CloudEventDelive // the TaskRun is complete. `tr` is used to obtain the list of targets but also // to construct the body of the func SendCloudEvents(tr *v1alpha1.TaskRun, ceclient CEClient, logger *zap.SugaredLogger) error { + logger = logger.With(zap.String("taskrun", tr.Name)) + + // Make the event we would like to send: + event, err := EventForTaskRun(tr) + if err != nil || event == nil { + logger.With(zap.Error(err)).Error("failed to produce a cloudevent from TaskRun.") + return err + } + // Using multierror here so we can attempt to send all cloud events defined, // regardless of whether they fail or not, and report all failed ones var merr *multierror.Error @@ -77,7 +88,11 @@ func SendCloudEvents(tr *v1alpha1.TaskRun, ceclient CEClient, logger *zap.Sugare if eventStatus.Condition != v1alpha1.CloudEventConditionUnknown || eventStatus.RetryCount > 0 { continue } - _, err := SendTaskRunCloudEvent(cloudEventDelivery.Target, tr, logger, ceclient) + + // Send the event. + err := ceclient.Send(cloudevents.ContextWithTarget(context.Background(), cloudEventDelivery.Target), *event) + + // Record the result. eventStatus.SentAt = &metav1.Time{Time: time.Now()} eventStatus.RetryCount++ if err != nil { @@ -85,12 +100,12 @@ func SendCloudEvents(tr *v1alpha1.TaskRun, ceclient CEClient, logger *zap.Sugare eventStatus.Condition = v1alpha1.CloudEventConditionFailed eventStatus.Error = merr.Error() } else { - logger.Infof("Sent event for target %s", cloudEventDelivery.Target) + logger.Infow("Event sent.", zap.String("target", cloudEventDelivery.Target)) eventStatus.Condition = v1alpha1.CloudEventConditionSent } } if merr != nil && merr.Len() > 0 { - logger.Errorf("Failed to send %d cloud events for TaskRun %s", merr.Len(), tr.Name) + logger.With(zap.Error(merr)).Errorw("Failed to send events for TaskRun.", zap.Int("count", merr.Len())) } return merr.ErrorOrNil() } diff --git a/pkg/reconciler/taskrun/resources/cloudevent/cloudevent.go b/pkg/reconciler/taskrun/resources/cloudevent/cloudevent.go index 01c01e97a42..fab0a8b122a 100644 --- a/pkg/reconciler/taskrun/resources/cloudevent/cloudevent.go +++ b/pkg/reconciler/taskrun/resources/cloudevent/cloudevent.go @@ -17,21 +17,15 @@ limitations under the License. package cloudevent import ( - "context" - "encoding/json" "errors" "fmt" "strings" - "time" - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/client" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/google/uuid" + + cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "go.uber.org/zap" - "knative.dev/eventing-contrib/pkg/kncloudevents" "knative.dev/pkg/apis" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" @@ -49,8 +43,12 @@ const ( TektonTaskRunFailedV1 TektonEventType = "dev.tekton.event.task.failed.v1" ) -// CEClient matches the `Client` interface from github.com/cloudevents/sdk-go/pkg/cloudevents -type CEClient client.Client +func (t TektonEventType) String() string { + return string(t) +} + +// CEClient matches the `Client` interface from github.com/cloudevents/sdk-go/v2/cloudevents +type CEClient cloudevents.Client // TektonCloudEventData type is used to marshal and unmarshal the payload of // a Tekton cloud event. It only includes a TaskRun for now. Using a type opens @@ -66,68 +64,34 @@ func NewTektonCloudEventData(taskRun *v1alpha1.TaskRun) TektonCloudEventData { } } -// SendCloudEvent sends a Cloud Event to the specified SinkURI -func SendCloudEvent(sinkURI, eventID, eventSourceURI string, data []byte, eventType TektonEventType, logger *zap.SugaredLogger, cloudEventClient CEClient) (cloudevents.Event, error) { - var event cloudevents.Event - - cloudEventSource := types.ParseURLRef(eventSourceURI) - if cloudEventSource == nil { - logger.Errorf("Invalid eventSourceURI: %s", eventSourceURI) - return event, fmt.Errorf("invalid eventSourceURI: %s", eventSourceURI) - } - - event = cloudevents.Event{ - Context: cloudevents.EventContextV02{ - ID: eventID, - Type: string(eventType), - Source: *cloudEventSource, - Time: &types.Timestamp{Time: time.Now()}, - Extensions: nil, - }.AsV02(), - Data: data, - } - ctxt := cecontext.WithTarget(context.TODO(), sinkURI) - _, _, err := cloudEventClient.Send(ctxt, event) - if err != nil { - logger.Errorf("Error sending the cloud-event: %s", err) - return event, err - } - return event, nil -} - -// SendTaskRunCloudEvent sends a cloud event for a TaskRun -func SendTaskRunCloudEvent(sinkURI string, taskRun *v1alpha1.TaskRun, logger *zap.SugaredLogger, cloudEventClient CEClient) (cloudevents.Event, error) { - var event cloudevents.Event - var err error - // Check if a client was provided, if not build one on the fly - if cloudEventClient == nil { - cloudEventClient, err = kncloudevents.NewDefaultClient() - if err != nil { - logger.Errorf("Error creating the cloud-event client: %s", err) - return event, err - } - } +// EventForTaskRun will create a new event based on a TaskRun, +// or return an error if not possible. +func EventForTaskRun(taskRun *v1alpha1.TaskRun) (*cloudevents.Event, error) { // Check if the TaskRun is defined if taskRun == nil { - return event, errors.New("Cannot send an event for an empty TaskRun") + return nil, errors.New("Cannot send an event for an empty TaskRun") } - eventID := taskRun.ObjectMeta.Name - taskRunStatus := taskRun.Status.GetCondition(apis.ConditionSucceeded) - var eventType TektonEventType + event := cloudevents.NewEvent() + event.SetID(uuid.New().String()) + event.SetSubject(taskRun.ObjectMeta.Name) + event.SetSource(taskRun.ObjectMeta.SelfLink) // TODO: SelfLink is deprecated + + c := taskRun.Status.GetCondition(apis.ConditionSucceeded) switch { - case taskRunStatus.IsUnknown(): - eventType = TektonTaskRunUnknownV1 - case taskRunStatus.IsFalse(): - eventType = TektonTaskRunFailedV1 - case taskRunStatus.IsTrue(): - eventType = TektonTaskRunSuccessfulV1 + case c.IsUnknown(): + event.SetType(TektonTaskRunUnknownV1.String()) + case c.IsFalse(): + event.SetType(TektonTaskRunFailedV1.String()) + case c.IsTrue(): + event.SetType(TektonTaskRunSuccessfulV1.String()) default: - return event, fmt.Errorf("unknown condition for in TaskRun.Status %s", taskRunStatus.Status) + return nil, fmt.Errorf("unknown condition for in TaskRun.Status %s", c.Status) + } + + if err := event.SetData(cloudevents.ApplicationJSON, NewTektonCloudEventData(taskRun)); err != nil { + return nil, err } - eventSourceURI := taskRun.ObjectMeta.SelfLink - data, _ := json.Marshal(NewTektonCloudEventData(taskRun)) - event, err = SendCloudEvent(sinkURI, eventID, eventSourceURI, data, eventType, logger, cloudEventClient) - return event, err + return &event, nil } // GetCloudEventDeliveryCompareOptions returns compare options to sort diff --git a/pkg/reconciler/taskrun/resources/cloudevent/cloudevent_test.go b/pkg/reconciler/taskrun/resources/cloudevent/cloudevent_test.go index 0663bac91dd..17d122bd469 100644 --- a/pkg/reconciler/taskrun/resources/cloudevent/cloudevent_test.go +++ b/pkg/reconciler/taskrun/resources/cloudevent/cloudevent_test.go @@ -17,100 +17,22 @@ limitations under the License. package cloudevent import ( - "encoding/json" - "fmt" - "regexp" "testing" "github.com/google/go-cmp/cmp" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" - "github.com/tektoncd/pipeline/pkg/logging" "github.com/tektoncd/pipeline/test/names" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "knative.dev/eventing-contrib/pkg/kncloudevents" "knative.dev/pkg/apis" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" ) const ( - defaultSinkURI = "http://sink" - invalidSinkURI = "invalid_URI" - defaultEventID = "event1234" - defaultEventSourceURI = "/taskrun/1234" - invalidEventSourceURI = "htt%23p://_invalid_URI##" - defaultEventType = TektonTaskRunUnknownV1 - taskRunName = "faketaskrunname" - invalidConditionSuccessStatus = "foobar" + defaultEventSourceURI = "/taskrun/1234" + taskRunName = "faketaskrunname" ) -var ( - defaultRawData = []byte(`{"metadata": {"name":"faketaskrun"}}`) - nilEventType TektonEventType - defaultCloudEventClient, _ = kncloudevents.NewDefaultClient() - happyClientBehaviour = FakeClientBehaviour{SendSuccessfully: true} - failingClientBehaviour = FakeClientBehaviour{SendSuccessfully: false} -) - -func TestSendCloudEvent(t *testing.T) { - for _, c := range []struct { - desc string - sinkURI string - eventSourceURI string - cloudEventClient CEClient - wantErr bool - errRegexp string - }{{ - desc: "send a cloud event when all inputs are valid", - sinkURI: defaultSinkURI, - eventSourceURI: defaultEventSourceURI, - cloudEventClient: NewFakeClient(&happyClientBehaviour), - wantErr: false, - errRegexp: "", - }, { - desc: "send a cloud event with invalid sink URI", - sinkURI: invalidSinkURI, - eventSourceURI: defaultEventSourceURI, - cloudEventClient: defaultCloudEventClient, - wantErr: true, - errRegexp: fmt.Sprintf("\"?%s\"?: unsupported protocol scheme", invalidSinkURI), - }, { - desc: "send a cloud event, fail to send", - sinkURI: defaultSinkURI, - eventSourceURI: defaultEventSourceURI, - cloudEventClient: NewFakeClient(&failingClientBehaviour), - wantErr: true, - errRegexp: fmt.Sprintf("%s had to fail", defaultEventID), - }, { - desc: "send a cloud event with invalid source URI", - sinkURI: defaultSinkURI, - eventSourceURI: invalidEventSourceURI, - cloudEventClient: defaultCloudEventClient, - wantErr: true, - errRegexp: fmt.Sprintf("invalid eventSourceURI: %s", invalidEventSourceURI), - }} { - t.Run(c.desc, func(t *testing.T) { - logger, _ := logging.NewLogger("", "") - names.TestingSeed() - _, err := SendCloudEvent(c.sinkURI, defaultEventID, c.eventSourceURI, defaultRawData, defaultEventType, logger, c.cloudEventClient) - if c.wantErr != (err != nil) { - if c.wantErr { - t.Fatalf("I expected an error but I got nil") - } else { - t.Fatalf("I did not expect an error but I got %s", err) - } - } else { - if c.wantErr { - match, _ := regexp.Match(c.errRegexp, []byte(err.Error())) - if !match { - t.Fatalf("I expected an error like %s, but I got %s", c.errRegexp, err) - } - } - } - }) - } -} - func getTaskRunByCondition(status corev1.ConditionStatus) *v1alpha1.TaskRun { return &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -130,7 +52,7 @@ func getTaskRunByCondition(status corev1.ConditionStatus) *v1alpha1.TaskRun { } } -func TestSendTaskRunCloudEvent(t *testing.T) { +func TestEventForTaskRun(t *testing.T) { for _, c := range []struct { desc string taskRun *v1alpha1.TaskRun @@ -149,60 +71,30 @@ func TestSendTaskRunCloudEvent(t *testing.T) { wantEventType: TektonTaskRunFailedV1, }} { t.Run(c.desc, func(t *testing.T) { - logger, _ := logging.NewLogger("", "") names.TestingSeed() - event, err := SendTaskRunCloudEvent(defaultSinkURI, c.taskRun, logger, NewFakeClient(&happyClientBehaviour)) + + got, err := EventForTaskRun(c.taskRun) if err != nil { t.Fatalf("I did not expect an error but I got %s", err) } else { - wantEventID := taskRunName - if diff := cmp.Diff(wantEventID, event.Context.GetID()); diff != "" { + wantSubject := taskRunName + if diff := cmp.Diff(wantSubject, got.Subject()); diff != "" { t.Errorf("Wrong Event ID (-want +got) = %s", diff) } - gotEventType := event.Context.GetType() - if diff := cmp.Diff(string(c.wantEventType), gotEventType); diff != "" { + if diff := cmp.Diff(string(c.wantEventType), got.Type()); diff != "" { t.Errorf("Wrong Event Type (-want +got) = %s", diff) } - wantData, _ := json.Marshal(NewTektonCloudEventData(c.taskRun)) - gotData, err := event.DataBytes() - if err != nil { - t.Fatalf("Could not get data from event %v: %v", event, err) + wantData := NewTektonCloudEventData(c.taskRun) + gotData := TektonCloudEventData{} + if err := got.DataAs(&gotData); err != nil { + t.Errorf("Unexpected error from DataAsl; %s", err) } if diff := cmp.Diff(wantData, gotData); diff != "" { t.Errorf("Wrong Event data (-want +got) = %s", diff) } - } - }) - } -} -func TestSendTaskRunCloudEventErrors(t *testing.T) { - for _, c := range []struct { - desc string - taskRun *v1alpha1.TaskRun - wantEventType TektonEventType - errRegexp string - }{{ - desc: "send a cloud event with a nil taskrun", - taskRun: nil, - wantEventType: nilEventType, - errRegexp: "Cannot send an event for an empty TaskRun", - }, { - desc: "send a cloud event with invalid status taskrun", - taskRun: getTaskRunByCondition(invalidConditionSuccessStatus), - wantEventType: nilEventType, - errRegexp: fmt.Sprintf("unknown condition for in TaskRun.Status %s", invalidConditionSuccessStatus), - }} { - t.Run(c.desc, func(t *testing.T) { - logger, _ := logging.NewLogger("", "") - names.TestingSeed() - _, err := SendTaskRunCloudEvent(defaultSinkURI, c.taskRun, logger, NewFakeClient(&happyClientBehaviour)) - if err == nil { - t.Fatalf("I expected an error but I got nil") - } else { - match, _ := regexp.Match(c.errRegexp, []byte(err.Error())) - if !match { - t.Fatalf("I expected an error like %s, but I got %s", c.errRegexp, err) + if err := got.Validate(); err != nil { + t.Errorf("Expected event to be valid; %s", err) } } }) diff --git a/pkg/reconciler/taskrun/resources/cloudevent/cloudeventclient.go b/pkg/reconciler/taskrun/resources/cloudevent/cloudeventclient.go index fc54ac59f35..372f8db4ad5 100644 --- a/pkg/reconciler/taskrun/resources/cloudevent/cloudeventclient.go +++ b/pkg/reconciler/taskrun/resources/cloudevent/cloudeventclient.go @@ -19,10 +19,10 @@ package cloudevent import ( "context" - rest "k8s.io/client-go/rest" - "knative.dev/eventing-contrib/pkg/kncloudevents" - injection "knative.dev/pkg/injection" - logging "knative.dev/pkg/logging" + cloudevents "github.com/cloudevents/sdk-go/v2" + "k8s.io/client-go/rest" + "knative.dev/pkg/injection" + "knative.dev/pkg/logging" ) func init() { @@ -33,11 +33,18 @@ func init() { type CECKey struct{} func withCloudEventClient(ctx context.Context, cfg *rest.Config) context.Context { - cloudEventClient, err := kncloudevents.NewDefaultClient() + logger := logging.FromContext(ctx) + p, err := cloudevents.NewHTTP() if err != nil { - // If we cannot setup a client, die - panic(err) + logger.Panicf("Error creating the cloudevents http protocol: %s", err) + return ctx } + + cloudEventClient, err := cloudevents.NewClient(p, cloudevents.WithUUIDs(), cloudevents.WithTimeNow()) + if err != nil { + logger.Panicf("Error creating the cloudevents client: %s", err) + } + return context.WithValue(ctx, CECKey{}, cloudEventClient) } diff --git a/pkg/reconciler/taskrun/resources/cloudevent/cloudeventsfakeclient.go b/pkg/reconciler/taskrun/resources/cloudevent/cloudeventsfakeclient.go index bcc3876b2a2..a2e8663f4a2 100644 --- a/pkg/reconciler/taskrun/resources/cloudevent/cloudeventsfakeclient.go +++ b/pkg/reconciler/taskrun/resources/cloudevent/cloudeventsfakeclient.go @@ -20,8 +20,7 @@ import ( "context" "fmt" - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/client" + cloudevents "github.com/cloudevents/sdk-go/v2" ) // FakeClientBehaviour defines how the client will behave @@ -37,23 +36,34 @@ type FakeClient struct { } // NewFakeClient is a FakeClient factory, it returns a client for the target -func NewFakeClient(behaviour *FakeClientBehaviour) client.Client { +func NewFakeClient(behaviour *FakeClientBehaviour) cloudevents.Client { c := FakeClient{ behaviour: behaviour, } return c } -// Send fakes the Send method from kncloudevents.NewDefaultClient -func (c FakeClient) Send(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) { +var _ cloudevents.Client = (*FakeClient)(nil) + +// Send fakes the Send method from cloudevents.Client +func (c FakeClient) Send(ctx context.Context, event cloudevents.Event) error { + c.event = event + if c.behaviour.SendSuccessfully { + return nil + } + return fmt.Errorf("%s had to fail", event.ID()) +} + +// Request fakes the Request method from cloudevents.Client +func (c FakeClient) Request(ctx context.Context, event cloudevents.Event) (*cloudevents.Event, error) { c.event = event if c.behaviour.SendSuccessfully { - return ctx, &event, nil + return &event, nil } - return ctx, nil, fmt.Errorf("%s had to fail", event.Context.GetID()) + return nil, fmt.Errorf("%s had to fail", event.ID()) } -// StartReceiver fakes the StartReceiver method from kncloudevents.NewDefaultClient +// StartReceiver fakes StartReceiver method from cloudevents.Client func (c FakeClient) StartReceiver(ctx context.Context, fn interface{}) error { return nil } diff --git a/third_party/github.com/cloudevents/sdk-go/LICENSE b/third_party/github.com/cloudevents/sdk-go/v2/LICENSE similarity index 100% rename from third_party/github.com/cloudevents/sdk-go/LICENSE rename to third_party/github.com/cloudevents/sdk-go/v2/LICENSE diff --git a/third_party/github.com/hashicorp/errwrap/go.mod b/third_party/github.com/hashicorp/errwrap/go.mod index d7ed369809b..c9b84022cf7 100644 --- a/third_party/github.com/hashicorp/errwrap/go.mod +++ b/third_party/github.com/hashicorp/errwrap/go.mod @@ -1,3 +1 @@ module github.com/hashicorp/errwrap - -go 1.13 diff --git a/third_party/github.com/hashicorp/go-multierror/go.mod b/third_party/github.com/hashicorp/go-multierror/go.mod index 8c91af65b26..2534331d5f9 100644 --- a/third_party/github.com/hashicorp/go-multierror/go.mod +++ b/third_party/github.com/hashicorp/go-multierror/go.mod @@ -1,5 +1,3 @@ module github.com/hashicorp/go-multierror require github.com/hashicorp/errwrap v1.0.0 - -go 1.13 diff --git a/third_party/github.com/lightstep/tracecontext.go/LICENSE b/third_party/github.com/lightstep/tracecontext.go/LICENSE new file mode 100644 index 00000000000..853b46db127 --- /dev/null +++ b/third_party/github.com/lightstep/tracecontext.go/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cloudevents/sdk-go/.gitignore b/vendor/github.com/cloudevents/sdk-go/.gitignore deleted file mode 100644 index 2f9d9da00b0..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Operating system temporary files -.DS_Store - -# Editor/IDE specific settings -.idea -.vscode/ - -# Temporary output of build tools -bazel-* - -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool -*.out - -# Others -## IDE-specific -*.iml -test/benchmark/http/results/ -tmp/ - diff --git a/vendor/github.com/cloudevents/sdk-go/LICENSE b/vendor/github.com/cloudevents/sdk-go/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/cloudevents/sdk-go/README.md b/vendor/github.com/cloudevents/sdk-go/README.md deleted file mode 100644 index 4eb3e83b886..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# Go SDK for [CloudEvents](https://github.com/cloudevents/spec) - -[![go-doc](https://godoc.org/github.com/cloudevents/sdk-go?status.svg)](https://godoc.org/github.com/cloudevents/sdk-go) -[![Go Report Card](https://goreportcard.com/badge/github.com/cloudevents/sdk-go)](https://goreportcard.com/report/github.com/cloudevents/sdk-go) -[![CircleCI](https://circleci.com/gh/cloudevents/sdk-go.svg?style=svg)](https://circleci.com/gh/cloudevents/sdk-go) -[![Releases](https://img.shields.io/github/release-pre/cloudevents/sdk-go.svg)](https://github.com/cloudevents/sdk-go/releases) -[![LICENSE](https://img.shields.io/github/license/cloudevents/sdk-go.svg)](https://github.com/cloudevents/sdk-go/blob/master/LICENSE) - -## Status - -This SDK is still considered work in progress. - -**With v1.0.0:** - -The API that exists under [`pkg/cloudevents`](./pkg/cloudevents) will follow -semver rules. This applies to the root [`./alias.go`](./alias.go) file as well. - -Even though `pkg/cloudevents` is v1.0.0, there could still be minor bugs and -performance issues. We will continue to track and fix these issues as they come -up. Please file a pull request or issue if you experience problems. - -The API that exists under [`pkg/bindings`](./pkg/bindings) is a new API that -will become SDK v2.x, and will replace `pkg/cloudevents`. This area is still -under heavy development and will not be following the same semver rules as -`pkg/cloudevents`. If a release is required to ship changes to `pkg/bindings`, a -bug fix release will be issued (x.y.z+1). - -We will target ~2 months of development to release v2 of this SDK with an end -date of March 27, 2020. You can read more about the plan for SDK v2 in the -[SDK v2 planning doc](./docs/SDK_v2.md). - -This SDK current supports the following versions of CloudEvents: - -- v1.0 -- v0.3 -- v0.2 -- v0.1 - -## Working with CloudEvents - -Package [cloudevents](./pkg/cloudevents) provides primitives to work with -CloudEvents specification: https://github.com/cloudevents/spec. - -Import this repo to get the `cloudevents` package: - -```go -import "github.com/cloudevents/sdk-go" -``` - -Receiving a cloudevents.Event via the HTTP Transport: - -```go -func Receive(event cloudevents.Event) { - // do something with event.Context and event.Data (via event.DataAs(foo) -} - -func main() { - c, err := cloudevents.NewDefaultClient() - if err != nil { - log.Fatalf("failed to create client, %v", err) - } - log.Fatal(c.StartReceiver(context.Background(), Receive)); -} -``` - -Creating a minimal CloudEvent in version 0.2: - -```go -event := cloudevents.NewEvent() -event.SetID("ABC-123") -event.SetType("com.cloudevents.readme.sent") -event.SetSource("http://localhost:8080/") -event.SetData(data) -``` - -Sending a cloudevents.Event via the HTTP Transport with Binary v0.2 encoding: - -```go -t, err := cloudevents.NewHTTPTransport( - cloudevents.WithTarget("http://localhost:8080/"), - cloudevents.WithEncoding(cloudevents.HTTPBinaryV02), -) -if err != nil { - panic("failed to create transport, " + err.Error()) -} - -c, err := cloudevents.NewClient(t) -if err != nil { - panic("unable to create cloudevent client: " + err.Error()) -} -if err := c.Send(ctx, event); err != nil { - panic("failed to send cloudevent: " + err.Error()) -} -``` - -Or, the transport can be set to produce CloudEvents using the selected encoding -but not change the provided event version, here the client is set to output -structured encoding: - -```go -t, err := cloudevents.NewHTTPTransport( - cloudevents.WithTarget("http://localhost:8080/"), - cloudevents.WithStructuredEncoding(), -) -``` - -If you are using advanced transport features or have implemented your own -transport integration, provide it to a client so your integration does not -change: - -```go -t, err := cloudevents.NewHTTPTransport( - cloudevents.WithPort(8181), - cloudevents.WithPath("/events/") -) -// or a custom transport: t := &custom.MyTransport{Cool:opts} - -c, err := cloudevents.NewClient(t, opts...) -``` - -Checkout the sample [sender](./cmd/samples/http/sender) and -[receiver](./cmd/samples/http/receiver) applications for working demo. - -## Community - -- There are bi-weekly calls immediately following the - [Serverless/CloudEvents call](https://github.com/cloudevents/spec#meeting-time) - at 9am PT (US Pacific). Which means they will typically start at 10am PT, but - if the other call ends early then the SDK call will start early as well. See - the - [CloudEvents meeting minutes](https://docs.google.com/document/d/1OVF68rpuPK5shIHILK9JOqlZBbfe91RNzQ7u_P7YCDE/edit#) - to determine which week will have the call. -- Slack: #cloudeventssdk channel under - [CNCF's Slack workspace](https://slack.cncf.io/). -- Contact for additional information: Scott Nichols (`@Scott Nichols` on slack). diff --git a/vendor/github.com/cloudevents/sdk-go/alias.go b/vendor/github.com/cloudevents/sdk-go/alias.go deleted file mode 100644 index 7bc4e54d398..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/alias.go +++ /dev/null @@ -1,150 +0,0 @@ -package cloudevents - -// Package cloudevents alias' common functions and types to improve discoverability and reduce -// the number of imports for simple HTTP clients. - -import ( - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/client" - "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// Client - -type ClientOption client.Option -type Client = client.Client -type ConvertFn = client.ConvertFn - -// Event - -type Event = cloudevents.Event -type EventResponse = cloudevents.EventResponse - -// Context - -type EventContext = cloudevents.EventContext -type EventContextV1 = cloudevents.EventContextV1 -type EventContextV01 = cloudevents.EventContextV01 -type EventContextV02 = cloudevents.EventContextV02 -type EventContextV03 = cloudevents.EventContextV03 - -// Custom Types - -type Timestamp = types.Timestamp -type URLRef = types.URLRef - -// HTTP Transport - -type HTTPOption http.Option -type HTTPTransport = http.Transport -type HTTPTransportContext = http.TransportContext -type HTTPTransportResponseContext = http.TransportResponseContext -type HTTPEncoding = http.Encoding - -const ( - // Encoding - - ApplicationXML = cloudevents.ApplicationXML - ApplicationJSON = cloudevents.ApplicationJSON - ApplicationCloudEventsJSON = cloudevents.ApplicationCloudEventsJSON - ApplicationCloudEventsBatchJSON = cloudevents.ApplicationCloudEventsBatchJSON - Base64 = cloudevents.Base64 - - // Event Versions - - VersionV1 = cloudevents.CloudEventsVersionV1 - VersionV01 = cloudevents.CloudEventsVersionV01 - VersionV02 = cloudevents.CloudEventsVersionV02 - VersionV03 = cloudevents.CloudEventsVersionV03 - - // HTTP Transport Encodings - - HTTPBinaryV1 = http.BinaryV1 - HTTPStructuredV1 = http.StructuredV1 - HTTPBatchedV1 = http.BatchedV1 - HTTPBinaryV01 = http.BinaryV01 - HTTPStructuredV01 = http.StructuredV01 - HTTPBinaryV02 = http.BinaryV02 - HTTPStructuredV02 = http.StructuredV02 - HTTPBinaryV03 = http.BinaryV03 - HTTPStructuredV03 = http.StructuredV03 - HTTPBatchedV03 = http.BatchedV03 - - // Context HTTP Transport Encodings - - Binary = http.Binary - Structured = http.Structured -) - -var ( - // ContentType Helpers - - StringOfApplicationJSON = cloudevents.StringOfApplicationJSON - StringOfApplicationXML = cloudevents.StringOfApplicationXML - StringOfApplicationCloudEventsJSON = cloudevents.StringOfApplicationCloudEventsJSON - StringOfApplicationCloudEventsBatchJSON = cloudevents.StringOfApplicationCloudEventsBatchJSON - StringOfBase64 = cloudevents.StringOfBase64 - - // Client Creation - - NewClient = client.New - NewDefaultClient = client.NewDefault - - // Client Options - - WithEventDefaulter = client.WithEventDefaulter - WithUUIDs = client.WithUUIDs - WithTimeNow = client.WithTimeNow - WithConverterFn = client.WithConverterFn - WithDataContentType = client.WithDataContentType - - // Event Creation - - NewEvent = cloudevents.New - - // Tracing - - EnableTracing = observability.EnableTracing - - // Context - - ContextWithTarget = context.WithTarget - TargetFromContext = context.TargetFrom - ContextWithEncoding = context.WithEncoding - EncodingFromContext = context.EncodingFrom - - // Custom Types - - ParseTimestamp = types.ParseTimestamp - ParseURLRef = types.ParseURLRef - ParseURIRef = types.ParseURIRef - ParseURI = types.ParseURI - - // HTTP Transport - - NewHTTPTransport = http.New - - // HTTP Transport Options - - WithTarget = http.WithTarget - WithMethod = http.WithMethod - WitHHeader = http.WithHeader - WithShutdownTimeout = http.WithShutdownTimeout - WithEncoding = http.WithEncoding - WithContextBasedEncoding = http.WithContextBasedEncoding - WithBinaryEncoding = http.WithBinaryEncoding - WithStructuredEncoding = http.WithStructuredEncoding - WithPort = http.WithPort - WithPath = http.WithPath - WithMiddleware = http.WithMiddleware - WithLongPollTarget = http.WithLongPollTarget - WithListener = http.WithListener - - // HTTP Context - - HTTPTransportContextFrom = http.TransportContextFrom - ContextWithHeader = http.ContextWithHeader -) diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/client.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/client.go deleted file mode 100644 index a5e5c27a1d5..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/client.go +++ /dev/null @@ -1,196 +0,0 @@ -package client - -import ( - "context" - "fmt" - "sync" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http" -) - -// Client interface defines the runtime contract the CloudEvents client supports. -type Client interface { - // Send will transmit the given event over the client's configured transport. - Send(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) - - // StartReceiver will register the provided function for callback on receipt - // of a cloudevent. It will also start the underlying transport as it has - // been configured. - // This call is blocking. - // Valid fn signatures are: - // * func() - // * func() error - // * func(context.Context) - // * func(context.Context) error - // * func(cloudevents.Event) - // * func(cloudevents.Event) error - // * func(context.Context, cloudevents.Event) - // * func(context.Context, cloudevents.Event) error - // * func(cloudevents.Event, *cloudevents.EventResponse) - // * func(cloudevents.Event, *cloudevents.EventResponse) error - // * func(context.Context, cloudevents.Event, *cloudevents.EventResponse) - // * func(context.Context, cloudevents.Event, *cloudevents.EventResponse) error - // Note: if fn returns an error, it is treated as a critical and - // EventResponse will not be processed. - StartReceiver(ctx context.Context, fn interface{}) error -} - -// New produces a new client with the provided transport object and applied -// client options. -func New(t transport.Transport, opts ...Option) (Client, error) { - c := &ceClient{ - transport: t, - } - if err := c.applyOptions(opts...); err != nil { - return nil, err - } - t.SetReceiver(c) - return c, nil -} - -// NewDefault provides the good defaults for the common case using an HTTP -// Transport client. The http transport has had WithBinaryEncoding http -// transport option applied to it. The client will always send Binary -// encoding but will inspect the outbound event context and match the version. -// The WithTimeNow, WithUUIDs and WithDataContentType("application/json") -// client options are also applied to the client, all outbound events will have -// a time and id set if not already present. -func NewDefault() (Client, error) { - t, err := http.New(http.WithBinaryEncoding()) - if err != nil { - return nil, err - } - c, err := New(t, WithTimeNow(), WithUUIDs(), WithDataContentType(cloudevents.ApplicationJSON)) - if err != nil { - return nil, err - } - return c, nil -} - -type ceClient struct { - transport transport.Transport - fn *receiverFn - - convertFn ConvertFn - - receiverMu sync.Mutex - eventDefaulterFns []EventDefaulter -} - -// Send transmits the provided event on a preconfigured Transport. -// Send returns a response event if there is a response or an error if there -// was an an issue validating the outbound event or the transport returns an -// error. -func (c *ceClient) Send(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) { - ctx, r := observability.NewReporter(ctx, reportSend) - rctx, resp, err := c.obsSend(ctx, event) - if err != nil { - r.Error() - } else { - r.OK() - } - return rctx, resp, err -} - -func (c *ceClient) obsSend(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) { - // Confirm we have a transport set. - if c.transport == nil { - return ctx, nil, fmt.Errorf("client not ready, transport not initialized") - } - // Apply the defaulter chain to the incoming event. - if len(c.eventDefaulterFns) > 0 { - for _, fn := range c.eventDefaulterFns { - event = fn(ctx, event) - } - } - - // Validate the event conforms to the CloudEvents Spec. - if err := event.Validate(); err != nil { - return ctx, nil, err - } - // Send the event over the transport. - return c.transport.Send(ctx, event) -} - -// Receive is called from from the transport on event delivery. -func (c *ceClient) Receive(ctx context.Context, event cloudevents.Event, resp *cloudevents.EventResponse) error { - ctx, r := observability.NewReporter(ctx, reportReceive) - err := c.obsReceive(ctx, event, resp) - if err != nil { - r.Error() - } else { - r.OK() - } - return err -} - -func (c *ceClient) obsReceive(ctx context.Context, event cloudevents.Event, resp *cloudevents.EventResponse) error { - if c.fn != nil { - ctx, rFn := observability.NewReporter(ctx, reportReceiveFn) - err := c.fn.invoke(ctx, event, resp) - if err != nil { - rFn.Error() - } else { - rFn.OK() - } - - // Apply the defaulter chain to the outgoing event. - if err == nil && resp != nil && resp.Event != nil && len(c.eventDefaulterFns) > 0 { - for _, fn := range c.eventDefaulterFns { - *resp.Event = fn(ctx, *resp.Event) - } - // Validate the event conforms to the CloudEvents Spec. - if err := resp.Event.Validate(); err != nil { - return fmt.Errorf("cloudevent validation failed on response event: %v", err) - } - } - return err - } - return nil -} - -// StartReceiver sets up the given fn to handle Receive. -// See Client.StartReceiver for details. This is a blocking call. -func (c *ceClient) StartReceiver(ctx context.Context, fn interface{}) error { - c.receiverMu.Lock() - defer c.receiverMu.Unlock() - - if c.transport == nil { - return fmt.Errorf("client not ready, transport not initialized") - } - if c.fn != nil { - return fmt.Errorf("client already has a receiver") - } - - if fn, err := receiver(fn); err != nil { - return err - } else { - c.fn = fn - } - - defer func() { - c.fn = nil - }() - - return c.transport.StartReceiver(ctx) -} - -func (c *ceClient) applyOptions(opts ...Option) error { - for _, fn := range opts { - if err := fn(c); err != nil { - return err - } - } - return nil -} - -// Convert implements transport Converter.Convert. -func (c *ceClient) Convert(ctx context.Context, m transport.Message, err error) (*cloudevents.Event, error) { - if c.convertFn != nil { - return c.convertFn(ctx, m, err) - } - return nil, err -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/observability.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/observability.go deleted file mode 100644 index b844c19a86e..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/observability.go +++ /dev/null @@ -1,68 +0,0 @@ -package client - -import ( - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" -) - -var ( - // LatencyMs measures the latency in milliseconds for the CloudEvents - // client methods. - LatencyMs = stats.Float64("cloudevents.io/sdk-go/client/latency", "The latency in milliseconds for the CloudEvents client methods.", "ms") -) - -var ( - // LatencyView is an OpenCensus view that shows client method latency. - LatencyView = &view.View{ - Name: "client/latency", - Measure: LatencyMs, - Description: "The distribution of latency inside of client for CloudEvents.", - Aggregation: view.Distribution(0, .01, .1, 1, 10, 100, 1000, 10000), - TagKeys: observability.LatencyTags(), - } -) - -type observed int32 - -// Adheres to Observable -var _ observability.Observable = observed(0) - -const ( - reportSend observed = iota - reportReceive - reportReceiveFn -) - -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportSend: - return "client/send" - case reportReceive: - return "client/receive" - case reportReceiveFn: - return "client/receive/fn" - default: - return "client/unknown" - } -} - -// MethodName implements Observable.MethodName -func (o observed) MethodName() string { - switch o { - case reportSend: - return "send" - case reportReceive: - return "receive" - case reportReceiveFn: - return "receive/fn" - default: - return "unknown" - } -} - -// LatencyMs implements Observable.LatencyMs -func (o observed) LatencyMs() *stats.Float64Measure { - return LatencyMs -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/options.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/options.go deleted file mode 100644 index bb2eff9cc7b..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/options.go +++ /dev/null @@ -1,63 +0,0 @@ -package client - -import ( - "fmt" -) - -// Option is the function signature required to be considered an client.Option. -type Option func(*ceClient) error - -// WithEventDefaulter adds an event defaulter to the end of the defaulter chain. -func WithEventDefaulter(fn EventDefaulter) Option { - return func(c *ceClient) error { - if fn == nil { - return fmt.Errorf("client option was given an nil event defaulter") - } - c.eventDefaulterFns = append(c.eventDefaulterFns, fn) - return nil - } -} - -// WithUUIDs adds DefaultIDToUUIDIfNotSet event defaulter to the end of the -// defaulter chain. -func WithUUIDs() Option { - return func(c *ceClient) error { - c.eventDefaulterFns = append(c.eventDefaulterFns, DefaultIDToUUIDIfNotSet) - return nil - } -} - -// WithDataContentType adds the resulting defaulter from -// NewDefaultDataContentTypeIfNotSet event defaulter to the end of the -// defaulter chain. -func WithDataContentType(contentType string) Option { - return func(c *ceClient) error { - c.eventDefaulterFns = append(c.eventDefaulterFns, NewDefaultDataContentTypeIfNotSet(contentType)) - return nil - } -} - -// WithTimeNow adds DefaultTimeToNowIfNotSet event defaulter to the end of the -// defaulter chain. -func WithTimeNow() Option { - return func(c *ceClient) error { - c.eventDefaulterFns = append(c.eventDefaulterFns, DefaultTimeToNowIfNotSet) - return nil - } -} - -// WithConverterFn defines the function the transport will use to delegate -// conversion of non-decodable messages. -func WithConverterFn(fn ConvertFn) Option { - return func(c *ceClient) error { - if fn == nil { - return fmt.Errorf("client option was given an nil message converter") - } - if c.transport.HasConverter() { - return fmt.Errorf("transport converter already set") - } - c.convertFn = fn - c.transport.SetConverter(c) - return nil - } -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/receiver.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/receiver.go deleted file mode 100644 index 9734341d43f..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/receiver.go +++ /dev/null @@ -1,193 +0,0 @@ -package client - -import ( - "context" - "errors" - "fmt" - "reflect" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" -) - -// Receive is the signature of a fn to be invoked for incoming cloudevents. -// If fn returns an error, EventResponse will not be considered by the client or -// or transport. -// This is just an FYI: -type ReceiveFull func(context.Context, cloudevents.Event, *cloudevents.EventResponse) error - -type receiverFn struct { - numIn int - fnValue reflect.Value - - hasContextIn bool - hasEventIn bool - hasEventResponseIn bool - - hasErrorOut bool -} - -// ConvertFn defines the signature the client expects to enable conversion -// delegation. -type ConvertFn func(context.Context, transport.Message, error) (*cloudevents.Event, error) - -const ( - inParamUsage = "expected a function taking either no parameters, one or more of (context.Context, cloudevents.Event, *cloudevents.EventResponse) ordered" - outParamUsage = "expected a function returning either nothing or an error" -) - -var ( - contextType = reflect.TypeOf((*context.Context)(nil)).Elem() - eventType = reflect.TypeOf((*cloudevents.Event)(nil)).Elem() - eventResponseType = reflect.TypeOf((*cloudevents.EventResponse)(nil)) // want the ptr type - errorType = reflect.TypeOf((*error)(nil)).Elem() -) - -// receiver creates a receiverFn wrapper class that is used by the client to -// validate and invoke the provided function. -// Valid fn signatures are: -// * func() -// * func() error -// * func(context.Context) -// * func(context.Context) error -// * func(cloudevents.Event) -// * func(cloudevents.Event) error -// * func(context.Context, cloudevents.Event) -// * func(context.Context, cloudevents.Event) error -// * func(cloudevents.Event, *cloudevents.EventResponse) -// * func(cloudevents.Event, *cloudevents.EventResponse) error -// * func(context.Context, cloudevents.Event, *cloudevents.EventResponse) -// * func(context.Context, cloudevents.Event, *cloudevents.EventResponse) error -// -func receiver(fn interface{}) (*receiverFn, error) { - fnType := reflect.TypeOf(fn) - if fnType.Kind() != reflect.Func { - return nil, errors.New("must pass a function to handle events") - } - - r := &receiverFn{ - fnValue: reflect.ValueOf(fn), - numIn: fnType.NumIn(), - } - if err := r.validate(fnType); err != nil { - return nil, err - } - - return r, nil -} - -func (r *receiverFn) invoke(ctx context.Context, event cloudevents.Event, resp *cloudevents.EventResponse) error { - args := make([]reflect.Value, 0, r.numIn) - - if r.numIn > 0 { - if r.hasContextIn { - args = append(args, reflect.ValueOf(ctx)) - } - if r.hasEventIn { - args = append(args, reflect.ValueOf(event)) - } - if r.hasEventResponseIn { - args = append(args, reflect.ValueOf(resp)) - } - } - v := r.fnValue.Call(args) - if r.hasErrorOut && len(v) >= 1 { - if err, ok := v[0].Interface().(error); ok { - return err - } - } - return nil -} - -// Verifies that the inputs to a function have a valid signature -// Valid input is to be [0, all] of -// context.Context, cloudevents.Event, *cloudevents.EventResponse in this order. -func (r *receiverFn) validateInParamSignature(fnType reflect.Type) error { - r.hasContextIn = false - r.hasEventIn = false - r.hasEventResponseIn = false - - switch fnType.NumIn() { - case 3: - // has to be cloudevents.Event, *cloudevents.EventResponse - if !fnType.In(2).ConvertibleTo(eventResponseType) { - return fmt.Errorf("%s; cannot convert parameter 2 from %s to *cloudevents.EventResponse", inParamUsage, fnType.In(2)) - } else { - r.hasEventResponseIn = true - } - fallthrough - case 2: - // can be cloudevents.Event or *cloudevents.EventResponse - if !fnType.In(1).ConvertibleTo(eventResponseType) { - if !fnType.In(1).ConvertibleTo(eventType) { - return fmt.Errorf("%s; cannot convert parameter 1 from %s to cloudevents.Event or *cloudevents.EventResponse", inParamUsage, fnType.In(1)) - } else { - r.hasEventIn = true - } - } else if r.hasEventResponseIn { - return fmt.Errorf("%s; duplicate parameter of type *cloudevents.EventResponse", inParamUsage) - } else { - r.hasEventResponseIn = true - } - fallthrough - case 1: - if !fnType.In(0).ConvertibleTo(contextType) { - if !fnType.In(0).ConvertibleTo(eventResponseType) { - if !fnType.In(0).ConvertibleTo(eventType) { - return fmt.Errorf("%s; cannot convert parameter 0 from %s to context.Context, cloudevents.Event or *cloudevents.EventResponse", inParamUsage, fnType.In(0)) - } else if r.hasEventIn { - return fmt.Errorf("%s; duplicate parameter of type cloudevents.Event", inParamUsage) - } else { - r.hasEventIn = true - } - } else if r.hasEventResponseIn { - return fmt.Errorf("%s; duplicate parameter of type *cloudevents.EventResponse", inParamUsage) - } else if r.hasEventIn { - return fmt.Errorf("%s; out of order parameter 0 for %s", inParamUsage, fnType.In(1)) - } else { - r.hasEventResponseIn = true - } - } else { - r.hasContextIn = true - } - fallthrough - case 0: - return nil - default: - return fmt.Errorf("%s; function has too many parameters (%d)", inParamUsage, fnType.NumIn()) - } -} - -// Verifies that the outputs of a function have a valid signature -// Valid output signatures: -// (), (error) -func (r *receiverFn) validateOutParamSignature(fnType reflect.Type) error { - r.hasErrorOut = false - switch fnType.NumOut() { - case 1: - paramNo := fnType.NumOut() - 1 - paramType := fnType.Out(paramNo) - if !paramType.ConvertibleTo(errorType) { - return fmt.Errorf("%s; cannot convert return type %d from %s to error", outParamUsage, paramNo, paramType) - } else { - r.hasErrorOut = true - } - fallthrough - case 0: - return nil - default: - return fmt.Errorf("%s; function has too many return types (%d)", outParamUsage, fnType.NumOut()) - } -} - -// validateReceiverFn validates that a function has the right number of in and -// out params and that they are of allowed types. -func (r *receiverFn) validate(fnType reflect.Type) error { - if err := r.validateInParamSignature(fnType); err != nil { - return err - } - if err := r.validateOutParamSignature(fnType); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_data.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_data.go deleted file mode 100644 index 26ce70ea33d..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_data.go +++ /dev/null @@ -1,135 +0,0 @@ -package cloudevents - -import ( - "context" - "encoding/base64" - "errors" - "fmt" - "strconv" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec" -) - -// Data is special. Break it out into it's own file. - -// SetData implements EventWriter.SetData -func (e *Event) SetData(obj interface{}) error { - if e.SpecVersion() != CloudEventsVersionV1 { - return e.legacySetData(obj) - } - - // Version 1.0 and above. - - // TODO: we will have to be smarter about how data relates to media type. - // but the issue is we can not just encode data anymore without understanding - // what the encoding will be on the outbound event. Structured will use - // data_base64, binary will not (if the transport supports binary mode). - - // TODO: look at content encoding too. - - switch obj.(type) { - case []byte: - e.Data = obj - e.DataEncoded = true - e.DataBinary = true - default: - data, err := datacodec.Encode(context.Background(), e.DataMediaType(), obj) - if err != nil { - return err - } - e.Data = data - e.DataEncoded = true - e.DataBinary = false - } - - return nil -} - -func (e *Event) legacySetData(obj interface{}) error { - data, err := datacodec.Encode(context.Background(), e.DataMediaType(), obj) - if err != nil { - return err - } - if e.DeprecatedDataContentEncoding() == Base64 { - buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) - base64.StdEncoding.Encode(buf, data) - e.Data = string(buf) - } else { - e.Data = data - } - e.DataEncoded = true - return nil -} - -func (e *Event) DataBytes() ([]byte, error) { - if !e.DataEncoded { - if err := e.SetData(e.Data); err != nil { - return nil, err - } - } - - b, ok := e.Data.([]byte) - if !ok { - if s, ok := e.Data.(string); ok { - b = []byte(s) - } else { - // No data. - return []byte(nil), nil - } - } - return b, nil -} - -const ( - quotes = `"'` -) - -// DataAs attempts to populate the provided data object with the event payload. -// data should be a pointer type. -func (e Event) DataAs(data interface{}) error { // TODO: Clean this function up - if e.Data == nil { - return nil - } - obj, ok := e.Data.([]byte) - if !ok { - if s, ok := e.Data.(string); ok { - obj = []byte(s) - } else { - return errors.New("data was not a byte slice or string") - } - } - if len(obj) == 0 { - // No data. - return nil - } - if e.Context.DeprecatedGetDataContentEncoding() == Base64 { - var bs []byte - // test to see if we need to unquote the data. - if obj[0] == quotes[0] || obj[0] == quotes[1] { - str, err := strconv.Unquote(string(obj)) - if err != nil { - return err - } - bs = []byte(str) - } else { - bs = obj - } - - buf := make([]byte, base64.StdEncoding.DecodedLen(len(bs))) - n, err := base64.StdEncoding.Decode(buf, bs) - if err != nil { - return fmt.Errorf("failed to decode data from base64: %s", err.Error()) - } - obj = buf[:n] - } - - mediaType := "" - if e.Context.GetDataContentType() != "" { - var err error - mediaType, err = e.Context.GetDataMediaType() - if err != nil { - return err - } - } - return datacodec.Decode(context.Background(), mediaType, obj, data) -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_response.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_response.go deleted file mode 100644 index 0e5f7ce75d4..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_response.go +++ /dev/null @@ -1,37 +0,0 @@ -package cloudevents - -// EventResponse represents the canonical representation of a Response to a -// CloudEvent from a receiver. Response implementation is Transport dependent. -type EventResponse struct { - Status int - Event *Event - Reason string - // Context is transport specific struct to allow for controlling transport - // response details. - // For example, see http.TransportResponseContext. - Context interface{} -} - -// RespondWith sets up the instance of EventResponse to be set with status and -// an event. Response implementation is Transport dependent. -func (e *EventResponse) RespondWith(status int, event *Event) { - if e == nil { - // if nil, response not supported - return - } - e.Status = status - if event != nil { - e.Event = event - } -} - -// Error sets the instance of EventResponse to be set with an error code and -// reason string. Response implementation is Transport dependent. -func (e *EventResponse) Error(status int, reason string) { - if e == nil { - // if nil, response not supported - return - } - e.Status = status - e.Reason = reason -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01.go deleted file mode 100644 index 0b01823beb6..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01.go +++ /dev/null @@ -1,272 +0,0 @@ -package cloudevents - -import ( - "fmt" - "sort" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -const ( - // CloudEventsVersionV01 represents the version 0.1 of the CloudEvents spec. - CloudEventsVersionV01 = "0.1" -) - -// EventContextV01 holds standard metadata about an event. See -// https://github.com/cloudevents/spec/blob/v0.1/spec.md#context-attributes for -// details on these fields. -type EventContextV01 struct { - // The version of the CloudEvents specification used by the event. - CloudEventsVersion string `json:"cloudEventsVersion,omitempty"` - // ID of the event; must be non-empty and unique within the scope of the producer. - EventID string `json:"eventID"` - // Timestamp when the event happened. - EventTime *types.Timestamp `json:"eventTime,omitempty"` - // Type of occurrence which has happened. - EventType string `json:"eventType"` - // The version of the `eventType`; this is producer-specific. - EventTypeVersion *string `json:"eventTypeVersion,omitempty"` - // A link to the schema that the `data` attribute adheres to. - SchemaURL *types.URLRef `json:"schemaURL,omitempty"` - // A MIME (RFC 2046) string describing the media type of `data`. - // TODO: Should an empty string assume `application/json`, or auto-detect the content? - ContentType *string `json:"contentType,omitempty"` - // A URI describing the event producer. - Source types.URLRef `json:"source"` - // Additional metadata without a well-defined structure. - Extensions map[string]interface{} `json:"extensions,omitempty"` -} - -// Adhere to EventContext -var _ EventContext = (*EventContextV01)(nil) - -// ExtensionAs implements EventContextReader.ExtensionAs -func (ec EventContextV01) ExtensionAs(name string, obj interface{}) error { - value, ok := ec.Extensions[name] - if !ok { - return fmt.Errorf("extension %q does not exist", name) - } - // Only support *string for now. - switch v := obj.(type) { - case *string: - if valueAsString, ok := value.(string); ok { - *v = valueAsString - return nil - } else { - return fmt.Errorf("invalid type for extension %q", name) - } - default: - return fmt.Errorf("unknown extension type %T", obj) - } -} - -// SetExtension adds the extension 'name' with value 'value' to the CloudEvents context. -func (ec *EventContextV01) SetExtension(name string, value interface{}) error { - if ec.Extensions == nil { - ec.Extensions = make(map[string]interface{}) - } - if value == nil { - delete(ec.Extensions, name) - } else { - ec.Extensions[name] = value - } - return nil -} - -// Clone implements EventContextConverter.Clone -func (ec EventContextV01) Clone() EventContext { - return ec.AsV01() -} - -// AsV01 implements EventContextConverter.AsV01 -func (ec EventContextV01) AsV01() *EventContextV01 { - ec.CloudEventsVersion = CloudEventsVersionV01 - return &ec -} - -// AsV02 implements EventContextConverter.AsV02 -func (ec EventContextV01) AsV02() *EventContextV02 { - ret := EventContextV02{ - SpecVersion: CloudEventsVersionV02, - Type: ec.EventType, - Source: ec.Source, - ID: ec.EventID, - Time: ec.EventTime, - SchemaURL: ec.SchemaURL, - ContentType: ec.ContentType, - Extensions: make(map[string]interface{}), - } - - // eventTypeVersion was retired in v0.2, so put it in an extension. - if ec.EventTypeVersion != nil { - _ = ret.SetExtension(EventTypeVersionKey, *ec.EventTypeVersion) - } - if ec.Extensions != nil { - for k, v := range ec.Extensions { - ret.Extensions[k] = v - } - } - if len(ret.Extensions) == 0 { - ret.Extensions = nil - } - return &ret -} - -// AsV03 implements EventContextConverter.AsV03 -func (ec EventContextV01) AsV03() *EventContextV03 { - return ec.AsV02().AsV03() -} - -// AsV1 implements EventContextConverter.AsV1 -func (ec EventContextV01) AsV1() *EventContextV1 { - return ec.AsV02().AsV03().AsV1() -} - -// Validate returns errors based on requirements from the CloudEvents spec. -// For more details, see https://github.com/cloudevents/spec/blob/v0.1/spec.md -func (ec EventContextV01) Validate() error { - errors := []string(nil) - - // eventType - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - // SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the organization which defines the semantics of this event type. - eventType := strings.TrimSpace(ec.EventType) - if eventType == "" { - errors = append(errors, "eventType: MUST be a non-empty string") - } - - // eventTypeVersion - // Type: String - // Constraints: - // OPTIONAL - // If present, MUST be a non-empty string - if ec.EventTypeVersion != nil { - eventTypeVersion := strings.TrimSpace(*ec.EventTypeVersion) - if eventTypeVersion == "" { - errors = append(errors, "eventTypeVersion: if present, MUST be a non-empty string") - } - } - - // cloudEventsVersion - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - cloudEventsVersion := strings.TrimSpace(ec.CloudEventsVersion) - if cloudEventsVersion == "" { - errors = append(errors, "cloudEventsVersion: MUST be a non-empty string") - } - - // source - // Type: URI - // Constraints: - // REQUIRED - source := strings.TrimSpace(ec.Source.String()) - if source == "" { - errors = append(errors, "source: REQUIRED") - } - - // eventID - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - // MUST be unique within the scope of the producer - eventID := strings.TrimSpace(ec.EventID) - if eventID == "" { - errors = append(errors, "eventID: MUST be a non-empty string") - - // no way to test "MUST be unique within the scope of the producer" - } - - // eventTime - // Type: Timestamp - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 3339 - // --> no need to test this, no way to set the eventTime without it being valid. - - // schemaURL - // Type: URI - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 3986 - if ec.SchemaURL != nil { - schemaURL := strings.TrimSpace(ec.SchemaURL.String()) - // empty string is not RFC 3986 compatible. - if schemaURL == "" { - errors = append(errors, "schemaURL: if present, MUST adhere to the format specified in RFC 3986") - } - } - - // contentType - // Type: String per RFC 2046 - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 2046 - if ec.ContentType != nil { - contentType := strings.TrimSpace(*ec.ContentType) - if contentType == "" { - // TODO: need to test for RFC 2046 - errors = append(errors, "contentType: if present, MUST adhere to the format specified in RFC 2046") - } - } - - // extensions - // Type: Map - // Constraints: - // OPTIONAL - // If present, MUST contain at least one entry - if ec.Extensions != nil { - if len(ec.Extensions) == 0 { - errors = append(errors, "extensions: if present, MUST contain at least one entry") - } - } - - if len(errors) > 0 { - return fmt.Errorf(strings.Join(errors, "\n")) - } - return nil -} - -// String returns a pretty-printed representation of the EventContext. -func (ec EventContextV01) String() string { - b := strings.Builder{} - - b.WriteString("Context Attributes,\n") - - b.WriteString(" cloudEventsVersion: " + ec.CloudEventsVersion + "\n") - b.WriteString(" eventType: " + ec.EventType + "\n") - if ec.EventTypeVersion != nil { - b.WriteString(" eventTypeVersion: " + *ec.EventTypeVersion + "\n") - } - b.WriteString(" source: " + ec.Source.String() + "\n") - b.WriteString(" eventID: " + ec.EventID + "\n") - if ec.EventTime != nil { - b.WriteString(" eventTime: " + ec.EventTime.String() + "\n") - } - if ec.SchemaURL != nil { - b.WriteString(" schemaURL: " + ec.SchemaURL.String() + "\n") - } - if ec.ContentType != nil { - b.WriteString(" contentType: " + *ec.ContentType + "\n") - } - - if ec.Extensions != nil && len(ec.Extensions) > 0 { - b.WriteString("Extensions,\n") - keys := make([]string, 0, len(ec.Extensions)) - for k := range ec.Extensions { - keys = append(keys, k) - } - sort.Strings(keys) - for _, key := range keys { - b.WriteString(fmt.Sprintf(" %s: %v\n", key, ec.Extensions[key])) - } - } - - return b.String() -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_reader.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_reader.go deleted file mode 100644 index 8d75ea70c4c..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_reader.go +++ /dev/null @@ -1,101 +0,0 @@ -package cloudevents - -import ( - "fmt" - "mime" - "time" -) - -// Adhere to EventContextReader -var _ EventContextReader = (*EventContextV01)(nil) - -// GetSpecVersion implements EventContextReader.GetSpecVersion -func (ec EventContextV01) GetSpecVersion() string { - if ec.CloudEventsVersion != "" { - return ec.CloudEventsVersion - } - return CloudEventsVersionV01 -} - -// GetDataContentType implements EventContextReader.GetDataContentType -func (ec EventContextV01) GetDataContentType() string { - if ec.ContentType != nil { - return *ec.ContentType - } - return "" -} - -// GetDataMediaType implements EventContextReader.GetDataMediaType -func (ec EventContextV01) GetDataMediaType() (string, error) { - if ec.ContentType != nil { - mediaType, _, err := mime.ParseMediaType(*ec.ContentType) - if err != nil { - return "", err - } - return mediaType, nil - } - return "", nil -} - -// GetType implements EventContextReader.GetType -func (ec EventContextV01) GetType() string { - return ec.EventType -} - -// GetSource implements EventContextReader.GetSource -func (ec EventContextV01) GetSource() string { - return ec.Source.String() -} - -// GetSubject implements EventContextReader.GetSubject -func (ec EventContextV01) GetSubject() string { - var sub string - if err := ec.ExtensionAs(SubjectKey, &sub); err != nil { - return "" - } - return sub -} - -// GetID implements EventContextReader.GetID -func (ec EventContextV01) GetID() string { - return ec.EventID -} - -// GetTime implements EventContextReader.GetTime -func (ec EventContextV01) GetTime() time.Time { - if ec.EventTime != nil { - return ec.EventTime.Time - } - return time.Time{} -} - -// GetDataSchema implements EventContextReader.GetDataSchema -func (ec EventContextV01) GetDataSchema() string { - if ec.SchemaURL != nil { - return ec.SchemaURL.String() - } - return "" -} - -// DeprecatedGetDataContentEncoding implements EventContextReader.DeprecatedGetDataContentEncoding -func (ec EventContextV01) DeprecatedGetDataContentEncoding() string { - var enc string - if err := ec.ExtensionAs(DataContentEncodingKey, &enc); err != nil { - return "" - } - return enc -} - -// GetExtensions implements EventContextReader.GetExtensions -func (ec EventContextV01) GetExtensions() map[string]interface{} { - return ec.Extensions -} - -// GetExtension implements EventContextReader.GetExtension -func (ec EventContextV01) GetExtension(key string) (interface{}, error) { - v, ok := caseInsensitiveSearch(key, ec.Extensions) - if !ok { - return "", fmt.Errorf("%q not found", key) - } - return v, nil -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_writer.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_writer.go deleted file mode 100644 index e49d3cca727..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_writer.go +++ /dev/null @@ -1,104 +0,0 @@ -package cloudevents - -import ( - "errors" - "fmt" - "net/url" - "strings" - "time" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// Adhere to EventContextWriter -var _ EventContextWriter = (*EventContextV01)(nil) - -// SetSpecVersion implements EventContextWriter.SetSpecVersion -func (ec *EventContextV01) SetSpecVersion(v string) error { - if v != CloudEventsVersionV01 { - return fmt.Errorf("invalid version %q, expecting %q", v, CloudEventsVersionV01) - } - ec.CloudEventsVersion = CloudEventsVersionV01 - return nil -} - -// SetDataContentType implements EventContextWriter.SetDataContentType -func (ec *EventContextV01) SetDataContentType(ct string) error { - ct = strings.TrimSpace(ct) - if ct == "" { - ec.ContentType = nil - } else { - ec.ContentType = &ct - } - return nil -} - -// SetType implements EventContextWriter.SetType -func (ec *EventContextV01) SetType(t string) error { - t = strings.TrimSpace(t) - ec.EventType = t - return nil -} - -// SetSource implements EventContextWriter.SetSource -func (ec *EventContextV01) SetSource(u string) error { - pu, err := url.Parse(u) - if err != nil { - return err - } - ec.Source = types.URLRef{URL: *pu} - return nil -} - -// SetSubject implements EventContextWriter.SetSubject -func (ec *EventContextV01) SetSubject(s string) error { - s = strings.TrimSpace(s) - if s == "" { - return ec.SetExtension(SubjectKey, nil) - } - return ec.SetExtension(SubjectKey, s) -} - -// SetID implements EventContextWriter.SetID -func (ec *EventContextV01) SetID(id string) error { - id = strings.TrimSpace(id) - if id == "" { - return errors.New("event id is required to be a non-empty string") - } - ec.EventID = id - return nil -} - -// SetTime implements EventContextWriter.SetTime -func (ec *EventContextV01) SetTime(t time.Time) error { - if t.IsZero() { - ec.EventTime = nil - } else { - ec.EventTime = &types.Timestamp{Time: t} - } - return nil -} - -// SetDataSchema implements EventContextWriter.SetDataSchema -func (ec *EventContextV01) SetDataSchema(u string) error { - u = strings.TrimSpace(u) - if u == "" { - ec.SchemaURL = nil - return nil - } - pu, err := url.Parse(u) - if err != nil { - return err - } - ec.SchemaURL = &types.URLRef{URL: *pu} - return nil -} - -// DeprecatedSetDataContentEncoding implements EventContextWriter.DeprecatedSetDataContentEncoding -func (ec *EventContextV01) DeprecatedSetDataContentEncoding(e string) error { - e = strings.ToLower(strings.TrimSpace(e)) - if e == "" { - return ec.SetExtension(DataContentEncodingKey, nil) - } - return ec.SetExtension(DataContentEncodingKey, e) -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02.go deleted file mode 100644 index 3dde8a19b18..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02.go +++ /dev/null @@ -1,291 +0,0 @@ -package cloudevents - -import ( - "encoding/json" - "fmt" - "sort" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -const ( - // CloudEventsVersionV02 represents the version 0.2 of the CloudEvents spec. - CloudEventsVersionV02 = "0.2" -) - -// EventContextV02 represents the non-data attributes of a CloudEvents v0.2 -// event. -type EventContextV02 struct { - // The version of the CloudEvents specification used by the event. - SpecVersion string `json:"specversion"` - // The type of the occurrence which has happened. - Type string `json:"type"` - // A URI describing the event producer. - Source types.URLRef `json:"source"` - // ID of the event; must be non-empty and unique within the scope of the producer. - ID string `json:"id"` - // Timestamp when the event happened. - Time *types.Timestamp `json:"time,omitempty"` - // A link to the schema that the `data` attribute adheres to. - SchemaURL *types.URLRef `json:"schemaurl,omitempty"` - // A MIME (RFC2046) string describing the media type of `data`. - // TODO: Should an empty string assume `application/json`, `application/octet-stream`, or auto-detect the content? - ContentType *string `json:"contenttype,omitempty"` - // Additional extension metadata beyond the base spec. - Extensions map[string]interface{} `json:"-"` -} - -// Adhere to EventContext -var _ EventContext = (*EventContextV02)(nil) - -// ExtensionAs implements EventContext.ExtensionAs -func (ec EventContextV02) ExtensionAs(name string, obj interface{}) error { - value, ok := ec.Extensions[name] - if !ok { - return fmt.Errorf("extension %q does not exist", name) - } - - // Try to unmarshal extension if we find it as a RawMessage. - switch v := value.(type) { - case json.RawMessage: - if err := json.Unmarshal(v, obj); err == nil { - // if that worked, return with obj set. - return nil - } - } - // else try as a string ptr. - - // Only support *string for now. - switch v := obj.(type) { - case *string: - if valueAsString, ok := value.(string); ok { - *v = valueAsString - return nil - } else { - return fmt.Errorf("invalid type for extension %q", name) - } - default: - return fmt.Errorf("unknown extension type %T", obj) - } -} - -// SetExtension adds the extension 'name' with value 'value' to the CloudEvents context. -func (ec *EventContextV02) SetExtension(name string, value interface{}) error { - if ec.Extensions == nil { - ec.Extensions = make(map[string]interface{}) - } - if value == nil { - delete(ec.Extensions, name) - } else { - ec.Extensions[name] = value - } - return nil -} - -// Clone implements EventContextConverter.Clone -func (ec EventContextV02) Clone() EventContext { - return ec.AsV02() -} - -// AsV01 implements EventContextConverter.AsV01 -func (ec EventContextV02) AsV01() *EventContextV01 { - ret := EventContextV01{ - CloudEventsVersion: CloudEventsVersionV01, - EventID: ec.ID, - EventTime: ec.Time, - EventType: ec.Type, - SchemaURL: ec.SchemaURL, - Source: ec.Source, - ContentType: ec.ContentType, - Extensions: make(map[string]interface{}), - } - - for k, v := range ec.Extensions { - // eventTypeVersion was retired in v0.2 - if strings.EqualFold(k, EventTypeVersionKey) { - etv, ok := v.(string) - if ok && etv != "" { - ret.EventTypeVersion = &etv - } - continue - } - ret.Extensions[k] = v - } - if len(ret.Extensions) == 0 { - ret.Extensions = nil - } - return &ret -} - -// AsV02 implements EventContextConverter.AsV02 -func (ec EventContextV02) AsV02() *EventContextV02 { - ec.SpecVersion = CloudEventsVersionV02 - return &ec -} - -// AsV03 implements EventContextConverter.AsV03 -func (ec EventContextV02) AsV03() *EventContextV03 { - ret := EventContextV03{ - SpecVersion: CloudEventsVersionV03, - ID: ec.ID, - Time: ec.Time, - Type: ec.Type, - SchemaURL: ec.SchemaURL, - DataContentType: ec.ContentType, - Source: ec.Source, - Extensions: make(map[string]interface{}), - } - - for k, v := range ec.Extensions { - // Subject was introduced in 0.3 - if strings.EqualFold(k, SubjectKey) { - sub, ok := v.(string) - if ok && sub != "" { - ret.Subject = &sub - } - continue - } - // DeprecatedDataContentEncoding was introduced in 0.3 - if strings.EqualFold(k, DataContentEncodingKey) { - etv, ok := v.(string) - if ok && etv != "" { - ret.DataContentEncoding = &etv - } - continue - } - ret.Extensions[k] = v - } - if len(ret.Extensions) == 0 { - ret.Extensions = nil - } - - return &ret -} - -// AsV1 implements EventContextConverter.AsV1 -func (ec EventContextV02) AsV1() *EventContextV1 { - return ec.AsV03().AsV1() -} - -// Validate returns errors based on requirements from the CloudEvents spec. -// For more details, see https://github.com/cloudevents/spec/blob/v0.2/spec.md -func (ec EventContextV02) Validate() error { - errors := []string(nil) - - // type - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - // SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the organization which defines the semantics of this event type. - eventType := strings.TrimSpace(ec.Type) - if eventType == "" { - errors = append(errors, "type: MUST be a non-empty string") - } - - // specversion - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - specVersion := strings.TrimSpace(ec.SpecVersion) - if specVersion == "" { - errors = append(errors, "specversion: MUST be a non-empty string") - } - - // source - // Type: URI-reference - // Constraints: - // REQUIRED - source := strings.TrimSpace(ec.Source.String()) - if source == "" { - errors = append(errors, "source: REQUIRED") - } - - // id - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - // MUST be unique within the scope of the producer - id := strings.TrimSpace(ec.ID) - if id == "" { - errors = append(errors, "id: MUST be a non-empty string") - - // no way to test "MUST be unique within the scope of the producer" - } - - // time - // Type: Timestamp - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 3339 - // --> no need to test this, no way to set the time without it being valid. - - // schemaurl - // Type: URI - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 3986 - if ec.SchemaURL != nil { - schemaURL := strings.TrimSpace(ec.SchemaURL.String()) - // empty string is not RFC 3986 compatible. - if schemaURL == "" { - errors = append(errors, "schemaurl: if present, MUST adhere to the format specified in RFC 3986") - } - } - - // contenttype - // Type: String per RFC 2046 - // Constraints: - // OPTIONAL - // If present, MUST adhere to the format specified in RFC 2046 - if ec.ContentType != nil { - contentType := strings.TrimSpace(*ec.ContentType) - if contentType == "" { - // TODO: need to test for RFC 2046 - errors = append(errors, "contenttype: if present, MUST adhere to the format specified in RFC 2046") - } - } - - if len(errors) > 0 { - return fmt.Errorf(strings.Join(errors, "\n")) - } - return nil -} - -// String returns a pretty-printed representation of the EventContext. -func (ec EventContextV02) String() string { - b := strings.Builder{} - - b.WriteString("Context Attributes,\n") - - b.WriteString(" specversion: " + ec.SpecVersion + "\n") - b.WriteString(" type: " + ec.Type + "\n") - b.WriteString(" source: " + ec.Source.String() + "\n") - b.WriteString(" id: " + ec.ID + "\n") - if ec.Time != nil { - b.WriteString(" time: " + ec.Time.String() + "\n") - } - if ec.SchemaURL != nil { - b.WriteString(" schemaurl: " + ec.SchemaURL.String() + "\n") - } - if ec.ContentType != nil { - b.WriteString(" contenttype: " + *ec.ContentType + "\n") - } - - if ec.Extensions != nil && len(ec.Extensions) > 0 { - b.WriteString("Extensions,\n") - keys := make([]string, 0, len(ec.Extensions)) - for k := range ec.Extensions { - keys = append(keys, k) - } - sort.Strings(keys) - for _, key := range keys { - b.WriteString(fmt.Sprintf(" %s: %v\n", key, ec.Extensions[key])) - } - } - - return b.String() -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_reader.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_reader.go deleted file mode 100644 index 120cdb87ec6..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_reader.go +++ /dev/null @@ -1,101 +0,0 @@ -package cloudevents - -import ( - "fmt" - "mime" - "time" -) - -// Adhere to EventContextReader -var _ EventContextReader = (*EventContextV02)(nil) - -// GetSpecVersion implements EventContextReader.GetSpecVersion -func (ec EventContextV02) GetSpecVersion() string { - if ec.SpecVersion != "" { - return ec.SpecVersion - } - return CloudEventsVersionV02 -} - -// GetType implements EventContextReader.GetType -func (ec EventContextV02) GetType() string { - return ec.Type -} - -// GetSource implements EventContextReader.GetSource -func (ec EventContextV02) GetSource() string { - return ec.Source.String() -} - -// GetSubject implements EventContextReader.GetSubject -func (ec EventContextV02) GetSubject() string { - var sub string - if err := ec.ExtensionAs(SubjectKey, &sub); err != nil { - return "" - } - return sub -} - -// GetID implements EventContextReader.GetID -func (ec EventContextV02) GetID() string { - return ec.ID -} - -// GetTime implements EventContextReader.GetTime -func (ec EventContextV02) GetTime() time.Time { - if ec.Time != nil { - return ec.Time.Time - } - return time.Time{} -} - -// GetDataSchema implements EventContextReader.GetDataSchema -func (ec EventContextV02) GetDataSchema() string { - if ec.SchemaURL != nil { - return ec.SchemaURL.String() - } - return "" -} - -// GetDataContentType implements EventContextReader.GetDataContentType -func (ec EventContextV02) GetDataContentType() string { - if ec.ContentType != nil { - return *ec.ContentType - } - return "" -} - -// GetDataMediaType implements EventContextReader.GetDataMediaType -func (ec EventContextV02) GetDataMediaType() (string, error) { - if ec.ContentType != nil { - mediaType, _, err := mime.ParseMediaType(*ec.ContentType) - if err != nil { - return "", err - } - return mediaType, nil - } - return "", nil -} - -// DeprecatedGetDataContentEncoding implements EventContextReader.DeprecatedGetDataContentEncoding -func (ec EventContextV02) DeprecatedGetDataContentEncoding() string { - var enc string - if err := ec.ExtensionAs(DataContentEncodingKey, &enc); err != nil { - return "" - } - return enc -} - -// GetExtensions implements EventContextReader.GetExtensions -func (ec EventContextV02) GetExtensions() map[string]interface{} { - return ec.Extensions -} - -// GetExtension implements EventContextReader.GetExtension -func (ec EventContextV02) GetExtension(key string) (interface{}, error) { - v, ok := caseInsensitiveSearch(key, ec.Extensions) - if !ok { - return "", fmt.Errorf("%q not found", key) - } - return v, nil -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_writer.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_writer.go deleted file mode 100644 index 25b8a16c8d3..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_writer.go +++ /dev/null @@ -1,104 +0,0 @@ -package cloudevents - -import ( - "errors" - "fmt" - "net/url" - "strings" - "time" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// Adhere to EventContextWriter -var _ EventContextWriter = (*EventContextV02)(nil) - -// SetSpecVersion implements EventContextWriter.SetSpecVersion -func (ec *EventContextV02) SetSpecVersion(v string) error { - if v != CloudEventsVersionV02 { - return fmt.Errorf("invalid version %q, expecting %q", v, CloudEventsVersionV02) - } - ec.SpecVersion = CloudEventsVersionV02 - return nil -} - -// SetDataContentType implements EventContextWriter.SetDataContentType -func (ec *EventContextV02) SetDataContentType(ct string) error { - ct = strings.TrimSpace(ct) - if ct == "" { - ec.ContentType = nil - } else { - ec.ContentType = &ct - } - return nil -} - -// SetType implements EventContextWriter.SetType -func (ec *EventContextV02) SetType(t string) error { - t = strings.TrimSpace(t) - ec.Type = t - return nil -} - -// SetSource implements EventContextWriter.SetSource -func (ec *EventContextV02) SetSource(u string) error { - pu, err := url.Parse(u) - if err != nil { - return err - } - ec.Source = types.URLRef{URL: *pu} - return nil -} - -// SetSubject implements EventContextWriter.SetSubject -func (ec *EventContextV02) SetSubject(s string) error { - s = strings.TrimSpace(s) - if s == "" { - return ec.SetExtension(SubjectKey, nil) - } - return ec.SetExtension(SubjectKey, s) -} - -// SetID implements EventContextWriter.SetID -func (ec *EventContextV02) SetID(id string) error { - id = strings.TrimSpace(id) - if id == "" { - return errors.New("id is required to be a non-empty string") - } - ec.ID = id - return nil -} - -// SetTime implements EventContextWriter.SetTime -func (ec *EventContextV02) SetTime(t time.Time) error { - if t.IsZero() { - ec.Time = nil - } else { - ec.Time = &types.Timestamp{Time: t} - } - return nil -} - -// SetDataSchema implements EventContextWriter.SetDataSchema -func (ec *EventContextV02) SetDataSchema(u string) error { - u = strings.TrimSpace(u) - if u == "" { - ec.SchemaURL = nil - return nil - } - pu, err := url.Parse(u) - if err != nil { - return err - } - ec.SchemaURL = &types.URLRef{URL: *pu} - return nil -} - -// DeprecatedSetDataContentEncoding implements EventContextWriter.DeprecatedSetDataContentEncoding -func (ec *EventContextV02) DeprecatedSetDataContentEncoding(e string) error { - e = strings.ToLower(strings.TrimSpace(e)) - if e == "" { - return ec.SetExtension(DataContentEncodingKey, nil) - } - return ec.SetExtension(DataContentEncodingKey, e) -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/codec.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/codec.go deleted file mode 100644 index 091064c9155..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/codec.go +++ /dev/null @@ -1,35 +0,0 @@ -package transport - -import ( - "context" - "fmt" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" -) - -// Codec is the interface for transport codecs to convert between transport -// specific payloads and the Message interface. -type Codec interface { - Encode(context.Context, cloudevents.Event) (Message, error) - Decode(context.Context, Message) (*cloudevents.Event, error) -} - -// ErrMessageEncodingUnknown is an error produced when the encoding for an incoming -// message can not be understood. -type ErrMessageEncodingUnknown struct { - codec string - transport string -} - -// NewErrMessageEncodingUnknown makes a new ErrMessageEncodingUnknown. -func NewErrMessageEncodingUnknown(codec, transport string) *ErrMessageEncodingUnknown { - return &ErrMessageEncodingUnknown{ - codec: codec, - transport: transport, - } -} - -// Error implements error.Error -func (e *ErrMessageEncodingUnknown) Error() string { - return fmt.Sprintf("message encoding unknown for %s codec on %s transport", e.codec, e.transport) -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/doc.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/doc.go deleted file mode 100644 index c2cbadde0d2..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -/* - -Package transport defines interfaces to decouple the client package -from transport implementations. - -Most event sender and receiver applications should not use this -package, they should use the client package. This package is for -infrastructure developers implementing new transports, or intermediary -components like importers, channels or brokers. - -*/ -package transport diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec.go deleted file mode 100644 index 889c228ddec..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec.go +++ /dev/null @@ -1,154 +0,0 @@ -package http - -import ( - "context" - "errors" - "fmt" - "sync" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" -) - -// Codec is the wrapper for all versions of codecs supported by the http -// transport. -type Codec struct { - // Encoding is the setting to inform the DefaultEncodingSelectionFn for - // selecting a codec. - Encoding Encoding - - // DefaultEncodingSelectionFn allows for encoding selection strategies to be injected. - DefaultEncodingSelectionFn EncodingSelector - - v01 *CodecV01 - v02 *CodecV02 - v03 *CodecV03 - v1 *CodecV1 - - _v01 sync.Once - _v02 sync.Once - _v03 sync.Once - _v1 sync.Once -} - -// Adheres to Codec -var _ transport.Codec = (*Codec)(nil) - -func (c *Codec) loadCodec(encoding Encoding) (transport.Codec, error) { - switch encoding { - case Default: - fallthrough - case BinaryV01, StructuredV01: - c._v01.Do(func() { - c.v01 = &CodecV01{DefaultEncoding: c.Encoding} - }) - return c.v01, nil - case BinaryV02, StructuredV02: - c._v02.Do(func() { - c.v02 = &CodecV02{DefaultEncoding: c.Encoding} - }) - return c.v02, nil - case BinaryV03, StructuredV03, BatchedV03: - c._v03.Do(func() { - c.v03 = &CodecV03{DefaultEncoding: c.Encoding} - }) - return c.v03, nil - case BinaryV1, StructuredV1, BatchedV1: - c._v1.Do(func() { - c.v1 = &CodecV1{DefaultEncoding: c.Encoding} - }) - return c.v1, nil - } - return nil, fmt.Errorf("unknown encoding: %s", encoding) -} - -// Encode encodes the provided event into a transport message. -func (c *Codec) Encode(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - encoding := c.Encoding - if encoding == Default && c.DefaultEncodingSelectionFn != nil { - encoding = c.DefaultEncodingSelectionFn(ctx, e) - } - codec, err := c.loadCodec(encoding) - if err != nil { - return nil, err - } - ctx = cecontext.WithEncoding(ctx, encoding.Name()) - return codec.Encode(ctx, e) -} - -// Decode converts a provided transport message into an Event, or error. -func (c *Codec) Decode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - codec, err := c.loadCodec(c.inspectEncoding(ctx, msg)) - if err != nil { - return nil, err - } - event, err := codec.Decode(ctx, msg) - if err != nil { - return nil, err - } - return c.convertEvent(event) -} - -// Give the context back as the user expects -func (c *Codec) convertEvent(event *cloudevents.Event) (*cloudevents.Event, error) { - if event == nil { - return nil, errors.New("event is nil, can not convert") - } - - switch c.Encoding { - case Default: - return event, nil - case BinaryV01, StructuredV01: - ca := event.Context.AsV01() - event.Context = ca - return event, nil - case BinaryV02, StructuredV02: - ca := event.Context.AsV02() - event.Context = ca - return event, nil - case BinaryV03, StructuredV03, BatchedV03: - ca := event.Context.AsV03() - event.Context = ca - return event, nil - case BinaryV1, StructuredV1, BatchedV1: - ca := event.Context.AsV1() - event.Context = ca - return event, nil - default: - return nil, fmt.Errorf("unknown encoding: %s", c.Encoding) - } -} - -func (c *Codec) inspectEncoding(ctx context.Context, msg transport.Message) Encoding { - // Try v1.0. - _, _ = c.loadCodec(BinaryV1) - encoding := c.v1.inspectEncoding(ctx, msg) - if encoding != Unknown { - return encoding - } - - // Try v0.3. - _, _ = c.loadCodec(BinaryV03) - encoding = c.v03.inspectEncoding(ctx, msg) - if encoding != Unknown { - return encoding - } - - // Try v0.2. - _, _ = c.loadCodec(BinaryV02) - encoding = c.v02.inspectEncoding(ctx, msg) - if encoding != Unknown { - return encoding - } - - // Try v0.1 first. - _, _ = c.loadCodec(BinaryV01) - encoding = c.v01.inspectEncoding(ctx, msg) - if encoding != Unknown { - return encoding - } - - // We do not understand the message encoding. - return Unknown -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_structured.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_structured.go deleted file mode 100644 index d67d7186ee6..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_structured.go +++ /dev/null @@ -1,44 +0,0 @@ -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" -) - -// CodecStructured represents an structured http transport codec for all versions. -// Intended to be used as a base class. -type CodecStructured struct { - DefaultEncoding Encoding -} - -func (v CodecStructured) encodeStructured(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - header := http.Header{} - header.Set("Content-Type", cloudevents.ApplicationCloudEventsJSON) - - body, err := json.Marshal(e) - if err != nil { - return nil, err - } - - msg := &Message{ - Header: header, - Body: body, - } - - return msg, nil -} - -func (v CodecStructured) decodeStructured(ctx context.Context, version string, msg transport.Message) (*cloudevents.Event, error) { - m, ok := msg.(*Message) - if !ok { - return nil, fmt.Errorf("failed to convert transport.Message to http.Message") - } - event := cloudevents.New(version) - err := json.Unmarshal(m.Body, &event) - return &event, err -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v01.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v01.go deleted file mode 100644 index 435ba93fb5d..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v01.go +++ /dev/null @@ -1,232 +0,0 @@ -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// CodecV01 represents a http transport codec that uses CloudEvents spec v0.1 -type CodecV01 struct { - CodecStructured - - DefaultEncoding Encoding -} - -// Adheres to Codec -var _ transport.Codec = (*CodecV01)(nil) - -// Encode implements Codec.Encode -func (v CodecV01) Encode(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - encoding := v.DefaultEncoding - strEnc := cecontext.EncodingFrom(ctx) - if strEnc != "" { - switch strEnc { - case Binary: - encoding = BinaryV01 - case Structured: - encoding = StructuredV01 - } - } - - _, r := observability.NewReporter(context.Background(), CodecObserved{o: reportEncode, c: encoding.Codec()}) - m, err := v.obsEncode(ctx, e, encoding) - if err != nil { - r.Error() - } else { - r.OK() - } - return m, err -} - -func (v CodecV01) obsEncode(ctx context.Context, e cloudevents.Event, encoding Encoding) (transport.Message, error) { - switch encoding { - case Default: - fallthrough - case BinaryV01: - return v.encodeBinary(ctx, e) - case StructuredV01: - return v.encodeStructured(ctx, e) - default: - return nil, fmt.Errorf("unknown encoding: %d", encoding) - } -} - -// Decode implements Codec.Decode -func (v CodecV01) Decode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - _, r := observability.NewReporter(ctx, CodecObserved{o: reportDecode, c: v.inspectEncoding(ctx, msg).Codec()}) // TODO: inspectEncoding is not free. - e, err := v.obsDecode(ctx, msg) - if err != nil { - r.Error() - } else { - r.OK() - } - return e, err -} - -func (v CodecV01) obsDecode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - switch v.inspectEncoding(ctx, msg) { - case BinaryV01: - return v.decodeBinary(ctx, msg) - case StructuredV01: - return v.decodeStructured(ctx, cloudevents.CloudEventsVersionV01, msg) - default: - return nil, transport.NewErrMessageEncodingUnknown("v01", TransportName) - } -} - -func (v CodecV01) encodeBinary(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - header, err := v.toHeaders(e.Context.AsV01()) - if err != nil { - return nil, err - } - - body, err := e.DataBytes() - if err != nil { - panic("encode") - } - - msg := &Message{ - Header: header, - Body: body, - } - - return msg, nil -} - -func (v CodecV01) toHeaders(ec *cloudevents.EventContextV01) (http.Header, error) { - // Preserve case in v0.1, even though HTTP headers are case-insensitive. - h := http.Header{} - h["CE-CloudEventsVersion"] = []string{ec.CloudEventsVersion} - h["CE-EventID"] = []string{ec.EventID} - h["CE-EventType"] = []string{ec.EventType} - h["CE-Source"] = []string{ec.Source.String()} - if ec.EventTime != nil && !ec.EventTime.IsZero() { - h["CE-EventTime"] = []string{ec.EventTime.String()} - } - if ec.EventTypeVersion != nil { - h["CE-EventTypeVersion"] = []string{*ec.EventTypeVersion} - } - if ec.SchemaURL != nil { - h["CE-DataSchema"] = []string{ec.SchemaURL.String()} - } - if ec.ContentType != nil && *ec.ContentType != "" { - h.Set("Content-Type", *ec.ContentType) - } - - // Regarding Extensions, v0.1 Spec says the following: - // * Each map entry name MUST be prefixed with "CE-X-" - // * Each map entry name's first character MUST be capitalized - for k, v := range ec.Extensions { - encoded, err := json.Marshal(v) - if err != nil { - return nil, err - } - h["CE-X-"+strings.Title(k)] = []string{string(encoded)} - } - return h, nil -} - -func (v CodecV01) decodeBinary(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - m, ok := msg.(*Message) - if !ok { - return nil, fmt.Errorf("failed to convert transport.Message to http.Message") - } - ca, err := v.fromHeaders(m.Header) - if err != nil { - return nil, err - } - var body interface{} - if len(m.Body) > 0 { - body = m.Body - } - return &cloudevents.Event{ - Context: &ca, - Data: body, - DataEncoded: body != nil, - }, nil -} - -func (v CodecV01) fromHeaders(h http.Header) (cloudevents.EventContextV01, error) { - // Normalize headers. - for k, v := range h { - ck := textproto.CanonicalMIMEHeaderKey(k) - if k != ck { - h[ck] = v - } - } - - ec := cloudevents.EventContextV01{} - ec.CloudEventsVersion = h.Get("CE-CloudEventsVersion") - h.Del("CE-CloudEventsVersion") - ec.EventID = h.Get("CE-EventID") - h.Del("CE-EventID") - ec.EventType = h.Get("CE-EventType") - h.Del("CE-EventType") - source := types.ParseURLRef(h.Get("CE-Source")) - h.Del("CE-Source") - if source != nil { - ec.Source = *source - } - var err error - ec.EventTime, err = types.ParseTimestamp(h.Get("CE-EventTime")) - if err != nil { - return ec, err - } - h.Del("CE-EventTime") - etv := h.Get("CE-EventTypeVersion") - h.Del("CE-EventTypeVersion") - if etv != "" { - ec.EventTypeVersion = &etv - } - ec.SchemaURL = types.ParseURLRef(h.Get("CE-DataSchema")) - h.Del("CE-DataSchema") - et := h.Get("Content-Type") - if et != "" { - ec.ContentType = &et - } - - extensions := make(map[string]interface{}) - for k, v := range h { - if len(k) > len("CE-X-") && strings.EqualFold(k[:len("CE-X-")], "CE-X-") { - key := k[len("CE-X-"):] - var tmp interface{} - if err := json.Unmarshal([]byte(v[0]), &tmp); err == nil { - extensions[key] = tmp - } else { - // If we can't unmarshal the data, treat it as a string. - extensions[key] = v[0] - } - h.Del(k) - } - } - if len(extensions) > 0 { - ec.Extensions = extensions - } - return ec, nil -} - -func (v CodecV01) inspectEncoding(ctx context.Context, msg transport.Message) Encoding { - version := msg.CloudEventsVersion() - if version != cloudevents.CloudEventsVersionV01 { - return Unknown - } - m, ok := msg.(*Message) - if !ok { - return Unknown - } - contentType := m.Header.Get("Content-Type") - if contentType == cloudevents.ApplicationCloudEventsJSON { - return StructuredV01 - } - return BinaryV01 -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v02.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v02.go deleted file mode 100644 index aeb67c0e8c0..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v02.go +++ /dev/null @@ -1,261 +0,0 @@ -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// CodecV02 represents a http transport codec that uses CloudEvents spec v0.2 -type CodecV02 struct { - CodecStructured - - DefaultEncoding Encoding -} - -// Adheres to Codec -var _ transport.Codec = (*CodecV02)(nil) - -// Encode implements Codec.Encode -func (v CodecV02) Encode(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - encoding := v.DefaultEncoding - strEnc := cecontext.EncodingFrom(ctx) - if strEnc != "" { - switch strEnc { - case Binary: - encoding = BinaryV02 - case Structured: - encoding = StructuredV02 - } - } - - _, r := observability.NewReporter(ctx, CodecObserved{o: reportEncode, c: encoding.Codec()}) - m, err := v.obsEncode(ctx, e, encoding) - if err != nil { - r.Error() - } else { - r.OK() - } - return m, err -} - -func (v CodecV02) obsEncode(ctx context.Context, e cloudevents.Event, encoding Encoding) (transport.Message, error) { - switch encoding { - case Default: - fallthrough - case BinaryV02: - return v.encodeBinary(ctx, e) - case StructuredV02: - return v.encodeStructured(ctx, e) - default: - return nil, fmt.Errorf("unknown encoding: %d", encoding) - } -} - -// Decode implements Codec.Decode -func (v CodecV02) Decode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - _, r := observability.NewReporter(ctx, CodecObserved{o: reportDecode, c: v.inspectEncoding(ctx, msg).Codec()}) // TODO: inspectEncoding is not free. - e, err := v.obsDecode(ctx, msg) - if err != nil { - r.Error() - } else { - r.OK() - } - return e, err -} - -func (v CodecV02) obsDecode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - switch v.inspectEncoding(ctx, msg) { - case BinaryV02: - return v.decodeBinary(ctx, msg) - case StructuredV02: - return v.decodeStructured(ctx, cloudevents.CloudEventsVersionV02, msg) - default: - return nil, transport.NewErrMessageEncodingUnknown("v02", TransportName) - } -} - -func (v CodecV02) encodeBinary(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - header, err := v.toHeaders(e.Context.AsV02()) - if err != nil { - return nil, err - } - body, err := e.DataBytes() - if err != nil { - return nil, err - } - - msg := &Message{ - Header: header, - Body: body, - } - - return msg, nil -} - -func (v CodecV02) toHeaders(ec *cloudevents.EventContextV02) (http.Header, error) { - h := http.Header{} - h.Set("ce-specversion", ec.SpecVersion) - h.Set("ce-type", ec.Type) - h.Set("ce-source", ec.Source.String()) - h.Set("ce-id", ec.ID) - if ec.Time != nil && !ec.Time.IsZero() { - h.Set("ce-time", ec.Time.String()) - } - if ec.SchemaURL != nil { - h.Set("ce-schemaurl", ec.SchemaURL.String()) - } - if ec.ContentType != nil && *ec.ContentType != "" { - h.Set("Content-Type", *ec.ContentType) - } - for k, v := range ec.Extensions { - // Per spec, map-valued extensions are converted to a list of headers as: - // CE-attrib-key - if mapVal, ok := v.(map[string]interface{}); ok { - for subkey, subval := range mapVal { - encoded, err := json.Marshal(subval) - if err != nil { - return nil, err - } - h.Set("ce-"+k+"-"+subkey, string(encoded)) - } - continue - } - encoded, err := json.Marshal(v) - if err != nil { - return nil, err - } - h.Set("ce-"+k, string(encoded)) - } - - return h, nil -} - -func (v CodecV02) decodeBinary(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - m, ok := msg.(*Message) - if !ok { - return nil, fmt.Errorf("failed to convert transport.Message to http.Message") - } - ca, err := v.fromHeaders(m.Header) - if err != nil { - return nil, err - } - var body interface{} - if len(m.Body) > 0 { - body = m.Body - } - return &cloudevents.Event{ - Context: &ca, - Data: body, - DataEncoded: body != nil, - }, nil -} - -func (v CodecV02) fromHeaders(h http.Header) (cloudevents.EventContextV02, error) { - // Normalize headers. - for k, v := range h { - ck := textproto.CanonicalMIMEHeaderKey(k) - if k != ck { - delete(h, k) - h[ck] = v - } - } - - ec := cloudevents.EventContextV02{} - - ec.SpecVersion = h.Get("ce-specversion") - h.Del("ce-specversion") - - ec.ID = h.Get("ce-id") - h.Del("ce-id") - - ec.Type = h.Get("ce-type") - h.Del("ce-type") - - source := types.ParseURLRef(h.Get("ce-source")) - if source != nil { - ec.Source = *source - } - h.Del("ce-source") - - var err error - ec.Time, err = types.ParseTimestamp(h.Get("ce-time")) - if err != nil { - return ec, err - } - h.Del("ce-time") - - ec.SchemaURL = types.ParseURLRef(h.Get("ce-schemaurl")) - h.Del("ce-schemaurl") - - contentType := h.Get("Content-Type") - if contentType != "" { - ec.ContentType = &contentType - } - h.Del("Content-Type") - - // At this point, we have deleted all the known headers. - // Everything left is assumed to be an extension. - - extensions := make(map[string]interface{}) - for k, v := range h { - if len(k) > len("ce-") && strings.EqualFold(k[:len("ce-")], "ce-") { - ak := strings.ToLower(k[len("ce-"):]) - if i := strings.Index(ak, "-"); i > 0 { - // attrib-key - attrib := ak[:i] - key := ak[(i + 1):] - if xv, ok := extensions[attrib]; ok { - if m, ok := xv.(map[string]interface{}); ok { - m[key] = v - continue - } - // TODO: revisit how we want to bubble errors up. - return ec, fmt.Errorf("failed to process map type extension") - } else { - m := make(map[string]interface{}) - m[key] = v - extensions[attrib] = m - } - } else { - // key - var tmp interface{} - if err := json.Unmarshal([]byte(v[0]), &tmp); err == nil { - extensions[ak] = tmp - } else { - // If we can't unmarshal the data, treat it as a string. - extensions[ak] = v[0] - } - } - } - } - if len(extensions) > 0 { - ec.Extensions = extensions - } - return ec, nil -} - -func (v CodecV02) inspectEncoding(ctx context.Context, msg transport.Message) Encoding { - version := msg.CloudEventsVersion() - if version != cloudevents.CloudEventsVersionV02 { - return Unknown - } - m, ok := msg.(*Message) - if !ok { - return Unknown - } - contentType := m.Header.Get("Content-Type") - if contentType == cloudevents.ApplicationCloudEventsJSON { - return StructuredV02 - } - return BinaryV02 -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v03.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v03.go deleted file mode 100644 index b2b3c87ee9b..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v03.go +++ /dev/null @@ -1,302 +0,0 @@ -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// CodecV03 represents a http transport codec that uses CloudEvents spec v0.3 -type CodecV03 struct { - CodecStructured - - DefaultEncoding Encoding -} - -// Adheres to Codec -var _ transport.Codec = (*CodecV03)(nil) - -// Encode implements Codec.Encode -func (v CodecV03) Encode(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - encoding := v.DefaultEncoding - strEnc := cecontext.EncodingFrom(ctx) - if strEnc != "" { - switch strEnc { - case Binary: - encoding = BinaryV03 - case Structured: - encoding = StructuredV03 - } - } - - _, r := observability.NewReporter(ctx, CodecObserved{o: reportEncode, c: encoding.Codec()}) - m, err := v.obsEncode(ctx, e, encoding) - if err != nil { - r.Error() - } else { - r.OK() - } - return m, err -} - -func (v CodecV03) obsEncode(ctx context.Context, e cloudevents.Event, encoding Encoding) (transport.Message, error) { - switch encoding { - case Default: - fallthrough - case BinaryV03: - return v.encodeBinary(ctx, e) - case StructuredV03: - return v.encodeStructured(ctx, e) - case BatchedV03: - return nil, fmt.Errorf("not implemented") - default: - return nil, fmt.Errorf("unknown encoding: %d", encoding) - } -} - -// Decode implements Codec.Decode -func (v CodecV03) Decode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - _, r := observability.NewReporter(ctx, CodecObserved{o: reportDecode, c: v.inspectEncoding(ctx, msg).Codec()}) // TODO: inspectEncoding is not free. - e, err := v.obsDecode(ctx, msg) - if err != nil { - r.Error() - } else { - r.OK() - } - return e, err -} - -func (v CodecV03) obsDecode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - switch v.inspectEncoding(ctx, msg) { - case BinaryV03: - return v.decodeBinary(ctx, msg) - case StructuredV03: - return v.decodeStructured(ctx, cloudevents.CloudEventsVersionV03, msg) - case BatchedV03: - return nil, fmt.Errorf("not implemented") - default: - return nil, transport.NewErrMessageEncodingUnknown("v03", TransportName) - } -} - -func (v CodecV03) encodeBinary(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - header, err := v.toHeaders(e.Context.AsV03()) - if err != nil { - return nil, err - } - - body, err := e.DataBytes() - if err != nil { - return nil, err - } - - msg := &Message{ - Header: header, - Body: body, - } - - return msg, nil -} - -func (v CodecV03) toHeaders(ec *cloudevents.EventContextV03) (http.Header, error) { - h := http.Header{} - h.Set("ce-specversion", ec.SpecVersion) - h.Set("ce-type", ec.Type) - h.Set("ce-source", ec.Source.String()) - if ec.Subject != nil { - h.Set("ce-subject", *ec.Subject) - } - h.Set("ce-id", ec.ID) - if ec.Time != nil && !ec.Time.IsZero() { - h.Set("ce-time", ec.Time.String()) - } - if ec.SchemaURL != nil { - h.Set("ce-schemaurl", ec.SchemaURL.String()) - } - if ec.DataContentType != nil && *ec.DataContentType != "" { - h.Set("Content-Type", *ec.DataContentType) - } - if ec.DataContentEncoding != nil { - h.Set("ce-datacontentencoding", *ec.DataContentEncoding) - } - - for k, v := range ec.Extensions { - k = strings.ToLower(k) - // Per spec, map-valued extensions are converted to a list of headers as: - // CE-attrib-key - switch v.(type) { - case string: - h.Set("ce-"+k, v.(string)) - - case map[string]interface{}: - mapVal := v.(map[string]interface{}) - - for subkey, subval := range mapVal { - if subvalstr, ok := v.(string); ok { - h.Set("ce-"+k+"-"+subkey, subvalstr) - continue - } - - encoded, err := json.Marshal(subval) - if err != nil { - return nil, err - } - h.Set("ce-"+k+"-"+subkey, string(encoded)) - } - - default: - encoded, err := json.Marshal(v) - if err != nil { - return nil, err - } - h.Set("ce-"+k, string(encoded)) - } - } - - return h, nil -} - -func (v CodecV03) decodeBinary(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - m, ok := msg.(*Message) - if !ok { - return nil, fmt.Errorf("failed to convert transport.Message to http.Message") - } - ca, err := v.fromHeaders(m.Header) - if err != nil { - return nil, err - } - var body interface{} - if len(m.Body) > 0 { - body = m.Body - } - return &cloudevents.Event{ - Context: &ca, - Data: body, - DataEncoded: body != nil, - }, nil -} - -func (v CodecV03) fromHeaders(h http.Header) (cloudevents.EventContextV03, error) { - // Normalize headers. - for k, v := range h { - ck := textproto.CanonicalMIMEHeaderKey(k) - if k != ck { - delete(h, k) - h[ck] = v - } - } - - ec := cloudevents.EventContextV03{} - - ec.SpecVersion = h.Get("ce-specversion") - h.Del("ce-specversion") - - ec.ID = h.Get("ce-id") - h.Del("ce-id") - - ec.Type = h.Get("ce-type") - h.Del("ce-type") - - source := types.ParseURLRef(h.Get("ce-source")) - if source != nil { - ec.Source = *source - } - h.Del("ce-source") - - subject := h.Get("ce-subject") - if subject != "" { - ec.Subject = &subject - } - h.Del("ce-subject") - - var err error - ec.Time, err = types.ParseTimestamp(h.Get("ce-time")) - if err != nil { - return ec, err - } - h.Del("ce-time") - - ec.SchemaURL = types.ParseURLRef(h.Get("ce-schemaurl")) - h.Del("ce-schemaurl") - - contentType := h.Get("Content-Type") - if contentType != "" { - ec.DataContentType = &contentType - } - h.Del("Content-Type") - - dataContentEncoding := h.Get("ce-datacontentencoding") - if dataContentEncoding != "" { - ec.DataContentEncoding = &dataContentEncoding - } - h.Del("ce-datacontentencoding") - - // At this point, we have deleted all the known headers. - // Everything left is assumed to be an extension. - - extensions := make(map[string]interface{}) - for k, v := range h { - k = strings.ToLower(k) - if len(k) > len("ce-") && strings.EqualFold(k[:len("ce-")], "ce-") { - ak := strings.ToLower(k[len("ce-"):]) - if i := strings.Index(ak, "-"); i > 0 { - // attrib-key - attrib := ak[:i] - key := ak[(i + 1):] - if xv, ok := extensions[attrib]; ok { - if m, ok := xv.(map[string]interface{}); ok { - m[key] = v - continue - } - // TODO: revisit how we want to bubble errors up. - return ec, fmt.Errorf("failed to process map type extension") - } else { - m := make(map[string]interface{}) - m[key] = v - extensions[attrib] = m - } - } else { - // key - var tmp interface{} - if err := json.Unmarshal([]byte(v[0]), &tmp); err == nil { - extensions[ak] = tmp - } else { - // If we can't unmarshal the data, treat it as a string. - extensions[ak] = v[0] - } - } - } - } - if len(extensions) > 0 { - ec.Extensions = extensions - } - return ec, nil -} - -func (v CodecV03) inspectEncoding(ctx context.Context, msg transport.Message) Encoding { - version := msg.CloudEventsVersion() - if version != cloudevents.CloudEventsVersionV03 { - return Unknown - } - m, ok := msg.(*Message) - if !ok { - return Unknown - } - contentType := m.Header.Get("Content-Type") - if contentType == cloudevents.ApplicationCloudEventsJSON { - return StructuredV03 - } - if contentType == cloudevents.ApplicationCloudEventsBatchJSON { - return BatchedV03 - } - return BinaryV03 -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v1.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v1.go deleted file mode 100644 index 4ebe7422b07..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v1.go +++ /dev/null @@ -1,245 +0,0 @@ -package http - -import ( - "context" - "fmt" - "net/http" - "net/textproto" - "strings" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" -) - -// CodecV1 represents a http transport codec that uses CloudEvents spec v1.0 -type CodecV1 struct { - CodecStructured - - DefaultEncoding Encoding -} - -// Adheres to Codec -var _ transport.Codec = (*CodecV1)(nil) - -// Encode implements Codec.Encode -func (v CodecV1) Encode(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - encoding := v.DefaultEncoding - strEnc := cecontext.EncodingFrom(ctx) - if strEnc != "" { - switch strEnc { - case Binary: - encoding = BinaryV1 - case Structured: - encoding = StructuredV1 - } - } - - _, r := observability.NewReporter(ctx, CodecObserved{o: reportEncode, c: encoding.Codec()}) - m, err := v.obsEncode(ctx, e, encoding) - if err != nil { - r.Error() - } else { - r.OK() - } - return m, err -} - -func (v CodecV1) obsEncode(ctx context.Context, e cloudevents.Event, encoding Encoding) (transport.Message, error) { - switch encoding { - case Default: - fallthrough - case BinaryV1: - return v.encodeBinary(ctx, e) - case StructuredV1: - return v.encodeStructured(ctx, e) - case BatchedV1: - return nil, fmt.Errorf("not implemented") - default: - return nil, fmt.Errorf("unknown encoding: %d", encoding) - } -} - -// Decode implements Codec.Decode -func (v CodecV1) Decode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - _, r := observability.NewReporter(ctx, CodecObserved{o: reportDecode, c: v.inspectEncoding(ctx, msg).Codec()}) // TODO: inspectEncoding is not free. - e, err := v.obsDecode(ctx, msg) - if err != nil { - r.Error() - } else { - r.OK() - } - return e, err -} - -func (v CodecV1) obsDecode(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - switch v.inspectEncoding(ctx, msg) { - case BinaryV1: - return v.decodeBinary(ctx, msg) - case StructuredV1: - return v.decodeStructured(ctx, cloudevents.CloudEventsVersionV1, msg) - case BatchedV1: - return nil, fmt.Errorf("not implemented") - default: - return nil, transport.NewErrMessageEncodingUnknown("V1", TransportName) - } -} - -func (v CodecV1) encodeBinary(ctx context.Context, e cloudevents.Event) (transport.Message, error) { - header, err := v.toHeaders(e.Context.AsV1()) - if err != nil { - return nil, err - } - - body, err := e.DataBytes() - if err != nil { - return nil, err - } - - msg := &Message{ - Header: header, - Body: body, - } - - return msg, nil -} - -func (v CodecV1) toHeaders(ec *cloudevents.EventContextV1) (http.Header, error) { - h := http.Header{} - h.Set("ce-specversion", ec.SpecVersion) - h.Set("ce-type", ec.Type) - h.Set("ce-source", ec.Source.String()) - if ec.Subject != nil { - h.Set("ce-subject", *ec.Subject) - } - h.Set("ce-id", ec.ID) - if ec.Time != nil && !ec.Time.IsZero() { - h.Set("ce-time", ec.Time.String()) - } - if ec.DataSchema != nil { - h.Set("ce-dataschema", ec.DataSchema.String()) - } - if ec.DataContentType != nil && *ec.DataContentType != "" { - h.Set("Content-Type", *ec.DataContentType) - } - - for k, v := range ec.Extensions { - k = strings.ToLower(k) - // Per spec, extensions are strings and converted to a list of headers as: - // ce-key: value - cstr, err := types.Format(v) - if err != nil { - return h, err - } - h.Set("ce-"+k, cstr) - } - - return h, nil -} - -func (v CodecV1) decodeBinary(ctx context.Context, msg transport.Message) (*cloudevents.Event, error) { - m, ok := msg.(*Message) - if !ok { - return nil, fmt.Errorf("failed to convert transport.Message to http.Message") - } - ca, err := v.fromHeaders(m.Header) - if err != nil { - return nil, err - } - var body interface{} - if len(m.Body) > 0 { - body = m.Body - } - return &cloudevents.Event{ - Context: &ca, - Data: body, - DataEncoded: body != nil, - }, nil -} - -func (v CodecV1) fromHeaders(h http.Header) (cloudevents.EventContextV1, error) { - // Normalize headers. - for k, v := range h { - ck := textproto.CanonicalMIMEHeaderKey(k) - if k != ck { - delete(h, k) - h[ck] = v - } - } - - ec := cloudevents.EventContextV1{} - - ec.SpecVersion = h.Get("ce-specversion") - h.Del("ce-specversion") - - ec.ID = h.Get("ce-id") - h.Del("ce-id") - - ec.Type = h.Get("ce-type") - h.Del("ce-type") - - source := types.ParseURIRef(h.Get("ce-source")) - if source != nil { - ec.Source = *source - } - h.Del("ce-source") - - subject := h.Get("ce-subject") - if subject != "" { - ec.Subject = &subject - } - h.Del("ce-subject") - - var err error - ec.Time, err = types.ParseTimestamp(h.Get("ce-time")) - if err != nil { - return ec, err - } - h.Del("ce-time") - - ec.DataSchema = types.ParseURI(h.Get("ce-dataschema")) - h.Del("ce-dataschema") - - contentType := h.Get("Content-Type") - if contentType != "" { - ec.DataContentType = &contentType - } - h.Del("Content-Type") - - // At this point, we have deleted all the known headers. - // Everything left is assumed to be an extension. - - extensions := make(map[string]interface{}) - for k := range h { - k = strings.ToLower(k) - if len(k) > len("ce-") && strings.EqualFold(k[:len("ce-")], "ce-") { - ak := strings.ToLower(k[len("ce-"):]) - extensions[ak] = h.Get(k) - } - } - if len(extensions) > 0 { - ec.Extensions = extensions - } - return ec, nil -} - -func (v CodecV1) inspectEncoding(ctx context.Context, msg transport.Message) Encoding { - version := msg.CloudEventsVersion() - if version != cloudevents.CloudEventsVersionV1 { - return Unknown - } - m, ok := msg.(*Message) - if !ok { - return Unknown - } - contentType := m.Header.Get("Content-Type") - if contentType == cloudevents.ApplicationCloudEventsJSON { - return StructuredV1 - } - if contentType == cloudevents.ApplicationCloudEventsBatchJSON { - return BatchedV1 - } - return BinaryV1 -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/context.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/context.go deleted file mode 100644 index cf8b8510d7a..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/context.go +++ /dev/null @@ -1,207 +0,0 @@ -package http - -import ( - "context" - "fmt" - "net/http" - "net/url" - "strconv" - "strings" -) - -// TransportContext allows a Receiver to understand the context of a request. -type TransportContext struct { - URI string - Host string - Method string - Header http.Header - StatusCode int - - // IgnoreHeaderPrefixes controls what comes back from AttendToHeaders. - // AttendToHeaders controls what is output for .String() - IgnoreHeaderPrefixes []string -} - -// NewTransportContext creates a new TransportContext from a http.Request. -func NewTransportContext(req *http.Request) TransportContext { - var tx *TransportContext - if req != nil { - tx = &TransportContext{ - URI: req.RequestURI, - Host: req.Host, - Method: req.Method, - Header: req.Header, - } - } else { - tx = &TransportContext{} - } - tx.AddIgnoreHeaderPrefix("accept-encoding", "user-agent", "connection", "content-type") - return *tx -} - -// NewTransportContextFromResponse creates a new TransportContext from a http.Response. -// If `res` is nil, it returns a context with a http.StatusInternalServerError status code. -func NewTransportContextFromResponse(res *http.Response) TransportContext { - var tx *TransportContext - if res != nil { - tx = &TransportContext{ - Header: res.Header, - StatusCode: res.StatusCode, - } - } else { - tx = &TransportContext{StatusCode: http.StatusInternalServerError} - } - tx.AddIgnoreHeaderPrefix("accept-encoding", "user-agent", "connection", "content-type") - return *tx -} - -// TransportResponseContext allows a Receiver response with http transport specific fields. -type TransportResponseContext struct { - // Header will be merged with the response headers. - Header http.Header -} - -// AttendToHeaders returns the list of headers that exist in the TransportContext that are not currently in -// tx.IgnoreHeaderPrefix. -func (tx TransportContext) AttendToHeaders() []string { - a := []string(nil) - if tx.Header != nil && len(tx.Header) > 0 { - for k := range tx.Header { - if tx.shouldIgnoreHeader(k) { - continue - } - a = append(a, k) - } - } - return a -} - -func (tx TransportContext) shouldIgnoreHeader(h string) bool { - for _, v := range tx.IgnoreHeaderPrefixes { - if strings.HasPrefix(strings.ToLower(h), strings.ToLower(v)) { - return true - } - } - return false -} - -// String generates a pretty-printed version of the resource as a string. -func (tx TransportContext) String() string { - b := strings.Builder{} - - b.WriteString("Transport Context,\n") - - empty := b.Len() - - if tx.URI != "" { - b.WriteString(" URI: " + tx.URI + "\n") - } - if tx.Host != "" { - b.WriteString(" Host: " + tx.Host + "\n") - } - - if tx.Method != "" { - b.WriteString(" Method: " + tx.Method + "\n") - } - - if tx.StatusCode != 0 { - b.WriteString(" StatusCode: " + strconv.Itoa(tx.StatusCode) + "\n") - } - - if tx.Header != nil && len(tx.Header) > 0 { - b.WriteString(" Header:\n") - for _, k := range tx.AttendToHeaders() { - b.WriteString(fmt.Sprintf(" %s: %s\n", k, tx.Header.Get(k))) - } - } - - if b.Len() == empty { - b.WriteString(" nil\n") - } - - return b.String() -} - -// AddIgnoreHeaderPrefix controls what header key is to be attended to and/or printed. -func (tx *TransportContext) AddIgnoreHeaderPrefix(prefix ...string) { - if tx.IgnoreHeaderPrefixes == nil { - tx.IgnoreHeaderPrefixes = []string(nil) - } - tx.IgnoreHeaderPrefixes = append(tx.IgnoreHeaderPrefixes, prefix...) -} - -// Opaque key type used to store TransportContext -type transportContextKeyType struct{} - -var transportContextKey = transportContextKeyType{} - -// WithTransportContext return a context with the given TransportContext into the provided context object. -func WithTransportContext(ctx context.Context, tcxt TransportContext) context.Context { - return context.WithValue(ctx, transportContextKey, tcxt) -} - -// TransportContextFrom pulls a TransportContext out of a context. Always -// returns a non-nil object. -func TransportContextFrom(ctx context.Context) TransportContext { - tctx := ctx.Value(transportContextKey) - if tctx != nil { - if tx, ok := tctx.(TransportContext); ok { - return tx - } - if tx, ok := tctx.(*TransportContext); ok { - return *tx - } - } - return TransportContext{} -} - -// Opaque key type used to store Headers -type headerKeyType struct{} - -var headerKey = headerKeyType{} - -// ContextWithHeader returns a context with a header added to the given context. -// Can be called multiple times to set multiple header key/value pairs. -func ContextWithHeader(ctx context.Context, key, value string) context.Context { - header := HeaderFrom(ctx) - header.Add(key, value) - return context.WithValue(ctx, headerKey, header) -} - -// HeaderFrom extracts the header object in the given context. Always returns a non-nil Header. -func HeaderFrom(ctx context.Context) http.Header { - ch := http.Header{} - header := ctx.Value(headerKey) - if header != nil { - if h, ok := header.(http.Header); ok { - copyHeaders(h, ch) - } - } - return ch -} - -// Opaque key type used to store long poll target. -type longPollTargetKeyType struct{} - -var longPollTargetKey = longPollTargetKeyType{} - -// WithLongPollTarget returns a new context with the given long poll target. -// `target` should be a full URL and will be injected into the long polling -// http request within StartReceiver. -func ContextWithLongPollTarget(ctx context.Context, target string) context.Context { - return context.WithValue(ctx, longPollTargetKey, target) -} - -// LongPollTargetFrom looks in the given context and returns `target` as a -// parsed url if found and valid, otherwise nil. -func LongPollTargetFrom(ctx context.Context) *url.URL { - c := ctx.Value(longPollTargetKey) - if c != nil { - if s, ok := c.(string); ok && s != "" { - if target, err := url.Parse(s); err == nil { - return target - } - } - } - return nil -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/doc.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/doc.go deleted file mode 100644 index 1a171e46e1e..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -/* -Package http implements the CloudEvent transport implementation using HTTP. -*/ -package http diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/encoding.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/encoding.go deleted file mode 100644 index 60f3e3ea3e6..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/encoding.go +++ /dev/null @@ -1,205 +0,0 @@ -package http - -import ( - "context" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" -) - -// Encoding to use for HTTP transport. -type Encoding int32 - -type EncodingSelector func(context.Context, cloudevents.Event) Encoding - -const ( - // Default - Default Encoding = iota - // BinaryV01 is Binary CloudEvents spec v0.1. - BinaryV01 - // StructuredV01 is Structured CloudEvents spec v0.1. - StructuredV01 - // BinaryV02 is Binary CloudEvents spec v0.2. - BinaryV02 - // StructuredV02 is Structured CloudEvents spec v0.2. - StructuredV02 - // BinaryV03 is Binary CloudEvents spec v0.3. - BinaryV03 - // StructuredV03 is Structured CloudEvents spec v0.3. - StructuredV03 - // BatchedV03 is Batched CloudEvents spec v0.3. - BatchedV03 - // BinaryV1 is Binary CloudEvents spec v1.0. - BinaryV1 - // StructuredV03 is Structured CloudEvents spec v1.0. - StructuredV1 - // BatchedV1 is Batched CloudEvents spec v1.0. - BatchedV1 - - // Unknown is unknown. - Unknown - - // Binary is used for Context Based Encoding Selections to use the - // DefaultBinaryEncodingSelectionStrategy - Binary = "binary" - - // Structured is used for Context Based Encoding Selections to use the - // DefaultStructuredEncodingSelectionStrategy - Structured = "structured" - - // Batched is used for Context Based Encoding Selections to use the - // DefaultStructuredEncodingSelectionStrategy - Batched = "batched" -) - -func ContextBasedEncodingSelectionStrategy(ctx context.Context, e cloudevents.Event) Encoding { - encoding := cecontext.EncodingFrom(ctx) - switch encoding { - case "", Binary: - return DefaultBinaryEncodingSelectionStrategy(ctx, e) - case Structured: - return DefaultStructuredEncodingSelectionStrategy(ctx, e) - } - return Default -} - -// DefaultBinaryEncodingSelectionStrategy implements a selection process for -// which binary encoding to use based on spec version of the event. -func DefaultBinaryEncodingSelectionStrategy(ctx context.Context, e cloudevents.Event) Encoding { - switch e.SpecVersion() { - case cloudevents.CloudEventsVersionV01: - return BinaryV01 - case cloudevents.CloudEventsVersionV02: - return BinaryV02 - case cloudevents.CloudEventsVersionV03: - return BinaryV03 - case cloudevents.CloudEventsVersionV1: - return BinaryV1 - } - // Unknown version, return Default. - return Default -} - -// DefaultStructuredEncodingSelectionStrategy implements a selection process -// for which structured encoding to use based on spec version of the event. -func DefaultStructuredEncodingSelectionStrategy(ctx context.Context, e cloudevents.Event) Encoding { - switch e.SpecVersion() { - case cloudevents.CloudEventsVersionV01: - return StructuredV01 - case cloudevents.CloudEventsVersionV02: - return StructuredV02 - case cloudevents.CloudEventsVersionV03: - return StructuredV03 - case cloudevents.CloudEventsVersionV1: - return StructuredV1 - } - // Unknown version, return Default. - return Default -} - -// String pretty-prints the encoding as a string. -func (e Encoding) String() string { - switch e { - case Default: - return "Default Encoding " + e.Version() - - // Binary - case BinaryV01, BinaryV02, BinaryV03, BinaryV1: - return "Binary Encoding " + e.Version() - - // Structured - case StructuredV01, StructuredV02, StructuredV03, StructuredV1: - return "Structured Encoding " + e.Version() - - // Batched - case BatchedV03, BatchedV1: - return "Batched Encoding " + e.Version() - - default: - return "Unknown Encoding" - } -} - -// Version pretty-prints the encoding version as a string. -func (e Encoding) Version() string { - switch e { - case Default: - return "Default" - - // Version 0.1 - case BinaryV01, StructuredV01: - return "v0.1" - - // Version 0.2 - case BinaryV02, StructuredV02: - return "v0.2" - - // Version 0.3 - case BinaryV03, StructuredV03, BatchedV03: - return "v0.3" - - // Version 1.0 - case BinaryV1, StructuredV1, BatchedV1: - return "v1.0" - - // Unknown - default: - return "Unknown" - } -} - -// Codec creates a structured string to represent the the codec version. -func (e Encoding) Codec() string { - switch e { - case Default: - return "default" - - // Version 0.1 - case BinaryV01: - return "binary/v0.1" - case StructuredV01: - return "structured/v0.1" - - // Version 0.2 - case BinaryV02: - return "binary/v0.2" - case StructuredV02: - return "structured/v0.2" - - // Version 0.3 - case BinaryV03: - return "binary/v0.3" - case StructuredV03: - return "structured/v0.3" - case BatchedV03: - return "batched/v0.3" - - // Version 1.0 - case BinaryV1: - return "binary/v1.0" - case StructuredV1: - return "structured/v1.0" - case BatchedV1: - return "batched/v1.0" - - // Unknown - default: - return "unknown" - } -} - -// Name creates a string to represent the the codec name. -func (e Encoding) Name() string { - switch e { - case Default: - return Binary - case BinaryV01, BinaryV02, BinaryV03, BinaryV1: - return Binary - case StructuredV01, StructuredV02, StructuredV03, StructuredV1: - return Structured - case BatchedV03, BatchedV1: - return Batched - default: - return Binary - } -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/message.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/message.go deleted file mode 100644 index a6cdbecb1c6..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/message.go +++ /dev/null @@ -1,148 +0,0 @@ -package http - -import ( - "bytes" - "encoding/json" - - "io" - "io/ioutil" - "net/http" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" -) - -// type check that this transport message impl matches the contract -var _ transport.Message = (*Message)(nil) - -// Message is an http transport message. -type Message struct { - Header http.Header - Body []byte -} - -// Response is an http transport response. -type Response struct { - StatusCode int - Message -} - -// CloudEventsVersion inspects a message and tries to discover and return the -// CloudEvents spec version. -func (m Message) CloudEventsVersion() string { - - // TODO: the impl of this method needs to move into the codec. - - if m.Header != nil { - // Try headers first. - // v0.1, cased from the spec - // Note: don't pass literal string direct to m.Header[] so that - // go vet won't complain about non-canonical case. - name := "CE-CloudEventsVersion" - if v := m.Header[name]; len(v) == 1 { - return v[0] - } - // v0.2, canonical casing - if ver := m.Header.Get("CE-CloudEventsVersion"); ver != "" { - return ver - } - - // v0.2, cased from the spec - name = "ce-specversion" - if v := m.Header[name]; len(v) == 1 { - return v[0] - } - // v0.2, canonical casing - name = "ce-specversion" - if ver := m.Header.Get(name); ver != "" { - return ver - } - } - - // Then try the data body. - // TODO: we need to use the correct decoding based on content type. - - raw := make(map[string]json.RawMessage) - if err := json.Unmarshal(m.Body, &raw); err != nil { - return "" - } - - // v0.1 - if v, ok := raw["cloudEventsVersion"]; ok { - var version string - if err := json.Unmarshal(v, &version); err != nil { - return "" - } - return version - } - - // v0.2 - if v, ok := raw["specversion"]; ok { - var version string - if err := json.Unmarshal(v, &version); err != nil { - return "" - } - return version - } - - return "" -} - -func readAllClose(r io.ReadCloser) ([]byte, error) { - if r != nil { - defer r.Close() - return ioutil.ReadAll(r) - } - return nil, nil -} - -// NewMessage creates a new message from the Header and Body of -// an http.Request or http.Response -func NewMessage(header http.Header, body io.ReadCloser) (*Message, error) { - var m Message - err := m.Init(header, body) - return &m, err -} - -// NewResponse creates a new response from the Header and Body of -// an http.Request or http.Response -func NewResponse(header http.Header, body io.ReadCloser, statusCode int) (*Response, error) { - resp := Response{StatusCode: statusCode} - err := resp.Init(header, body) - return &resp, err -} - -// Copy copies a new Body and Header into a message, replacing any previous data. -func (m *Message) Init(header http.Header, body io.ReadCloser) error { - m.Header = make(http.Header, len(header)) - copyHeadersEnsure(header, &m.Header) - var err error - m.Body, err = readAllClose(body) - return err -} - -func (m *Message) copyOut(header *http.Header, body *io.ReadCloser) { - copyHeadersEnsure(m.Header, header) - *body = nil - if m.Body != nil { - copy := append([]byte(nil), m.Body...) - *body = ioutil.NopCloser(bytes.NewBuffer(copy)) - } -} - -// ToRequest updates a http.Request from a Message. -// Replaces Body, ContentLength and Method, updates Headers. -// Panic if req is nil -func (m *Message) ToRequest(req *http.Request) { - m.copyOut(&req.Header, &req.Body) - req.ContentLength = int64(len(m.Body)) - req.Method = http.MethodPost -} - -// ToResponse updates a http.Response from a Response. -// Replaces Body, updates Headers. -// Panic if resp is nil -func (m *Response) ToResponse(resp *http.Response) { - m.copyOut(&resp.Header, &resp.Body) - resp.ContentLength = int64(len(m.Body)) - resp.StatusCode = m.StatusCode -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/observability.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/observability.go deleted file mode 100644 index 1da56dc2ad5..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/observability.go +++ /dev/null @@ -1,109 +0,0 @@ -package http - -import ( - "fmt" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" -) - -var ( - // LatencyMs measures the latency in milliseconds for the http transport - // methods for CloudEvents. - LatencyMs = stats.Float64( - "cloudevents.io/sdk-go/transport/http/latency", - "The latency in milliseconds for the http transport methods for CloudEvents.", - "ms") -) - -var ( - // LatencyView is an OpenCensus view that shows http transport method latency. - LatencyView = &view.View{ - Name: "transport/http/latency", - Measure: LatencyMs, - Description: "The distribution of latency inside of http transport for CloudEvents.", - Aggregation: view.Distribution(0, .01, .1, 1, 10, 100, 1000, 10000), - TagKeys: observability.LatencyTags(), - } -) - -type observed int32 - -// Adheres to Observable -var _ observability.Observable = observed(0) - -const ( - reportSend observed = iota - reportReceive - reportServeHTTP - reportEncode - reportDecode -) - -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportSend: - return "transport/http/send" - case reportReceive: - return "transport/http/receive" - case reportServeHTTP: - return "transport/http/servehttp" - case reportEncode: - return "transport/http/encode" - case reportDecode: - return "transport/http/decode" - default: - return "transport/http/unknown" - } -} - -// MethodName implements Observable.MethodName -func (o observed) MethodName() string { - switch o { - case reportSend: - return "send" - case reportReceive: - return "receive" - case reportServeHTTP: - return "servehttp" - case reportEncode: - return "encode" - case reportDecode: - return "decode" - default: - return "unknown" - } -} - -// LatencyMs implements Observable.LatencyMs -func (o observed) LatencyMs() *stats.Float64Measure { - return LatencyMs -} - -// CodecObserved is a wrapper to append version to observed. -type CodecObserved struct { - // Method - o observed - // Codec - c string -} - -// Adheres to Observable -var _ observability.Observable = (*CodecObserved)(nil) - -// TraceName implements Observable.TraceName -func (c CodecObserved) TraceName() string { - return fmt.Sprintf("%s/%s", c.o.TraceName(), c.c) -} - -// MethodName implements Observable.MethodName -func (c CodecObserved) MethodName() string { - return fmt.Sprintf("%s/%s", c.o.MethodName(), c.c) -} - -// LatencyMs implements Observable.LatencyMs -func (c CodecObserved) LatencyMs() *stats.Float64Measure { - return c.o.LatencyMs() -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/options.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/options.go deleted file mode 100644 index 0276157fccd..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/options.go +++ /dev/null @@ -1,266 +0,0 @@ -package http - -import ( - "fmt" - "net" - nethttp "net/http" - "net/url" - "strings" - "time" -) - -// Option is the function signature required to be considered an http.Option. -type Option func(*Transport) error - -// WithTarget sets the outbound recipient of cloudevents when using an HTTP -// request. -func WithTarget(targetUrl string) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http target option can not set nil transport") - } - targetUrl = strings.TrimSpace(targetUrl) - if targetUrl != "" { - var err error - var target *url.URL - target, err = url.Parse(targetUrl) - if err != nil { - return fmt.Errorf("http target option failed to parse target url: %s", err.Error()) - } - - if t.Req == nil { - t.Req = &nethttp.Request{ - Method: nethttp.MethodPost, - } - } - t.Req.URL = target - return nil - } - return fmt.Errorf("http target option was empty string") - } -} - -// WithMethod sets the outbound recipient of cloudevents when using an HTTP -// request. -func WithMethod(method string) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http method option can not set nil transport") - } - method = strings.TrimSpace(method) - if method != "" { - if t.Req == nil { - t.Req = &nethttp.Request{} - } - t.Req.Method = method - return nil - } - return fmt.Errorf("http method option was empty string") - } -} - -// WithHeader sets an additional default outbound header for all cloudevents -// when using an HTTP request. -func WithHeader(key, value string) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http header option can not set nil transport") - } - key = strings.TrimSpace(key) - if key != "" { - if t.Req == nil { - t.Req = &nethttp.Request{} - } - if t.Req.Header == nil { - t.Req.Header = nethttp.Header{} - } - t.Req.Header.Add(key, value) - return nil - } - return fmt.Errorf("http header option was empty string") - } -} - -// WithShutdownTimeout sets the shutdown timeout when the http server is being shutdown. -func WithShutdownTimeout(timeout time.Duration) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http shutdown timeout option can not set nil transport") - } - t.ShutdownTimeout = &timeout - return nil - } -} - -// WithEncoding sets the encoding for clients with HTTP transports. -func WithEncoding(encoding Encoding) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http encoding option can not set nil transport") - } - t.Encoding = encoding - return nil - } -} - -// WithDefaultEncodingSelector sets the encoding selection strategy for -// default encoding selections based on Event. -func WithDefaultEncodingSelector(fn EncodingSelector) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http default encoding selector option can not set nil transport") - } - if fn != nil { - t.DefaultEncodingSelectionFn = fn - return nil - } - return fmt.Errorf("http fn for DefaultEncodingSelector was nil") - } -} - -// WithContextBasedEncoding sets the encoding selection strategy for -// default encoding selections based context and then on Event, the encoded -// event will be the given version in the encoding specified by the given -// context, or Binary if not set. -func WithContextBasedEncoding() Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http context based encoding option can not set nil transport") - } - - t.DefaultEncodingSelectionFn = ContextBasedEncodingSelectionStrategy - return nil - } -} - -// WithBinaryEncoding sets the encoding selection strategy for -// default encoding selections based on Event, the encoded event will be the -// given version in Binary form. -func WithBinaryEncoding() Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http binary encoding option can not set nil transport") - } - - t.DefaultEncodingSelectionFn = DefaultBinaryEncodingSelectionStrategy - return nil - } -} - -// WithStructuredEncoding sets the encoding selection strategy for -// default encoding selections based on Event, the encoded event will be the -// given version in Structured form. -func WithStructuredEncoding() Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http structured encoding option can not set nil transport") - } - - t.DefaultEncodingSelectionFn = DefaultStructuredEncodingSelectionStrategy - return nil - } -} - -func checkListen(t *Transport, prefix string) error { - switch { - case t.Port != nil: - return fmt.Errorf("%v port already set", prefix) - case t.listener != nil: - return fmt.Errorf("%v listener already set", prefix) - } - return nil -} - -// WithPort sets the listening port for StartReceiver. -// Only one of WithListener or WithPort is allowed. -func WithPort(port int) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http port option can not set nil transport") - } - if port < 0 || port > 65535 { - return fmt.Errorf("http port option was given an invalid port: %d", port) - } - if err := checkListen(t, "http port option"); err != nil { - return err - } - t.setPort(port) - return nil - } -} - -// WithListener sets the listener for StartReceiver. -// Only one of WithListener or WithPort is allowed. -func WithListener(l net.Listener) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http listener option can not set nil transport") - } - if err := checkListen(t, "http port option"); err != nil { - return err - } - t.listener = l - _, err := t.listen() - return err - } -} - -// WithPath sets the path to receive cloudevents on for HTTP transports. -func WithPath(path string) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http path option can not set nil transport") - } - path = strings.TrimSpace(path) - if len(path) == 0 { - return fmt.Errorf("http path option was given an invalid path: %q", path) - } - t.Path = path - return nil - } -} - -// Middleware is a function that takes an existing http.Handler and wraps it in middleware, -// returning the wrapped http.Handler. -type Middleware func(next nethttp.Handler) nethttp.Handler - -// WithMiddleware adds an HTTP middleware to the transport. It may be specified multiple times. -// Middleware is applied to everything before it. For example -// `NewClient(WithMiddleware(foo), WithMiddleware(bar))` would result in `bar(foo(original))`. -func WithMiddleware(middleware Middleware) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http middleware option can not set nil transport") - } - t.middleware = append(t.middleware, middleware) - return nil - } -} - -// WithLongPollTarget sets the receivers URL to perform long polling after -// StartReceiver is called. -func WithLongPollTarget(targetUrl string) Option { - return func(t *Transport) error { - if t == nil { - return fmt.Errorf("http long poll target option can not set nil transport") - } - targetUrl = strings.TrimSpace(targetUrl) - if targetUrl != "" { - var err error - var target *url.URL - target, err = url.Parse(targetUrl) - if err != nil { - return fmt.Errorf("http long poll target option failed to parse target url: %s", err.Error()) - } - - if t.LongPollReq == nil { - t.LongPollReq = &nethttp.Request{ - Method: nethttp.MethodGet, - } - } - t.LongPollReq.URL = target - return nil - } - return fmt.Errorf("http long poll target option was empty string") - } -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/transport.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/transport.go deleted file mode 100644 index f68abb1ad4b..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/transport.go +++ /dev/null @@ -1,689 +0,0 @@ -package http - -import ( - "context" - "errors" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "strconv" - "strings" - "sync" - "time" - - "go.uber.org/zap" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" - cecontext "github.com/cloudevents/sdk-go/pkg/cloudevents/context" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport" -) - -// Transport adheres to transport.Transport. -var _ transport.Transport = (*Transport)(nil) - -const ( - // DefaultShutdownTimeout defines the default timeout given to the http.Server when calling Shutdown. - DefaultShutdownTimeout = time.Minute * 1 - - // TransportName is the name of this transport. - TransportName = "HTTP" -) - -// Transport acts as both a http client and a http handler. -type Transport struct { - // The encoding used to select the codec for outbound events. - Encoding Encoding - - // DefaultEncodingSelectionFn allows for other encoding selection strategies to be injected. - DefaultEncodingSelectionFn EncodingSelector - - // ShutdownTimeout defines the timeout given to the http.Server when calling Shutdown. - // If nil, DefaultShutdownTimeout is used. - ShutdownTimeout *time.Duration - - // Sending - - // Client is the http client that will be used to send requests. - // If nil, the Transport will create a one. - Client *http.Client - // Req is the base http request that is used for http.Do. - // Only .Method, .URL, .Close, and .Header is considered. - // If not set, Req.Method defaults to POST. - // Req.URL or context.WithTarget(url) are required for sending. - Req *http.Request - - // Receiving - - // Receiver is invoked target for incoming events. - Receiver transport.Receiver - // Converter is invoked if the incoming transport receives an undecodable - // message. - Converter transport.Converter - // Port is the port to bind the receiver to. Defaults to 8080. - Port *int - // Path is the path to bind the receiver to. Defaults to "/". - Path string - // Handler is the handler the http Server will use. Use this to reuse the - // http server. If nil, the Transport will create a one. - Handler *http.ServeMux - - // LongPollClient is the http client that will be used to long poll. - // If nil and LongPollReq is set, the Transport will create a one. - LongPollClient *http.Client - // LongPollReq is the base http request that is used for long poll. - // Only .Method, .URL, .Close, and .Header is considered. - // If not set, LongPollReq.Method defaults to GET. - // LongPollReq.URL or context.WithLongPollTarget(url) are required to long - // poll on StartReceiver. - LongPollReq *http.Request - - listener net.Listener - server *http.Server - handlerRegistered bool - codec transport.Codec - // Create Mutex - crMu sync.Mutex - // Receive Mutex - reMu sync.Mutex - - middleware []Middleware -} - -func New(opts ...Option) (*Transport, error) { - t := &Transport{ - Req: &http.Request{ - Method: http.MethodPost, - }, - } - if err := t.applyOptions(opts...); err != nil { - return nil, err - } - return t, nil -} - -func (t *Transport) applyOptions(opts ...Option) error { - for _, fn := range opts { - if err := fn(t); err != nil { - return err - } - } - return nil -} - -func (t *Transport) loadCodec(ctx context.Context) bool { - if t.codec == nil { - t.crMu.Lock() - if t.DefaultEncodingSelectionFn != nil && t.Encoding != Default { - logger := cecontext.LoggerFrom(ctx) - logger.Warn("transport has a DefaultEncodingSelectionFn set but Encoding is not Default. DefaultEncodingSelectionFn will be ignored.") - - t.codec = &Codec{ - Encoding: t.Encoding, - } - } else { - t.codec = &Codec{ - Encoding: t.Encoding, - DefaultEncodingSelectionFn: t.DefaultEncodingSelectionFn, - } - } - t.crMu.Unlock() - } - return true -} - -func copyHeaders(from, to http.Header) { - if from == nil || to == nil { - return - } - for header, values := range from { - for _, value := range values { - to.Add(header, value) - } - } -} - -// Ensure to is a non-nil map before copying -func copyHeadersEnsure(from http.Header, to *http.Header) { - if len(from) > 0 { - if *to == nil { - *to = http.Header{} - } - copyHeaders(from, *to) - } -} - -// Send implements Transport.Send -func (t *Transport) Send(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) { - ctx, r := observability.NewReporter(ctx, reportSend) - rctx, resp, err := t.obsSend(ctx, event) - if err != nil { - r.Error() - } else { - r.OK() - } - return rctx, resp, err -} - -func (t *Transport) obsSend(ctx context.Context, event cloudevents.Event) (context.Context, *cloudevents.Event, error) { - if t.Client == nil { - t.crMu.Lock() - if t.Client == nil { - t.Client = &http.Client{} - } - t.crMu.Unlock() - } - - req := http.Request{ - Header: HeaderFrom(ctx), - } - if t.Req != nil { - req.Method = t.Req.Method - req.URL = t.Req.URL - req.Close = t.Req.Close - req.Host = t.Req.Host - copyHeadersEnsure(t.Req.Header, &req.Header) - } - - // Override the default request with target from context. - if target := cecontext.TargetFrom(ctx); target != nil { - req.URL = target - } - - if ok := t.loadCodec(ctx); !ok { - return WithTransportContext(ctx, NewTransportContextFromResponse(nil)), nil, fmt.Errorf("unknown encoding set on transport: %d", t.Encoding) - } - - msg, err := t.codec.Encode(ctx, event) - if err != nil { - return WithTransportContext(ctx, NewTransportContextFromResponse(nil)), nil, err - } - - if m, ok := msg.(*Message); ok { - m.ToRequest(&req) - return httpDo(ctx, t.Client, &req, func(resp *http.Response, err error) (context.Context, *cloudevents.Event, error) { - rctx := WithTransportContext(ctx, NewTransportContextFromResponse(resp)) - if err != nil { - return rctx, nil, err - } - defer resp.Body.Close() - - body, _ := ioutil.ReadAll(resp.Body) - respEvent, err := t.MessageToEvent(ctx, &Message{ - Header: resp.Header, - Body: body, - }) - if err != nil { - isErr := true - handled := false - if txerr, ok := err.(*transport.ErrTransportMessageConversion); ok { - if !txerr.IsFatal() { - isErr = false - } - if txerr.Handled() { - handled = true - } - } - if isErr { - return rctx, nil, err - } - if handled { - return rctx, nil, nil - } - } - if accepted(resp) { - return rctx, respEvent, nil - } - return rctx, respEvent, fmt.Errorf("error sending cloudevent: %s", resp.Status) - }) - } - return WithTransportContext(ctx, NewTransportContextFromResponse(nil)), nil, fmt.Errorf("failed to encode Event into a Message") -} - -func (t *Transport) MessageToEvent(ctx context.Context, msg *Message) (*cloudevents.Event, error) { - logger := cecontext.LoggerFrom(ctx) - var event *cloudevents.Event - var err error - - if msg.CloudEventsVersion() != "" { - // This is likely a cloudevents encoded message, try to decode it. - if ok := t.loadCodec(ctx); !ok { - err = transport.NewErrTransportMessageConversion("http", fmt.Sprintf("unknown encoding set on transport: %d", t.Encoding), false, true) - logger.Error("failed to load codec", zap.Error(err)) - } else { - event, err = t.codec.Decode(ctx, msg) - } - } else { - err = transport.NewErrTransportMessageConversion("http", "cloudevents version unknown", false, false) - } - - // If codec returns and error, or could not load the correct codec, try - // with the converter if it is set. - if err != nil && t.HasConverter() { - event, err = t.Converter.Convert(ctx, msg, err) - } - - // If err is still set, it means that there was no converter, or the - // converter failed to convert. - if err != nil { - logger.Debug("failed to decode message", zap.Error(err)) - } - - // If event and error are both nil, then there is nothing to do with this event, it was handled. - if err == nil && event == nil { - logger.Debug("convert function returned (nil, nil)") - err = transport.NewErrTransportMessageConversion("http", "convert function handled request", true, false) - } - - return event, err -} - -// SetReceiver implements Transport.SetReceiver -func (t *Transport) SetReceiver(r transport.Receiver) { - t.Receiver = r -} - -// SetConverter implements Transport.SetConverter -func (t *Transport) SetConverter(c transport.Converter) { - t.Converter = c -} - -// HasConverter implements Transport.HasConverter -func (t *Transport) HasConverter() bool { - return t.Converter != nil -} - -// StartReceiver implements Transport.StartReceiver -// NOTE: This is a blocking call. -func (t *Transport) StartReceiver(ctx context.Context) error { - t.reMu.Lock() - defer t.reMu.Unlock() - - if t.LongPollReq != nil { - go func() { _ = t.longPollStart(ctx) }() - } - - if t.Handler == nil { - t.Handler = http.NewServeMux() - } - if !t.handlerRegistered { - // handler.Handle might panic if the user tries to use the same path as the sdk. - t.Handler.Handle(t.GetPath(), t) - t.handlerRegistered = true - } - - addr, err := t.listen() - if err != nil { - return err - } - - t.server = &http.Server{ - Addr: addr.String(), - Handler: attachMiddleware(t.Handler, t.middleware), - } - - // Shutdown - defer func() { - t.server.Close() - t.server = nil - }() - - errChan := make(chan error, 1) - go func() { - errChan <- t.server.Serve(t.listener) - }() - - // wait for the server to return or ctx.Done(). - select { - case <-ctx.Done(): - // Try a gracefully shutdown. - timeout := DefaultShutdownTimeout - if t.ShutdownTimeout != nil { - timeout = *t.ShutdownTimeout - } - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - err := t.server.Shutdown(ctx) - <-errChan // Wait for server goroutine to exit - return err - case err := <-errChan: - return err - } -} - -func (t *Transport) longPollStart(ctx context.Context) error { - logger := cecontext.LoggerFrom(ctx) - logger.Info("starting long poll receiver") - - if t.LongPollClient == nil { - t.crMu.Lock() - t.LongPollClient = &http.Client{} - t.crMu.Unlock() - } - req := &http.Request{ - // TODO: decide if it is ok to use HeaderFrom context here. - Header: HeaderFrom(ctx), - } - if t.LongPollReq != nil { - req.Method = t.LongPollReq.Method - req.URL = t.LongPollReq.URL - req.Close = t.LongPollReq.Close - copyHeaders(t.LongPollReq.Header, req.Header) - } - - // Override the default request with target from context. - if target := LongPollTargetFrom(ctx); target != nil { - req.URL = target - } - - if req.URL == nil { - return errors.New("no long poll target found") - } - - req = req.WithContext(ctx) - msgCh := make(chan Message) - defer close(msgCh) - isClosed := false - - go func(ch chan<- Message) { - for { - if isClosed { - return - } - - if resp, err := t.LongPollClient.Do(req); err != nil { - logger.Errorw("long poll request returned error", err) - uErr := err.(*url.Error) - if uErr.Temporary() || uErr.Timeout() { - continue - } - // TODO: if the transport is throwing errors, we might want to try again. Maybe with a back-off sleep. - // But this error also might be that there was a done on the context. - } else if resp.StatusCode == http.StatusNotModified { - // Keep polling. - continue - } else if resp.StatusCode == http.StatusOK { - body, _ := ioutil.ReadAll(resp.Body) - if err := resp.Body.Close(); err != nil { - logger.Warnw("error closing long poll response body", zap.Error(err)) - } - msg := Message{ - Header: resp.Header, - Body: body, - } - msgCh <- msg - } else { - // TODO: not sure what to do with upstream errors yet. - logger.Errorw("unhandled long poll response", zap.Any("resp", resp)) - } - } - }(msgCh) - - // Attach the long poll request context to the context. - ctx = WithTransportContext(ctx, TransportContext{ - URI: req.URL.RequestURI(), - Host: req.URL.Host, - Method: req.Method, - }) - - for { - select { - case <-ctx.Done(): - isClosed = true - return nil - case msg := <-msgCh: - logger.Debug("got a message", zap.Any("msg", msg)) - if event, err := t.MessageToEvent(ctx, &msg); err != nil { - logger.Errorw("could not convert http message to event", zap.Error(err)) - } else { - logger.Debugw("got an event", zap.Any("event", event)) - // TODO: deliver event. - if _, err := t.invokeReceiver(ctx, *event); err != nil { - logger.Errorw("could not invoke receiver event", zap.Error(err)) - } - } - } - } -} - -// attachMiddleware attaches the HTTP middleware to the specified handler. -func attachMiddleware(h http.Handler, middleware []Middleware) http.Handler { - for _, m := range middleware { - h = m(h) - } - return h -} - -type eventError struct { - ctx context.Context - event *cloudevents.Event - err error -} - -func httpDo(ctx context.Context, client *http.Client, req *http.Request, fn func(*http.Response, error) (context.Context, *cloudevents.Event, error)) (context.Context, *cloudevents.Event, error) { - // Run the HTTP request in a goroutine and pass the response to fn. - c := make(chan eventError, 1) - req = req.WithContext(ctx) - go func() { - rctx, event, err := fn(client.Do(req)) - c <- eventError{ctx: rctx, event: event, err: err} - }() - select { - case <-ctx.Done(): - return ctx, nil, ctx.Err() - case ee := <-c: - return ee.ctx, ee.event, ee.err - } -} - -// accepted is a helper method to understand if the response from the target -// accepted the CloudEvent. -func accepted(resp *http.Response) bool { - if resp.StatusCode >= 200 && resp.StatusCode < 300 { - return true - } - return false -} - -func (t *Transport) invokeReceiver(ctx context.Context, event cloudevents.Event) (*Response, error) { - ctx, r := observability.NewReporter(ctx, reportReceive) - resp, err := t.obsInvokeReceiver(ctx, event) - if err != nil { - r.Error() - } else { - r.OK() - } - return resp, err -} - -func (t *Transport) obsInvokeReceiver(ctx context.Context, event cloudevents.Event) (*Response, error) { - logger := cecontext.LoggerFrom(ctx) - if t.Receiver != nil { - // Note: http does not use eventResp.Reason - eventResp := cloudevents.EventResponse{} - resp := Response{} - - err := t.Receiver.Receive(ctx, event, &eventResp) - if err != nil { - logger.Warnw("got an error from receiver fn", zap.Error(err)) - resp.StatusCode = http.StatusInternalServerError - return &resp, err - } - - if eventResp.Event != nil { - if t.loadCodec(ctx) { - if m, err := t.codec.Encode(ctx, *eventResp.Event); err != nil { - logger.Errorw("failed to encode response from receiver fn", zap.Error(err)) - } else if msg, ok := m.(*Message); ok { - resp.Message = *msg - } - } else { - logger.Error("failed to load codec") - resp.StatusCode = http.StatusInternalServerError - return &resp, err - } - // Look for a transport response context - var trx *TransportResponseContext - if ptrTrx, ok := eventResp.Context.(*TransportResponseContext); ok { - // found a *TransportResponseContext, use it. - trx = ptrTrx - } else if realTrx, ok := eventResp.Context.(TransportResponseContext); ok { - // found a TransportResponseContext, make it a pointer. - trx = &realTrx - } - // If we found a TransportResponseContext, use it. - if trx != nil && trx.Header != nil && len(trx.Header) > 0 { - copyHeadersEnsure(trx.Header, &resp.Message.Header) - } - } - - if eventResp.Status != 0 { - resp.StatusCode = eventResp.Status - } else { - resp.StatusCode = http.StatusAccepted // default is 202 - Accepted - } - return &resp, err - } - return nil, nil -} - -// ServeHTTP implements http.Handler -func (t *Transport) ServeHTTP(w http.ResponseWriter, req *http.Request) { - ctx, r := observability.NewReporter(req.Context(), reportServeHTTP) - // Add the transport context to ctx. - ctx = WithTransportContext(ctx, NewTransportContext(req)) - logger := cecontext.LoggerFrom(ctx) - - body, err := ioutil.ReadAll(req.Body) - if err != nil { - logger.Errorw("failed to handle request", zap.Error(err)) - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(`{"error":"Invalid request"}`)) - r.Error() - return - } - - event, err := t.MessageToEvent(ctx, &Message{ - Header: req.Header, - Body: body, - }) - if err != nil { - isFatal := true - handled := false - if txerr, ok := err.(*transport.ErrTransportMessageConversion); ok { - isFatal = txerr.IsFatal() - handled = txerr.Handled() - } - if isFatal { - logger.Errorw("failed to convert http message to event", zap.Error(err)) - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(fmt.Sprintf(`{"error":%q}`, err.Error()))) - r.Error() - return - } - // if handled, do not pass to receiver. - if handled { - w.WriteHeader(http.StatusNoContent) - r.OK() - return - } - } - if event == nil { - logger.Error("failed to get non-nil event from MessageToEvent") - w.WriteHeader(http.StatusBadRequest) - r.Error() - return - } - - resp, err := t.invokeReceiver(ctx, *event) - if err != nil { - logger.Warnw("error returned from invokeReceiver", zap.Error(err)) - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte(fmt.Sprintf(`{"error":%q}`, err.Error()))) - r.Error() - return - } - - if resp != nil { - if t.Req != nil { - copyHeaders(t.Req.Header, w.Header()) - } - if len(resp.Message.Header) > 0 { - copyHeaders(resp.Message.Header, w.Header()) - } - - status := http.StatusAccepted - if resp.StatusCode >= 200 && resp.StatusCode < 600 { - status = resp.StatusCode - } - w.Header().Add("Content-Length", strconv.Itoa(len(resp.Message.Body))) - w.WriteHeader(status) - - if len(resp.Message.Body) > 0 { - if _, err := w.Write(resp.Message.Body); err != nil { - r.Error() - return - } - } - - r.OK() - return - } - - w.WriteHeader(http.StatusNoContent) - r.OK() -} - -// GetPort returns the listening port. -// Returns -1 if there is a listening error. -// Note this will call net.Listen() if the listener is not already started. -func (t *Transport) GetPort() int { - // Ensure we have a listener and therefore a port. - if _, err := t.listen(); err == nil || t.Port != nil { - return *t.Port - } - return -1 -} - -func (t *Transport) setPort(port int) { - if t.Port == nil { - t.Port = new(int) - } - *t.Port = port -} - -// listen if not already listening, update t.Port -func (t *Transport) listen() (net.Addr, error) { - if t.listener == nil { - port := 8080 - if t.Port != nil { - port = *t.Port - if port < 0 || port > 65535 { - return nil, fmt.Errorf("invalid port %d", port) - } - } - var err error - if t.listener, err = net.Listen("tcp", fmt.Sprintf(":%d", port)); err != nil { - return nil, err - } - } - addr := t.listener.Addr() - if tcpAddr, ok := addr.(*net.TCPAddr); ok { - t.setPort(tcpAddr.Port) - } - return addr, nil -} - -// GetPath returns the path the transport is hosted on. If the path is '/', -// the transport will handle requests on any URI. To discover the true path -// a request was received on, inspect the context from Receive(cxt, ...) with -// TransportContextFrom(ctx). -func (t *Transport) GetPath() string { - path := strings.TrimSpace(t.Path) - if len(path) > 0 { - return path - } - return "/" // default -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/message.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/message.go deleted file mode 100644 index e2ed55c970f..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/message.go +++ /dev/null @@ -1,9 +0,0 @@ -package transport - -// Message is the abstract transport message wrapper. -type Message interface { - // CloudEventsVersion returns the version of the CloudEvent. - CloudEventsVersion() string - - // TODO maybe get encoding -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/transport.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/transport.go deleted file mode 100644 index a08d5a12e52..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/transport.go +++ /dev/null @@ -1,44 +0,0 @@ -package transport - -import ( - "context" - - "github.com/cloudevents/sdk-go/pkg/cloudevents" -) - -// Transport is the interface for transport sender to send the converted Message -// over the underlying transport. -type Transport interface { - Send(context.Context, cloudevents.Event) (context.Context, *cloudevents.Event, error) - - SetReceiver(Receiver) - StartReceiver(context.Context) error - - // SetConverter sets the delegate to use for converting messages that have - // failed to be decoded from known codecs for this transport. - SetConverter(Converter) - // HasConverter is true when a non-nil converter has been set. - HasConverter() bool -} - -// Receiver is an interface to define how a transport will invoke a listener -// of incoming events. -type Receiver interface { - Receive(context.Context, cloudevents.Event, *cloudevents.EventResponse) error -} - -// ReceiveFunc wraps a function as a Receiver object. -type ReceiveFunc func(ctx context.Context, e cloudevents.Event, er *cloudevents.EventResponse) error - -// Receive implements Receiver.Receive -func (f ReceiveFunc) Receive(ctx context.Context, e cloudevents.Event, er *cloudevents.EventResponse) error { - return f(ctx, e, er) -} - -// Converter is an interface to define how a transport delegate to convert an -// non-understood transport message from the internal codecs. Providing a -// Converter allows incoming requests to be bridged to CloudEvents format if -// they have not been sent as an event in CloudEvents format. -type Converter interface { - Convert(context.Context, Message, error) (*cloudevents.Event, error) -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/urlref.go b/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/urlref.go deleted file mode 100644 index 2578801cd83..00000000000 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/urlref.go +++ /dev/null @@ -1,79 +0,0 @@ -package types - -import ( - "encoding/json" - "encoding/xml" - "fmt" - "net/url" -) - -// URLRef is a wrapper to url.URL. It is intended to enforce compliance with -// the CloudEvents spec for their definition of URI-Reference. Custom -// marshal methods are implemented to ensure the outbound URLRef object is -// is a flat string. -// -// deprecated: use URIRef. -type URLRef struct { - url.URL -} - -// ParseURLRef attempts to parse the given string as a URI-Reference. -func ParseURLRef(u string) *URLRef { - if u == "" { - return nil - } - pu, err := url.Parse(u) - if err != nil { - return nil - } - return &URLRef{URL: *pu} -} - -// MarshalJSON implements a custom json marshal method used when this type is -// marshaled using json.Marshal. -func (u URLRef) MarshalJSON() ([]byte, error) { - b := fmt.Sprintf("%q", u.String()) - return []byte(b), nil -} - -// UnmarshalJSON implements the json unmarshal method used when this type is -// unmarshaled using json.Unmarshal. -func (u *URLRef) UnmarshalJSON(b []byte) error { - var ref string - if err := json.Unmarshal(b, &ref); err != nil { - return err - } - r := ParseURLRef(ref) - if r != nil { - *u = *r - } - return nil -} - -// MarshalXML implements a custom xml marshal method used when this type is -// marshaled using xml.Marshal. -func (u URLRef) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - return e.EncodeElement(u.String(), start) -} - -// UnmarshalXML implements the xml unmarshal method used when this type is -// unmarshaled using xml.Unmarshal. -func (u *URLRef) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - var ref string - if err := d.DecodeElement(&ref, &start); err != nil { - return err - } - r := ParseURLRef(ref) - if r != nil { - *u = *r - } - return nil -} - -// String returns the full string representation of the URI-Reference. -func (u *URLRef) String() string { - if u == nil { - return "" - } - return u.URL.String() -} diff --git a/third_party/knative.dev/eventing-contrib/pkg/kncloudevents/LICENSE b/vendor/github.com/cloudevents/sdk-go/v2/LICENSE similarity index 100% rename from third_party/knative.dev/eventing-contrib/pkg/kncloudevents/LICENSE rename to vendor/github.com/cloudevents/sdk-go/v2/LICENSE diff --git a/vendor/github.com/cloudevents/sdk-go/v2/alias.go b/vendor/github.com/cloudevents/sdk-go/v2/alias.go new file mode 100644 index 00000000000..6d15c4e1abe --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/alias.go @@ -0,0 +1,145 @@ +package v2 + +// Package cloudevents alias' common functions and types to improve discoverability and reduce +// the number of imports for simple HTTP clients. + +import ( + "github.com/cloudevents/sdk-go/v2/binding" + "github.com/cloudevents/sdk-go/v2/client" + "github.com/cloudevents/sdk-go/v2/context" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/observability" + "github.com/cloudevents/sdk-go/v2/protocol" + "github.com/cloudevents/sdk-go/v2/protocol/http" + "github.com/cloudevents/sdk-go/v2/types" +) + +// Client + +type ClientOption client.Option +type Client = client.Client + +// Event + +type Event = event.Event + +// Context + +type EventContext = event.EventContext +type EventContextV1 = event.EventContextV1 +type EventContextV03 = event.EventContextV03 + +// Custom Types + +type Timestamp = types.Timestamp +type URIRef = types.URIRef + +// HTTP Protocol + +type HTTPOption http.Option + +type HTTPProtocol = http.Protocol + +// Encoding + +type Encoding = binding.Encoding + +// Message + +type Message = binding.Message + +const ( + // ReadEncoding + + ApplicationXML = event.ApplicationXML + ApplicationJSON = event.ApplicationJSON + TextPlain = event.TextPlain + ApplicationCloudEventsJSON = event.ApplicationCloudEventsJSON + ApplicationCloudEventsBatchJSON = event.ApplicationCloudEventsBatchJSON + Base64 = event.Base64 + + // Event Versions + + VersionV1 = event.CloudEventsVersionV1 + VersionV03 = event.CloudEventsVersionV03 + + // Encoding + + EncodingBinary = binding.EncodingBinary + EncodingStructured = binding.EncodingStructured +) + +var ( + + // ContentType Helpers + + StringOfApplicationJSON = event.StringOfApplicationJSON + StringOfApplicationXML = event.StringOfApplicationXML + StringOfTextPlain = event.StringOfTextPlain + StringOfApplicationCloudEventsJSON = event.StringOfApplicationCloudEventsJSON + StringOfApplicationCloudEventsBatchJSON = event.StringOfApplicationCloudEventsBatchJSON + StringOfBase64 = event.StringOfBase64 + + // Client Creation + + NewClient = client.New + NewClientObserved = client.NewObserved + NewDefaultClient = client.NewDefault + NewHTTPReceiveHandler = client.NewHTTPReceiveHandler + + // Client Options + + WithEventDefaulter = client.WithEventDefaulter + WithUUIDs = client.WithUUIDs + WithTimeNow = client.WithTimeNow + WithTracePropagation = client.WithTracePropagation() + + // Event Creation + + NewEvent = event.New + NewResult = protocol.NewResult + + NewHTTPResult = http.NewResult + + // Message Creation + + ToMessage = binding.ToMessage + + // HTTP Messages + + WriteHTTPRequest = http.WriteRequest + + // Tracing + + EnableTracing = observability.EnableTracing + + // Context + + ContextWithTarget = context.WithTarget + TargetFromContext = context.TargetFrom + WithEncodingBinary = binding.WithForceBinary + WithEncodingStructured = binding.WithForceStructured + + // Custom Types + + ParseTimestamp = types.ParseTimestamp + ParseURIRef = types.ParseURIRef + ParseURI = types.ParseURI + + // HTTP Protocol + + NewHTTP = http.New + + // HTTP Protocol Options + + WithTarget = http.WithTarget + WithHeader = http.WithHeader + WithShutdownTimeout = http.WithShutdownTimeout + //WithEncoding = http.WithEncoding + //WithStructuredEncoding = http.WithStructuredEncoding // TODO: expose new way + WithPort = http.WithPort + WithPath = http.WithPath + WithMiddleware = http.WithMiddleware + WithListener = http.WithListener + WithRoundTripper = http.WithRoundTripper +) diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/binary_writer.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/binary_writer.go new file mode 100644 index 00000000000..5d2fafe5d68 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/binary_writer.go @@ -0,0 +1,39 @@ +package binding + +import ( + "context" + "io" + + "github.com/cloudevents/sdk-go/v2/binding/spec" +) + +// BinaryWriter is used to visit a binary Message and generate a new representation. +// +// Protocols that supports binary encoding should implement this interface to implement direct +// binary to binary encoding and event to binary encoding. +// +// Start() and End() methods are invoked every time this BinaryWriter implementation is used to visit a Message +type BinaryWriter interface { + // Method invoked at the beginning of the visit. Useful to perform initial memory allocations + Start(ctx context.Context) error + + // Set a standard attribute. + // + // The value can either be the correct golang type for the attribute, or a canonical + // string encoding. See package types to perform the needed conversions + SetAttribute(attribute spec.Attribute, value interface{}) error + + // Set an extension attribute. + // + // The value can either be the correct golang type for the attribute, or a canonical + // string encoding. See package types to perform the needed conversions + SetExtension(name string, value interface{}) error + + // SetData receives an io.Reader for the data attribute. + // io.Reader is not invoked when the data attribute is empty + SetData(data io.Reader) error + + // End method is invoked only after the whole encoding process ends successfully. + // If it fails, it's never invoked. It can be used to finalize the message. + End(ctx context.Context) error +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/doc.go new file mode 100644 index 00000000000..e69902d0e9a --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/doc.go @@ -0,0 +1,64 @@ +package binding + +/* + +Package binding defines interfaces for protocol bindings. + +NOTE: Most applications that emit or consume events should use the ../client +package, which provides a simpler API to the underlying binding. + +The interfaces in this package provide extra encoding and protocol information +to allow efficient forwarding and end-to-end reliable delivery between a +Receiver and a Sender belonging to different bindings. This is useful for +intermediary applications that route or forward events, but not necessary for +most "endpoint" applications that emit or consume events. + +Protocol Bindings + +A protocol binding usually implements a Message, a Sender and Receiver, a StructuredWriter and a BinaryWriter (depending on the supported encodings of the protocol) and an Write[ProtocolMessage] method. + +Read and write events + +The core of this package is the binding.Message interface. +Through binding.MessageReader It defines how to read a protocol specific message for an +encoded event in structured mode or binary mode. +The entity who receives a protocol specific data structure representing a message +(e.g. an HttpRequest) encapsulates it in a binding.Message implementation using a NewMessage method (e.g. http.NewMessage). +Then the entity that wants to send the binding.Message back on the wire, +translates it back to the protocol specific data structure (e.g. a Kafka ConsumerMessage), using +the writers BinaryWriter and StructuredWriter specific to that protocol. +Binding implementations exposes their writers +through a specific Write[ProtocolMessage] function (e.g. kafka.EncodeProducerMessage), +in order to simplify the encoding process. + +The encoding process can be customized in order to mutate the final result with binding.TransformerFactory. +A bunch of these are provided directly by the binding/transformer module. + +Usually binding.Message implementations can be encoded only one time, because the encoding process drain the message itself. +In order to consume a message several times, the binding/buffering module provides several APIs to buffer the Message. + +A message can be converted to an event.Event using binding.ToEvent() method. +An event.Event can be used as Message casting it to binding.EventMessage. + +In order to simplify the encoding process for each protocol, this package provide several utility methods like binding.Write and binding.DirectWrite. +The binding.Write method tries to preserve the structured/binary encoding, in order to be as much efficient as possible. + +Messages can be eventually wrapped to change their behaviours and binding their lifecycle, like the binding.FinishMessage. +Every Message wrapper implements the MessageWrapper interface + +Sender and Receiver + +A Receiver receives protocol specific messages and wraps them to into binding.Message implementations. + +A Sender converts arbitrary Message implementations to a protocol-specific form using the protocol specific Write method +and sends them. + +Message and ExactlyOnceMessage provide methods to allow acknowledgments to +propagate when a reliable messages is forwarded from a Receiver to a Sender. +QoS 0 (unreliable), 1 (at-least-once) and 2 (exactly-once) are supported. + +Transport + +A binding implementation providing Sender and Receiver implementations can be used as a Transport through the BindingTransport adapter. + +*/ diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/encoding.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/encoding.go new file mode 100644 index 00000000000..b5d3e3a1ca6 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/encoding.go @@ -0,0 +1,26 @@ +package binding + +import "errors" + +// Encoding enum specifies the type of encodings supported by binding interfaces +type Encoding int + +const ( + // Binary encoding as specified in https://github.com/cloudevents/spec/blob/master/spec.md#message + EncodingBinary Encoding = iota + // Structured encoding as specified in https://github.com/cloudevents/spec/blob/master/spec.md#message + EncodingStructured + // Message is an instance of EventMessage or it contains EventMessage nested (through MessageWrapper) + EncodingEvent + // When the encoding is unknown (which means that the message is a non-event) + EncodingUnknown +) + +// Error to specify that or the Message is not an event or it is encoded with an unknown encoding +var ErrUnknownEncoding = errors.New("unknown Message encoding") + +// ErrNotStructured returned by Message.Structured for non-structured messages. +var ErrNotStructured = errors.New("message is not in structured mode") + +// ErrNotBinary returned by Message.Binary for non-binary messages. +var ErrNotBinary = errors.New("message is not in binary mode") diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/event_message.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/event_message.go new file mode 100644 index 00000000000..0d1a3b4d001 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/event_message.go @@ -0,0 +1,90 @@ +package binding + +import ( + "bytes" + "context" + + "github.com/cloudevents/sdk-go/v2/binding/format" + "github.com/cloudevents/sdk-go/v2/binding/spec" + "github.com/cloudevents/sdk-go/v2/event" +) + +const ( + FORMAT_EVENT_STRUCTURED = "FORMAT_EVENT_STRUCTURED" +) + +// EventMessage type-converts a event.Event object to implement Message. +// This allows local event.Event objects to be sent directly via Sender.Send() +// s.Send(ctx, binding.EventMessage(e)) +// When an event is wrapped into a EventMessage, the original event could be +// potentially mutated. If you need to use the Event again, after wrapping it into +// an Event message, you should copy it before +type EventMessage event.Event + +func ToMessage(e *event.Event) Message { + return (*EventMessage)(e) +} + +func (m *EventMessage) ReadEncoding() Encoding { + return EncodingEvent +} + +func (m *EventMessage) ReadStructured(ctx context.Context, builder StructuredWriter) error { + f := GetOrDefaultFromCtx(ctx, FORMAT_EVENT_STRUCTURED, format.JSON).(format.Format) + b, err := f.Marshal((*event.Event)(m)) + if err != nil { + return err + } + return builder.SetStructuredEvent(ctx, f, bytes.NewReader(b)) +} + +func (m *EventMessage) ReadBinary(ctx context.Context, b BinaryWriter) (err error) { + err = b.Start(ctx) + if err != nil { + return err + } + err = eventContextToBinaryWriter(m.Context, b) + if err != nil { + return err + } + // Pass the body + body := (*event.Event)(m).Data() + if len(body) > 0 { + err = b.SetData(bytes.NewReader(body)) + if err != nil { + return err + } + } + return b.End(ctx) +} + +func eventContextToBinaryWriter(c event.EventContext, b BinaryWriter) (err error) { + // Pass all attributes + sv := spec.VS.Version(c.GetSpecVersion()) + for _, a := range sv.Attributes() { + value := a.Get(c) + if value != nil { + err = b.SetAttribute(a, value) + } + if err != nil { + return err + } + } + // Pass all extensions + for k, v := range c.GetExtensions() { + err = b.SetExtension(k, v) + if err != nil { + return err + } + } + return nil +} + +func (*EventMessage) Finish(error) error { return nil } + +var _ Message = (*EventMessage)(nil) // Test it conforms to the interface + +// Configure which format to use when marshalling the event to structured mode +func UseFormatForEvent(ctx context.Context, f format.Format) context.Context { + return context.WithValue(ctx, FORMAT_EVENT_STRUCTURED, f) +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/finish_message.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/finish_message.go new file mode 100644 index 00000000000..3c4efc5c0aa --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/finish_message.go @@ -0,0 +1,27 @@ +package binding + +type finishMessage struct { + Message + finish func(error) +} + +func (m *finishMessage) GetWrappedMessage() Message { + return m.Message +} + +func (m *finishMessage) Finish(err error) error { + err2 := m.Message.Finish(err) // Finish original message first + if m.finish != nil { + m.finish(err) // Notify callback + } + return err2 +} + +var _ MessageWrapper = (*finishMessage)(nil) + +// WithFinish returns a wrapper for m that calls finish() and +// m.Finish() in its Finish(). +// Allows code to be notified when a message is Finished. +func WithFinish(m Message, finish func(error)) Message { + return &finishMessage{Message: m, finish: finish} +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/format/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/format/doc.go new file mode 100644 index 00000000000..61058dfadc6 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/format/doc.go @@ -0,0 +1,8 @@ +package format + +/* +Package format formats structured events. + +The "application/cloudevents+json" format is built-in and always +available. Other formats may be added. +*/ diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/format/format.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/format/format.go new file mode 100644 index 00000000000..2f275c98338 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/format/format.go @@ -0,0 +1,71 @@ +package format + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/cloudevents/sdk-go/v2/event" +) + +// Format marshals and unmarshals structured events to bytes. +type Format interface { + // MediaType identifies the format + MediaType() string + // Marshal event to bytes + Marshal(*event.Event) ([]byte, error) + // Unmarshal bytes to event + Unmarshal([]byte, *event.Event) error +} + +// Prefix for event-format media types. +const Prefix = "application/cloudevents" + +// IsFormat returns true if mediaType begins with "application/cloudevents" +func IsFormat(mediaType string) bool { return strings.HasPrefix(mediaType, Prefix) } + +// JSON is the built-in "application/cloudevents+json" format. +var JSON = jsonFmt{} + +type jsonFmt struct{} + +func (jsonFmt) MediaType() string { return event.ApplicationCloudEventsJSON } + +func (jsonFmt) Marshal(e *event.Event) ([]byte, error) { return json.Marshal(e) } +func (jsonFmt) Unmarshal(b []byte, e *event.Event) error { + return json.Unmarshal(b, e) +} + +// built-in formats +var formats map[string]Format + +func init() { + formats = map[string]Format{} + Add(JSON) +} + +// Lookup returns the format for mediaType, or nil if not found. +func Lookup(mediaType string) Format { return formats[mediaType] } + +func unknown(mediaType string) error { + return fmt.Errorf("unknown event format media-type %#v", mediaType) +} + +// Add a new Format. It can be retrieved by Lookup(f.MediaType()) +func Add(f Format) { formats[f.MediaType()] = f } + +// Marshal an event to bytes using the mediaType event format. +func Marshal(mediaType string, e *event.Event) ([]byte, error) { + if f := formats[mediaType]; f != nil { + return f.Marshal(e) + } + return nil, unknown(mediaType) +} + +// Unmarshal bytes to an event using the mediaType event format. +func Unmarshal(mediaType string, b []byte, e *event.Event) error { + if f := formats[mediaType]; f != nil { + return f.Unmarshal(b, e) + } + return unknown(mediaType) +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/message.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/message.go new file mode 100644 index 00000000000..e37cd3ca1d5 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/message.go @@ -0,0 +1,99 @@ +package binding + +import "context" + +// The ReadStructured and ReadBinary methods allows to perform an optimized encoding of a Message to a specific data structure. +// A Sender should try each method of interest and fall back to binding.ToEvent() if none are supported. +// An out of the box algorithm is provided for writing a message: binding.Write(). +type MessageReader interface { + // Return the type of the message Encoding. + // The encoding should be preferably computed when the message is constructed. + ReadEncoding() Encoding + + // ReadStructured transfers a structured-mode event to a StructuredWriter. + // It must return ErrNotStructured if message is not in structured mode. + // + // Returns a different err if something wrong happened while trying to read the structured event. + // In this case, the caller must Finish the message with appropriate error. + // + // This allows Senders to avoid re-encoding messages that are + // already in suitable structured form. + ReadStructured(context.Context, StructuredWriter) error + + // ReadBinary transfers a binary-mode event to an BinaryWriter. + // It must return ErrNotBinary if message is not in binary mode. + // + // Returns a different err if something wrong happened while trying to read the binary event + // In this case, the caller must Finish the message with appropriate error + // + // This allows Senders to avoid re-encoding messages that are + // already in suitable binary form. + ReadBinary(context.Context, BinaryWriter) error +} + +// Message is the interface to a binding-specific message containing an event. +// +// Reliable Delivery +// +// There are 3 reliable qualities of service for messages: +// +// 0/at-most-once/unreliable: messages can be dropped silently. +// +// 1/at-least-once: messages are not dropped without signaling an error +// to the sender, but they may be duplicated in the event of a re-send. +// +// 2/exactly-once: messages are never dropped (without error) or +// duplicated, as long as both sending and receiving ends maintain +// some binding-specific delivery state. Whether this is persisted +// depends on the configuration of the binding implementations. +// +// The Message interface supports QoS 0 and 1, the ExactlyOnceMessage interface +// supports QoS 2 +// +// Message includes the MessageReader interface to read messages. Every binding.Message implementation *must* specify if the message can be accessed one or more times. +// +// When a Message can be forgotten by the entity who produced the message, Message.Finish() *must* be invoked. +type Message interface { + MessageReader + + // Finish *must* be called when message from a Receiver can be forgotten by + // the receiver. A QoS 1 sender should not call Finish() until it gets an acknowledgment of + // receipt on the underlying transport. For QoS 2 see ExactlyOnceMessage. + // + // Note that, depending on the Message implementation, forgetting to Finish the message + // could produce memory/resources leaks! + // + // Passing a non-nil err indicates sending or processing failed. + // A non-nil return indicates that the message was not accepted + // by the receivers peer. + Finish(error) error +} + +// ExactlyOnceMessage is implemented by received Messages +// that support QoS 2. Only transports that support QoS 2 need to +// implement or use this interface. +type ExactlyOnceMessage interface { + Message + + // Received is called by a forwarding QoS2 Sender when it gets + // acknowledgment of receipt (e.g. AMQP 'accept' or MQTT PUBREC) + // + // The receiver must call settle(nil) when it get's the ack-of-ack + // (e.g. AMQP 'settle' or MQTT PUBCOMP) or settle(err) if the + // transfer fails. + // + // Finally the Sender calls Finish() to indicate the message can be + // discarded. + // + // If sending fails, or if the sender does not support QoS 2, then + // Finish() may be called without any call to Received() + Received(settle func(error)) +} + +// Message Wrapper interface is used to walk through a decorated Message and unwrap it. +type MessageWrapper interface { + Message + + // Method to get the wrapped message + GetWrappedMessage() Message +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/attributes.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/attributes.go new file mode 100644 index 00000000000..20ec1ce92fe --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/attributes.go @@ -0,0 +1,136 @@ +package spec + +import ( + "fmt" + "time" + + "github.com/cloudevents/sdk-go/v2/event" + + "github.com/cloudevents/sdk-go/v2/types" +) + +// Kind is a version-independent identifier for a CloudEvent context attribute. +type Kind uint8 + +const ( + // Required cloudevents attributes + ID Kind = iota + Source + SpecVersion + Type + // Optional cloudevents attributes + DataContentType + DataSchema + Subject + Time +) +const nAttrs = int(Time) + 1 + +var kindNames = [nAttrs]string{ + "id", + "source", + "specversion", + "type", + "datacontenttype", + "dataschema", + "subject", + "time", +} + +// String is a human-readable string, for a valid attribute name use Attribute.Name +func (k Kind) String() string { return kindNames[k] } + +// IsRequired returns true for attributes defined as "required" by the CE spec. +func (k Kind) IsRequired() bool { return k < DataContentType } + +// Attribute is a named attribute accessor. +// The attribute name is specific to a Version. +type Attribute interface { + Kind() Kind + // Name of the attribute with respect to the current spec Version() with prefix + PrefixedName() string + // Name of the attribute with respect to the current spec Version() + Name() string + // Version of the spec that this attribute belongs to + Version() Version + // Get the value of this attribute from an event context + Get(event.EventContextReader) interface{} + // Set the value of this attribute on an event context + Set(event.EventContextWriter, interface{}) error + // Delete this attribute from and event context, when possible + Delete(event.EventContextWriter) error +} + +// accessor provides Kind, Get, Set. +type accessor interface { + Kind() Kind + Get(event.EventContextReader) interface{} + Set(event.EventContextWriter, interface{}) error + Delete(event.EventContextWriter) error +} + +var acc = [nAttrs]accessor{ + &aStr{aKind(ID), event.EventContextReader.GetID, event.EventContextWriter.SetID}, + &aStr{aKind(Source), event.EventContextReader.GetSource, event.EventContextWriter.SetSource}, + &aStr{aKind(SpecVersion), event.EventContextReader.GetSpecVersion, func(writer event.EventContextWriter, s string) error { return nil }}, + &aStr{aKind(Type), event.EventContextReader.GetType, event.EventContextWriter.SetType}, + &aStr{aKind(DataContentType), event.EventContextReader.GetDataContentType, event.EventContextWriter.SetDataContentType}, + &aStr{aKind(DataSchema), event.EventContextReader.GetDataSchema, event.EventContextWriter.SetDataSchema}, + &aStr{aKind(Subject), event.EventContextReader.GetSubject, event.EventContextWriter.SetSubject}, + &aTime{aKind(Time), event.EventContextReader.GetTime, event.EventContextWriter.SetTime}, +} + +// aKind implements Kind() +type aKind Kind + +func (kind aKind) Kind() Kind { return Kind(kind) } + +type aStr struct { + aKind + get func(event.EventContextReader) string + set func(event.EventContextWriter, string) error +} + +func (a *aStr) Get(c event.EventContextReader) interface{} { + if s := a.get(c); s != "" { + return s + } + return nil // Treat blank as missing +} + +func (a *aStr) Set(c event.EventContextWriter, v interface{}) error { + s, err := types.ToString(v) + if err != nil { + return fmt.Errorf("invalid value for %s: %#v", a.Kind(), v) + } + return a.set(c, s) +} + +func (a *aStr) Delete(c event.EventContextWriter) error { + return a.set(c, "") +} + +type aTime struct { + aKind + get func(event.EventContextReader) time.Time + set func(event.EventContextWriter, time.Time) error +} + +func (a *aTime) Get(c event.EventContextReader) interface{} { + if v := a.get(c); !v.IsZero() { + return v + } + return nil // Treat zero time as missing. +} + +func (a *aTime) Set(c event.EventContextWriter, v interface{}) error { + t, err := types.ToTime(v) + if err != nil { + return fmt.Errorf("invalid value for %s: %#v", a.Kind(), v) + } + return a.set(c, t) +} + +func (a *aTime) Delete(c event.EventContextWriter) error { + return a.set(c, time.Time{}) +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/doc.go new file mode 100644 index 00000000000..618098194d2 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/doc.go @@ -0,0 +1,9 @@ +package spec + +/* +Package spec provides spec-version metadata. + +For use by code that maps events using (prefixed) attribute name strings. +Supports handling multiple spec versions uniformly. + +*/ diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/spec.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/spec.go new file mode 100644 index 00000000000..4de589185e5 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/spec/spec.go @@ -0,0 +1,184 @@ +package spec + +import ( + "strings" + + "github.com/cloudevents/sdk-go/v2/event" +) + +// Version provides meta-data for a single spec-version. +type Version interface { + // String name of the version, e.g. "1.0" + String() string + // Prefix for attribute names. + Prefix() string + // Attribute looks up a prefixed attribute name (case insensitive). + // Returns nil if not found. + Attribute(prefixedName string) Attribute + // Attribute looks up the attribute from kind. + // Returns nil if not found. + AttributeFromKind(kind Kind) Attribute + // Attributes returns all the context attributes for this version. + Attributes() []Attribute + // Convert translates a context to this version. + Convert(event.EventContextConverter) event.EventContext + // NewContext returns a new context for this version. + NewContext() event.EventContext + // SetAttribute sets named attribute to value. + // + // Name is case insensitive. + // Does nothing if name does not start with prefix. + SetAttribute(context event.EventContextWriter, name string, value interface{}) error +} + +// Versions contains all known versions with the same attribute prefix. +type Versions struct { + prefix string + all []Version + m map[string]Version +} + +// Versions returns the list of all known versions, most recent first. +func (vs *Versions) Versions() []Version { return vs.all } + +// Version returns the named version. +func (vs *Versions) Version(name string) Version { + return vs.m[name] +} + +// Latest returns the latest Version +func (vs *Versions) Latest() Version { return vs.all[0] } + +// PrefixedSpecVersionName returns the specversion attribute PrefixedName +func (vs *Versions) PrefixedSpecVersionName() string { return vs.prefix + "specversion" } + +// Prefix is the lowercase attribute name prefix. +func (vs *Versions) Prefix() string { return vs.prefix } + +type attribute struct { + accessor + name string + version Version +} + +func (a *attribute) PrefixedName() string { return a.version.Prefix() + a.name } +func (a *attribute) Name() string { return a.name } +func (a *attribute) Version() Version { return a.version } + +type version struct { + prefix string + context event.EventContext + convert func(event.EventContextConverter) event.EventContext + attrMap map[string]Attribute + attrs []Attribute +} + +func (v *version) Attribute(name string) Attribute { return v.attrMap[strings.ToLower(name)] } +func (v *version) Attributes() []Attribute { return v.attrs } +func (v *version) String() string { return v.context.GetSpecVersion() } +func (v *version) Prefix() string { return v.prefix } +func (v *version) NewContext() event.EventContext { return v.context.Clone() } + +// HasPrefix is a case-insensitive prefix check. +func (v *version) HasPrefix(name string) bool { + return strings.HasPrefix(strings.ToLower(name), v.prefix) +} + +func (v *version) Convert(c event.EventContextConverter) event.EventContext { return v.convert(c) } + +func (v *version) SetAttribute(c event.EventContextWriter, name string, value interface{}) error { + if a := v.Attribute(name); a != nil { // Standard attribute + return a.Set(c, value) + } + name = strings.ToLower(name) + var err error + if v.HasPrefix(name) { // Extension attribute + return c.SetExtension(strings.TrimPrefix(name, v.prefix), value) + } + return err +} + +func (v *version) AttributeFromKind(kind Kind) Attribute { + for _, a := range v.Attributes() { + if a.Kind() == kind { + return a + } + } + return nil +} + +func newVersion( + prefix string, + context event.EventContext, + convert func(event.EventContextConverter) event.EventContext, + attrs ...*attribute, +) *version { + v := &version{ + prefix: strings.ToLower(prefix), + context: context, + convert: convert, + attrMap: map[string]Attribute{}, + attrs: make([]Attribute, len(attrs)), + } + for i, a := range attrs { + a.version = v + v.attrs[i] = a + v.attrMap[strings.ToLower(a.PrefixedName())] = a + } + return v +} + +// WithPrefix returns a set of versions with prefix added to all attribute names. +func WithPrefix(prefix string) *Versions { + attr := func(name string, kind Kind) *attribute { + return &attribute{accessor: acc[kind], name: name} + } + vs := &Versions{ + m: map[string]Version{}, + prefix: prefix, + all: []Version{ + newVersion(prefix, event.EventContextV1{}.AsV1(), + func(c event.EventContextConverter) event.EventContext { return c.AsV1() }, + attr("id", ID), + attr("source", Source), + attr("specversion", SpecVersion), + attr("type", Type), + attr("datacontenttype", DataContentType), + attr("dataschema", DataSchema), + attr("subject", Subject), + attr("time", Time), + ), + newVersion(prefix, event.EventContextV03{}.AsV03(), + func(c event.EventContextConverter) event.EventContext { return c.AsV03() }, + attr("specversion", SpecVersion), + attr("type", Type), + attr("source", Source), + attr("schemaurl", DataSchema), + attr("subject", Subject), + attr("id", ID), + attr("time", Time), + attr("datacontenttype", DataContentType), + ), + }, + } + for _, v := range vs.all { + vs.m[v.String()] = v + } + return vs +} + +// New returns a set of versions +func New() *Versions { return WithPrefix("") } + +// Built-in un-prefixed versions. +var ( + VS *Versions + V03 Version + V1 Version +) + +func init() { + VS = New() + V03 = VS.Version("0.3") + V1 = VS.Version("1.0") +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/structured_writer.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/structured_writer.go new file mode 100644 index 00000000000..8cf2bbe3e36 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/structured_writer.go @@ -0,0 +1,17 @@ +package binding + +import ( + "context" + "io" + + "github.com/cloudevents/sdk-go/v2/binding/format" +) + +// StructuredWriter is used to visit a structured Message and generate a new representation. +// +// Protocols that supports structured encoding should implement this interface to implement direct +// structured to structured encoding and event to structured encoding. +type StructuredWriter interface { + // Event receives an io.Reader for the whole event. + SetStructuredEvent(ctx context.Context, format format.Format, event io.Reader) error +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/to_event.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/to_event.go new file mode 100644 index 00000000000..603b999ef10 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/to_event.go @@ -0,0 +1,127 @@ +package binding + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + + "github.com/cloudevents/sdk-go/v2/binding/format" + "github.com/cloudevents/sdk-go/v2/binding/spec" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/types" +) + +// Generic error when a conversion of a Message to an Event fails +var ErrCannotConvertToEvent = errors.New("cannot convert message to event") + +// Translates a Message with a valid Structured or Binary representation to an Event. +// This function returns the Event generated from the Message and the original encoding of the message or +// an error that points the conversion error. +// transformers can be nil and this function guarantees that they are invoked only once during the encoding process. +func ToEvent(ctx context.Context, message MessageReader, transformers ...TransformerFactory) (*event.Event, error) { + messageEncoding := message.ReadEncoding() + if messageEncoding == EncodingEvent { + m := message + for m != nil { + if em, ok := m.(*EventMessage); ok { + e := (*event.Event)(em) + var tf TransformerFactories + tf = transformers + if err := tf.EventTransformer()(e); err != nil { + return nil, err + } + return e, nil + } + if mw, ok := m.(MessageWrapper); ok { + m = mw.GetWrappedMessage() + } else { + break + } + } + return nil, ErrCannotConvertToEvent + } + + e := event.New() + encoder := &messageToEventBuilder{event: &e} + if _, err := DirectWrite( + context.TODO(), + message, + encoder, + encoder, + ); err != nil { + return nil, err + } + var tf TransformerFactories + tf = transformers + if err := tf.EventTransformer()(&e); err != nil { + return nil, err + } + return &e, nil +} + +type messageToEventBuilder struct { + event *event.Event +} + +var _ StructuredWriter = (*messageToEventBuilder)(nil) +var _ BinaryWriter = (*messageToEventBuilder)(nil) + +func (b *messageToEventBuilder) SetStructuredEvent(ctx context.Context, format format.Format, event io.Reader) error { + var buf bytes.Buffer + _, err := io.Copy(&buf, event) + if err != nil { + return err + } + return format.Unmarshal(buf.Bytes(), b.event) +} + +func (b *messageToEventBuilder) Start(ctx context.Context) error { + return nil +} + +func (b *messageToEventBuilder) End(ctx context.Context) error { + return nil +} + +func (b *messageToEventBuilder) SetData(data io.Reader) error { + var buf bytes.Buffer + w, err := io.Copy(&buf, data) + if err != nil { + return err + } + if w != 0 { + b.event.DataEncoded = buf.Bytes() + } + return nil +} + +func (b *messageToEventBuilder) SetAttribute(attribute spec.Attribute, value interface{}) error { + // If spec version we need to change to right context struct + if attribute.Kind() == spec.SpecVersion { + str, err := types.ToString(value) + if err != nil { + return err + } + switch str { + case event.CloudEventsVersionV03: + b.event.Context = b.event.Context.AsV03() + case event.CloudEventsVersionV1: + b.event.Context = b.event.Context.AsV1() + default: + return fmt.Errorf("unrecognized event version %s", str) + } + return nil + } + return attribute.Set(b.event.Context, value) +} + +func (b *messageToEventBuilder) SetExtension(name string, value interface{}) error { + value, err := types.Validate(value) + if err != nil { + return err + } + b.event.SetExtension(name, value) + return nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/transformer.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/transformer.go new file mode 100644 index 00000000000..2e4b73153cb --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/transformer.go @@ -0,0 +1,73 @@ +package binding + +import ( + "github.com/cloudevents/sdk-go/v2/event" +) + +// Implements a transformation process while transferring the event from the Message implementation +// to the provided encoder +// +// A transformer could optionally not provide an implementation for binary and/or structured encodings, +// returning nil to the respective factory method. +type TransformerFactory interface { + // Can return nil if the transformation doesn't support structured encoding directly + StructuredTransformer(writer StructuredWriter) StructuredWriter + + // Can return nil if the transformation doesn't support binary encoding directly + BinaryTransformer(writer BinaryWriter) BinaryWriter + + // Can return nil if the transformation doesn't support events + EventTransformer() EventTransformer +} + +// Utility type alias to manage multiple TransformerFactory +type TransformerFactories []TransformerFactory + +func (t TransformerFactories) StructuredTransformer(writer StructuredWriter) StructuredWriter { + if writer == nil { + return nil + } + res := writer + for _, b := range t { + if r := b.StructuredTransformer(res); r != nil { + res = r + } else { + return nil // Structured not supported! + } + } + return res +} + +func (t TransformerFactories) BinaryTransformer(writer BinaryWriter) BinaryWriter { + if writer == nil { + return nil + } + res := writer + for i := range t { + b := t[len(t)-i-1] + if r := b.BinaryTransformer(res); r != nil { + res = r + } else { + return nil // Binary not supported! + } + } + return res +} + +func (t TransformerFactories) EventTransformer() EventTransformer { + return func(e *event.Event) error { + for _, b := range t { + f := b.EventTransformer() + if f != nil { + err := f(e) + if err != nil { + return err + } + } + } + return nil + } +} + +// EventTransformer mutates the provided Event +type EventTransformer func(*event.Event) error diff --git a/vendor/github.com/cloudevents/sdk-go/v2/binding/write.go b/vendor/github.com/cloudevents/sdk-go/v2/binding/write.go new file mode 100644 index 00000000000..690d51fc455 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/binding/write.go @@ -0,0 +1,148 @@ +package binding + +import ( + "context" + + "github.com/cloudevents/sdk-go/v2/event" +) + +const ( + SKIP_DIRECT_STRUCTURED_ENCODING = "SKIP_DIRECT_STRUCTURED_ENCODING" + SKIP_DIRECT_BINARY_ENCODING = "SKIP_DIRECT_BINARY_ENCODING" + PREFERRED_EVENT_ENCODING = "PREFERRED_EVENT_ENCODING" +) + +// Invokes the encoders. structuredWriter and binaryWriter could be nil if the protocol doesn't support it. +// transformers can be nil and this function guarantees that they are invoked only once during the encoding process. +// +// Returns: +// * EncodingStructured, nil if message is correctly encoded in structured encoding +// * EncodingBinary, nil if message is correctly encoded in binary encoding +// * EncodingStructured, err if message was structured but error happened during the encoding +// * EncodingBinary, err if message was binary but error happened during the encoding +// * EncodingUnknown, ErrUnknownEncoding if message is not a structured or a binary Message +func DirectWrite( + ctx context.Context, + message MessageReader, + structuredWriter StructuredWriter, + binaryWriter BinaryWriter, + transformers ...TransformerFactory, +) (Encoding, error) { + if structuredWriter != nil && !GetOrDefaultFromCtx(ctx, SKIP_DIRECT_STRUCTURED_ENCODING, false).(bool) { + // Wrap the transformers in the structured builder + structuredWriter = TransformerFactories(transformers).StructuredTransformer(structuredWriter) + + // StructuredTransformer could return nil if one of transcoders doesn't support + // direct structured transcoding + if structuredWriter != nil { + if err := message.ReadStructured(ctx, structuredWriter); err == nil { + return EncodingStructured, nil + } else if err != ErrNotStructured { + return EncodingStructured, err + } + } + } + + if binaryWriter != nil && !GetOrDefaultFromCtx(ctx, SKIP_DIRECT_BINARY_ENCODING, false).(bool) { + binaryWriter = TransformerFactories(transformers).BinaryTransformer(binaryWriter) + if binaryWriter != nil { + if err := message.ReadBinary(ctx, binaryWriter); err == nil { + return EncodingBinary, nil + } else if err != ErrNotBinary { + return EncodingBinary, err + } + } + } + + return EncodingUnknown, ErrUnknownEncoding +} + +// This is the full algorithm to encode a Message using transformers: +// 1. It first tries direct encoding using DirectWrite +// 2. If no direct encoding is possible, it uses ToEvent to generate an Event representation +// 3. From the Event, the message is encoded back to the provided structured or binary encoders +// You can tweak the encoding process using the context decorators WithForceStructured, WithForceStructured, etc. +// transformers can be nil and this function guarantees that they are invoked only once during the encoding process. +// Returns: +// * EncodingStructured, nil if message is correctly encoded in structured encoding +// * EncodingBinary, nil if message is correctly encoded in binary encoding +// * EncodingUnknown, ErrUnknownEncoding if message.ReadEncoding() == EncodingUnknown +// * _, err if error happened during the encoding +func Write( + ctx context.Context, + message MessageReader, + structuredWriter StructuredWriter, + binaryWriter BinaryWriter, + transformers ...TransformerFactory, +) (Encoding, error) { + enc := message.ReadEncoding() + var err error + // Skip direct encoding if the event is an event message + if enc != EncodingEvent { + enc, err = DirectWrite(ctx, message, structuredWriter, binaryWriter, transformers...) + if enc != EncodingUnknown { + // Message directly encoded, nothing else to do here + return enc, err + } + } + + var e *event.Event + e, err = ToEvent(ctx, message, transformers...) + if err != nil { + return enc, err + } + + message = (*EventMessage)(e) + + if GetOrDefaultFromCtx(ctx, PREFERRED_EVENT_ENCODING, EncodingBinary).(Encoding) == EncodingStructured { + if structuredWriter != nil { + return EncodingStructured, message.ReadStructured(ctx, structuredWriter) + } + if binaryWriter != nil { + return EncodingBinary, message.ReadBinary(ctx, binaryWriter) + } + } else { + if binaryWriter != nil { + return EncodingBinary, message.ReadBinary(ctx, binaryWriter) + } + if structuredWriter != nil { + return EncodingStructured, message.ReadStructured(ctx, structuredWriter) + } + } + + return EncodingUnknown, ErrUnknownEncoding +} + +// Skip direct structured to structured encoding during the encoding process +func WithSkipDirectStructuredEncoding(ctx context.Context, skip bool) context.Context { + return context.WithValue(ctx, SKIP_DIRECT_STRUCTURED_ENCODING, skip) +} + +// Skip direct binary to binary encoding during the encoding process +func WithSkipDirectBinaryEncoding(ctx context.Context, skip bool) context.Context { + return context.WithValue(ctx, SKIP_DIRECT_BINARY_ENCODING, skip) +} + +// Define the preferred encoding from event to message during the encoding process +func WithPreferredEventEncoding(ctx context.Context, enc Encoding) context.Context { + return context.WithValue(ctx, PREFERRED_EVENT_ENCODING, enc) +} + +// Force structured encoding during the encoding process +func WithForceStructured(ctx context.Context) context.Context { + return context.WithValue(context.WithValue(ctx, PREFERRED_EVENT_ENCODING, EncodingStructured), SKIP_DIRECT_BINARY_ENCODING, true) +} + +// Force binary encoding during the encoding process +func WithForceBinary(ctx context.Context) context.Context { + return context.WithValue(context.WithValue(ctx, PREFERRED_EVENT_ENCODING, EncodingBinary), SKIP_DIRECT_STRUCTURED_ENCODING, true) +} + +// Get a configuration value from the provided context +func GetOrDefaultFromCtx(ctx context.Context, key string, def interface{}) interface{} { + if val := ctx.Value(key); val != nil { + return val + } else { + return def + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/client.go b/vendor/github.com/cloudevents/sdk-go/v2/client/client.go new file mode 100644 index 00000000000..8b0a9d15279 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/client.go @@ -0,0 +1,213 @@ +package client + +import ( + "context" + "errors" + "fmt" + "io" + "sync" + + "go.uber.org/zap" + + "github.com/cloudevents/sdk-go/v2/binding" + cecontext "github.com/cloudevents/sdk-go/v2/context" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/protocol" +) + +// Client interface defines the runtime contract the CloudEvents client supports. +type Client interface { + // Send will transmit the given event over the client's configured transport. + Send(ctx context.Context, event event.Event) error + + // Request will transmit the given event over the client's configured + // transport and return any response event. + Request(ctx context.Context, event event.Event) (*event.Event, error) + + // StartReceiver will register the provided function for callback on receipt + // of a cloudevent. It will also start the underlying protocol as it has + // been configured. + // This call is blocking. + // Valid fn signatures are: + // * func() + // * func() error + // * func(context.Context) + // * func(context.Context) protocol.Result + // * func(event.Event) + // * func(event.Event) protocol.Result + // * func(context.Context, event.Event) + // * func(context.Context, event.Event) protocol.Result + // * func(event.Event) *event.Event + // * func(event.Event) (*event.Event, protocol.Result) + // * func(context.Context, event.Event) *event.Event + // * func(context.Context, event.Event) (*event.Event, protocol.Result) + StartReceiver(ctx context.Context, fn interface{}) error +} + +// New produces a new client with the provided transport object and applied +// client options. +func New(obj interface{}, opts ...Option) (Client, error) { + c := &ceClient{} + + if p, ok := obj.(protocol.Sender); ok { + c.sender = p + } + if p, ok := obj.(protocol.Requester); ok { + c.requester = p + } + if p, ok := obj.(protocol.Responder); ok { + c.responder = p + } + if p, ok := obj.(protocol.Receiver); ok { + c.receiver = p + } + if p, ok := obj.(protocol.Opener); ok { + c.opener = p + } + + if err := c.applyOptions(opts...); err != nil { + return nil, err + } + return c, nil +} + +type ceClient struct { + sender protocol.Sender + requester protocol.Requester + receiver protocol.Receiver + responder protocol.Responder + // Optional. + opener protocol.Opener + + outboundContextDecorators []func(context.Context) context.Context + invoker Invoker + receiverMu sync.Mutex + eventDefaulterFns []EventDefaulter +} + +func (c *ceClient) applyOptions(opts ...Option) error { + for _, fn := range opts { + if err := fn(c); err != nil { + return err + } + } + return nil +} + +func (c *ceClient) Send(ctx context.Context, e event.Event) error { + if c.sender == nil { + return errors.New("sender not set") + } + + for _, f := range c.outboundContextDecorators { + ctx = f(ctx) + } + + if len(c.eventDefaulterFns) > 0 { + for _, fn := range c.eventDefaulterFns { + e = fn(ctx, e) + } + } + + if err := e.Validate(); err != nil { + return err + } + + return c.sender.Send(ctx, (*binding.EventMessage)(&e)) +} + +func (c *ceClient) Request(ctx context.Context, e event.Event) (*event.Event, error) { + if c.requester == nil { + return nil, errors.New("requester not set") + } + for _, f := range c.outboundContextDecorators { + ctx = f(ctx) + } + + if len(c.eventDefaulterFns) > 0 { + for _, fn := range c.eventDefaulterFns { + e = fn(ctx, e) + } + } + + if err := e.Validate(); err != nil { + return nil, err + } + + // If provided a requester, use it to do request/response. + var resp *event.Event + msg, err := c.requester.Request(ctx, (*binding.EventMessage)(&e)) + defer func() { + if err := msg.Finish(err); err != nil { + cecontext.LoggerFrom(ctx).Warnw("failed calling message.Finish", zap.Error(err)) + } + }() + if err == nil { + fmt.Printf("%#v", msg) + if rs, err := binding.ToEvent(ctx, msg); err != nil { + cecontext.LoggerFrom(ctx).Infow("failed calling ToEvent", zap.Error(err), zap.Any("resp", msg)) + } else { + resp = rs + } + } + return resp, err +} + +// StartReceiver sets up the given fn to handle Receive. +// See Client.StartReceiver for details. This is a blocking call. +func (c *ceClient) StartReceiver(ctx context.Context, fn interface{}) error { + c.receiverMu.Lock() + defer c.receiverMu.Unlock() + + if c.invoker != nil { + return fmt.Errorf("client already has a receiver") + } + + invoker, err := newReceiveInvoker(fn, c.eventDefaulterFns...) // TODO: this will have to pick between a observed invoker or not. + if err != nil { + return err + } + if invoker.IsReceiver() && c.receiver == nil { + return fmt.Errorf("mismatched receiver callback without protocol.Receiver supported by protocol") + } + if invoker.IsResponder() && c.responder == nil { + return fmt.Errorf("mismatched receiver callback without protocol.Responder supported by protocol") + } + c.invoker = invoker + + defer func() { + c.invoker = nil + }() + + // Start the opener, if set. + if c.opener != nil { + go func() { + // TODO: handle error correctly here. + if err := c.opener.OpenInbound(ctx); err != nil { + panic(err) + } + }() + } + + var msg binding.Message + var respFn protocol.ResponseFn + // Start Polling. + for { + if c.responder != nil { + msg, respFn, err = c.responder.Respond(ctx) + } else if c.receiver != nil { + msg, err = c.receiver.Receive(ctx) + } else { + return errors.New("responder and receiver not set") + } + + if err == io.EOF { // Normal close + return nil + } else if err != nil { + return err + } + if err := c.invoker.Invoke(ctx, msg, respFn); err != nil { + return err + } + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/client_default.go b/vendor/github.com/cloudevents/sdk-go/v2/client/client_default.go new file mode 100644 index 00000000000..82877d6791d --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/client_default.go @@ -0,0 +1,26 @@ +package client + +import ( + "github.com/cloudevents/sdk-go/v2/protocol/http" +) + +// NewDefault provides the good defaults for the common case using an HTTP +// Protocol client. The http transport has had WithBinaryEncoding http +// transport option applied to it. The client will always send Binary +// encoding but will inspect the outbound event context and match the version. +// The WithTimeNow, and WithUUIDs client options are also applied to the +// client, all outbound events will have a time and id set if not already +// present. +func NewDefault() (Client, error) { + p, err := http.New() + if err != nil { + return nil, err + } + + c, err := NewObserved(p, WithTimeNow(), WithUUIDs()) + if err != nil { + return nil, err + } + + return c, nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/client_observed.go b/vendor/github.com/cloudevents/sdk-go/v2/client/client_observed.go new file mode 100644 index 00000000000..583b9dc2b2b --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/client_observed.go @@ -0,0 +1,99 @@ +package client + +import ( + "context" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/extensions" + "github.com/cloudevents/sdk-go/v2/observability" + "go.opencensus.io/trace" +) + +// New produces a new client with the provided transport object and applied +// client options. +func NewObserved(protocol interface{}, opts ...Option) (Client, error) { + client, err := New(protocol, opts...) + if err != nil { + return nil, err + } + + c := &obsClient{client: client} + + if err := c.applyOptions(opts...); err != nil { + return nil, err + } + return c, nil +} + +type obsClient struct { + client Client + + addTracing bool +} + +func (c *obsClient) applyOptions(opts ...Option) error { + for _, fn := range opts { + if err := fn(c); err != nil { + return err + } + } + return nil +} + +// Send transmits the provided event on a preconfigured Protocol. Send returns +// an error if there was an an issue validating the outbound event or the +// transport returns an error. +func (c *obsClient) Send(ctx context.Context, e event.Event) error { + ctx, r := observability.NewReporter(ctx, reportSend) + ctx, span := trace.StartSpan(ctx, observability.ClientSpanName, trace.WithSpanKind(trace.SpanKindClient)) + defer span.End() + if span.IsRecordingEvents() { + span.AddAttributes(EventTraceAttributes(&e)...) + } + + if c.addTracing { + e.Context = e.Context.Clone() + extensions.FromSpanContext(span.SpanContext()).AddTracingAttributes(&e) + } + + err := c.client.Send(ctx, e) + + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} + +func (c *obsClient) Request(ctx context.Context, e event.Event) (*event.Event, error) { + ctx, r := observability.NewReporter(ctx, reportRequest) + ctx, span := trace.StartSpan(ctx, observability.ClientSpanName, trace.WithSpanKind(trace.SpanKindClient)) + defer span.End() + if span.IsRecordingEvents() { + span.AddAttributes(EventTraceAttributes(&e)...) + } + + resp, err := c.client.Request(ctx, e) + + if err != nil { + r.Error() + } else { + r.OK() + } + return resp, err +} + +// StartReceiver sets up the given fn to handle Receive. +// See Client.StartReceiver for details. This is a blocking call. +func (c *obsClient) StartReceiver(ctx context.Context, fn interface{}) error { + ctx, r := observability.NewReporter(ctx, reportStartReceiver) + + err := c.client.StartReceiver(ctx, fn) + + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/defaulters.go b/vendor/github.com/cloudevents/sdk-go/v2/client/defaulters.go similarity index 73% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/defaulters.go rename to vendor/github.com/cloudevents/sdk-go/v2/client/defaulters.go index e827dec23d9..5d0d7bc9412 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/defaulters.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/defaulters.go @@ -4,17 +4,18 @@ import ( "context" "time" - "github.com/cloudevents/sdk-go/pkg/cloudevents" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/google/uuid" ) // EventDefaulter is the function signature for extensions that are able // to perform event defaulting. -type EventDefaulter func(ctx context.Context, event cloudevents.Event) cloudevents.Event +type EventDefaulter func(ctx context.Context, event event.Event) event.Event // DefaultIDToUUIDIfNotSet will inspect the provided event and assign a UUID to // context.ID if it is found to be empty. -func DefaultIDToUUIDIfNotSet(ctx context.Context, event cloudevents.Event) cloudevents.Event { +func DefaultIDToUUIDIfNotSet(ctx context.Context, event event.Event) event.Event { if event.Context != nil { if event.ID() == "" { event.Context = event.Context.Clone() @@ -26,7 +27,7 @@ func DefaultIDToUUIDIfNotSet(ctx context.Context, event cloudevents.Event) cloud // DefaultTimeToNowIfNotSet will inspect the provided event and assign a new // Timestamp to context.Time if it is found to be nil or zero. -func DefaultTimeToNowIfNotSet(ctx context.Context, event cloudevents.Event) cloudevents.Event { +func DefaultTimeToNowIfNotSet(ctx context.Context, event event.Event) event.Event { if event.Context != nil { if event.Time().IsZero() { event.Context = event.Context.Clone() @@ -40,7 +41,7 @@ func DefaultTimeToNowIfNotSet(ctx context.Context, event cloudevents.Event) clou // provided event and set the provided content type if content type is found // to be empty. func NewDefaultDataContentTypeIfNotSet(contentType string) EventDefaulter { - return func(ctx context.Context, event cloudevents.Event) cloudevents.Event { + return func(ctx context.Context, event event.Event) event.Event { if event.Context != nil { if event.DataContentType() == "" { event.SetDataContentType(contentType) diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/client/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/client/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/http_receiver.go b/vendor/github.com/cloudevents/sdk-go/v2/client/http_receiver.go new file mode 100644 index 00000000000..416e971e69a --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/http_receiver.go @@ -0,0 +1,39 @@ +package client + +import ( + "context" + "net/http" + + thttp "github.com/cloudevents/sdk-go/v2/protocol/http" +) + +func NewHTTPReceiveHandler(ctx context.Context, p *thttp.Protocol, fn interface{}) (*EventReceiver, error) { + invoker, err := newReceiveInvoker(fn) + if err != nil { + return nil, err + } + + return &EventReceiver{ + p: p, + invoker: invoker, + }, nil +} + +type EventReceiver struct { + p *thttp.Protocol + invoker Invoker +} + +func (r *EventReceiver) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + go func() { + r.p.ServeHTTP(rw, req) + }() + + ctx := context.Background() + msg, respFn, err := r.p.Respond(ctx) + if err != nil { + // TODO + } else if err := r.invoker.Invoke(ctx, msg, respFn); err != nil { + // TODO + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/invoker.go b/vendor/github.com/cloudevents/sdk-go/v2/client/invoker.go new file mode 100644 index 00000000000..e7c064021d9 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/invoker.go @@ -0,0 +1,82 @@ +package client + +import ( + "context" + "fmt" + + "github.com/cloudevents/sdk-go/v2/binding" + "github.com/cloudevents/sdk-go/v2/protocol" +) + +type Invoker interface { + Invoke(context.Context, binding.Message, protocol.ResponseFn) error + IsReceiver() bool + IsResponder() bool +} + +var _ Invoker = (*receiveInvoker)(nil) + +func newReceiveInvoker(fn interface{}, fns ...EventDefaulter) (Invoker, error) { + r := &receiveInvoker{ + eventDefaulterFns: fns, + } + + if fn, err := receiver(fn); err != nil { + return nil, err + } else { + r.fn = fn + } + + return r, nil +} + +type receiveInvoker struct { + fn *receiverFn + eventDefaulterFns []EventDefaulter +} + +func (r *receiveInvoker) Invoke(ctx context.Context, m binding.Message, respFn protocol.ResponseFn) (err error) { + defer func() { + if err2 := m.Finish(err); err2 == nil { + err = err2 + } + }() + + e, err := binding.ToEvent(ctx, m) + if err != nil { + return err + } + + if e != nil && r.fn != nil { + resp, result := r.fn.invoke(ctx, *e) + + // Apply the defaulter chain to the outgoing event. + if resp != nil && len(r.eventDefaulterFns) > 0 { + for _, fn := range r.eventDefaulterFns { + *resp = fn(ctx, *resp) + } + // Validate the event conforms to the CloudEvents Spec. + if verr := resp.Validate(); verr != nil { + return fmt.Errorf("cloudevent validation failed on response event: %v, %w", verr, err) + } + } + if respFn != nil { + var rm binding.Message + if resp != nil { + rm = (*binding.EventMessage)(resp) + } + + return respFn(ctx, rm, result) // TODO: there is a chance this never gets called. Is that ok? + } + } + + return nil +} + +func (r *receiveInvoker) IsReceiver() bool { + return !r.fn.hasEventOut +} + +func (r *receiveInvoker) IsResponder() bool { + return r.fn.hasEventOut +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/observability.go b/vendor/github.com/cloudevents/sdk-go/v2/client/observability.go new file mode 100644 index 00000000000..8e8add28e7d --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/observability.go @@ -0,0 +1,94 @@ +package client + +import ( + "context" + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/extensions" + "github.com/cloudevents/sdk-go/v2/observability" + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/trace" +) + +var ( + // LatencyMs measures the latency in milliseconds for the CloudEvents + // client methods. + LatencyMs = stats.Float64("cloudevents.io/sdk-go/client/latency", "The latency in milliseconds for the CloudEvents client methods.", "ms") +) + +var ( + // LatencyView is an OpenCensus view that shows client method latency. + LatencyView = &view.View{ + Name: "client/latency", + Measure: LatencyMs, + Description: "The distribution of latency inside of client for CloudEvents.", + Aggregation: view.Distribution(0, .01, .1, 1, 10, 100, 1000, 10000), + TagKeys: observability.LatencyTags(), + } +) + +type observed int32 + +// Adheres to Observable +var _ observability.Observable = observed(0) + +const ( + specversionAttr = "cloudevents.specversion" + typeAttr = "cloudevents.type" + sourceAttr = "cloudevents.source" + subjectAttr = "cloudevents.subject" + datacontenttypeAttr = "cloudevents.datacontenttype" + + reportSend observed = iota + reportRequest + reportStartReceiver +) + +// MethodName implements Observable.MethodName +func (o observed) MethodName() string { + switch o { + case reportSend: + return "send" + case reportRequest: + return "request" + case reportStartReceiver: + return "start_receiver" + default: + return "unknown" + } +} + +// LatencyMs implements Observable.LatencyMs +func (o observed) LatencyMs() *stats.Float64Measure { + return LatencyMs +} + +func EventTraceAttributes(e event.EventReader) []trace.Attribute { + as := []trace.Attribute{ + trace.StringAttribute(specversionAttr, e.SpecVersion()), + trace.StringAttribute(typeAttr, e.Type()), + trace.StringAttribute(sourceAttr, e.Source()), + } + if sub := e.Subject(); sub != "" { + as = append(as, trace.StringAttribute(subjectAttr, sub)) + } + if dct := e.DataContentType(); dct != "" { + as = append(as, trace.StringAttribute(datacontenttypeAttr, dct)) + } + return as +} + +// TraceSpan returns context and trace.Span based on event. Caller must call span.End() +func TraceSpan(ctx context.Context, e event.Event) (context.Context, *trace.Span) { + var span *trace.Span + if ext, ok := extensions.GetDistributedTracingExtension(e); ok { + ctx, span = ext.StartChildSpan(ctx, observability.ClientSpanName, trace.WithSpanKind(trace.SpanKindServer)) + } + if span == nil { + ctx, span = trace.StartSpan(ctx, observability.ClientSpanName, trace.WithSpanKind(trace.SpanKindServer)) + } + if span.IsRecordingEvents() { + span.AddAttributes(EventTraceAttributes(&e)...) + } + return ctx, span +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/options.go b/vendor/github.com/cloudevents/sdk-go/v2/client/options.go new file mode 100644 index 00000000000..3a1b40fe9ea --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/options.go @@ -0,0 +1,73 @@ +package client + +import ( + "fmt" + "github.com/cloudevents/sdk-go/v2/binding" +) + +// Option is the function signature required to be considered an client.Option. +type Option func(interface{}) error + +// WithEventDefaulter adds an event defaulter to the end of the defaulter chain. +func WithEventDefaulter(fn EventDefaulter) Option { + return func(i interface{}) error { + if c, ok := i.(*ceClient); ok { + if fn == nil { + return fmt.Errorf("client option was given an nil event defaulter") + } + c.eventDefaulterFns = append(c.eventDefaulterFns, fn) + } + return nil + } +} + +func WithForceBinary() Option { + return func(i interface{}) error { + if c, ok := i.(*ceClient); ok { + c.outboundContextDecorators = append(c.outboundContextDecorators, binding.WithForceBinary) + } + return nil + } +} + +func WithForceStructured() Option { + return func(i interface{}) error { + if c, ok := i.(*ceClient); ok { + c.outboundContextDecorators = append(c.outboundContextDecorators, binding.WithForceStructured) + } + return nil + } +} + +// WithUUIDs adds DefaultIDToUUIDIfNotSet event defaulter to the end of the +// defaulter chain. +func WithUUIDs() Option { + return func(i interface{}) error { + if c, ok := i.(*ceClient); ok { + c.eventDefaulterFns = append(c.eventDefaulterFns, DefaultIDToUUIDIfNotSet) + } + return nil + } +} + +// WithTimeNow adds DefaultTimeToNowIfNotSet event defaulter to the end of the +// defaulter chain. +func WithTimeNow() Option { + return func(i interface{}) error { + if c, ok := i.(*ceClient); ok { + c.eventDefaulterFns = append(c.eventDefaulterFns, DefaultTimeToNowIfNotSet) + } + return nil + } +} + +// WithTracePropagation enables trace propagation via the distributed tracing +// extension. +func WithTracePropagation() Option { + return func(i interface{}) error { + if c, ok := i.(*obsClient); ok { + c.addTracing = true + } + return nil + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/client/receiver.go b/vendor/github.com/cloudevents/sdk-go/v2/client/receiver.go new file mode 100644 index 00000000000..e75f9abb987 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/client/receiver.go @@ -0,0 +1,189 @@ +package client + +import ( + "context" + "errors" + "fmt" + "reflect" + + "github.com/cloudevents/sdk-go/v2/event" + "github.com/cloudevents/sdk-go/v2/protocol" +) + +// Receive is the signature of a fn to be invoked for incoming cloudevents. +type ReceiveFull func(context.Context, event.Event) protocol.Result + +type receiverFn struct { + numIn int + numOut int + fnValue reflect.Value + + hasContextIn bool + hasEventIn bool + + hasEventOut bool + hasResultOut bool +} + +const ( + inParamUsage = "expected a function taking either no parameters, one or more of (context.Context, event.Event) ordered" + outParamUsage = "expected a function returning one or mode of (*event.Event, protocol.Result) ordered" +) + +var ( + contextType = reflect.TypeOf((*context.Context)(nil)).Elem() + eventType = reflect.TypeOf((*event.Event)(nil)).Elem() + eventPtrType = reflect.TypeOf((*event.Event)(nil)) // want the ptr type + resultType = reflect.TypeOf((*protocol.Result)(nil)).Elem() +) + +// receiver creates a receiverFn wrapper class that is used by the client to +// validate and invoke the provided function. +// Valid fn signatures are: +// * func() +// * func() error +// * func(context.Context) +// * func(context.Context) transport.Result +// * func(event.Event) +// * func(event.Event) transport.Result +// * func(context.Context, event.Event) +// * func(context.Context, event.Event) transport.Result +// * func(event.Event) *event.Event +// * func(event.Event) (*event.Event, transport.Result) +// * func(context.Context, event.Event, *event.Event +// * func(context.Context, event.Event) (*event.Event, transport.Result) +// +func receiver(fn interface{}) (*receiverFn, error) { + fnType := reflect.TypeOf(fn) + if fnType.Kind() != reflect.Func { + return nil, errors.New("must pass a function to handle events") + } + + r := &receiverFn{ + fnValue: reflect.ValueOf(fn), + numIn: fnType.NumIn(), + numOut: fnType.NumOut(), + } + + if err := r.validate(fnType); err != nil { + return nil, err + } + + return r, nil +} + +func (r *receiverFn) invoke(ctx context.Context, e event.Event) (*event.Event, protocol.Result) { + args := make([]reflect.Value, 0, r.numIn) + + if r.numIn > 0 { + if r.hasContextIn { + args = append(args, reflect.ValueOf(ctx)) + } + if r.hasEventIn { + args = append(args, reflect.ValueOf(e)) + } + } + v := r.fnValue.Call(args) + var respOut protocol.Result + var eOut *event.Event + if r.numOut > 0 { + i := 0 + if r.hasEventOut { + if eo, ok := v[i].Interface().(*event.Event); ok { + eOut = eo + } + i++ // <-- note, need to inc i. + } + if r.hasResultOut { + if resp, ok := v[i].Interface().(protocol.Result); ok { + respOut = resp + } + } + } + return eOut, respOut +} + +// Verifies that the inputs to a function have a valid signature +// Valid input is to be [0, all] of +// context.Context, event.Event in this order. +func (r *receiverFn) validateInParamSignature(fnType reflect.Type) error { + r.hasContextIn = false + r.hasEventIn = false + + switch fnType.NumIn() { + case 2: + // has to be (context.Context, event.Event) + if !fnType.In(1).ConvertibleTo(eventType) { + return fmt.Errorf("%s; cannot convert parameter 2 from %s to event.Event", inParamUsage, fnType.In(1)) + } else { + r.hasEventIn = true + } + fallthrough + case 1: + if !fnType.In(0).ConvertibleTo(contextType) { + if !fnType.In(0).ConvertibleTo(eventType) { + return fmt.Errorf("%s; cannot convert parameter 1 from %s to context.Context or event.Event", inParamUsage, fnType.In(0)) + } else if r.hasEventIn { + return fmt.Errorf("%s; duplicate parameter of type event.Event", inParamUsage) + } else { + r.hasEventIn = true + } + } else { + r.hasContextIn = true + } + fallthrough + case 0: + return nil + + default: + return fmt.Errorf("%s; function has too many parameters (%d)", inParamUsage, fnType.NumIn()) + } +} + +// Verifies that the outputs of a function have a valid signature +// Valid output signatures to be [0, all] of +// *event.Event, transport.Result in this order +func (r *receiverFn) validateOutParamSignature(fnType reflect.Type) error { + r.hasEventOut = false + r.hasResultOut = false + + switch fnType.NumOut() { + case 2: + // has to be (*event.Event, transport.Result) + if !fnType.Out(1).ConvertibleTo(resultType) { + return fmt.Errorf("%s; cannot convert parameter 2 from %s to event.Response", outParamUsage, fnType.Out(1)) + } else { + r.hasResultOut = true + } + fallthrough + case 1: + if !fnType.Out(0).ConvertibleTo(resultType) { + if !fnType.Out(0).ConvertibleTo(eventPtrType) { + return fmt.Errorf("%s; cannot convert parameter 1 from %s to *event.Event or transport.Result", outParamUsage, fnType.Out(0)) + } else { + r.hasEventOut = true + } + } else if r.hasResultOut { + return fmt.Errorf("%s; duplicate parameter of type event.Response", outParamUsage) + } else { + r.hasResultOut = true + } + fallthrough + case 0: + return nil + default: + return fmt.Errorf("%s; function has too many return types (%d)", outParamUsage, fnType.NumOut()) + } +} + +// validateReceiverFn validates that a function has the right number of in and +// out params and that they are of allowed types. +func (r *receiverFn) validate(fnType reflect.Type) error { + if err := r.validateInParamSignature(fnType); err != nil { + return err + } + if err := r.validateOutParamSignature(fnType); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/context.go b/vendor/github.com/cloudevents/sdk-go/v2/context/context.go similarity index 62% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/context.go rename to vendor/github.com/cloudevents/sdk-go/v2/context/context.go index e580360f130..0cf24f496cf 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/context.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/context/context.go @@ -3,7 +3,6 @@ package context import ( "context" "net/url" - "strings" ) // Opaque key type used to store target @@ -51,26 +50,3 @@ func TopicFrom(ctx context.Context) string { } return "" } - -// Opaque key type used to store encoding -type encodingKeyType struct{} - -var encodingKey = encodingKeyType{} - -// WithEncoding returns back a new context with the given encoding. Encoding is intended to be transport dependent. -// For http transport, `encoding` should be one of [binary, structured] and will be used to override the outbound -// codec encoding setting. If the transport does not understand the encoding, it will be ignored. -func WithEncoding(ctx context.Context, encoding string) context.Context { - return context.WithValue(ctx, encodingKey, strings.ToLower(encoding)) -} - -// EncodingFrom looks in the given context and returns `target` as a parsed url if found and valid, otherwise nil. -func EncodingFrom(ctx context.Context) string { - c := ctx.Value(encodingKey) - if c != nil { - if s, ok := c.(string); ok && s != "" { - return s - } - } - return "" -} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/context/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/context/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/logger.go b/vendor/github.com/cloudevents/sdk-go/v2/context/logger.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/context/logger.go rename to vendor/github.com/cloudevents/sdk-go/v2/context/logger.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/content_type.go b/vendor/github.com/cloudevents/sdk-go/v2/event/content_type.go similarity index 84% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/content_type.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/content_type.go index e4e0e17f2b7..591878e5dc7 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/content_type.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/content_type.go @@ -1,6 +1,7 @@ -package cloudevents +package event const ( + TextPlain = "text/plain" TextJSON = "text/json" ApplicationJSON = "application/json" ApplicationXML = "application/xml" @@ -20,6 +21,12 @@ func StringOfApplicationXML() *string { return &a } +// StringOfTextPlain returns a string pointer to "text/plain" +func StringOfTextPlain() *string { + a := TextPlain + return &a +} + // StringOfApplicationCloudEventsJSON returns a string pointer to // "application/cloudevents+json" func StringOfApplicationCloudEventsJSON() *string { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/data_content_encoding.go b/vendor/github.com/cloudevents/sdk-go/v2/event/data_content_encoding.go similarity index 87% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/data_content_encoding.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/data_content_encoding.go index 180102ee3fa..24c4094fc30 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/data_content_encoding.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/data_content_encoding.go @@ -1,4 +1,4 @@ -package cloudevents +package event const ( Base64 = "base64" diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/codec.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec.go similarity index 75% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/codec.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec.go index b9674889c62..21161c70e4e 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/codec.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec.go @@ -4,10 +4,9 @@ import ( "context" "fmt" - "github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json" - "github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/text" - "github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/event/datacodec/json" + "github.com/cloudevents/sdk-go/v2/event/datacodec/text" + "github.com/cloudevents/sdk-go/v2/event/datacodec/xml" ) // Decoder is the expected function signature for decoding `in` to `out`. What @@ -57,17 +56,6 @@ func AddEncoder(contentType string, fn Encoder) { // type. An error is returned if no decoder is registered for the given // content type. func Decode(ctx context.Context, contentType string, in, out interface{}) error { - _, r := observability.NewReporter(ctx, reportDecode) - err := obsDecode(ctx, contentType, in, out) - if err != nil { - r.Error() - } else { - r.OK() - } - return err -} - -func obsDecode(ctx context.Context, contentType string, in, out interface{}) error { if fn, ok := decoder[contentType]; ok { return fn(ctx, in, out) } @@ -78,17 +66,6 @@ func obsDecode(ctx context.Context, contentType string, in, out interface{}) err // type. An error is returned if no encoder is registered for the given // content type. func Encode(ctx context.Context, contentType string, in interface{}) ([]byte, error) { - _, r := observability.NewReporter(ctx, reportEncode) - b, err := obsEncode(ctx, contentType, in) - if err != nil { - r.Error() - } else { - r.OK() - } - return b, err -} - -func obsEncode(ctx context.Context, contentType string, in interface{}) ([]byte, error) { if fn, ok := encoder[contentType]; ok { return fn(ctx, in) } diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec_observed.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec_observed.go new file mode 100644 index 00000000000..f45bae885bb --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec_observed.go @@ -0,0 +1,50 @@ +package datacodec + +import ( + "context" + + "github.com/cloudevents/sdk-go/v2/event/datacodec/json" + "github.com/cloudevents/sdk-go/v2/event/datacodec/text" + "github.com/cloudevents/sdk-go/v2/event/datacodec/xml" + "github.com/cloudevents/sdk-go/v2/observability" +) + +func SetObservedCodecs() { + AddDecoder("", json.DecodeObserved) + AddDecoder("application/json", json.DecodeObserved) + AddDecoder("text/json", json.DecodeObserved) + AddDecoder("application/xml", xml.DecodeObserved) + AddDecoder("text/xml", xml.DecodeObserved) + AddDecoder("text/plain", text.DecodeObserved) + + AddEncoder("", json.Encode) + AddEncoder("application/json", json.EncodeObserved) + AddEncoder("text/json", json.EncodeObserved) + AddEncoder("application/xml", xml.EncodeObserved) + AddEncoder("text/xml", xml.EncodeObserved) + AddEncoder("text/plain", text.EncodeObserved) +} + +// DecodeObserved calls Decode and records the result. +func DecodeObserved(ctx context.Context, contentType string, in, out interface{}) error { + _, r := observability.NewReporter(ctx, reportDecode) + err := Decode(ctx, contentType, in, out) + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} + +// EncodeObserved calls Encode and records the result. +func EncodeObserved(ctx context.Context, contentType string, in interface{}) ([]byte, error) { + _, r := observability.NewReporter(ctx, reportEncode) + b, err := Encode(ctx, contentType, in) + if err != nil { + r.Error() + } else { + r.OK() + } + return b, err +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/data.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data.go similarity index 79% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/data.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data.go index 926c344fed0..2862049f854 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/data.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data.go @@ -6,25 +6,12 @@ import ( "fmt" "reflect" "strconv" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" ) // Decode takes `in` as []byte, or base64 string, normalizes in to unquoted and // base64 decoded []byte if required, and then attempts to use json.Unmarshal // to convert those bytes to `out`. Returns and error if this process fails. func Decode(ctx context.Context, in, out interface{}) error { - _, r := observability.NewReporter(ctx, reportDecode) - err := obsDecode(ctx, in, out) - if err != nil { - r.Error() - } else { - r.OK() - } - return err -} - -func obsDecode(ctx context.Context, in, out interface{}) error { if in == nil { return nil } @@ -63,17 +50,6 @@ func obsDecode(ctx context.Context, in, out interface{}) error { // and returns `in` unmodified if it is detected that `in` is already a []byte; // Or json.Marshal errors. func Encode(ctx context.Context, in interface{}) ([]byte, error) { - _, r := observability.NewReporter(ctx, reportEncode) - b, err := obsEncode(ctx, in) - if err != nil { - r.Error() - } else { - r.OK() - } - return b, err -} - -func obsEncode(ctx context.Context, in interface{}) ([]byte, error) { if in == nil { return nil, nil } diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data_observed.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data_observed.go new file mode 100644 index 00000000000..6e79f5d26ef --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data_observed.go @@ -0,0 +1,30 @@ +package json + +import ( + "context" + "github.com/cloudevents/sdk-go/v2/observability" +) + +// DecodeObserved calls Decode and records the results. +func DecodeObserved(ctx context.Context, in, out interface{}) error { + _, r := observability.NewReporter(ctx, reportDecode) + err := Decode(ctx, in, out) + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} + +// EncodeObserved calls Encode and records the results. +func EncodeObserved(ctx context.Context, in interface{}) ([]byte, error) { + _, r := observability.NewReporter(ctx, reportEncode) + b, err := Encode(ctx, in) + if err != nil { + r.Error() + } else { + r.OK() + } + return b, err +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/observability.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/observability.go similarity index 79% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/observability.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/observability.go index d38a4b7d250..7ff79659043 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json/observability.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/observability.go @@ -1,7 +1,7 @@ package json import ( - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/observability" "go.opencensus.io/stats" "go.opencensus.io/stats/view" ) @@ -33,18 +33,6 @@ const ( reportDecode ) -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportEncode: - return "datacodec/json/encode" - case reportDecode: - return "datacodec/json/decode" - default: - return "datacodec/json/unknown" - } -} - // MethodName implements Observable.MethodName func (o observed) MethodName() string { switch o { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/observability.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/observability.go similarity index 80% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/observability.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/observability.go index a51e05eb9fc..870ec5dfe83 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/observability.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/observability.go @@ -1,7 +1,7 @@ package datacodec import ( - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/observability" "go.opencensus.io/stats" "go.opencensus.io/stats/view" ) @@ -33,18 +33,6 @@ const ( reportDecode ) -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportEncode: - return "datacodec/encode" - case reportDecode: - return "datacodec/decode" - default: - return "datacodec/unknown" - } -} - // MethodName implements Observable.MethodName func (o observed) MethodName() string { switch o { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/text/text.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/text/text.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data.go diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data_observed.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data_observed.go new file mode 100644 index 00000000000..b9773fa41a0 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data_observed.go @@ -0,0 +1,30 @@ +package text + +import ( + "context" + "github.com/cloudevents/sdk-go/v2/observability" +) + +// DecodeObserved calls Decode and records the results. +func DecodeObserved(ctx context.Context, in, out interface{}) error { + _, r := observability.NewReporter(ctx, reportDecode) + err := Decode(ctx, in, out) + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} + +// EncodeObserved calls Encode and records the results. +func EncodeObserved(ctx context.Context, in interface{}) ([]byte, error) { + _, r := observability.NewReporter(ctx, reportEncode) + b, err := Encode(ctx, in) + if err != nil { + r.Error() + } else { + r.OK() + } + return b, err +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/doc.go new file mode 100644 index 00000000000..13316702ec5 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/doc.go @@ -0,0 +1,4 @@ +/* +Package text holds the encoder/decoder implementation for `text/plain`. +*/ +package text diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/observability.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/observability.go new file mode 100644 index 00000000000..ede85a2adb9 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/observability.go @@ -0,0 +1,51 @@ +package text + +import ( + "github.com/cloudevents/sdk-go/v2/observability" + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" +) + +var ( + // LatencyMs measures the latency in milliseconds for the CloudEvents xml data + // codec methods. + LatencyMs = stats.Float64("cloudevents.io/sdk-go/datacodec/text/latency", "The latency in milliseconds for the CloudEvents text data codec methods.", "ms") +) + +var ( + // LatencyView is an OpenCensus view that shows data codec xml method latency. + LatencyView = &view.View{ + Name: "datacodec/text/latency", + Measure: LatencyMs, + Description: "The distribution of latency inside of the text data codec for CloudEvents.", + Aggregation: view.Distribution(0, .01, .1, 1, 10, 100, 1000, 10000), + TagKeys: observability.LatencyTags(), + } +) + +type observed int32 + +// Adheres to Observable +var _ observability.Observable = observed(0) + +const ( + reportEncode observed = iota + reportDecode +) + +// MethodName implements Observable.MethodName +func (o observed) MethodName() string { + switch o { + case reportEncode: + return "encode" + case reportDecode: + return "decode" + default: + return "unknown" + } +} + +// LatencyMs implements Observable.LatencyMs +func (o observed) LatencyMs() *stats.Float64Measure { + return LatencyMs +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/data.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data.go similarity index 78% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/data.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data.go index 6339e444337..8f2b72540da 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/data.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data.go @@ -6,25 +6,12 @@ import ( "encoding/xml" "fmt" "strconv" - - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" ) // Decode takes `in` as []byte, or base64 string, normalizes in to unquoted and // base64 decoded []byte if required, and then attempts to use xml.Unmarshal // to convert those bytes to `out`. Returns and error if this process fails. func Decode(ctx context.Context, in, out interface{}) error { - _, r := observability.NewReporter(ctx, reportDecode) - err := obsDecode(ctx, in, out) - if err != nil { - r.Error() - } else { - r.OK() - } - return err -} - -func obsDecode(ctx context.Context, in, out interface{}) error { if in == nil { return nil } @@ -68,17 +55,6 @@ func obsDecode(ctx context.Context, in, out interface{}) error { // and returns `in` unmodified if it is detected that `in` is already a []byte; // Or xml.Marshal errors. func Encode(ctx context.Context, in interface{}) ([]byte, error) { - _, r := observability.NewReporter(ctx, reportEncode) - b, err := obsEncode(ctx, in) - if err != nil { - r.Error() - } else { - r.OK() - } - return b, err -} - -func obsEncode(ctx context.Context, in interface{}) ([]byte, error) { if b, ok := in.([]byte); ok { // check to see if it is a pre-encoded byte string. if len(b) > 0 && b[0] == byte('"') { diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data_observed.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data_observed.go new file mode 100644 index 00000000000..bee23a43a13 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data_observed.go @@ -0,0 +1,30 @@ +package xml + +import ( + "context" + "github.com/cloudevents/sdk-go/v2/observability" +) + +// DecodeObserved calls Decode and records the result. +func DecodeObserved(ctx context.Context, in, out interface{}) error { + _, r := observability.NewReporter(ctx, reportDecode) + err := Decode(ctx, in, out) + if err != nil { + r.Error() + } else { + r.OK() + } + return err +} + +// EncodeObserved calls Encode and records the result. +func EncodeObserved(ctx context.Context, in interface{}) ([]byte, error) { + _, r := observability.NewReporter(ctx, reportEncode) + b, err := Encode(ctx, in) + if err != nil { + r.Error() + } else { + r.OK() + } + return b, err +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/observability.go b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/observability.go similarity index 79% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/observability.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/observability.go index 31b0bb26998..b0f4c935d02 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml/observability.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/observability.go @@ -1,7 +1,7 @@ package xml import ( - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/observability" "go.opencensus.io/stats" "go.opencensus.io/stats/view" ) @@ -33,18 +33,6 @@ const ( reportDecode ) -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportEncode: - return "datacodec/xml/encode" - case reportDecode: - return "datacodec/xml/decode" - default: - return "datacodec/xml/unknown" - } -} - // MethodName implements Observable.MethodName func (o observed) MethodName() string { switch o { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/event/doc.go similarity index 86% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/doc.go index cc2201da915..b389d1e4ef6 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/doc.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/doc.go @@ -1,4 +1,4 @@ /* Package cloudevents provides primitives to work with CloudEvents specification: https://github.com/cloudevents/spec. */ -package cloudevents +package event diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event.go similarity index 70% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event.go index 8e034769346..b5dff9bd6d9 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "bytes" @@ -10,8 +10,7 @@ import ( // Event represents the canonical representation of a CloudEvent. type Event struct { Context EventContext - Data interface{} - DataEncoded bool + DataEncoded []byte DataBinary bool FieldErrors map[string]error } @@ -34,9 +33,9 @@ func (e *Event) fieldOK(field string) { } // New returns a new Event, an optional version can be passed to change the -// default spec version from 0.2 to the provided version. +// default spec version from 1.0 to the provided version. func New(version ...string) Event { - specVersion := defaultEventVersion // TODO: should there be a default? or set a default? + specVersion := defaultEventVersion if len(version) >= 1 { specVersion = version[0] } @@ -81,8 +80,6 @@ func (e Event) Validate() error { return err } - // TODO: validate data. - return nil } @@ -104,29 +101,55 @@ func (e Event) String() string { b.WriteString(e.Context.String()) - if e.Data != nil { - b.WriteString("Data,\n ") - if strings.HasPrefix(e.DataContentType(), ApplicationJSON) { + if e.DataEncoded != nil { + if e.DataBinary { + b.WriteString("Data (binary),\n ") + } else { + b.WriteString("Data,\n ") + } + switch e.DataMediaType() { + case ApplicationJSON: var prettyJSON bytes.Buffer - - data, ok := e.Data.([]byte) - if !ok { - var err error - data, err = json.Marshal(e.Data) - if err != nil { - data = []byte(err.Error()) - } - } - err := json.Indent(&prettyJSON, data, " ", " ") + err := json.Indent(&prettyJSON, e.DataEncoded, " ", " ") if err != nil { - b.Write(e.Data.([]byte)) + b.Write(e.DataEncoded) } else { b.Write(prettyJSON.Bytes()) } - } else { - b.Write(e.Data.([]byte)) + default: + b.Write(e.DataEncoded) } b.WriteString("\n") } + return b.String() } + +func (e Event) Clone() Event { + out := Event{} + out.Context = e.Context.Clone() + out.DataEncoded = cloneBytes(e.DataEncoded) + out.DataBinary = e.DataBinary + out.FieldErrors = e.cloneFieldErrors() + return out +} + +func cloneBytes(in []byte) []byte { + if in == nil { + return nil + } + out := make([]byte, len(in)) + copy(out, in) + return out +} + +func (e Event) cloneFieldErrors() map[string]error { + if e.FieldErrors == nil { + return nil + } + newFE := make(map[string]error, len(e.FieldErrors)) + for k, v := range e.FieldErrors { + newFE[k] = v + } + return newFE +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/event/event_data.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_data.go new file mode 100644 index 00000000000..649a0e2ccd1 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_data.go @@ -0,0 +1,112 @@ +package event + +import ( + "context" + "encoding/base64" + "fmt" + "strconv" + + "github.com/cloudevents/sdk-go/v2/event/datacodec" +) + +// Data is special. Break it out into it's own file. + +// SetData implements EventWriter.SetData +func (e *Event) SetData(contentType string, obj interface{}) error { + e.SetDataContentType(contentType) + + if e.SpecVersion() != CloudEventsVersionV1 { + return e.legacySetData(obj) + } + + // Version 1.0 and above. + switch obj := obj.(type) { + case []byte: + e.DataEncoded = obj + e.DataBinary = true + default: + data, err := datacodec.Encode(context.Background(), e.DataMediaType(), obj) + if err != nil { + return err + } + e.DataEncoded = data + e.DataBinary = false + } + + return nil +} + +// Deprecated: Delete when we do not have to support Spec v0.3. +func (e *Event) legacySetData(obj interface{}) error { + data, err := datacodec.Encode(context.Background(), e.DataMediaType(), obj) + if err != nil { + return err + } + if e.DeprecatedDataContentEncoding() == Base64 { + buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) + base64.StdEncoding.Encode(buf, data) + e.DataEncoded = buf + e.DataBinary = false + } else { + data, err := datacodec.Encode(context.Background(), e.DataMediaType(), obj) + if err != nil { + return err + } + e.DataEncoded = data + e.DataBinary = false + } + return nil +} + +const ( + quotes = `"'` +) + +func (e Event) Data() []byte { + return e.DataEncoded +} + +// DataAs attempts to populate the provided data object with the event payload. +// data should be a pointer type. +func (e Event) DataAs(obj interface{}) error { + data := e.Data() + + if len(data) == 0 { + // No data. + return nil + } + + if e.SpecVersion() != CloudEventsVersionV1 { + var err error + if data, err = e.legacyConvertData(data); err != nil { + return err + } + } + + return datacodec.Decode(context.Background(), e.DataMediaType(), data, obj) +} + +func (e Event) legacyConvertData(data []byte) ([]byte, error) { + if e.Context.DeprecatedGetDataContentEncoding() == Base64 { + var bs []byte + // test to see if we need to unquote the data. + if data[0] == quotes[0] || data[0] == quotes[1] { + str, err := strconv.Unquote(string(data)) + if err != nil { + return nil, err + } + bs = []byte(str) + } else { + bs = data + } + + buf := make([]byte, base64.StdEncoding.DecodedLen(len(bs))) + n, err := base64.StdEncoding.Decode(buf, bs) + if err != nil { + return nil, fmt.Errorf("failed to decode data from base64: %s", err.Error()) + } + data = buf[:n] + } + + return data, nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_interface.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_interface.go similarity index 81% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_interface.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event_interface.go index 37bb82ab5af..d58268e4baf 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_interface.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_interface.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "time" @@ -33,12 +33,27 @@ type EventReader interface { // Extensions use the CloudEvents type system, details in package cloudevents/types. Extensions() map[string]interface{} - // DEPRECATED: see event.Context.ExtensionAs // ExtensionAs returns event.Context.ExtensionAs(name, obj). + // + // DEPRECATED: Access extensions directly via the e.Extensions() map. + // Use functions in the types package to convert extension values. + // For example replace this: + // + // var i int + // err := e.ExtensionAs("foo", &i) + // + // With this: + // + // i, err := types.ToInteger(e.Extensions["foo"]) + // ExtensionAs(string, interface{}) error // Data Attribute + // Data returns the raw data buffer, it might be encoded depending on data + // content type. + Data() []byte + // DataAs attempts to populate the provided data object with the event payload. // data should be a pointer type. DataAs(interface{}) error @@ -74,6 +89,6 @@ type EventWriter interface { // SetExtension performs event.Context.SetExtension. SetExtension(string, interface{}) - // SetData encodes the given payload with the current encoding settings. - SetData(interface{}) error + // SetData encodes the given payload with the given content type. + SetData(string, interface{}) error } diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_marshal.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_marshal.go similarity index 67% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_marshal.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event_marshal.go index 49a8de2cab6..a2f248c9054 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_marshal.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_marshal.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "context" @@ -11,7 +11,7 @@ import ( errors2 "github.com/pkg/errors" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/observability" ) // MarshalJSON implements a custom json marshal method used when this type is @@ -28,7 +28,7 @@ func (e Event) MarshalJSON() ([]byte, error) { var err error switch e.SpecVersion() { - case CloudEventsVersionV01, CloudEventsVersionV02, CloudEventsVersionV03: + case CloudEventsVersionV03: b, err = JsonEncodeLegacy(e) case CloudEventsVersionV1: b, err = JsonEncode(e) @@ -61,10 +61,6 @@ func (e *Event) UnmarshalJSON(b []byte) error { var err error switch version { - case CloudEventsVersionV01: - err = e.JsonDecodeV01(b, raw) - case CloudEventsVersionV02: - err = e.JsonDecodeV02(b, raw) case CloudEventsVersionV03: err = e.JsonDecodeV03(b, raw) case CloudEventsVersionV1: @@ -84,15 +80,6 @@ func (e *Event) UnmarshalJSON(b []byte) error { } func versionFromRawMessage(raw map[string]json.RawMessage) string { - // v0.1 - if v, ok := raw["cloudEventsVersion"]; ok { - var version string - if err := json.Unmarshal(v, &version); err != nil { - return "" - } - return version - } - // v0.2 and after if v, ok := raw["specversion"]; ok { var version string @@ -106,34 +93,20 @@ func versionFromRawMessage(raw map[string]json.RawMessage) string { // JsonEncode func JsonEncode(e Event) ([]byte, error) { - data, err := e.DataBytes() - if err != nil { - return nil, err - } - return jsonEncode(e.Context, data, e.DataBinary) + return jsonEncode(e.Context, e.DataEncoded, e.DataBinary) } // JsonEncodeLegacy func JsonEncodeLegacy(e Event) ([]byte, error) { - var data []byte isBase64 := e.Context.DeprecatedGetDataContentEncoding() == Base64 - var err error - data, err = e.DataBytes() - if err != nil { - return nil, err - } - return jsonEncode(e.Context, data, isBase64) + return jsonEncode(e.Context, e.Data(), isBase64) } func jsonEncode(ctx EventContextReader, data []byte, isBase64 bool) ([]byte, error) { var b map[string]json.RawMessage var err error - if ctx.GetSpecVersion() == CloudEventsVersionV01 { - b, err = marshalEventLegacy(ctx) - } else { - b, err = marshalEvent(ctx, ctx.GetExtensions()) - } + b, err = marshalEvent(ctx, ctx.GetExtensions()) if err != nil { return nil, err } @@ -179,71 +152,6 @@ func jsonEncode(ctx EventContextReader, data []byte, isBase64 bool) ([]byte, err return body, nil } -// JsonDecodeV01 takes in the byte representation of a version 0.1 structured json CloudEvent and returns a -// cloudevent.Event or an error if there are parsing errors. -func (e *Event) JsonDecodeV01(body []byte, raw map[string]json.RawMessage) error { - ec := EventContextV01{} - if err := json.Unmarshal(body, &ec); err != nil { - return err - } - - var data interface{} - if d, ok := raw["data"]; ok { - data = []byte(d) - } - - e.Context = &ec - e.Data = data - e.DataEncoded = data != nil - - return nil -} - -// JsonDecodeV02 takes in the byte representation of a version 0.2 structured json CloudEvent and returns a -// cloudevent.Event or an error if there are parsing errors. -func (e *Event) JsonDecodeV02(body []byte, raw map[string]json.RawMessage) error { - ec := EventContextV02{} - if err := json.Unmarshal(body, &ec); err != nil { - return err - } - - // TODO: could use reflection to get these. - delete(raw, "specversion") - delete(raw, "type") - delete(raw, "source") - delete(raw, "id") - delete(raw, "time") - delete(raw, "schemaurl") - delete(raw, "contenttype") - - var data interface{} - if d, ok := raw["data"]; ok { - data = []byte(d) - } - delete(raw, "data") - - if len(raw) > 0 { - extensions := make(map[string]interface{}, len(raw)) - ec.Extensions = extensions - for k, v := range raw { - k = strings.ToLower(k) - var tmp interface{} - if err := json.Unmarshal(v, &tmp); err != nil { - return err - } - if err := ec.SetExtension(k, tmp); err != nil { - return errors2.Wrap(err, "Cannot set extension with key "+k) - } - } - } - - e.Context = &ec - e.Data = data - e.DataEncoded = data != nil - - return nil -} - // JsonDecodeV03 takes in the byte representation of a version 0.3 structured json CloudEvent and returns a // cloudevent.Event or an error if there are parsing errors. func (e *Event) JsonDecodeV03(body []byte, raw map[string]json.RawMessage) error { @@ -263,9 +171,9 @@ func (e *Event) JsonDecodeV03(body []byte, raw map[string]json.RawMessage) error delete(raw, "datacontenttype") delete(raw, "datacontentencoding") - var data interface{} + var data []byte if d, ok := raw["data"]; ok { - data = []byte(d) + data = d } delete(raw, "data") @@ -285,8 +193,7 @@ func (e *Event) JsonDecodeV03(body []byte, raw map[string]json.RawMessage) error } e.Context = &ec - e.Data = data - e.DataEncoded = data != nil + e.DataEncoded = data return nil } @@ -308,9 +215,9 @@ func (e *Event) JsonDecodeV1(body []byte, raw map[string]json.RawMessage) error delete(raw, "dataschema") delete(raw, "datacontenttype") - var data interface{} + var data []byte if d, ok := raw["data"]; ok { - data = []byte(d) + data = d } delete(raw, "data") @@ -344,17 +251,18 @@ func (e *Event) JsonDecodeV1(body []byte, raw map[string]json.RawMessage) error return errors.New("parsing error: JSON decoder found both 'data', and 'data_base64' in JSON payload") } if data != nil { - e.Data = data + e.DataEncoded = data + e.DataBinary = false } else if dataBase64 != nil { - e.Data = dataBase64 + e.DataEncoded = dataBase64 + e.DataBinary = true } - e.DataEncoded = data != nil return nil } -func marshalEventLegacy(event interface{}) (map[string]json.RawMessage, error) { - b, err := json.Marshal(event) +func marshalEvent(eventCtx EventContextReader, extensions map[string]interface{}) (map[string]json.RawMessage, error) { + b, err := json.Marshal(eventCtx) if err != nil { return nil, err } @@ -364,19 +272,12 @@ func marshalEventLegacy(event interface{}) (map[string]json.RawMessage, error) { return nil, err } - return brm, nil -} - -func marshalEvent(event interface{}, extensions map[string]interface{}) (map[string]json.RawMessage, error) { - b, err := json.Marshal(event) + sv, err := json.Marshal(eventCtx.GetSpecVersion()) if err != nil { return nil, err } - brm := map[string]json.RawMessage{} - if err := json.Unmarshal(b, &brm); err != nil { - return nil, err - } + brm["specversion"] = sv for k, v := range extensions { k = strings.ToLower(k) diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_observability.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_observability.go similarity index 78% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_observability.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event_observability.go index bce63f5c600..e21a845f1cb 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_observability.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_observability.go @@ -1,9 +1,9 @@ -package cloudevents +package event import ( "fmt" - "github.com/cloudevents/sdk-go/pkg/cloudevents/observability" + "github.com/cloudevents/sdk-go/v2/observability" "go.opencensus.io/stats" "go.opencensus.io/stats/view" ) @@ -38,18 +38,6 @@ const ( reportUnmarshal ) -// TraceName implements Observable.TraceName -func (o observed) TraceName() string { - switch o { - case reportMarshal: - return "cloudevents/event/marshaljson" - case reportUnmarshal: - return "cloudevents/event/unmarshaljson" - default: - return "cloudevents/event/unknwown" - } -} - // MethodName implements Observable.MethodName func (o observed) MethodName() string { switch o { @@ -78,11 +66,6 @@ type eventJSONObserved struct { // Adheres to Observable var _ observability.Observable = (*eventJSONObserved)(nil) -// TraceName implements Observable.TraceName -func (c eventJSONObserved) TraceName() string { - return fmt.Sprintf("%s/%s", c.o.TraceName(), c.v) -} - // MethodName implements Observable.MethodName func (c eventJSONObserved) MethodName() string { return fmt.Sprintf("%s/%s", c.o.MethodName(), c.v) diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_reader.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_reader.go similarity index 99% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_reader.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event_reader.go index fe49e8424dc..86ca609b46b 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_reader.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_reader.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "time" diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_writer.go b/vendor/github.com/cloudevents/sdk-go/v2/event/event_writer.go similarity index 75% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_writer.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/event_writer.go index 19982ca5b3e..3d392d5601e 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_writer.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/event_writer.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "fmt" @@ -9,29 +9,26 @@ var _ EventWriter = (*Event)(nil) // SetSpecVersion implements EventWriter.SetSpecVersion func (e *Event) SetSpecVersion(v string) { - if e.Context == nil { - switch v { - case CloudEventsVersionV01: - e.Context = EventContextV01{}.AsV01() - case CloudEventsVersionV02: - e.Context = EventContextV02{}.AsV02() - case CloudEventsVersionV03: - e.Context = EventContextV03{}.AsV03() - case CloudEventsVersionV1: - e.Context = EventContextV1{}.AsV1() - default: - e.fieldError("specversion", fmt.Errorf("a valid spec version is required: [%s, %s, %s, %s]", - CloudEventsVersionV01, CloudEventsVersionV02, CloudEventsVersionV03, CloudEventsVersionV1)) - return + switch v { + case CloudEventsVersionV03: + if e.Context == nil { + e.Context = &EventContextV03{} + } else { + e.Context = e.Context.AsV03() } - e.fieldOK("specversion") + case CloudEventsVersionV1: + if e.Context == nil { + e.Context = &EventContextV1{} + } else { + e.Context = e.Context.AsV1() + } + default: + e.fieldError("specversion", fmt.Errorf("a valid spec version is required: [%s, %s]", + CloudEventsVersionV03, CloudEventsVersionV1)) return } - if err := e.Context.SetSpecVersion(v); err != nil { - e.fieldError("specversion", err) - } else { - e.fieldOK("specversion") - } + e.fieldOK("specversion") + return } // SetType implements EventWriter.SetType diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext.go similarity index 88% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext.go index 5683a82929d..5ad2374349f 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext.go @@ -1,4 +1,4 @@ -package cloudevents +package event import "time" @@ -57,8 +57,6 @@ type EventContextReader interface { // EventContextWriter are the methods required to be a writer of context // attributes. type EventContextWriter interface { - // SetSpecVersion sets the spec version of the context. - SetSpecVersion(string) error // SetType sets the type of the context. SetType(string) error // SetSource sets the source of the context. @@ -88,16 +86,6 @@ type EventContextWriter interface { // EventContextConverter are the methods that allow for event version // conversion. type EventContextConverter interface { - // AsV01 provides a translation from whatever the "native" encoding of the - // CloudEvent was to the equivalent in v0.1 field names, moving fields to or - // from extensions as necessary. - AsV01() *EventContextV01 - - // AsV02 provides a translation from whatever the "native" encoding of the - // CloudEvent was to the equivalent in v0.2 field names, moving fields to or - // from extensions as necessary. - AsV02() *EventContextV02 - // AsV03 provides a translation from whatever the "native" encoding of the // CloudEvent was to the equivalent in v0.3 field names, moving fields to or // from extensions as necessary. diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03.go similarity index 82% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03.go index 2e714d18768..51b64a77041 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "encoding/json" @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/cloudevents/sdk-go/v2/types" ) const ( @@ -17,12 +17,10 @@ const ( // EventContextV03 represents the non-data attributes of a CloudEvents v0.3 // event. type EventContextV03 struct { - // SpecVersion - The version of the CloudEvents specification used by the event. - SpecVersion string `json:"specversion"` // Type - The type of the occurrence which has happened. Type string `json:"type"` // Source - A URI describing the event producer. - Source types.URLRef `json:"source"` + Source types.URIRef `json:"source"` // Subject - The subject of the event in the context of the event producer // (identified by `source`). Subject *string `json:"subject,omitempty"` @@ -31,7 +29,7 @@ type EventContextV03 struct { // Time - A Timestamp when the event happened. Time *types.Timestamp `json:"time,omitempty"` // DataSchema - A link to the schema that the `data` attribute adheres to. - SchemaURL *types.URLRef `json:"schemaurl,omitempty"` + SchemaURL *types.URIRef `json:"schemaurl,omitempty"` // GetDataMediaType - A MIME (RFC2046) string describing the media type of `data`. // TODO: Should an empty string assume `application/json`, `application/octet-stream`, or auto-detect the content? DataContentType *string `json:"datacontenttype,omitempty"` @@ -82,6 +80,10 @@ func (ec *EventContextV03) SetExtension(name string, value interface{}) error { } if value == nil { delete(ec.Extensions, name) + if len(ec.Extensions) == 0 { + ec.Extensions = nil + } + return nil } else { v, err := types.Validate(value) if err == nil { @@ -89,61 +91,42 @@ func (ec *EventContextV03) SetExtension(name string, value interface{}) error { } return err } - return nil } // Clone implements EventContextConverter.Clone func (ec EventContextV03) Clone() EventContext { - return ec.AsV03() -} - -// AsV01 implements EventContextConverter.AsV01 -func (ec EventContextV03) AsV01() *EventContextV01 { - ecv2 := ec.AsV02() - return ecv2.AsV01() -} - -// AsV02 implements EventContextConverter.AsV02 -func (ec EventContextV03) AsV02() *EventContextV02 { - ret := EventContextV02{ - SpecVersion: CloudEventsVersionV02, - ID: ec.ID, - Time: ec.Time, - Type: ec.Type, - SchemaURL: ec.SchemaURL, - ContentType: ec.DataContentType, - Source: ec.Source, - Extensions: make(map[string]interface{}), - } - // Subject was introduced in 0.3, so put it in an extension for 0.2. - if ec.Subject != nil { - _ = ret.SetExtension(SubjectKey, *ec.Subject) + ec03 := ec.AsV03() + ec03.Source = types.Clone(ec.Source).(types.URIRef) + if ec.Time != nil { + ec03.Time = types.Clone(ec.Time).(*types.Timestamp) } - // DeprecatedDataContentEncoding was introduced in 0.3, so put it in an extension for 0.2. - if ec.DataContentEncoding != nil { - _ = ret.SetExtension(DataContentEncodingKey, *ec.DataContentEncoding) + if ec.SchemaURL != nil { + ec03.SchemaURL = types.Clone(ec.SchemaURL).(*types.URIRef) } - if ec.Extensions != nil { - for k, v := range ec.Extensions { - ret.Extensions[k] = v - } + ec03.Extensions = ec.cloneExtensions() + return ec03 +} + +func (ec *EventContextV03) cloneExtensions() map[string]interface{} { + old := ec.Extensions + if old == nil { + return nil } - if len(ret.Extensions) == 0 { - ret.Extensions = nil + new := make(map[string]interface{}, len(ec.Extensions)) + for k, v := range old { + new[k] = types.Clone(v) } - return &ret + return new } // AsV03 implements EventContextConverter.AsV03 func (ec EventContextV03) AsV03() *EventContextV03 { - ec.SpecVersion = CloudEventsVersionV03 return &ec } // AsV04 implements EventContextConverter.AsV04 func (ec EventContextV03) AsV1() *EventContextV1 { ret := EventContextV1{ - SpecVersion: CloudEventsVersionV1, ID: ec.ID, Time: ec.Time, Type: ec.Type, @@ -192,16 +175,6 @@ func (ec EventContextV03) Validate() error { errors = append(errors, "type: MUST be a non-empty string") } - // specversion - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - specVersion := strings.TrimSpace(ec.SpecVersion) - if specVersion == "" { - errors = append(errors, "specversion: MUST be a non-empty string") - } - // source // Type: URI-reference // Constraints: @@ -295,7 +268,7 @@ func (ec EventContextV03) String() string { b.WriteString("Context Attributes,\n") - b.WriteString(" specversion: " + ec.SpecVersion + "\n") + b.WriteString(" specversion: " + CloudEventsVersionV03 + "\n") b.WriteString(" type: " + ec.Type + "\n") b.WriteString(" source: " + ec.Source.String() + "\n") if ec.Subject != nil { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_reader.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_reader.go similarity index 96% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_reader.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_reader.go index 2b3cc207fc2..8e6eec5caa3 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_reader.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_reader.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "fmt" @@ -8,9 +8,6 @@ import ( // GetSpecVersion implements EventContextReader.GetSpecVersion func (ec EventContextV03) GetSpecVersion() string { - if ec.SpecVersion != "" { - return ec.SpecVersion - } return CloudEventsVersionV03 } diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_writer.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_writer.go similarity index 81% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_writer.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_writer.go index 0c1bb8428e4..94748c67c59 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v03_writer.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v03_writer.go @@ -1,27 +1,17 @@ -package cloudevents +package event import ( "errors" - "fmt" "net/url" "strings" "time" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/cloudevents/sdk-go/v2/types" ) // Adhere to EventContextWriter var _ EventContextWriter = (*EventContextV03)(nil) -// SetSpecVersion implements EventContextWriter.SetSpecVersion -func (ec *EventContextV03) SetSpecVersion(v string) error { - if v != CloudEventsVersionV03 { - return fmt.Errorf("invalid version %q, expecting %q", v, CloudEventsVersionV03) - } - ec.SpecVersion = CloudEventsVersionV03 - return nil -} - // SetDataContentType implements EventContextWriter.SetDataContentType func (ec *EventContextV03) SetDataContentType(ct string) error { ct = strings.TrimSpace(ct) @@ -46,7 +36,7 @@ func (ec *EventContextV03) SetSource(u string) error { if err != nil { return err } - ec.Source = types.URLRef{URL: *pu} + ec.Source = types.URIRef{URL: *pu} return nil } @@ -92,7 +82,7 @@ func (ec *EventContextV03) SetDataSchema(u string) error { if err != nil { return err } - ec.SchemaURL = &types.URLRef{URL: *pu} + ec.SchemaURL = &types.URIRef{URL: *pu} return nil } diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1.go similarity index 88% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1.go index 8bb8cb41bd7..41ed59a09c4 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "errors" @@ -7,7 +7,7 @@ import ( "sort" "strings" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/cloudevents/sdk-go/v2/types" ) // WIP: AS OF SEP 20, 2019 @@ -26,9 +26,6 @@ type EventContextV1 struct { // Source - A URI describing the event producer. // +required Source types.URIRef `json:"source"` - // SpecVersion - The version of the CloudEvents specification used by the event. - // +required - SpecVersion string `json:"specversion"` // Type - The type of the occurrence which has happened. // +required Type string `json:"type"` @@ -85,6 +82,9 @@ func (ec *EventContextV1) SetExtension(name string, value interface{}) error { } if value == nil { delete(ec.Extensions, name) + if len(ec.Extensions) == 0 { + ec.Extensions = nil + } return nil } else { v, err := types.Validate(value) // Ensure it's a legal CE attribute value @@ -97,36 +97,44 @@ func (ec *EventContextV1) SetExtension(name string, value interface{}) error { // Clone implements EventContextConverter.Clone func (ec EventContextV1) Clone() EventContext { - return ec.AsV1() -} - -// AsV01 implements EventContextConverter.AsV01 -func (ec EventContextV1) AsV01() *EventContextV01 { - ecv2 := ec.AsV02() - return ecv2.AsV01() + ec1 := ec.AsV1() + ec1.Source = types.Clone(ec.Source).(types.URIRef) + if ec.Time != nil { + ec1.Time = types.Clone(ec.Time).(*types.Timestamp) + } + if ec.DataSchema != nil { + ec1.DataSchema = types.Clone(ec.DataSchema).(*types.URI) + } + ec1.Extensions = ec.cloneExtensions() + return ec1 } -// AsV02 implements EventContextConverter.AsV02 -func (ec EventContextV1) AsV02() *EventContextV02 { - ecv3 := ec.AsV03() - return ecv3.AsV02() +func (ec *EventContextV1) cloneExtensions() map[string]interface{} { + old := ec.Extensions + if old == nil { + return nil + } + new := make(map[string]interface{}, len(ec.Extensions)) + for k, v := range old { + new[k] = types.Clone(v) + } + return new } // AsV03 implements EventContextConverter.AsV03 func (ec EventContextV1) AsV03() *EventContextV03 { ret := EventContextV03{ - SpecVersion: CloudEventsVersionV03, ID: ec.ID, Time: ec.Time, Type: ec.Type, DataContentType: ec.DataContentType, - Source: types.URLRef{URL: ec.Source.URL}, + Source: types.URIRef{URL: ec.Source.URL}, Subject: ec.Subject, Extensions: make(map[string]interface{}), } if ec.DataSchema != nil { - ret.SchemaURL = &types.URLRef{URL: ec.DataSchema.URL} + ret.SchemaURL = &types.URIRef{URL: ec.DataSchema.URL} } // TODO: DeprecatedDataContentEncoding needs to be moved to extensions. @@ -152,7 +160,6 @@ func (ec EventContextV1) AsV03() *EventContextV03 { // AsV04 implements EventContextConverter.AsV04 func (ec EventContextV1) AsV1() *EventContextV1 { - ec.SpecVersion = CloudEventsVersionV1 return &ec } @@ -184,16 +191,6 @@ func (ec EventContextV1) Validate() error { errors = append(errors, "source: REQUIRED") } - // specversion - // Type: String - // Constraints: - // REQUIRED - // MUST be a non-empty string - specVersion := strings.TrimSpace(ec.SpecVersion) - if specVersion == "" { - errors = append(errors, "specversion: MUST be a non-empty string") - } - // type // Type: String // Constraints: @@ -268,7 +265,7 @@ func (ec EventContextV1) String() string { b.WriteString("Context Attributes,\n") - b.WriteString(" specversion: " + ec.SpecVersion + "\n") + b.WriteString(" specversion: " + CloudEventsVersionV1 + "\n") b.WriteString(" type: " + ec.Type + "\n") b.WriteString(" source: " + ec.Source.String() + "\n") if ec.Subject != nil { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_reader.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_reader.go similarity index 95% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_reader.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_reader.go index e3f329d31b0..64f1a919b32 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_reader.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_reader.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "fmt" @@ -8,10 +8,7 @@ import ( // GetSpecVersion implements EventContextReader.GetSpecVersion func (ec EventContextV1) GetSpecVersion() string { - if ec.SpecVersion != "" { - return ec.SpecVersion - } - return CloudEventsVersionV03 + return CloudEventsVersionV1 } // GetDataContentType implements EventContextReader.GetDataContentType @@ -80,6 +77,9 @@ func (ec EventContextV1) DeprecatedGetDataContentEncoding() string { // GetExtensions implements EventContextReader.GetExtensions func (ec EventContextV1) GetExtensions() map[string]interface{} { + if len(ec.Extensions) == 0 { + return nil + } // For now, convert the extensions of v1.0 to the pre-v1.0 style. ext := make(map[string]interface{}, len(ec.Extensions)) for k, v := range ec.Extensions { diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_writer.go b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_writer.go similarity index 84% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_writer.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_writer.go index dc33ba2f6bb..1ec29e65e42 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v1_writer.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/eventcontext_v1_writer.go @@ -1,27 +1,17 @@ -package cloudevents +package event import ( "errors" - "fmt" "net/url" "strings" "time" - "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/cloudevents/sdk-go/v2/types" ) // Adhere to EventContextWriter var _ EventContextWriter = (*EventContextV1)(nil) -// SetSpecVersion implements EventContextWriter.SetSpecVersion -func (ec *EventContextV1) SetSpecVersion(v string) error { - if v != CloudEventsVersionV1 { - return fmt.Errorf("invalid version %q, expecting %q", v, CloudEventsVersionV1) - } - ec.SpecVersion = CloudEventsVersionV1 - return nil -} - // SetDataContentType implements EventContextWriter.SetDataContentType func (ec *EventContextV1) SetDataContentType(ct string) error { ct = strings.TrimSpace(ct) diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/extensions.go b/vendor/github.com/cloudevents/sdk-go/v2/event/extensions.go similarity index 65% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/extensions.go rename to vendor/github.com/cloudevents/sdk-go/v2/event/extensions.go index e6a7d5325c0..4a202e5e487 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/extensions.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/event/extensions.go @@ -1,4 +1,4 @@ -package cloudevents +package event import ( "regexp" @@ -9,12 +9,6 @@ const ( // DataContentEncodingKey is the key to DeprecatedDataContentEncoding for versions that do not support data content encoding // directly. DataContentEncodingKey = "datacontentencoding" - - // EventTypeVersionKey is the key to EventTypeVersion for versions that do not support event type version directly. - EventTypeVersionKey = "eventtypeversion" - - // SubjectKey is the key to Subject for versions that do not support subject directly. - SubjectKey = "subject" ) func caseInsensitiveSearch(key string, space map[string]interface{}) (interface{}, bool) { diff --git a/vendor/github.com/cloudevents/sdk-go/v2/extensions/distributed_tracing_extension.go b/vendor/github.com/cloudevents/sdk-go/v2/extensions/distributed_tracing_extension.go new file mode 100644 index 00000000000..f0206f33c1f --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/extensions/distributed_tracing_extension.go @@ -0,0 +1,126 @@ +package extensions + +import ( + "context" + "reflect" + "strings" + + "github.com/cloudevents/sdk-go/v2/event" + + "github.com/cloudevents/sdk-go/v2/types" + "github.com/lightstep/tracecontext.go/traceparent" + "github.com/lightstep/tracecontext.go/tracestate" + "go.opencensus.io/trace" + octs "go.opencensus.io/trace/tracestate" +) + +const ( + TraceParentExtension = "traceparent" + TraceStateExtension = "tracestate" +) + +// DistributedTracingExtension represents the extension for cloudevents context +type DistributedTracingExtension struct { + TraceParent string `json:"traceparent"` + TraceState string `json:"tracestate"` +} + +// AddTracingAttributes adds the tracing attributes traceparent and tracestate to the cloudevents context +func (d DistributedTracingExtension) AddTracingAttributes(e event.EventWriter) { + if d.TraceParent != "" { + value := reflect.ValueOf(d) + typeOf := value.Type() + + for i := 0; i < value.NumField(); i++ { + k := strings.ToLower(typeOf.Field(i).Name) + v := value.Field(i).Interface() + if k == TraceStateExtension && v == "" { + continue + } + e.SetExtension(k, v) + } + } +} + +func GetDistributedTracingExtension(event event.Event) (DistributedTracingExtension, bool) { + if tp, ok := event.Extensions()[TraceParentExtension]; ok { + if tpStr, err := types.ToString(tp); err == nil { + var tsStr string + if ts, ok := event.Extensions()[TraceStateExtension]; ok { + tsStr, _ = types.ToString(ts) + } + return DistributedTracingExtension{TraceParent: tpStr, TraceState: tsStr}, true + } + } + return DistributedTracingExtension{}, false +} + +// FromSpanContext populates DistributedTracingExtension from a SpanContext. +func FromSpanContext(sc trace.SpanContext) DistributedTracingExtension { + tp := traceparent.TraceParent{ + TraceID: sc.TraceID, + SpanID: sc.SpanID, + Flags: traceparent.Flags{ + Recorded: sc.IsSampled(), + }, + } + + entries := make([]string, 0, len(sc.Tracestate.Entries())) + for _, entry := range sc.Tracestate.Entries() { + entries = append(entries, strings.Join([]string{entry.Key, entry.Value}, "=")) + } + + return DistributedTracingExtension{ + TraceParent: tp.String(), + TraceState: strings.Join(entries, ","), + } +} + +// ToSpanContext creates a SpanContext from a DistributedTracingExtension instance. +func (d DistributedTracingExtension) ToSpanContext() (trace.SpanContext, error) { + tp, err := traceparent.ParseString(d.TraceParent) + if err != nil { + return trace.SpanContext{}, err + } + sc := trace.SpanContext{ + TraceID: tp.TraceID, + SpanID: tp.SpanID, + } + if tp.Flags.Recorded { + sc.TraceOptions &= 1 + } + + if ts, err := tracestate.ParseString(d.TraceState); err == nil { + entries := make([]octs.Entry, 0, len(ts)) + for _, member := range ts { + var key string + if member.Vendor != "" { + key = member.Tenant + "@" + member.Vendor + } else { + key = member.Tenant + } + entries = append(entries, octs.Entry{Key: key, Value: member.Value}) + } + sc.Tracestate, _ = octs.New(nil, entries...) + } + + return sc, nil +} + +func (d DistributedTracingExtension) StartChildSpan(ctx context.Context, name string, opts ...trace.StartOption) (context.Context, *trace.Span) { + if sc, err := d.ToSpanContext(); err == nil { + tSpan := trace.FromContext(ctx) + ctx, span := trace.StartSpanWithRemoteParent(ctx, name, sc, opts...) + if tSpan != nil { + // Add link to the previous in-process trace. + tsc := tSpan.SpanContext() + span.AddLink(trace.Link{ + TraceID: tsc.TraceID, + SpanID: tsc.SpanID, + Type: trace.LinkTypeParent, + }) + } + return ctx, span + } + return ctx, nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/go.mod b/vendor/github.com/cloudevents/sdk-go/v2/go.mod similarity index 54% rename from vendor/github.com/cloudevents/sdk-go/go.mod rename to vendor/github.com/cloudevents/sdk-go/v2/go.mod index 71896ac8d6a..242594b6d63 100644 --- a/vendor/github.com/cloudevents/sdk-go/go.mod +++ b/vendor/github.com/cloudevents/sdk-go/v2/go.mod @@ -1,24 +1,21 @@ -module github.com/cloudevents/sdk-go +module github.com/cloudevents/sdk-go/v2 require ( cloud.google.com/go v0.40.0 contrib.go.opencensus.io/exporter/prometheus v0.1.0 - github.com/Azure/azure-sdk-for-go v30.1.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.2.0 // indirect - github.com/Azure/go-autorest/autorest/to v0.2.0 // indirect - github.com/Azure/go-autorest/autorest/validation v0.1.0 // indirect - github.com/fortytw2/leaktest v1.3.0 // indirect + github.com/Shopify/sarama v1.19.0 + github.com/cloudevents/sdk-go v1.1.2 github.com/google/go-cmp v0.4.0 github.com/google/uuid v1.1.1 + github.com/gorilla/mux v1.6.2 github.com/kelseyhightower/envconfig v1.4.0 + github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac github.com/nats-io/nats-server/v2 v2.1.2 github.com/nats-io/nats.go v1.9.1 github.com/pkg/errors v0.8.1 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.5.1 github.com/valyala/bytebufferpool v1.0.0 go.opencensus.io v0.22.0 - go.uber.org/atomic v1.4.0 // indirect - go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.10.0 golang.org/x/sync v0.0.0-20190423024810-112230192c58 google.golang.org/api v0.15.0 diff --git a/vendor/github.com/cloudevents/sdk-go/go.sum b/vendor/github.com/cloudevents/sdk-go/v2/go.sum similarity index 88% rename from vendor/github.com/cloudevents/sdk-go/go.sum rename to vendor/github.com/cloudevents/sdk-go/v2/go.sum index c4b4dce970c..1272fb964e8 100644 --- a/vendor/github.com/cloudevents/sdk-go/go.sum +++ b/vendor/github.com/cloudevents/sdk-go/v2/go.sum @@ -1,5 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.40.0 h1:FjSY7bOj+WzJe6TZRVtXI2b9kAYvtNg4lMbcH2+MUkk= cloud.google.com/go v0.40.0/go.mod h1:Tk58MuI9rbLMKlAjeO/bDnteAx7tX2gJIXw4T5Jwlro= @@ -26,7 +27,9 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -38,13 +41,18 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/sdk-go v1.1.2 h1:mg/7d+BzubBPrPpH1bdeF85BQZYV85j7Ljqat3+m+qE= +github.com/cloudevents/sdk-go v1.1.2/go.mod h1:ss+jWJ88wypiewnPEzChSBzTYXGpdcILoN9YHk8uhTQ= 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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -67,6 +75,7 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -82,13 +91,16 @@ github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -97,9 +109,15 @@ github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk= +github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -116,9 +134,12 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -145,6 +166,7 @@ github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nL github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -153,6 +175,9 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -171,6 +196,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -191,6 +218,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -231,7 +260,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.6.0 h1:2tJEkRfnZL5g1GeBUlITh/rqT5HG3sFcoVCUUxmgJ2g= google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4= google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -244,7 +272,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101 h1:wuGevabY6r+ivPNagjUXGGxF+GqgMd+dBhjsxW4q9u4= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -258,12 +285,21 @@ google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/observability/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/observability/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/keys.go b/vendor/github.com/cloudevents/sdk-go/v2/observability/keys.go similarity index 80% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/keys.go rename to vendor/github.com/cloudevents/sdk-go/v2/observability/keys.go index f032b10ecf7..afadddcf5ac 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/keys.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/observability/keys.go @@ -12,6 +12,9 @@ var ( ) const ( + // ClientSpanName is the key used to start spans from the client. + ClientSpanName = "cloudevents.client" + // ResultError is a shared result tag value for error. ResultError = "error" // ResultOK is a shared result tag value for success. diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/observer.go b/vendor/github.com/cloudevents/sdk-go/v2/observability/observer.go similarity index 64% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/observer.go rename to vendor/github.com/cloudevents/sdk-go/v2/observability/observer.go index 76e7b12fda2..b27ffa97357 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/observability/observer.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/observability/observer.go @@ -7,20 +7,18 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/tag" - "go.opencensus.io/trace" ) // Observable represents the the customization used by the Reporter for a given // measurement and trace for a single method. type Observable interface { - TraceName() string MethodName() string LatencyMs() *stats.Float64Measure } -// Reporter represents a running latency counter and trace span. When Error or -// OK are called, the latency is calculated and the trace space is ended. Error -// or OK are only allowed to be called once. +// Reporter represents a running latency counter. When Error or OK are +// called, the latency is calculated. Error or OK are only allowed to +// be called once. type Reporter interface { Error() OK() @@ -28,7 +26,6 @@ type Reporter interface { type reporter struct { ctx context.Context - span *trace.Span on Observable start time.Time once sync.Once @@ -39,30 +36,14 @@ func LatencyTags() []tag.Key { return []tag.Key{KeyMethod, KeyResult} } -var ( - // Tracing is disabled by default. It is very useful for profiling an - // application. - tracingEnabled = false -) - -// EnableTracing allows control over if tracing is enabled for the sdk. -// Default is false. This applies to all of the -// `github.com/cloudevents/sdk-go/...` package. -func EnableTracing(enabled bool) { - tracingEnabled = enabled -} +// Deprecated. Tracing is always enabled. +func EnableTracing(enabled bool) {} -// NewReporter creates and returns a reporter wrapping the provided Observable, -// and injects a trace span into the context. +// NewReporter creates and returns a reporter wrapping the provided Observable. func NewReporter(ctx context.Context, on Observable) (context.Context, Reporter) { - var span *trace.Span - if tracingEnabled { - ctx, span = trace.StartSpan(ctx, on.TraceName()) - } r := &reporter{ ctx: ctx, on: on, - span: span, start: time.Now(), } r.tagMethod() @@ -80,9 +61,6 @@ func (r *reporter) tagMethod() { func (r *reporter) record() { ms := float64(time.Since(r.start) / time.Millisecond) stats.Record(r.ctx, r.on.LatencyMs().M(ms)) - if r.span != nil { - r.span.End() - } } // Error records the result as an error. diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/doc.go new file mode 100644 index 00000000000..ac31166fc79 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/doc.go @@ -0,0 +1,26 @@ +/* + +Package transport defines interfaces to decouple the client package +from transport implementations. + +Most event sender and receiver applications should not use this +package, they should use the client package. This package is for +infrastructure developers implementing new transports, or intermediary +components like importers, channels or brokers. + +*/ +// TODO: merge these two things ^^ vv +/* +Package bindings contains packages that implement different protocol bindings. + +Package binding provides interfaces and helper functions for implementing and using protocol bindings in a uniform way. + +Available bindings: + +* HTTP (using net/http) +* Kafka (using github.com/Shopify/sarama) +* AMQP (using pack.ag/amqp) + +*/ + +package protocol diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/error.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/error.go similarity index 98% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/error.go rename to vendor/github.com/cloudevents/sdk-go/v2/protocol/error.go index bb4e8ec9f82..894cbbf3b13 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/error.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/error.go @@ -1,4 +1,4 @@ -package transport +package protocol import "fmt" diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/doc.go new file mode 100644 index 00000000000..0cc93918275 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/doc.go @@ -0,0 +1,5 @@ +package http + +/* +Module http implements an HTTP binding using net/http module +*/ diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/message.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/message.go new file mode 100644 index 00000000000..5777fd9c1f4 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/message.go @@ -0,0 +1,131 @@ +package http + +import ( + "context" + "io" + nethttp "net/http" + "strings" + + "github.com/cloudevents/sdk-go/v2/binding" + "github.com/cloudevents/sdk-go/v2/binding/format" + "github.com/cloudevents/sdk-go/v2/binding/spec" +) + +const prefix = "Ce-" + +var specs = spec.WithPrefix(prefix) + +const ContentType = "Content-Type" +const ContentLength = "Content-Length" + +// Message holds the Header and Body of a HTTP Request or Response. +// The Message instance *must* be constructed from NewMessage function. +// This message *cannot* be read several times. In order to read it more times, buffer it using binding/buffering methods +type Message struct { + Header nethttp.Header + BodyReader io.ReadCloser + OnFinish func(error) error + + format format.Format + version spec.Version +} + +// Check if http.Message implements binding.Message +var _ binding.Message = (*Message)(nil) + +// NewMessage returns a binding.Message with header and data. +// The returned binding.Message *cannot* be read several times. In order to read it more times, buffer it using binding/buffering methods +func NewMessage(header nethttp.Header, body io.ReadCloser) *Message { + m := Message{Header: header} + if body != nil { + m.BodyReader = body + } + if m.format = format.Lookup(header.Get(ContentType)); m.format == nil { + m.version = specs.Version(m.Header.Get(specs.PrefixedSpecVersionName())) + } + return &m +} + +// NewMessageFromHttpRequest returns a binding.Message with header and data. +// The returned binding.Message *cannot* be read several times. In order to read it more times, buffer it using binding/buffering methods +func NewMessageFromHttpRequest(req *nethttp.Request) *Message { + if req == nil { + return nil + } + return NewMessage(req.Header, req.Body) +} + +// NewMessageFromHttpResponse returns a binding.Message with header and data. +// The returned binding.Message *cannot* be read several times. In order to read it more times, buffer it using binding/buffering methods +func NewMessageFromHttpResponse(resp *nethttp.Response) *Message { + if resp == nil { + return nil + } + return NewMessage(resp.Header, resp.Body) +} + +func (m *Message) ReadEncoding() binding.Encoding { + if m.version != nil { + return binding.EncodingBinary + } + if m.format != nil { + return binding.EncodingStructured + } + return binding.EncodingUnknown +} + +func (m *Message) ReadStructured(ctx context.Context, encoder binding.StructuredWriter) error { + if m.format == nil { + return binding.ErrNotStructured + } else { + return encoder.SetStructuredEvent(ctx, m.format, m.BodyReader) + } +} + +func (m *Message) ReadBinary(ctx context.Context, encoder binding.BinaryWriter) error { + if m.version == nil { + return binding.ErrNotBinary + } + + err := encoder.Start(ctx) + if err != nil { + return err + } + + for k, v := range m.Header { + if strings.HasPrefix(k, prefix) { + attr := m.version.Attribute(k) + if attr != nil { + err = encoder.SetAttribute(attr, v[0]) + } else { + err = encoder.SetExtension(strings.ToLower(strings.TrimPrefix(k, prefix)), v[0]) + } + } else if k == ContentType { + err = encoder.SetAttribute(m.version.AttributeFromKind(spec.DataContentType), v[0]) + } + if err != nil { + return err + } + } + + if m.BodyReader != nil { + err = encoder.SetData(m.BodyReader) + if err != nil { + return err + } + } + + return encoder.End(ctx) +} + +func (m *Message) Finish(err error) error { + if m.BodyReader != nil { + _ = m.BodyReader.Close() + } + if m.OnFinish != nil { + return m.OnFinish(err) + } + // TODO: if in binary mode, there could be nothing in this request or + // response. Meaning Message is not nil but never going to be a valid event. + return nil +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/options.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/options.go new file mode 100644 index 00000000000..5ced0748b30 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/options.go @@ -0,0 +1,186 @@ +package http + +import ( + "fmt" + "net" + nethttp "net/http" + "net/url" + "strings" + "time" +) + +// Option is the function signature required to be considered an http.Option. +type Option func(*Protocol) error + +// WithTarget sets the outbound recipient of cloudevents when using an HTTP +// request. +func WithTarget(targetUrl string) Option { + return func(p *Protocol) error { + if p == nil { + return fmt.Errorf("http target option can not set nil protocol") + } + targetUrl = strings.TrimSpace(targetUrl) + if targetUrl != "" { + var err error + var target *url.URL + target, err = url.Parse(targetUrl) + if err != nil { + return fmt.Errorf("http target option failed to parse target url: %s", err.Error()) + } + + p.Target = target + + if p.RequestTemplate == nil { + p.RequestTemplate = &nethttp.Request{ + Method: nethttp.MethodPost, + } + } + p.RequestTemplate.URL = target + + return nil + } + return fmt.Errorf("http target option was empty string") + } +} + +// WithHeader sets an additional default outbound header for all cloudevents +// when using an HTTP request. +func WithHeader(key, value string) Option { + return func(p *Protocol) error { + if p == nil { + return fmt.Errorf("http header option can not set nil protocol") + } + key = strings.TrimSpace(key) + if key != "" { + if p.RequestTemplate == nil { + p.RequestTemplate = &nethttp.Request{ + Method: nethttp.MethodPost, + } + } + if p.RequestTemplate.Header == nil { + p.RequestTemplate.Header = nethttp.Header{} + } + p.RequestTemplate.Header.Add(key, value) + return nil + } + return fmt.Errorf("http header option was empty string") + } +} + +// WithShutdownTimeout sets the shutdown timeout when the http server is being shutdown. +func WithShutdownTimeout(timeout time.Duration) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http shutdown timeout option can not set nil protocol") + } + t.ShutdownTimeout = &timeout + return nil + } +} + +func checkListen(t *Protocol, prefix string) error { + switch { + case t.Port != nil: + return fmt.Errorf("%v port already set", prefix) + case t.listener != nil: + return fmt.Errorf("%v listener already set", prefix) + } + return nil +} + +// WithPort sets the listening port for StartReceiver. +// Only one of WithListener or WithPort is allowed. +func WithPort(port int) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http port option can not set nil protocol") + } + if port < 0 || port > 65535 { + return fmt.Errorf("http port option was given an invalid port: %d", port) + } + if err := checkListen(t, "http port option"); err != nil { + return err + } + t.setPort(port) + return nil + } +} + +// WithListener sets the listener for StartReceiver. +// Only one of WithListener or WithPort is allowed. +func WithListener(l net.Listener) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http listener option can not set nil protocol") + } + if err := checkListen(t, "http port option"); err != nil { + return err + } + t.listener = l + _, err := t.listen() + return err + } +} + +// WithPath sets the path to receive cloudevents on for HTTP transports. +func WithPath(path string) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http path option can not set nil protocol") + } + path = strings.TrimSpace(path) + if len(path) == 0 { + return fmt.Errorf("http path option was given an invalid path: %q", path) + } + t.Path = path + return nil + } +} + +// WithMethod sets the HTTP verb (GET, POST, PUT, etc.) to use +// when using an HTTP request. +func WithMethod(method string) Option { + return func(p *Protocol) error { + if p == nil { + return fmt.Errorf("http method option can not set nil protocol") + } + method = strings.TrimSpace(method) + if method != "" { + if p.RequestTemplate == nil { + p.RequestTemplate = &nethttp.Request{} + } + p.RequestTemplate.Method = method + return nil + } + return fmt.Errorf("http method option was empty string") + } +} + +// +// Middleware is a function that takes an existing http.Handler and wraps it in middleware, +// returning the wrapped http.Handler. +type Middleware func(next nethttp.Handler) nethttp.Handler + +// WithMiddleware adds an HTTP middleware to the transport. It may be specified multiple times. +// Middleware is applied to everything before it. For example +// `NewClient(WithMiddleware(foo), WithMiddleware(bar))` would result in `bar(foo(original))`. +func WithMiddleware(middleware Middleware) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http middleware option can not set nil protocol") + } + t.middleware = append(t.middleware, middleware) + return nil + } +} + +// WithRoundTripper sets the HTTP RoundTripper. +func WithRoundTripper(roundTripper nethttp.RoundTripper) Option { + return func(t *Protocol) error { + if t == nil { + return fmt.Errorf("http round tripper option can not set nil protocol") + } + t.roundTripper = roundTripper + return nil + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol.go new file mode 100644 index 00000000000..5591f9700db --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol.go @@ -0,0 +1,261 @@ +package http + +import ( + "context" + "fmt" + "io" + "net" + "net/http" + "net/url" + "sync" + "time" + + "github.com/cloudevents/sdk-go/v2/protocol" + + "github.com/cloudevents/sdk-go/v2/binding" + cecontext "github.com/cloudevents/sdk-go/v2/context" +) + +const ( + // DefaultShutdownTimeout defines the default timeout given to the http.Server when calling Shutdown. + DefaultShutdownTimeout = time.Minute * 1 +) + +// Protocol acts as both a http client and a http handler. +type Protocol struct { + Target *url.URL + RequestTemplate *http.Request + transformers binding.TransformerFactories + Client *http.Client + incoming chan msgErr + + // To support Opener: + + // ShutdownTimeout defines the timeout given to the http.Server when calling Shutdown. + // If nil, DefaultShutdownTimeout is used. + ShutdownTimeout *time.Duration + + // Port is the port to bind the receiver to. Defaults to 8080. + Port *int + // Path is the path to bind the receiver to. Defaults to "/". + Path string + + // Receive Mutex + reMu sync.Mutex + // Handler is the handler the http Server will use. Use this to reuse the + // http server. If nil, the Protocol will create a one. + Handler *http.ServeMux + listener net.Listener + roundTripper http.RoundTripper // TODO: use this. + server *http.Server + handlerRegistered bool + middleware []Middleware +} + +func New(opts ...Option) (*Protocol, error) { + p := &Protocol{ + transformers: make(binding.TransformerFactories, 0), + incoming: make(chan msgErr), + } + if err := p.applyOptions(opts...); err != nil { + return nil, err + } + + if p.Client == nil { + p.Client = http.DefaultClient + } + + if p.ShutdownTimeout == nil { + timeout := DefaultShutdownTimeout + p.ShutdownTimeout = &timeout + } + + return p, nil +} + +func (p *Protocol) applyOptions(opts ...Option) error { + for _, fn := range opts { + if err := fn(p); err != nil { + return err + } + } + return nil +} + +// Send implements binding.Sender +func (p *Protocol) Send(ctx context.Context, m binding.Message) error { + if ctx == nil { + return fmt.Errorf("nil Context") + } else if m == nil { + return fmt.Errorf("nil Message") + } + + _, err := p.Request(ctx, m) + return err +} + +// Request implements binding.Requester +func (p *Protocol) Request(ctx context.Context, m binding.Message) (binding.Message, error) { + if ctx == nil { + return nil, fmt.Errorf("nil Context") + } else if m == nil { + return nil, fmt.Errorf("nil Message") + } + + var err error + defer func() { _ = m.Finish(err) }() + + req := p.makeRequest(ctx) + + if p.Client == nil || req == nil || req.URL == nil { + return nil, fmt.Errorf("not initialized: %#v", p) + } + + if err = WriteRequest(ctx, m, req, p.transformers); err != nil { + return nil, err + } + resp, err := p.Client.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode/100 != 2 { + return nil, fmt.Errorf("%d %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + return NewMessage(resp.Header, resp.Body), nil +} + +func (p *Protocol) makeRequest(ctx context.Context) *http.Request { + // TODO: support custom headers from context? + req := &http.Request{ + Method: http.MethodPost, + Header: make(http.Header), + // TODO: HeaderFrom(ctx), + } + + if p.RequestTemplate != nil { + req.Method = p.RequestTemplate.Method + req.URL = p.RequestTemplate.URL + req.Close = p.RequestTemplate.Close + req.Host = p.RequestTemplate.Host + copyHeadersEnsure(p.RequestTemplate.Header, &req.Header) + } + + if p.Target != nil { + req.URL = p.Target + } + + // Override the default request with target from context. + if target := cecontext.TargetFrom(ctx); target != nil { + req.URL = target + } + return req.WithContext(ctx) +} + +// Ensure to is a non-nil map before copying +func copyHeadersEnsure(from http.Header, to *http.Header) { + if len(from) > 0 { + if *to == nil { + *to = http.Header{} + } + copyHeaders(from, *to) + } +} + +func copyHeaders(from, to http.Header) { + if from == nil || to == nil { + return + } + for header, values := range from { + for _, value := range values { + to.Add(header, value) + } + } +} + +// Receive the next incoming HTTP request as a CloudEvent. +// Returns non-nil error if the incoming HTTP request fails to parse as a CloudEvent +// Returns io.EOF if the receiver is closed. +func (p *Protocol) Receive(ctx context.Context) (binding.Message, error) { + if ctx == nil { + return nil, fmt.Errorf("nil Context") + } + + msg, fn, err := p.Respond(ctx) + // No-op the response. + defer func() { + if fn != nil { + _ = fn(ctx, nil, nil) + } + }() + return msg, err +} + +// Respond receives the next incoming HTTP request as a CloudEvent and waits +// for the response callback to invoked before continuing. +// Returns non-nil error if the incoming HTTP request fails to parse as a CloudEvent +// Returns io.EOF if the receiver is closed. +func (p *Protocol) Respond(ctx context.Context) (binding.Message, protocol.ResponseFn, error) { + if ctx == nil { + return nil, nil, fmt.Errorf("nil Context") + } + + select { + case in, ok := <-p.incoming: + if !ok { + return nil, nil, io.EOF + } + return in.msg, in.respFn, in.err + case <-ctx.Done(): + return nil, nil, io.EOF + } +} + +type msgErr struct { + msg *Message + respFn protocol.ResponseFn + err error +} + +// ServeHTTP implements http.Handler. +// Blocks until Message.Finish is called. +func (p *Protocol) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + + m := NewMessageFromHttpRequest(req) + if m == nil || m.ReadEncoding() == binding.EncodingUnknown { + p.incoming <- msgErr{msg: nil, err: binding.ErrUnknownEncoding} + return // if there was no message, return. + } + + done := make(chan error) + + m.OnFinish = func(err error) error { + done <- err + return nil + } + + var fn protocol.ResponseFn = func(ctx context.Context, resp binding.Message, er protocol.Result) error { + if resp != nil { + status := http.StatusOK + if er != nil { + var result *Result + if protocol.ResultAs(er, &result) { + if result.Status > 100 && result.Status < 600 { + status = result.Status + } + } + } + + err := WriteResponseWriter(ctx, resp, status, rw, p.transformers) + return resp.Finish(err) + } + + return nil + } + + p.incoming <- msgErr{msg: m, respFn: fn} // Send to Request + if err := <-done; err != nil { + fmt.Println("attempting to write an error out on response writer:", err) + http.Error(rw, fmt.Sprintf("cannot forward CloudEvent: %v", err), http.StatusInternalServerError) + } +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol_lifecycle.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol_lifecycle.go new file mode 100644 index 00000000000..039ccfa02cb --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol_lifecycle.go @@ -0,0 +1,139 @@ +package http + +import ( + "context" + "fmt" + "net" + "net/http" + "strings" + + "github.com/cloudevents/sdk-go/v2/protocol" + "go.opencensus.io/plugin/ochttp" + "go.opencensus.io/plugin/ochttp/propagation/tracecontext" +) + +var _ protocol.Opener = (*Protocol)(nil) + +func (e *Protocol) OpenInbound(ctx context.Context) error { + e.reMu.Lock() + defer e.reMu.Unlock() + + if e.Handler == nil { + e.Handler = http.NewServeMux() + } + + if !e.handlerRegistered { + // handler.Handle might panic if the user tries to use the same path as the sdk. + e.Handler.Handle(e.GetPath(), e) + e.handlerRegistered = true + } + + addr, err := e.listen() + if err != nil { + return err + } + + e.server = &http.Server{ + Addr: addr.String(), + Handler: &ochttp.Handler{ + Propagation: &tracecontext.HTTPFormat{}, + Handler: attachMiddleware(e.Handler, e.middleware), + FormatSpanName: formatSpanName, + }, + } + + // Shutdown + defer func() { + _ = e.server.Close() + e.server = nil + }() + + errChan := make(chan error, 1) + go func() { + errChan <- e.server.Serve(e.listener) + }() + + // nil check and default + shutdown := DefaultShutdownTimeout + if e.ShutdownTimeout != nil { + shutdown = *e.ShutdownTimeout + } + + // wait for the server to return or ctx.Done(). + select { + case <-ctx.Done(): + // Try a gracefully shutdown. + timeout := shutdown + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + err := e.server.Shutdown(ctx) + <-errChan // Wait for server goroutine to exit + return err + case err := <-errChan: + return err + } +} + +// GetPort returns the listening port. +// Returns -1 if there is a listening error. +// Note this will call net.Listen() if the listener is not already started. +func (e *Protocol) GetPort() int { + // Ensure we have a listener and therefore a port. + if _, err := e.listen(); err == nil || e.Port != nil { + return *e.Port + } + return -1 +} + +func formatSpanName(r *http.Request) string { + return "cloudevents.http." + r.URL.Path +} + +func (e *Protocol) setPort(port int) { + if e.Port == nil { + e.Port = new(int) + } + *e.Port = port +} + +// listen if not already listening, update t.Port +func (e *Protocol) listen() (net.Addr, error) { + if e.listener == nil { + port := 8080 + if e.Port != nil { + port = *e.Port + if port < 0 || port > 65535 { + return nil, fmt.Errorf("invalid port %d", port) + } + } + var err error + if e.listener, err = net.Listen("tcp", fmt.Sprintf(":%d", port)); err != nil { + return nil, err + } + } + addr := e.listener.Addr() + if tcpAddr, ok := addr.(*net.TCPAddr); ok { + e.setPort(tcpAddr.Port) + } + return addr, nil +} + +// GetPath returns the path the transport is hosted on. If the path is '/', +// the transport will handle requests on any URI. To discover the true path +// a request was received on, inspect the context from Receive(cxt, ...) with +// TransportContextFrom(ctx). +func (e *Protocol) GetPath() string { + path := strings.TrimSpace(e.Path) + if len(path) > 0 { + return path + } + return "/" // default +} + +// attachMiddleware attaches the HTTP middleware to the specified handler. +func attachMiddleware(h http.Handler, middleware []Middleware) http.Handler { + for _, m := range middleware { + h = m(h) + } + return h +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/result.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/result.go new file mode 100644 index 00000000000..f88534c4c0c --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/result.go @@ -0,0 +1,47 @@ +package http + +import ( + "errors" + "fmt" + + "github.com/cloudevents/sdk-go/v2/protocol" +) + +// NewResult returns a fully populated http Result that should be used as +// a transport.Result. +func NewResult(status int, messageFmt string, args ...interface{}) protocol.Result { + return &Result{ + Status: status, + Format: messageFmt, + Args: args, + } +} + +// Result wraps the fields required to make adjustments for http Responses. +type Result struct { + Status int + Format string + Args []interface{} +} + +// make sure Result implements error. +var _ error = (*Result)(nil) + +// Is returns if the target error is a Result type checking target. +func (e *Result) Is(target error) bool { + if o, ok := target.(*Result); ok { + if e.Status == o.Status { + return true + } + return false + } + // Allow for wrapped errors. + err := fmt.Errorf(e.Format, e.Args...) + return errors.Is(err, target) +} + +// Error returns the string that is formed by using the format string with the +// provided args. +func (e *Result) Error() string { + return fmt.Sprintf(e.Format, e.Args...) +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_request.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_request.go new file mode 100644 index 00000000000..14184a7b7a5 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_request.go @@ -0,0 +1,131 @@ +package http + +import ( + "bytes" + "context" + "io" + "io/ioutil" + "net/http" + "strings" + + "github.com/cloudevents/sdk-go/v2/binding" + "github.com/cloudevents/sdk-go/v2/binding/format" + "github.com/cloudevents/sdk-go/v2/binding/spec" + "github.com/cloudevents/sdk-go/v2/types" +) + +// Fill the provided httpRequest with the message m. +// Using context you can tweak the encoding processing (more details on binding.Write documentation). +func WriteRequest(ctx context.Context, m binding.Message, httpRequest *http.Request, transformers ...binding.TransformerFactory) error { + structuredWriter := (*httpRequestWriter)(httpRequest) + binaryWriter := (*httpRequestWriter)(httpRequest) + + _, err := binding.Write( + ctx, + m, + structuredWriter, + binaryWriter, + transformers..., + ) + return err +} + +type httpRequestWriter http.Request + +func (b *httpRequestWriter) SetStructuredEvent(ctx context.Context, format format.Format, event io.Reader) error { + b.Header.Set(ContentType, format.MediaType()) + return b.setBody(event) +} + +func (b *httpRequestWriter) Start(ctx context.Context) error { + return nil +} + +func (b *httpRequestWriter) End(ctx context.Context) error { + return nil +} + +func (b *httpRequestWriter) SetData(data io.Reader) error { + return b.setBody(data) +} + +// setBody is a cherry-pick of the implementation in http.NewRequestWithContext +func (b *httpRequestWriter) setBody(body io.Reader) error { + rc, ok := body.(io.ReadCloser) + if !ok && body != nil { + rc = ioutil.NopCloser(body) + } + b.Body = rc + if body != nil { + switch v := body.(type) { + case *bytes.Buffer: + b.ContentLength = int64(v.Len()) + buf := v.Bytes() + b.GetBody = func() (io.ReadCloser, error) { + r := bytes.NewReader(buf) + return ioutil.NopCloser(r), nil + } + case *bytes.Reader: + b.ContentLength = int64(v.Len()) + snapshot := *v + b.GetBody = func() (io.ReadCloser, error) { + r := snapshot + return ioutil.NopCloser(&r), nil + } + case *strings.Reader: + b.ContentLength = int64(v.Len()) + snapshot := *v + b.GetBody = func() (io.ReadCloser, error) { + r := snapshot + return ioutil.NopCloser(&r), nil + } + default: + // This is where we'd set it to -1 (at least + // if body != NoBody) to mean unknown, but + // that broke people during the Go 1.8 testing + // period. People depend on it being 0 I + // guess. Maybe retry later. See Issue 18117. + } + // For client requests, Request.ContentLength of 0 + // means either actually 0, or unknown. The only way + // to explicitly say that the ContentLength is zero is + // to set the Body to nil. But turns out too much code + // depends on NewRequest returning a non-nil Body, + // so we use a well-known ReadCloser variable instead + // and have the http package also treat that sentinel + // variable to mean explicitly zero. + if b.GetBody != nil && b.ContentLength == 0 { + b.Body = http.NoBody + b.GetBody = func() (io.ReadCloser, error) { return http.NoBody, nil } + } + } + return nil +} + +func (b *httpRequestWriter) SetAttribute(attribute spec.Attribute, value interface{}) error { + // Http headers, everything is a string! + s, err := types.Format(value) + if err != nil { + return err + } + + if attribute.Kind() == spec.DataContentType { + b.Header.Add(ContentType, s) + } else { + b.Header.Add(prefix+attribute.Name(), s) + } + return nil +} + +func (b *httpRequestWriter) SetExtension(name string, value interface{}) error { + // Http headers, everything is a string! + s, err := types.Format(value) + if err != nil { + return err + } + b.Header.Add(prefix+name, s) + return nil +} + +var _ binding.StructuredWriter = (*httpRequestWriter)(nil) // Test it conforms to the interface +var _ binding.BinaryWriter = (*httpRequestWriter)(nil) // Test it conforms to the interface diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_responsewriter.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_responsewriter.go new file mode 100644 index 00000000000..09eb58aba40 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_responsewriter.go @@ -0,0 +1,90 @@ +package http + +import ( + "context" + "io" + "net/http" + "strconv" + + "github.com/cloudevents/sdk-go/v2/binding" + "github.com/cloudevents/sdk-go/v2/binding/format" + "github.com/cloudevents/sdk-go/v2/binding/spec" + "github.com/cloudevents/sdk-go/v2/types" +) + +// Write out to the the provided httpResponseWriter with the message m. +// Using context you can tweak the encoding processing (more details on binding.Write documentation). +func WriteResponseWriter(ctx context.Context, m binding.Message, status int, rw http.ResponseWriter, transformers ...binding.TransformerFactory) error { + if status < 200 || status >= 600 { + status = http.StatusOK + } + writer := &httpResponseWriter{rw: rw, status: status} + + _, err := binding.Write( + ctx, + m, + writer, + writer, + transformers..., + ) + return err +} + +type httpResponseWriter struct { + rw http.ResponseWriter + status int +} + +func (b *httpResponseWriter) SetStructuredEvent(ctx context.Context, format format.Format, event io.Reader) error { + b.rw.Header().Set(ContentType, format.MediaType()) + return b.SetData(event) +} + +func (b *httpResponseWriter) Start(ctx context.Context) error { + return nil +} + +func (b *httpResponseWriter) End(ctx context.Context) error { + return nil +} + +func (b *httpResponseWriter) SetData(reader io.Reader) error { + // Finalize the headers. + b.rw.WriteHeader(b.status) + + // Write body. + copied, err := io.Copy(b.rw, reader) + if err != nil { + return err + } + b.rw.Header().Set("Content-Length", strconv.FormatInt(copied, 10)) + return nil +} + +func (b *httpResponseWriter) SetAttribute(attribute spec.Attribute, value interface{}) error { + // Http headers, everything is a string! + s, err := types.Format(value) + if err != nil { + return err + } + + if attribute.Kind() == spec.DataContentType { + b.rw.Header().Add(ContentType, s) + } else { + b.rw.Header().Add(prefix+attribute.Name(), s) + } + return nil +} + +func (b *httpResponseWriter) SetExtension(name string, value interface{}) error { + // Http headers, everything is a string! + s, err := types.Format(value) + if err != nil { + return err + } + b.rw.Header().Add(prefix+name, s) + return nil +} + +var _ binding.StructuredWriter = (*httpResponseWriter)(nil) // Test it conforms to the interface +var _ binding.BinaryWriter = (*httpResponseWriter)(nil) // Test it conforms to the interface diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/inbound.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/inbound.go new file mode 100644 index 00000000000..9fb0a71c1e0 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/inbound.go @@ -0,0 +1,41 @@ +package protocol + +import ( + "context" + + "github.com/cloudevents/sdk-go/v2/binding" +) + +// Receiver receives messages. +type Receiver interface { + // Receive blocks till a message is received or ctx expires. + // + // A non-nil error means the receiver is closed. + // io.EOF means it closed cleanly, any other value indicates an error. + Receive(ctx context.Context) (binding.Message, error) +} + +// ReceiveCloser is a Receiver that can be closed. +type ReceiveCloser interface { + Receiver + Closer +} + +// ResponseFn is the function callback provided from Responder.Respond to allow +// for a receiver to "reply" to a message it receives. +type ResponseFn func(ctx context.Context, m binding.Message, r Result) error + +// Responder receives messages and is given a callback to respond. +type Responder interface { + // Receive blocks till a message is received or ctx expires. + // + // A non-nil error means the receiver is closed. + // io.EOF means it closed cleanly, any other value indicates an error. + Respond(ctx context.Context) (binding.Message, ResponseFn, error) +} + +// ResponderCloser is a Responder that can be closed. +type ResponderCloser interface { + Responder + Closer +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/lifecycle.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/lifecycle.go new file mode 100644 index 00000000000..bb4de5e8974 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/lifecycle.go @@ -0,0 +1,16 @@ +package protocol + +import ( + "context" +) + +// Opener is the common interface for things that need to be opened. +type Opener interface { + // Blocking call. Context is used to cancel. + OpenInbound(ctx context.Context) error +} + +// Closer is the common interface for things that can be closed. +type Closer interface { + Close(ctx context.Context) error +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/outbound.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/outbound.go new file mode 100644 index 00000000000..ff5f3973a66 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/outbound.go @@ -0,0 +1,42 @@ +package protocol + +import ( + "context" + + "github.com/cloudevents/sdk-go/v2/binding" +) + +// Sender sends messages. +type Sender interface { + // Send a message. + // + // Send returns when the "outbound" message has been sent. The Sender may + // still be expecting acknowledgment or holding other state for the message. + // + // m.Finish() is called when sending is finished (both succeeded or failed): + // expected acknowledgments (or errors) have been received, the Sender is + // no longer holding any state for the message. + // m.Finish() may be called during or after Send(). + Send(ctx context.Context, m binding.Message) error +} + +// SendCloser is a Sender that can be closed. +type SendCloser interface { + Sender + Closer +} + +// Requester sends a message and receives a response +// +// Optional interface that may be implemented by protocols that support +// request/response correlation. +type Requester interface { + // Request sends m like Sender.Send() but also arranges to receive a response. + Request(ctx context.Context, m binding.Message) (binding.Message, error) +} + +// RequesterCloser is a Requester that can be closed. +type RequesterCloser interface { + Requester + Closer +} diff --git a/vendor/github.com/cloudevents/sdk-go/v2/protocol/result.go b/vendor/github.com/cloudevents/sdk-go/v2/protocol/result.go new file mode 100644 index 00000000000..b47bae2fbc5 --- /dev/null +++ b/vendor/github.com/cloudevents/sdk-go/v2/protocol/result.go @@ -0,0 +1,39 @@ +package protocol + +import ( + "errors" + "fmt" +) + +// Result leverages go's 1.13 error wrapping. +type Result error + +// Is reports whether any error in err's chain matches target. +// +// The chain consists of err itself followed by the sequence of errors obtained by +// repeatedly calling Unwrap. +// +// An error is considered to match a target if it is equal to that target or if +// it implements a method Is(error) bool such that Is(target) returns true. +// (text from errors/wrap.go) +var ResultIs = errors.Is + +// As finds the first error in err's chain that matches target, and if so, sets +// target to that error value and returns true. +// +// The chain consists of err itself followed by the sequence of errors obtained by +// repeatedly calling Unwrap. +// +// An error matches target if the error's concrete value is assignable to the value +// pointed to by target, or if the error has a method As(interface{}) bool such that +// As(target) returns true. In the latter case, the As method is responsible for +// setting target. +// +// As will panic if target is not a non-nil pointer to either a type that implements +// error, or to any interface type. As returns false if err is nil. +// (text from errors/wrap.go) +var ResultAs = errors.As + +func NewResult(messageFmt string, args ...interface{}) Result { + return fmt.Errorf(messageFmt, args...) // TODO: look at adding Ack/Nak support. +} diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/allocate.go b/vendor/github.com/cloudevents/sdk-go/v2/types/allocate.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/allocate.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/allocate.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/doc.go b/vendor/github.com/cloudevents/sdk-go/v2/types/doc.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/doc.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/doc.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/timestamp.go b/vendor/github.com/cloudevents/sdk-go/v2/types/timestamp.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/timestamp.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/timestamp.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/uri.go b/vendor/github.com/cloudevents/sdk-go/v2/types/uri.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/uri.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/uri.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/uriref.go b/vendor/github.com/cloudevents/sdk-go/v2/types/uriref.go similarity index 100% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/uriref.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/uriref.go diff --git a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/value.go b/vendor/github.com/cloudevents/sdk-go/v2/types/value.go similarity index 83% rename from vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/value.go rename to vendor/github.com/cloudevents/sdk-go/v2/types/value.go index 4086808e66a..c4bea9393d4 100644 --- a/vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/value.go +++ b/vendor/github.com/cloudevents/sdk-go/v2/types/value.go @@ -110,23 +110,30 @@ func Validate(v interface{}) (interface{}, error) { if v == nil { break } - return URI{*v}, nil + return URI{URL: *v}, nil case url.URL: - return URI{v}, nil + return URI{URL: v}, nil + case *URIRef: + if v != nil { + return *v, nil + } + return nil, nil case URIRef: return v, nil + case *URI: + if v != nil { + return *v, nil + } + return nil, nil case URI: return v, nil - case URLRef: - // Convert old type to new one - return URIRef{v.URL}, nil case time.Time: - return Timestamp{v}, nil + return Timestamp{Time: v}, nil case *time.Time: if v == nil { break } - return Timestamp{*v}, nil + return Timestamp{Time: *v}, nil case Timestamp: return v, nil } @@ -138,6 +145,45 @@ func Validate(v interface{}) (interface{}, error) { return nil, fmt.Errorf("invalid CloudEvents value: %#v", v) } +// Clone v clones a CloudEvents attribute value, which is one of the valid types: +// bool, int32, string, []byte, types.URI, types.URIRef, types.Timestamp +// Returns the same type +// Panics if the type is not valid +func Clone(v interface{}) interface{} { + if v == nil { + return nil + } + switch v := v.(type) { + case bool, int32, string, nil: + return v // Already a CloudEvents type, no validation needed. + case []byte: + clone := make([]byte, len(v)) + copy(clone, v) + return v + case url.URL: + return URI{v} + case *url.URL: + return &URI{*v} + case URIRef: + return v + case *URIRef: + return &URIRef{v.URL} + case URI: + return v + case *URI: + return &URI{v.URL} + case time.Time: + return Timestamp{v} + case *time.Time: + return &Timestamp{*v} + case Timestamp: + return v + case *Timestamp: + return &Timestamp{v.Time} + } + panic(fmt.Errorf("invalid CloudEvents value: %#v", v)) +} + // ToBool accepts a bool value or canonical "true"/"false" string. func ToBool(v interface{}) (bool, error) { v, err := Validate(v) @@ -210,8 +256,12 @@ func ToURL(v interface{}) (*url.URL, error) { return nil, err } switch v := v.(type) { + case *URI: + return &v.URL, nil case URI: return &v.URL, nil + case *URIRef: + return &v.URL, nil case URIRef: return &v.URL, nil case string: diff --git a/vendor/github.com/lightstep/tracecontext.go/LICENSE b/vendor/github.com/lightstep/tracecontext.go/LICENSE new file mode 100644 index 00000000000..853b46db127 --- /dev/null +++ b/vendor/github.com/lightstep/tracecontext.go/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/lightstep/tracecontext.go/traceparent/package.go b/vendor/github.com/lightstep/tracecontext.go/traceparent/package.go new file mode 100644 index 00000000000..251f0842034 --- /dev/null +++ b/vendor/github.com/lightstep/tracecontext.go/traceparent/package.go @@ -0,0 +1,192 @@ +package traceparent + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "regexp" +) + +const ( + // Version represents the maximum `traceparent` header version that is fully supported. + // The library attempts optimistic forwards compatibility with higher versions. + Version = 0 +) + +var ( + // ErrInvalidFormat occurs when the format is invalid, such as if there are missing characters + // or a field contains an unexpected character set. + ErrInvalidFormat = errors.New("tracecontext: Invalid traceparent format") + // ErrInvalidVersion occurs when the encoded version is invalid, i.e., is 255. + ErrInvalidVersion = errors.New("tracecontext: Invalid traceparent version") + // ErrInvalidTraceID occurs when the encoded trace ID is invalid, i.e., all bytes are 0 + ErrInvalidTraceID = errors.New("tracecontext: Invalid traceparent trace ID") + // ErrInvalidSpanID occurs when the encoded span ID is invalid, i.e., all bytes are 0 + ErrInvalidSpanID = errors.New("tracecontext: Invalid traceparent span ID") +) + +const ( + maxVersion = 254 + + numVersionBytes = 1 + numTraceIDBytes = 16 + numSpanIDBytes = 8 + numFlagBytes = 1 +) + +var ( + re = regexp.MustCompile(`^([a-f0-9]{2})-([a-f0-9]{32})-([a-f0-9]{16})-([a-f0-9]{2})(-.*)?$`) + + invalidTraceIDAllZeroes = make([]byte, numTraceIDBytes, numTraceIDBytes) + invalidSpanIDAllZeroes = make([]byte, numSpanIDBytes, numSpanIDBytes) +) + +// Flags contain recommendations from the caller relevant to the whole trace, e.g., for sampling. +type Flags struct { + // Recorded indicates that at least one span in the trace may have been recorded. + // Tracing systems are advised to record all new spans in recorded traces, as incomplete traces may lead to + // a degraded tracing experience. + Recorded bool +} + +// String encodes the Flags in an 8-bit field. +func (f Flags) String() string { + var flags [1]byte + if f.Recorded { + flags[0] = 1 + } + return fmt.Sprintf("%02x", flags) +} + +// TraceParent indicates information about a span and the trace of which it is part, +// so that child spans started in the same trace may propagate necessary data and share relevant behaviour. +type TraceParent struct { + // Version represents the version used to encode the `TraceParent`. + // Typically, this is the minimum of this library's supported version and the version of the header from which the `TraceParent` was decoded. + Version uint8 + // TraceID is the trace ID of the whole trace, and should be constant across all spans in a given trace. + // A `TraceID` that contains only 0 bytes should be treated as invalid. + TraceID [16]byte + // SpanID is the span ID of the span from which the `TraceParent` was derived, i.e., the parent of the next span that will be started. + // Span IDs should be unique within a given trace. + // A `TraceID` that contains only 0 bytes should be treated as invalid. + SpanID [8]byte + // Flags indicate behaviour that is recommended when handling new spans. + Flags Flags +} + +// String encodes the `TraceParent` into a string formatted according to the W3C spec. +// The string may be invalid if any fields are invalid, e.g., if the `TraceID` contains only 0 bytes. +func (tp TraceParent) String() string { + return fmt.Sprintf("%02x-%032x-%016x-%s", tp.Version, tp.TraceID, tp.SpanID, tp.Flags) +} + +// Parse attempts to decode a `TraceParent` from a byte array. +// It returns an error if the byte array is incorrectly formatted or otherwise invalid. +func Parse(b []byte) (TraceParent, error) { + return parse(b) +} + +// ParseString attempts to decode a `TraceParent` from a string. +// It returns an error if the string is incorrectly formatted or otherwise invalid. +func ParseString(s string) (TraceParent, error) { + return parse([]byte(s)) +} + +func parse(b []byte) (tp TraceParent, err error) { + matches := re.FindSubmatch(b) + if len(matches) < 6 { + err = ErrInvalidFormat + return + } + + var version uint8 + if version, err = parseVersion(matches[1]); err != nil { + return + } + if version == Version && len(matches[5]) > 0 { + err = ErrInvalidFormat + return + } + + var traceID [16]byte + if traceID, err = parseTraceID(matches[2]); err != nil { + return + } + + var spanID [8]byte + if spanID, err = parseSpanID(matches[3]); err != nil { + return + } + + var flags Flags + if flags, err = parseFlags(matches[4]); err != nil { + return + } + + tp.Version = Version + tp.TraceID = traceID + tp.SpanID = spanID + tp.Flags = flags + + return tp, nil +} + +func parseVersion(b []byte) (uint8, error) { + version, ok := parseEncodedSegment(b, numVersionBytes) + if !ok { + return 0, ErrInvalidFormat + } + if version[0] > maxVersion { + return 0, ErrInvalidVersion + } + return version[0], nil +} + +func parseTraceID(b []byte) (traceID [16]byte, err error) { + id, ok := parseEncodedSegment(b, numTraceIDBytes) + if !ok { + return traceID, ErrInvalidFormat + } + if bytes.Equal(id, invalidTraceIDAllZeroes) { + return traceID, ErrInvalidTraceID + } + + copy(traceID[:], id) + + return traceID, nil +} + +func parseSpanID(b []byte) (spanID [8]byte, err error) { + id, ok := parseEncodedSegment(b, numSpanIDBytes) + if !ok { + return spanID, ErrInvalidFormat + } + if bytes.Equal(id, invalidSpanIDAllZeroes) { + return spanID, ErrInvalidSpanID + } + + copy(spanID[:], id) + + return spanID, nil +} + +func parseFlags(b []byte) (Flags, error) { + flags, ok := parseEncodedSegment(b, numFlagBytes) + if !ok { + return Flags{}, ErrInvalidFormat + } + + return Flags{ + Recorded: (flags[0] & 1) == 1, + }, nil +} + +func parseEncodedSegment(src []byte, expectedLen int) ([]byte, bool) { + dst := make([]byte, hex.DecodedLen(len(src))) + if n, err := hex.Decode(dst, src); n != expectedLen || err != nil { + return dst, false + } + return dst, true +} diff --git a/vendor/github.com/lightstep/tracecontext.go/tracestate/package.go b/vendor/github.com/lightstep/tracecontext.go/tracestate/package.go new file mode 100644 index 00000000000..563ad1f8a14 --- /dev/null +++ b/vendor/github.com/lightstep/tracecontext.go/tracestate/package.go @@ -0,0 +1,123 @@ +package tracestate + +import ( + "errors" + "fmt" + "regexp" + "strings" +) + +var ( + // ErrInvalidListMember occurs if at least one list member is invalid, e.g., contains an unexpected character. + ErrInvalidListMember = errors.New("tracecontext: Invalid tracestate list member") + // ErrDuplicateListMemberKey occurs if at least two list members contain the same vendor-tenant pair. + ErrDuplicateListMemberKey = errors.New("tracecontext: Duplicate list member key in tracestate") + // ErrTooManyListMembers occurs if the list contains more than the maximum number of members per the spec, i.e., 32. + ErrTooManyListMembers = errors.New("tracecontext: Too many list members in tracestate") +) + +const ( + maxMembers = 32 + + delimiter = "," +) + +var ( + re = regexp.MustCompile(`^\s*(?:([a-z0-9_\-*/]{1,241})@([a-z0-9_\-*/]{1,14})|([a-z0-9_\-*/]{1,256}))=([\x20-\x2b\x2d-\x3c\x3e-\x7e]*[\x21-\x2b\x2d-\x3c\x3e-\x7e])\s*$`) +) + +// Member contains vendor-specific data that should be propagated across all new spans started within a given trace. +type Member struct { + // Vendor is a key representing a particular trace vendor. + Vendor string + // Tenant is a key used to distinguish between tenants of a multi-tenant trace vendor. + Tenant string + // Value is the particular data that the vendor intents to pass to child spans. + Value string +} + +// String encodes a `Member` into a string formatted according to the W3C spec. +// The string may be invalid if any fields are invalid, e.g, the vendor contains a non-compliant character. +func (m Member) String() string { + if m.Tenant == "" { + return fmt.Sprintf("%s=%s", m.Vendor, m.Value) + } + return fmt.Sprintf("%s@%s=%s", m.Vendor, m.Tenant, m.Value) +} + +// TraceState represents a list of `Member`s that should be propagated to new spans started in a trace. +type TraceState []Member + +// String encodes all `Member`s of the `TraceState` into a single string, formatted according to the W3C spec. +// The string may be invalid if any `Member`s are invalid, e.g., containing a non-compliant character. +func (ts TraceState) String() string { + var members []string + for _, member := range ts { + members = append(members, member.String()) + } + return strings.Join(members, ",") +} + +// Parse attempts to decode a `TraceState` from a byte array. +// It returns an error if the byte array is invalid, e.g., it contains an incorrectly formatted list member. +func Parse(traceState []byte) (TraceState, error) { + return parse(string(traceState)) +} + +// ParseString attempts to decode a `TraceState` from a string. +// It returns an error if the string is invalid, e.g., it contains an incorrectly formatted list member. +func ParseString(traceState string) (TraceState, error) { + return parse(traceState) +} + +func parse(traceState string) (ts TraceState, err error) { + found := make(map[string]interface{}) + + members := strings.Split(traceState, delimiter) + + for _, member := range members { + if len(member) == 0 { + continue + } + + var m Member + m, err = parseMember(member) + if err != nil { + return + } + + key := fmt.Sprintf("%s%s", m.Vendor, m.Tenant) + if _, ok := found[key]; ok { + err = ErrDuplicateListMemberKey + return + } + found[key] = nil + + ts = append(ts, m) + + if len(ts) > maxMembers { + err = ErrTooManyListMembers + return + } + } + + return +} + +func parseMember(s string) (Member, error) { + matches := re.FindStringSubmatch(s) + if len(matches) != 5 { + return Member{}, ErrInvalidListMember + } + + vendor := matches[1] + if vendor == "" { + vendor = matches[3] + } + + return Member{ + Vendor: vendor, + Tenant: matches[2], + Value: matches[4], + }, nil +} diff --git a/vendor/go.opencensus.io/plugin/ochttp/propagation/tracecontext/propagation.go b/vendor/go.opencensus.io/plugin/ochttp/propagation/tracecontext/propagation.go new file mode 100644 index 00000000000..65ab1e9966c --- /dev/null +++ b/vendor/go.opencensus.io/plugin/ochttp/propagation/tracecontext/propagation.go @@ -0,0 +1,187 @@ +// Copyright 2018, OpenCensus Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package tracecontext contains HTTP propagator for TraceContext standard. +// See https://github.com/w3c/distributed-tracing for more information. +package tracecontext // import "go.opencensus.io/plugin/ochttp/propagation/tracecontext" + +import ( + "encoding/hex" + "fmt" + "net/http" + "net/textproto" + "regexp" + "strings" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/propagation" + "go.opencensus.io/trace/tracestate" +) + +const ( + supportedVersion = 0 + maxVersion = 254 + maxTracestateLen = 512 + traceparentHeader = "traceparent" + tracestateHeader = "tracestate" + trimOWSRegexFmt = `^[\x09\x20]*(.*[^\x20\x09])[\x09\x20]*$` +) + +var trimOWSRegExp = regexp.MustCompile(trimOWSRegexFmt) + +var _ propagation.HTTPFormat = (*HTTPFormat)(nil) + +// HTTPFormat implements the TraceContext trace propagation format. +type HTTPFormat struct{} + +// SpanContextFromRequest extracts a span context from incoming requests. +func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) { + h, ok := getRequestHeader(req, traceparentHeader, false) + if !ok { + return trace.SpanContext{}, false + } + sections := strings.Split(h, "-") + if len(sections) < 4 { + return trace.SpanContext{}, false + } + + if len(sections[0]) != 2 { + return trace.SpanContext{}, false + } + ver, err := hex.DecodeString(sections[0]) + if err != nil { + return trace.SpanContext{}, false + } + version := int(ver[0]) + if version > maxVersion { + return trace.SpanContext{}, false + } + + if version == 0 && len(sections) != 4 { + return trace.SpanContext{}, false + } + + if len(sections[1]) != 32 { + return trace.SpanContext{}, false + } + tid, err := hex.DecodeString(sections[1]) + if err != nil { + return trace.SpanContext{}, false + } + copy(sc.TraceID[:], tid) + + if len(sections[2]) != 16 { + return trace.SpanContext{}, false + } + sid, err := hex.DecodeString(sections[2]) + if err != nil { + return trace.SpanContext{}, false + } + copy(sc.SpanID[:], sid) + + opts, err := hex.DecodeString(sections[3]) + if err != nil || len(opts) < 1 { + return trace.SpanContext{}, false + } + sc.TraceOptions = trace.TraceOptions(opts[0]) + + // Don't allow all zero trace or span ID. + if sc.TraceID == [16]byte{} || sc.SpanID == [8]byte{} { + return trace.SpanContext{}, false + } + + sc.Tracestate = tracestateFromRequest(req) + return sc, true +} + +// getRequestHeader returns a combined header field according to RFC7230 section 3.2.2. +// If commaSeparated is true, multiple header fields with the same field name using be +// combined using ",". +// If no header was found using the given name, "ok" would be false. +// If more than one headers was found using the given name, while commaSeparated is false, +// "ok" would be false. +func getRequestHeader(req *http.Request, name string, commaSeparated bool) (hdr string, ok bool) { + v := req.Header[textproto.CanonicalMIMEHeaderKey(name)] + switch len(v) { + case 0: + return "", false + case 1: + return v[0], true + default: + return strings.Join(v, ","), commaSeparated + } +} + +// TODO(rghetia): return an empty Tracestate when parsing tracestate header encounters an error. +// Revisit to return additional boolean value to indicate parsing error when following issues +// are resolved. +// https://github.com/w3c/distributed-tracing/issues/172 +// https://github.com/w3c/distributed-tracing/issues/175 +func tracestateFromRequest(req *http.Request) *tracestate.Tracestate { + h, _ := getRequestHeader(req, tracestateHeader, true) + if h == "" { + return nil + } + + var entries []tracestate.Entry + pairs := strings.Split(h, ",") + hdrLenWithoutOWS := len(pairs) - 1 // Number of commas + for _, pair := range pairs { + matches := trimOWSRegExp.FindStringSubmatch(pair) + if matches == nil { + return nil + } + pair = matches[1] + hdrLenWithoutOWS += len(pair) + if hdrLenWithoutOWS > maxTracestateLen { + return nil + } + kv := strings.Split(pair, "=") + if len(kv) != 2 { + return nil + } + entries = append(entries, tracestate.Entry{Key: kv[0], Value: kv[1]}) + } + ts, err := tracestate.New(nil, entries...) + if err != nil { + return nil + } + + return ts +} + +func tracestateToRequest(sc trace.SpanContext, req *http.Request) { + var pairs = make([]string, 0, len(sc.Tracestate.Entries())) + if sc.Tracestate != nil { + for _, entry := range sc.Tracestate.Entries() { + pairs = append(pairs, strings.Join([]string{entry.Key, entry.Value}, "=")) + } + h := strings.Join(pairs, ",") + + if h != "" && len(h) <= maxTracestateLen { + req.Header.Set(tracestateHeader, h) + } + } +} + +// SpanContextToRequest modifies the given request to include traceparent and tracestate headers. +func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) { + h := fmt.Sprintf("%x-%x-%x-%x", + []byte{supportedVersion}, + sc.TraceID[:], + sc.SpanID[:], + []byte{byte(sc.TraceOptions)}) + req.Header.Set(traceparentHeader, h) + tracestateToRequest(sc, req) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go index 2f04ee5b5c2..dd7378c8a34 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go @@ -947,6 +947,10 @@ func readPasswordLine(reader io.Reader) ([]byte, error) { n, err := reader.Read(buf[:]) if n > 0 { switch buf[0] { + case '\b': + if len(ret) > 0 { + ret = ret[:len(ret)-1] + } case '\n': return ret, nil case '\r': diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go index 5cfdf8f3f03..f614e9cb607 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -85,8 +85,8 @@ func ReadPassword(fd int) ([]byte, error) { } old := st - st &^= (windows.ENABLE_ECHO_INPUT) - st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT) + st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT) if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil { return nil, err } diff --git a/vendor/knative.dev/eventing-contrib/AUTHORS b/vendor/knative.dev/eventing-contrib/AUTHORS deleted file mode 100644 index 9a8f2f769f4..00000000000 --- a/vendor/knative.dev/eventing-contrib/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -# This is the list of Knative authors for copyright purposes. -# -# This does not necessarily list everyone who has contributed code, since in -# some cases, their employer may be the copyright holder. To see the full list -# of contributors, see the revision history in source control. -Google LLC diff --git a/vendor/knative.dev/eventing-contrib/LICENSE b/vendor/knative.dev/eventing-contrib/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/vendor/knative.dev/eventing-contrib/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/knative.dev/eventing-contrib/pkg/kncloudevents/good_client.go b/vendor/knative.dev/eventing-contrib/pkg/kncloudevents/good_client.go deleted file mode 100644 index 83cd6ae6dc8..00000000000 --- a/vendor/knative.dev/eventing-contrib/pkg/kncloudevents/good_client.go +++ /dev/null @@ -1,30 +0,0 @@ -package kncloudevents - -import ( - cloudevents "github.com/cloudevents/sdk-go" - "github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http" -) - -func NewDefaultClient(target ...string) (cloudevents.Client, error) { - tOpts := []http.Option{cloudevents.WithBinaryEncoding()} - if len(target) > 0 && target[0] != "" { - tOpts = append(tOpts, cloudevents.WithTarget(target[0])) - } - - // Make an http transport for the CloudEvents client. - t, err := cloudevents.NewHTTPTransport(tOpts...) - if err != nil { - return nil, err - } - - // Use the transport to make a new CloudEvents client. - c, err := cloudevents.NewClient(t, - cloudevents.WithUUIDs(), - cloudevents.WithTimeNow(), - ) - - if err != nil { - return nil, err - } - return c, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index b26faf11a2a..e846455cdb7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -92,19 +92,23 @@ github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1 github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1 github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1 github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1 -# github.com/cloudevents/sdk-go v1.0.0 -github.com/cloudevents/sdk-go -github.com/cloudevents/sdk-go/pkg/cloudevents -github.com/cloudevents/sdk-go/pkg/cloudevents/client -github.com/cloudevents/sdk-go/pkg/cloudevents/context -github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec -github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/json -github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/text -github.com/cloudevents/sdk-go/pkg/cloudevents/datacodec/xml -github.com/cloudevents/sdk-go/pkg/cloudevents/observability -github.com/cloudevents/sdk-go/pkg/cloudevents/transport -github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http -github.com/cloudevents/sdk-go/pkg/cloudevents/types +# github.com/cloudevents/sdk-go/v2 v2.0.0-preview6 +github.com/cloudevents/sdk-go/v2 +github.com/cloudevents/sdk-go/v2/binding +github.com/cloudevents/sdk-go/v2/binding/format +github.com/cloudevents/sdk-go/v2/binding/spec +github.com/cloudevents/sdk-go/v2/client +github.com/cloudevents/sdk-go/v2/context +github.com/cloudevents/sdk-go/v2/event +github.com/cloudevents/sdk-go/v2/event/datacodec +github.com/cloudevents/sdk-go/v2/event/datacodec/json +github.com/cloudevents/sdk-go/v2/event/datacodec/text +github.com/cloudevents/sdk-go/v2/event/datacodec/xml +github.com/cloudevents/sdk-go/v2/extensions +github.com/cloudevents/sdk-go/v2/observability +github.com/cloudevents/sdk-go/v2/protocol +github.com/cloudevents/sdk-go/v2/protocol/http +github.com/cloudevents/sdk-go/v2/types # github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew/spew # github.com/dgrijalva/jwt-go v3.2.0+incompatible @@ -230,6 +234,9 @@ github.com/jstemmer/go-junit-report/formatter github.com/jstemmer/go-junit-report/parser # github.com/konsorten/go-windows-terminal-sequences v1.0.2 github.com/konsorten/go-windows-terminal-sequences +# github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac +github.com/lightstep/tracecontext.go/traceparent +github.com/lightstep/tracecontext.go/tracestate # github.com/mailru/easyjson v0.7.0 github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer @@ -291,6 +298,7 @@ go.opencensus.io/metric/metricproducer go.opencensus.io/plugin/ocgrpc go.opencensus.io/plugin/ochttp go.opencensus.io/plugin/ochttp/propagation/b3 +go.opencensus.io/plugin/ochttp/propagation/tracecontext go.opencensus.io/resource go.opencensus.io/resource/resourcekeys go.opencensus.io/stats @@ -317,7 +325,7 @@ go.uber.org/zap/internal/ztest go.uber.org/zap/zapcore go.uber.org/zap/zaptest go.uber.org/zap/zaptest/observer -# golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 +# golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 golang.org/x/crypto/pkcs12 golang.org/x/crypto/pkcs12/internal/rc2 golang.org/x/crypto/ssh/terminal @@ -851,8 +859,6 @@ knative.dev/caching/pkg/apis/caching/v1alpha1 knative.dev/caching/pkg/client/clientset/versioned knative.dev/caching/pkg/client/clientset/versioned/scheme knative.dev/caching/pkg/client/clientset/versioned/typed/caching/v1alpha1 -# knative.dev/eventing-contrib v0.11.2 -knative.dev/eventing-contrib/pkg/kncloudevents # knative.dev/pkg v0.0.0-20200227193851-2fe8db300072 => knative.dev/pkg v0.0.0-20200227193851-2fe8db300072 knative.dev/pkg/apis knative.dev/pkg/apis/duck