From 4202b698bcd201d28eca0de2ca534da13625e3ab Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Fri, 20 Mar 2020 16:01:57 -0700 Subject: [PATCH] Migrate tekton to the cloudevents sdk v2 While I was here, I also refactored some of the CloudEvents integration, some major points: you now send spec version 1.0 formatted events ID is not the task run name, this was a bad idea if you want to send more than one event for that run. The task run name is now used as the subject. ID is now a UUID. The event that is created for sending is only created once, and then used for all deliveries. This means that all subscribers get the same event content and ID. The event payload is marshaled inside the Event object. I show examples in the code and tests of how to set and get the payload as your custom struct. Removed a lot of the layers passing clients and event components around. Better to build the event and then call send on the client directly. This deleted a lot of code that was doing many things, like create an event, and then attempt to send it. Signed-off-by: Scott Nichols --- examples/v1alpha1/taskruns/cloud-event.yaml | 2 - go.mod | 6 +- go.sum | 17 +- .../cloudevent/cloud_event_controller.go | 21 +- .../resources/cloudevent/cloudevent.go | 98 +-- .../resources/cloudevent/cloudevent_test.go | 136 +--- .../resources/cloudevent/cloudeventclient.go | 21 +- .../cloudevent/cloudeventsfakeclient.go | 26 +- .../cloudevents/sdk-go/{ => v2}/LICENSE | 0 .../github.com/hashicorp/errwrap/go.mod | 2 - .../github.com/hashicorp/go-multierror/go.mod | 2 - .../lightstep/tracecontext.go/LICENSE | 21 + .../github.com/cloudevents/sdk-go/.gitignore | 29 - vendor/github.com/cloudevents/sdk-go/LICENSE | 201 ----- .../github.com/cloudevents/sdk-go/README.md | 135 ---- vendor/github.com/cloudevents/sdk-go/alias.go | 150 ---- .../sdk-go/pkg/cloudevents/client/client.go | 196 ----- .../pkg/cloudevents/client/observability.go | 68 -- .../sdk-go/pkg/cloudevents/client/options.go | 63 -- .../sdk-go/pkg/cloudevents/client/receiver.go | 193 ----- .../sdk-go/pkg/cloudevents/event_data.go | 135 ---- .../sdk-go/pkg/cloudevents/event_response.go | 37 - .../pkg/cloudevents/eventcontext_v01.go | 272 ------- .../cloudevents/eventcontext_v01_reader.go | 101 --- .../cloudevents/eventcontext_v01_writer.go | 104 --- .../pkg/cloudevents/eventcontext_v02.go | 291 -------- .../cloudevents/eventcontext_v02_reader.go | 101 --- .../cloudevents/eventcontext_v02_writer.go | 104 --- .../sdk-go/pkg/cloudevents/transport/codec.go | 35 - .../sdk-go/pkg/cloudevents/transport/doc.go | 12 - .../pkg/cloudevents/transport/http/codec.go | 154 ---- .../transport/http/codec_structured.go | 44 -- .../cloudevents/transport/http/codec_v01.go | 232 ------ .../cloudevents/transport/http/codec_v02.go | 261 ------- .../cloudevents/transport/http/codec_v03.go | 302 -------- .../cloudevents/transport/http/codec_v1.go | 245 ------- .../pkg/cloudevents/transport/http/context.go | 207 ------ .../pkg/cloudevents/transport/http/doc.go | 4 - .../cloudevents/transport/http/encoding.go | 205 ------ .../pkg/cloudevents/transport/http/message.go | 148 ---- .../transport/http/observability.go | 109 --- .../pkg/cloudevents/transport/http/options.go | 266 ------- .../cloudevents/transport/http/transport.go | 689 ------------------ .../pkg/cloudevents/transport/message.go | 9 - .../pkg/cloudevents/transport/transport.go | 44 -- .../sdk-go/pkg/cloudevents/types/urlref.go | 79 -- .../github.com/cloudevents/sdk-go/v2}/LICENSE | 0 .../github.com/cloudevents/sdk-go/v2/alias.go | 145 ++++ .../sdk-go/v2/binding/binary_writer.go | 39 + .../cloudevents/sdk-go/v2/binding/doc.go | 64 ++ .../cloudevents/sdk-go/v2/binding/encoding.go | 26 + .../sdk-go/v2/binding/event_message.go | 90 +++ .../sdk-go/v2/binding/finish_message.go | 27 + .../sdk-go/v2/binding/format/doc.go | 8 + .../sdk-go/v2/binding/format/format.go | 71 ++ .../cloudevents/sdk-go/v2/binding/message.go | 99 +++ .../sdk-go/v2/binding/spec/attributes.go | 136 ++++ .../cloudevents/sdk-go/v2/binding/spec/doc.go | 9 + .../sdk-go/v2/binding/spec/spec.go | 184 +++++ .../sdk-go/v2/binding/structured_writer.go | 17 + .../cloudevents/sdk-go/v2/binding/to_event.go | 127 ++++ .../sdk-go/v2/binding/transformer.go | 73 ++ .../cloudevents/sdk-go/v2/binding/write.go | 148 ++++ .../cloudevents/sdk-go/v2/client/client.go | 213 ++++++ .../sdk-go/v2/client/client_default.go | 26 + .../sdk-go/v2/client/client_observed.go | 99 +++ .../cloudevents => v2}/client/defaulters.go | 11 +- .../{pkg/cloudevents => v2}/client/doc.go | 0 .../sdk-go/v2/client/http_receiver.go | 39 + .../cloudevents/sdk-go/v2/client/invoker.go | 82 +++ .../sdk-go/v2/client/observability.go | 94 +++ .../cloudevents/sdk-go/v2/client/options.go | 73 ++ .../cloudevents/sdk-go/v2/client/receiver.go | 189 +++++ .../cloudevents => v2}/context/context.go | 24 - .../{pkg/cloudevents => v2}/context/doc.go | 0 .../{pkg/cloudevents => v2}/context/logger.go | 0 .../cloudevents => v2/event}/content_type.go | 9 +- .../event}/data_content_encoding.go | 2 +- .../event}/datacodec/codec.go | 29 +- .../v2/event/datacodec/codec_observed.go | 50 ++ .../cloudevents => v2/event}/datacodec/doc.go | 0 .../event}/datacodec/json/data.go | 24 - .../v2/event/datacodec/json/data_observed.go | 30 + .../event}/datacodec/json/doc.go | 0 .../event}/datacodec/json/observability.go | 14 +- .../event}/datacodec/observability.go | 14 +- .../event/datacodec/text/data.go} | 0 .../v2/event/datacodec/text/data_observed.go | 30 + .../sdk-go/v2/event/datacodec/text/doc.go | 4 + .../v2/event/datacodec/text/observability.go | 51 ++ .../event}/datacodec/xml/data.go | 24 - .../v2/event/datacodec/xml/data_observed.go | 30 + .../event}/datacodec/xml/doc.go | 0 .../event}/datacodec/xml/observability.go | 14 +- .../{pkg/cloudevents => v2/event}/doc.go | 2 +- .../{pkg/cloudevents => v2/event}/event.go | 69 +- .../cloudevents/sdk-go/v2/event/event_data.go | 112 +++ .../event}/event_interface.go | 23 +- .../cloudevents => v2/event}/event_marshal.go | 137 +--- .../event}/event_observability.go | 21 +- .../cloudevents => v2/event}/event_reader.go | 2 +- .../cloudevents => v2/event}/event_writer.go | 39 +- .../cloudevents => v2/event}/eventcontext.go | 14 +- .../event}/eventcontext_v03.go | 81 +- .../event}/eventcontext_v03_reader.go | 5 +- .../event}/eventcontext_v03_writer.go | 18 +- .../event}/eventcontext_v1.go | 59 +- .../event}/eventcontext_v1_reader.go | 10 +- .../event}/eventcontext_v1_writer.go | 14 +- .../cloudevents => v2/event}/extensions.go | 8 +- .../distributed_tracing_extension.go | 126 ++++ .../cloudevents/sdk-go/{ => v2}/go.mod | 15 +- .../cloudevents/sdk-go/{ => v2}/go.sum | 40 +- .../cloudevents => v2}/observability/doc.go | 0 .../cloudevents => v2}/observability/keys.go | 3 + .../observability/observer.go | 34 +- .../cloudevents/sdk-go/v2/protocol/doc.go | 26 + .../transport => v2/protocol}/error.go | 2 +- .../sdk-go/v2/protocol/http/doc.go | 5 + .../sdk-go/v2/protocol/http/message.go | 131 ++++ .../sdk-go/v2/protocol/http/options.go | 186 +++++ .../sdk-go/v2/protocol/http/protocol.go | 261 +++++++ .../v2/protocol/http/protocol_lifecycle.go | 139 ++++ .../sdk-go/v2/protocol/http/result.go | 47 ++ .../sdk-go/v2/protocol/http/write_request.go | 131 ++++ .../v2/protocol/http/write_responsewriter.go | 90 +++ .../cloudevents/sdk-go/v2/protocol/inbound.go | 41 ++ .../sdk-go/v2/protocol/lifecycle.go | 16 + .../sdk-go/v2/protocol/outbound.go | 42 ++ .../cloudevents/sdk-go/v2/protocol/result.go | 39 + .../{pkg/cloudevents => v2}/types/allocate.go | 0 .../{pkg/cloudevents => v2}/types/doc.go | 0 .../cloudevents => v2}/types/timestamp.go | 0 .../{pkg/cloudevents => v2}/types/uri.go | 0 .../{pkg/cloudevents => v2}/types/uriref.go | 0 .../{pkg/cloudevents => v2}/types/value.go | 64 +- .../lightstep/tracecontext.go/LICENSE | 21 + .../tracecontext.go/traceparent/package.go | 192 +++++ .../tracecontext.go/tracestate/package.go | 123 ++++ .../propagation/tracecontext/propagation.go | 187 +++++ .../x/crypto/ssh/terminal/terminal.go | 4 + .../x/crypto/ssh/terminal/util_windows.go | 4 +- vendor/knative.dev/eventing-contrib/AUTHORS | 6 - vendor/knative.dev/eventing-contrib/LICENSE | 201 ----- .../pkg/kncloudevents/good_client.go | 30 - vendor/modules.txt | 38 +- 146 files changed, 4654 insertions(+), 6219 deletions(-) rename third_party/github.com/cloudevents/sdk-go/{ => v2}/LICENSE (100%) create mode 100644 third_party/github.com/lightstep/tracecontext.go/LICENSE delete mode 100644 vendor/github.com/cloudevents/sdk-go/.gitignore delete mode 100644 vendor/github.com/cloudevents/sdk-go/LICENSE delete mode 100644 vendor/github.com/cloudevents/sdk-go/README.md delete mode 100644 vendor/github.com/cloudevents/sdk-go/alias.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/client.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/observability.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/options.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/client/receiver.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_data.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/event_response.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_reader.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v01_writer.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_reader.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/eventcontext_v02_writer.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/codec.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/doc.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_structured.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v01.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v02.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v03.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/codec_v1.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/context.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/doc.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/encoding.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/message.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/observability.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/options.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http/transport.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/message.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/transport/transport.go delete mode 100644 vendor/github.com/cloudevents/sdk-go/pkg/cloudevents/types/urlref.go rename {third_party/knative.dev/eventing-contrib/pkg/kncloudevents => vendor/github.com/cloudevents/sdk-go/v2}/LICENSE (100%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/alias.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/binary_writer.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/doc.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/encoding.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/event_message.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/finish_message.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/format/doc.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/format/format.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/message.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/spec/attributes.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/spec/doc.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/spec/spec.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/structured_writer.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/to_event.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/transformer.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/binding/write.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/client.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/client_default.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/client_observed.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/client/defaulters.go (73%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/client/doc.go (100%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/http_receiver.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/invoker.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/observability.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/options.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/client/receiver.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/context/context.go (62%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/context/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/context/logger.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/content_type.go (84%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/data_content_encoding.go (87%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/codec.go (75%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/codec_observed.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/json/data.go (79%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/json/data_observed.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/json/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/json/observability.go (79%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/observability.go (80%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents/datacodec/text/text.go => v2/event/datacodec/text/data.go} (100%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/data_observed.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/doc.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/text/observability.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/xml/data.go (78%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/datacodec/xml/data_observed.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/xml/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/datacodec/xml/observability.go (79%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/doc.go (86%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event.go (70%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/event/event_data.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event_interface.go (81%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event_marshal.go (67%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event_observability.go (78%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event_reader.go (99%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/event_writer.go (75%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext.go (88%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v03.go (82%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v03_reader.go (96%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v03_writer.go (81%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v1.go (88%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v1_reader.go (95%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/eventcontext_v1_writer.go (84%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2/event}/extensions.go (65%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/extensions/distributed_tracing_extension.go rename vendor/github.com/cloudevents/sdk-go/{ => v2}/go.mod (54%) rename vendor/github.com/cloudevents/sdk-go/{ => v2}/go.sum (88%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/observability/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/observability/keys.go (80%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/observability/observer.go (64%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/doc.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents/transport => v2/protocol}/error.go (98%) create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/doc.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/message.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/options.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/protocol_lifecycle.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/result.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_request.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/http/write_responsewriter.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/inbound.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/lifecycle.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/outbound.go create mode 100644 vendor/github.com/cloudevents/sdk-go/v2/protocol/result.go rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/allocate.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/doc.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/timestamp.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/uri.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/uriref.go (100%) rename vendor/github.com/cloudevents/sdk-go/{pkg/cloudevents => v2}/types/value.go (83%) create mode 100644 vendor/github.com/lightstep/tracecontext.go/LICENSE create mode 100644 vendor/github.com/lightstep/tracecontext.go/traceparent/package.go create mode 100644 vendor/github.com/lightstep/tracecontext.go/tracestate/package.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/propagation/tracecontext/propagation.go delete mode 100644 vendor/knative.dev/eventing-contrib/AUTHORS delete mode 100644 vendor/knative.dev/eventing-contrib/LICENSE delete mode 100644 vendor/knative.dev/eventing-contrib/pkg/kncloudevents/good_client.go 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