Skip to content

Cloud Events callback doesn't properly send Cloud Events #235

@mattmoor

Description

@mattmoor

I have a trivial function:

// handle shared the logic for producing the Response event from the Request.
const handle = (data) => {
    return {
	a: Math.floor(data.a / data.b),
	b: data.a % data.b
    }
}

function event(cloudEvent) {
  console.log(`Got event: ${JSON.stringify(cloudEvent, null, 2)}`)
  const newCloudEvent = new CloudEvent({
      type: 'dev.mink.apply.samples.divide',
      source: 'https://github.com/mattmoor/mink-apply-sample/divide',
      time: new Date(),
      dataContentType: 'application/json',
      data: handle(cloudEvent.data)
  })

  console.log(`Returning event: ${JSON.stringify(newCloudEvent.format(), null, 2)}`)
  return newCloudEvent
}

In the logs I see:

Got event: {
  "id": "2f835992-25a2-4084-b582-2cff75f2859b",
  "knativearrivaltime": "2020-11-09T20:51:00.193484373Z",
  "source": "/apis/v1/namespaces/default/pingsources/test-ping-source",
  "specversion": "1.0",
  "time": "2020-11-09T20:51:00.191970229Z",
  "type": "dev.knative.sources.ping",
  "data": {
    "a": 11,
    "b": 3
  }
}
Returning event: {
  "data": {
    "a": 3,
    "b": 2
  },
  "specversion": "1.0",
  "id": "3edc8093-c18c-42ce-bcde-ebb835f9b708",
  "time": "2020-11-09T20:51:00.215Z",
  "source": "https://github.com/mattmoor/mink-apply-sample/divide",
  "type": "dev.mink.apply.samples.divide",
  "datacontenttype": "application/json"
}

However, the returned event doesn't get properly returned as a cloud event:

curl -v -X POST -H 'Content-Type: application/json' -H 'ce-type: foo' -H 'ce-specversion: 1.0' -H 'ce-source: blah' -H 'ce-id: 1234' -d '{"a": 3, "b": 4}' http://divide.default.svc.cluster.local | jq .
Note: Unnecessary use of -X or --request, POST is already inferred.
* Rebuilt URL to: http://divide.default.svc.cluster.local/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.0.28.2...
* TCP_NODELAY set
* Connected to divide.default.svc.cluster.local (10.0.28.2) port 80 (#0)
> POST / HTTP/1.1
> Host: divide.default.svc.cluster.local
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Type: application/json
> ce-type: foo
> ce-specversion: 1.0
> ce-source: blah
> ce-id: 1234
> Content-Length: 16
> 
} [16 bytes data]
* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 200 OK
< content-length: 312
< content-type: application/json; charset=utf-8
< date: Mon, 09 Nov 2020 20:56:02 GMT
< etag: W/"138-pznfqQ6k5rUm3LHClNlYXVHInNQ"
< x-powered-by: Express
< x-envoy-upstream-service-time: 11
< vary: Accept-Encoding
< server: envoy
< 
{ [312 bytes data]
100   328  100   312  100    16   2260    115 --:--:-- --:--:-- --:--:--  2376
* Connection #0 to host divide.default.svc.cluster.local left intact
{
  "spec": {
    "payload": {
      "specversion": "1.0",
      "id": "14d3a7fb-9331-4e99-90d4-738661c4f66e",
      "time": "2020-11-09T20:56:02.558Z",
      "source": "https://github.com/mattmoor/mink-apply-sample/divide",
      "type": "dev.mink.apply.samples.divide",
      "datacontenttype": "application/json",
      "data": {
        "a": 0,
        "b": 3
      }
    }
  },
  "formatter": {},
  "extensions": []
}

This is neither a "structured" or a "binary" cloud event!

If I change the final return to:

  return newCloudEvent.format()

Then the returned body is a proper structured cloud event, with the wrong MIME type:

 curl -v -X POST -H 'Content-Type: application/json' -H 'ce-type: foo' -H 'ce-specversion: 1.0' -H 'ce-source: blah' -H 'ce-id: 1234' -d '{"a": 3, "b": 4}' http://divide.default.svc.cluster.local | jq .
Note: Unnecessary use of -X or --request, POST is already inferred.
* Rebuilt URL to: http://divide.default.svc.cluster.local/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.0.28.2...
* TCP_NODELAY set
* Connected to divide.default.svc.cluster.local (10.0.28.2) port 80 (#0)
> POST / HTTP/1.1
> Host: divide.default.svc.cluster.local
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Type: application/json
> ce-type: foo
> ce-specversion: 1.0
> ce-source: blah
> ce-id: 1234
> Content-Length: 16
> 
} [16 bytes data]
* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 200 OK
< content-length: 260
< content-type: application/json; charset=utf-8
< date: Mon, 09 Nov 2020 23:16:25 GMT
< etag: W/"104-lrVLt0nXAUiMN4jcclhUw2w+YZg"
< x-powered-by: Express
< x-envoy-upstream-service-time: 38
< vary: Accept-Encoding
< server: envoy
< 
{ [260 bytes data]
100   276  100   260  100    16   1566     96 --:--:-- --:--:-- --:--:--  1652
* Connection #0 to host divide.default.svc.cluster.local left intact
{
  "data": {
    "a": 0,
    "b": 3
  },
  "specversion": "1.0",
  "id": "7fcf9988-cd77-4fbb-af85-6c5bc2a25c3f",
  "time": "2020-11-09T23:16:25.415Z",
  "source": "https://github.com/mattmoor/mink-apply-sample/divide",
  "type": "dev.mink.apply.samples.divide",
  "datacontenttype": "application/json"
}

In the above the Content-Type header in the response should be application/cloudevent+json. OR it should return the body:

{
  "a": 0,
  "b": 3
}

... and return the remaining headers via their respective ce-prefixed equivalents (e.g. ce-type: dev.mink.apply.samples.divide).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions