Skip to content

Commit 87bfc19

Browse files
authored
Merge branch 'master' into expose-constants
2 parents fc5c653 + 250a0a1 commit 87bfc19

15 files changed

+588
-322
lines changed

README.md

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,60 @@ console.log(receivedEvent.format());
6262

6363
#### Emitting Events
6464

65-
Currently, to emit events, you'll need to decide whether the event is in
65+
To emit events, you'll need to decide whether the event should be sent in
6666
binary or structured format, and determine what version of the CloudEvents
6767
specification you want to send the event as.
6868

69-
```js
70-
const { CloudEvent } = require("cloudevents-sdk");
71-
const { StructuredHTTPEmitter } = require("cloudevents-sdk/v1");
69+
By default, the `HTTPEmitter` will emit events over HTTP POST using the
70+
1.0 specification, in binary mode. You can emit 0.3 events by providing
71+
the specication version in the constructor to `HTTPEmitter`. To send
72+
structured events, add that string as a parameter to `emitter.sent()`.
7273

73-
const myevent = new CloudEvent()
74-
.type("com.github.pull.create")
75-
.source("urn:event:from:myapi/resource/123");
74+
```js
75+
const { CloudEvent, HTTPEmitter } = require("cloudevents-sdk");
7676

77-
const emitter = new StructuredHTTPEmitter({
78-
method: "POST",
79-
url : "https://myserver.com"
77+
// With only an endpoint URL, this creates a v1 emitter
78+
const v1Emitter = new HTTPEmitter({
79+
url: "https://cloudevents.io/example"
8080
});
81+
const event = new CloudEvent()
82+
.type(type)
83+
.source(source)
84+
.time(new Date())
85+
.data(data)
86+
87+
// By default, the emitter will send binary events
88+
v1Emitter.send(event).then((response) => {
89+
// handle the response
90+
}).catch(console.error);
91+
92+
// To send a structured event, just add that as an option
93+
v1Emitter.send(event, { mode: "structured" })
94+
.then((response) => {
95+
// handle the response
96+
}).catch(console.error);
97+
98+
// To send an event to an alternate URL, add that as an option
99+
v1Emitter.send(event, { url: "https://alternate.com/api" })
100+
.then((response) => {
101+
// handle the response
102+
}).catch(console.error);
103+
104+
// Sending a v0.3 event works the same, just let the emitter know when
105+
// you create it that you are working with the 0.3 spec
106+
const v03Emitter = new HTTPEmitter({
107+
url: "https://cloudevents.io/example",
108+
version: "0.3"
109+
});
110+
111+
// Again, the default is to send binary events
112+
// To send a structured event or to an alternate URL, provide those
113+
// as parameters in a options object as above
114+
v3Emitter.send(event)
115+
.then((response) => {
116+
// handle the response
117+
}).catch(console.error);
81118

82-
// Emit the event
83-
emitter.emit(myevent)
84119
```
85120

86121
## Supported specification features

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
const CloudEvent = require("./lib/cloudevent.js");
22
const HTTPReceiver = require("./lib/bindings/http/http_receiver.js");
3+
const HTTPEmitter = require("./lib/bindings/http/http_emitter.js");
34
const Constants = require("./lib/bindings/http/constants.js");
45

56
module.exports = {
67
CloudEvent,
78
HTTPReceiver,
9+
HTTPEmitter,
810
Constants
911
};
Lines changed: 79 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,85 @@
11
const axios = require("axios");
22

3-
const Constants = require("./constants.js");
4-
const defaults = {};
5-
defaults[Constants.HEADERS] = {};
6-
defaults[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] =
7-
Constants.DEFAULT_CONTENT_TYPE;
8-
9-
function BinaryHTTPEmitter(config, headerByGetter, extensionPrefix) {
10-
this.config = Object.assign({}, defaults, config);
11-
this.headerByGetter = headerByGetter;
12-
this.extensionPrefix = extensionPrefix;
13-
}
3+
const {
4+
HEADERS,
5+
BINARY_HEADERS_03,
6+
BINARY_HEADERS_1,
7+
HEADER_CONTENT_TYPE,
8+
DEFAULT_CONTENT_TYPE,
9+
DATA_ATTRIBUTE,
10+
SPEC_V1,
11+
SPEC_V03
12+
} = require("./constants.js");
1413

15-
BinaryHTTPEmitter.prototype.emit = function(cloudevent) {
16-
const config = Object.assign({}, this.config);
17-
const headers = Object.assign({}, this.config[Constants.HEADERS]);
18-
19-
Object.keys(this.headerByGetter)
20-
.filter((getter) => cloudevent[getter]())
21-
.forEach((getter) => {
22-
const header = this.headerByGetter[getter];
23-
headers[header.name] =
24-
header.parser(
25-
cloudevent[getter]()
26-
);
27-
});
28-
29-
// Set the cloudevent payload
30-
const formatted = cloudevent.format();
31-
let data = formatted.data;
32-
data = (formatted.data_base64 ? formatted.data_base64 : data);
33-
34-
// Have extensions?
35-
const exts = cloudevent.getExtensions();
36-
Object.keys(exts)
37-
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
38-
.forEach((ext) => {
39-
headers[this.extensionPrefix + ext] = exts[ext];
40-
});
41-
42-
config[Constants.DATA_ATTRIBUTE] = data;
43-
config.headers = headers;
44-
45-
// Return the Promise
46-
return axios.request(config);
14+
const defaults = {
15+
[HEADERS]: {
16+
[HEADER_CONTENT_TYPE]: DEFAULT_CONTENT_TYPE
17+
},
18+
method: "POST"
4719
};
4820

21+
/**
22+
* A class to emit binary CloudEvents over HTTP.
23+
*/
24+
class BinaryHTTPEmitter {
25+
/**
26+
* Create a new {BinaryHTTPEmitter} for the provided CloudEvent specification version.
27+
* Once an instance is created for a given spec version, it may only be used to send
28+
* events for that version.
29+
* Default version is 1.0
30+
* @param {string} version - the CloudEvent HTTP specification version.
31+
* Default: 1.0
32+
*/
33+
constructor(version) {
34+
if (version === SPEC_V1) {
35+
this.headerByGetter = require("./emitter_binary_1.js");
36+
this.extensionPrefix = BINARY_HEADERS_1.EXTENSIONS_PREFIX;
37+
} else if (version === SPEC_V03) {
38+
this.headerByGetter = require("./emitter_binary_0_3.js");
39+
this.extensionPrefix = BINARY_HEADERS_03.EXTENSIONS_PREFIX;
40+
}
41+
}
42+
43+
/**
44+
* Sends this cloud event to a receiver over HTTP.
45+
*
46+
* @param {Object} options The configuration options for this event. Options
47+
* provided other than `url` will be passed along to Node.js `http.request`.
48+
* https://nodejs.org/api/http.html#http_http_request_options_callback
49+
* @param {URL} options.url The HTTP/S url that should receive this event
50+
* @param {Object} cloudevent the CloudEvent to be sent
51+
* @returns {Promise} Promise with an eventual response from the receiver
52+
*/
53+
async emit(options, cloudevent) {
54+
const config = { ...options, ...defaults };
55+
const headers = config[HEADERS];
56+
57+
Object.keys(this.headerByGetter)
58+
.filter((getter) => cloudevent[getter]())
59+
.forEach((getter) => {
60+
const header = this.headerByGetter[getter];
61+
headers[header.name] = header.parser(cloudevent[getter]());
62+
});
63+
64+
// Set the cloudevent payload
65+
const formatted = cloudevent.format();
66+
let data = formatted.data;
67+
data = (formatted.data_base64 ? formatted.data_base64 : data);
68+
69+
// Have extensions?
70+
const exts = cloudevent.getExtensions();
71+
Object.keys(exts)
72+
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
73+
.forEach((ext) => {
74+
headers[this.extensionPrefix + ext] = exts[ext];
75+
});
76+
77+
config[DATA_ATTRIBUTE] = data;
78+
config.headers = headers;
79+
80+
// Return the Promise
81+
return axios.request(config);
82+
}
83+
}
84+
4985
module.exports = BinaryHTTPEmitter;
Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,53 @@
1-
const BinaryHTTPEmitter = require("./emitter_binary.js");
2-
3-
const Constants = require("./constants.js");
1+
const {
2+
HEADER_CONTENT_TYPE,
3+
BINARY_HEADERS_03
4+
} = require("./constants.js");
45

56
const headerByGetter = {};
67

78
headerByGetter.getDataContentType = {
8-
name: Constants.HEADER_CONTENT_TYPE,
9+
name: HEADER_CONTENT_TYPE,
910
parser: (v) => v
1011
};
1112

1213
headerByGetter.getDataContentEncoding = {
13-
name: Constants.BINARY_HEADERS_03.CONTENT_ENCONDING,
14+
name: BINARY_HEADERS_03.CONTENT_ENCONDING,
1415
parser: (v) => v
1516
};
1617

1718
headerByGetter.getSubject = {
18-
name: Constants.BINARY_HEADERS_03.SUBJECT,
19+
name: BINARY_HEADERS_03.SUBJECT,
1920
parser: (v) => v
2021
};
2122

2223
headerByGetter.getType = {
23-
name: Constants.BINARY_HEADERS_03.TYPE,
24+
name: BINARY_HEADERS_03.TYPE,
2425
parser: (v) => v
2526
};
2627

2728
headerByGetter.getSpecversion = {
28-
name: Constants.BINARY_HEADERS_03.SPEC_VERSION,
29+
name: BINARY_HEADERS_03.SPEC_VERSION,
2930
parser: (v) => v
3031
};
3132

3233
headerByGetter.getSource = {
33-
name: Constants.BINARY_HEADERS_03.SOURCE,
34+
name: BINARY_HEADERS_03.SOURCE,
3435
parser: (v) => v
3536
};
3637

3738
headerByGetter.getId = {
38-
name: Constants.BINARY_HEADERS_03.ID,
39+
name: BINARY_HEADERS_03.ID,
3940
parser: (v) => v
4041
};
4142

4243
headerByGetter.getTime = {
43-
name: Constants.BINARY_HEADERS_03.TIME,
44+
name: BINARY_HEADERS_03.TIME,
4445
parser: (v) => v
4546
};
4647

4748
headerByGetter.getSchemaurl = {
48-
name: Constants.BINARY_HEADERS_03.SCHEMA_URL,
49+
name: BINARY_HEADERS_03.SCHEMA_URL,
4950
parser: (v) => v
5051
};
5152

52-
function HTTPBinary(configuration) {
53-
this.emitter = new BinaryHTTPEmitter(
54-
configuration,
55-
headerByGetter,
56-
Constants.BINARY_HEADERS_03.EXTENSIONS_PREFIX
57-
);
58-
}
59-
60-
HTTPBinary.prototype.emit = function(cloudevent) {
61-
return this.emitter.emit(cloudevent);
62-
};
63-
64-
module.exports = HTTPBinary;
53+
module.exports = headerByGetter;
Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,48 @@
1-
const BinaryHTTPEmitter = require("./emitter_binary.js");
2-
3-
const Constants = require("./constants.js");
1+
const {
2+
HEADER_CONTENT_TYPE,
3+
BINARY_HEADERS_1
4+
} = require("./constants.js");
45

56
const headerByGetter = {};
67

78
headerByGetter.getDataContentType = {
8-
name: Constants.HEADER_CONTENT_TYPE,
9+
name: HEADER_CONTENT_TYPE,
910
parser: (v) => v
1011
};
1112

1213
headerByGetter.getSubject = {
13-
name: Constants.BINARY_HEADERS_1.SUBJECT,
14+
name: BINARY_HEADERS_1.SUBJECT,
1415
parser: (v) => v
1516
};
1617

1718
headerByGetter.getType = {
18-
name: Constants.BINARY_HEADERS_1.TYPE,
19+
name: BINARY_HEADERS_1.TYPE,
1920
parser: (v) => v
2021
};
2122

2223
headerByGetter.getSpecversion = {
23-
name: Constants.BINARY_HEADERS_1.SPEC_VERSION,
24+
name: BINARY_HEADERS_1.SPEC_VERSION,
2425
parser: (v) => v
2526
};
2627

2728
headerByGetter.getSource = {
28-
name: Constants.BINARY_HEADERS_1.SOURCE,
29+
name: BINARY_HEADERS_1.SOURCE,
2930
parser: (v) => v
3031
};
3132

3233
headerByGetter.getId = {
33-
name: Constants.BINARY_HEADERS_1.ID,
34+
name: BINARY_HEADERS_1.ID,
3435
parser: (v) => v
3536
};
3637

3738
headerByGetter.getTime = {
38-
name: Constants.BINARY_HEADERS_1.TIME,
39+
name: BINARY_HEADERS_1.TIME,
3940
parser: (v) => v
4041
};
4142

4243
headerByGetter.getDataschema = {
43-
name: Constants.BINARY_HEADERS_1.DATA_SCHEMA,
44+
name: BINARY_HEADERS_1.DATA_SCHEMA,
4445
parser: (v) => v
4546
};
4647

47-
function HTTPBinary(configuration) {
48-
this.emitter = new BinaryHTTPEmitter(
49-
configuration,
50-
headerByGetter,
51-
Constants.BINARY_HEADERS_1.EXTENSIONS_PREFIX
52-
);
53-
}
54-
55-
HTTPBinary.prototype.emit = function(cloudevent) {
56-
return this.emitter.emit(cloudevent);
57-
};
58-
59-
module.exports = HTTPBinary;
48+
module.exports = headerByGetter;

0 commit comments

Comments
 (0)