Class: CloudEvents::Event::V1

Inherits:
Object
  • Object
show all
Includes:
CloudEvents::Event
Defined in:
lib/cloud_events/event/v1.rb

Overview

A CloudEvents V1 data type.

This object represents a complete CloudEvent, including the event data and context attributes. It supports the standard required and optional attributes defined in CloudEvents V1.0, and arbitrary extension attributes.

Values for most attributes can be obtained in their encoded string form via the #[] method. Additionally, standard attributes have their own accessor methods that may return decoded Ruby objects (such as a DateTime object for the time attribute).

The data attribute is treated specially because it is subject to arbitrary encoding governed by the datacontenttype attribute. Data is expressed in two related fields: #data and #data_encoded. The former, data, may be an arbitrary Ruby object representing the decoded form of the data (for example, a Hash for most JSON-formatted data.) The latter, data_encoded, must, if present, be a Ruby String object representing the encoded string or byte array form of the data.

When the CloudEvents Ruby SDK encodes an event for transmission, it will use the data_encoded field if present. Otherwise, it will attempt to encode the data field using any available encoder that recognizes the content-type. Currently, text and JSON types are supported. If the type is not supported, event encoding may fail. It is thus recommended that applications provide a data_encoded string, if the data object is nontrivially encoded.

This object is immutable, and Ractor-shareable on Ruby 3. The data and attribute values can be retrieved but not modified. To obtain an event with modifications, use the #with method to create a copy with the desired changes.

See https://github.com/cloudevents/spec/blob/v1.0/spec.md for descriptions of the standard attributes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from CloudEvents::Event

create

Constructor Details

#initialize(set_attributes: nil, attributes: nil, **args) ⇒ V1

Create a new cloud event object with the given data and attributes.

Specifying event attributes

Event attributes may be presented as keyword arguments, or as a Hash passed in via the special :set_attributes keyword argument (but not both). The :set_attributes keyword argument is useful for passing in attributes whose keys are strings rather than symbols, which some versions of Ruby will not accept as keyword arguments.

The following standard attributes are supported and exposed as attribute methods on the object.

  • :spec_version (or :specversion) [String] - required - The CloudEvents spec version (i.e. the specversion field.)
  • :id [String] - required - The event id field.
  • :source [String, URI] - required - The event source field.
  • :type [String] - required - The event type field.
  • :data [Object] - optional - The "decoded" Ruby object form of the event data field, if known. (e.g. a Hash representing a JSON document)
  • :data_encoded [String] - optional - The "encoded" string form of the event data field, if known. This should be set along with the data_content_type.
  • :data_content_type (or :datacontenttype) [String, ContentType] - optional - The content-type for the encoded data (i.e. the event datacontenttype field.)
  • :data_schema (or :dataschema) [String, URI] - optional - The event dataschema field.
  • :subject [String] - optional - The event subject field.
  • :time [String, DateTime, Time] - optional - The event time field.

Any additional attributes are assumed to be extension attributes. They are not available as separate methods, but can be accessed via the #[] operator.

Note that attribute objects passed in may get deep-frozen if they are used in the final event object. This is particularly important for the :data field, for example if you pass a structured hash. If this is an issue, make a deep copy of objects before passing to this constructor.

Specifying payload data

Typically you should provide both the :data and :data_encoded fields, the former representing the decoded (Ruby object) form of the data, and the second providing a hint to formatters and protocol bindings for how to seralize the data. In this case, the #data and #data_encoded methods will return the corresponding values, and #data_decoded? will return true to indicate that #data represents the decoded form.

If you provide only the :data field, omitting :data_encoded, then the value is expected to represent the decoded (Ruby object) form of the data. The #data method will return this decoded value, and #data_decoded? will return true. The #data_encoded method will return nil. When serializing such an event, it will be up to the formatter or protocol binding to encode the data. This means serialization could fail if the formatter does not understand the data's content type. Omitting :data_encoded is common if the content type is JSON related (e.g. application/json) and the event is being encoded in JSON structured format, because the data encoding is trivial. This form can also be used when the content type is text/*, for which encoding is also trivial.

If you provide only the :data_encoded field, omitting :data, then the value is expected to represent the encoded (string) form of the data. The #data_encoded method will return this value. Additionally, the #data method will return the same encoded value, and #data_decoded? will return false. Event objects of this form may be returned from a protocol binding when it decodes an event with a datacontenttype that it does not know how to interpret. Applications should query #data_decoded? to determine whether the #data method returns encoded or decoded data.

If you provide neither :data nor :data_encoded, the event will have no payload data. Both #data and #data_encoded will return nil, and #data_decoded? will return false. (Additionally, #data? will return false to signal the absence of any data.)

Parameters:

  • set_attributes (Hash) (defaults to: nil)

    The data and attributes, as a hash. (Also available using the deprecated keyword attributes.)

  • args (keywords)

    The data and attributes, as keyword arguments.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/cloud_events/event/v1.rb', line 139

def initialize set_attributes: nil, attributes: nil, **args
  interpreter = FieldInterpreter.new set_attributes || attributes || args
  @spec_version = interpreter.spec_version ["specversion", "spec_version"], accept: /^1(\.|$)/
  @id = interpreter.string ["id"], required: true
  @source = interpreter.uri ["source"], required: true
  @type = interpreter.string ["type"], required: true
  @data_encoded = interpreter.string ["data_encoded"], allow_empty: true
  @data = interpreter.data_object ["data"]
  if @data == FieldInterpreter::UNDEFINED
    @data = @data_encoded
    @data_decoded = false
  else
    @data_decoded = true
  end
  @data_content_type = interpreter.content_type ["datacontenttype", "data_content_type"]
  @data_schema = interpreter.uri ["dataschema", "data_schema"]
  @subject = interpreter.string ["subject"]
  @time = interpreter.rfc3339_date_time ["time"]
  @attributes = interpreter.finish_attributes
  freeze
end

Instance Attribute Details

#dataObject, ... (readonly)

The event data field, or nil if there is no data.

This may return the data as an encoded string or as a decoded Ruby object. The #data_decoded? method specifies whether the data value is decoded or encoded.

In most cases, #data returns a decoded value, unless the event was received from a source that could not decode the content. For example, most protocol bindings understand how to decode JSON, so an event received with a #data_content_type of application/json will usually return a decoded object (usually a Hash) from #data.

See also #data_encoded and #data_decoded?.

Returns:

  • (Object)

    if containing decoded data

  • (String)

    if containing encoded data

  • (nil)

    if there is no data



262
263
264
# File 'lib/cloud_events/event/v1.rb', line 262

def data
  @data
end

#data_content_typeCloudEvents::ContentType? (readonly) Also known as: datacontenttype

The optional datacontenttype field as a ContentType object, or nil if the field is absent.

Returns:



305
306
307
# File 'lib/cloud_events/event/v1.rb', line 305

def data_content_type
  @data_content_type
end

#data_encodedString? (readonly)

The encoded string representation of the data, i.e. its raw form used when encoding an event for transmission. This may be nil if there is no data, or if the encoded form is not known.

See also #data.

Returns:

  • (String, nil)


273
274
275
# File 'lib/cloud_events/event/v1.rb', line 273

def data_encoded
  @data_encoded
end

#data_schemaURI? (readonly) Also known as: dataschema

The optional dataschema field as a URI object, or nil if the field is absent.

Returns:

  • (URI, nil)


314
315
316
# File 'lib/cloud_events/event/v1.rb', line 314

def data_schema
  @data_schema
end

#idString (readonly)

The id field. Required.

Returns:

  • (String)


219
220
221
# File 'lib/cloud_events/event/v1.rb', line 219

def id
  @id
end

#sourceURI (readonly)

The source field as a URI object. Required.

Returns:

  • (URI)


226
227
228
# File 'lib/cloud_events/event/v1.rb', line 226

def source
  @source
end

#spec_versionString (readonly) Also known as: specversion

The specversion field. Required.

Returns:

  • (String)


240
241
242
# File 'lib/cloud_events/event/v1.rb', line 240

def spec_version
  @spec_version
end

#subjectString? (readonly)

The optional subject field, or nil if the field is absent.

Returns:

  • (String, nil)


322
323
324
# File 'lib/cloud_events/event/v1.rb', line 322

def subject
  @subject
end

#timeDateTime? (readonly)

The optional time field as a DateTime object, or nil if the field is absent.

Returns:

  • (DateTime, nil)


330
331
332
# File 'lib/cloud_events/event/v1.rb', line 330

def time
  @time
end

#typeString (readonly)

The type field. Required.

Returns:

  • (String)


233
234
235
# File 'lib/cloud_events/event/v1.rb', line 233

def type
  @type
end

Instance Method Details

#[](key) ⇒ String?

Return the value of the given named attribute. Both standard and extension attributes are supported.

Attribute names must be given as defined in the standard CloudEvents specification. For example specversion rather than spec_version.

Results are given in their "raw" form, generally a string. This may be different from the Ruby object returned from corresponding attribute methods. For example:

event["time"]     # => String rfc3339 representation
event.time        # => DateTime object

Results are also always frozen and cannot be modified in place.

Parameters:

  • key (String, Symbol)

    The attribute name.

Returns:

  • (String, nil)


200
201
202
# File 'lib/cloud_events/event/v1.rb', line 200

def [] key
  @attributes[key.to_s]
end

#data?boolean

Indicates whether the data field is present. If there is no data, #data will return nil, and #data_decoded? will return false.

Generally, if there is no data, the #data_content_type field should also be absent, but this is not enforced.

Returns:

  • (boolean)


295
296
297
# File 'lib/cloud_events/event/v1.rb', line 295

def data?
  !@data.nil? || @data_decoded
end

#data_decoded?true, false

Indicates whether the #data field returns decoded data.

Returns:

  • (true)

    if #data returns a decoded Ruby object

  • (false)

    if #data returns an encoded string or if the event has no data.



282
283
284
# File 'lib/cloud_events/event/v1.rb', line 282

def data_decoded?
  @data_decoded
end

#to_hHash

Return a hash representation of this event. The returned hash is an unfrozen deep copy. Modifications do not affect the original event.

Returns:

  • (Hash)


210
211
212
# File 'lib/cloud_events/event/v1.rb', line 210

def to_h
  Utils.deep_dup @attributes
end

#with(**changes) ⇒ FunctionFramework::CloudEvents::Event

Create and return a copy of this event with the given changes. See the constructor for the parameters that can be passed. In general, you can pass a new value for any attribute, or pass nil to remove an optional attribute.

Parameters:

  • changes (keywords)

    See #initialize for a list of arguments.

Returns:

  • (FunctionFramework::CloudEvents::Event)


170
171
172
173
174
175
176
177
178
179
# File 'lib/cloud_events/event/v1.rb', line 170

def with **changes
  changes = Utils.keys_to_strings changes
  attributes = @attributes.dup
  if changes.key?("data") || changes.key?("data_encoded")
    attributes.delete "data"
    attributes.delete "data_encoded"
  end
  attributes.merge! changes
  V1.new set_attributes: attributes
end