Skip to content

Commit 85f610d

Browse files
committed
fixup: make send accept an alternate URL
Signed-off-by: Lance Ball <[email protected]>
1 parent 1c2856e commit 85f610d

File tree

3 files changed

+86
-18
lines changed

3 files changed

+86
-18
lines changed

lib/bindings/http/http_emitter.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,46 @@ class HTTPEmitter {
1818
* Creates a new instance of {HTTPEmitter}. The default emitter uses the 1.0
1919
* protocol specification in binary mode.
2020
*
21-
* @param {string} [version] The HTTP binding specification version. Default: "1.0"
21+
* @param {Object} [options] The configuration options for this event emitter
22+
* @param {URL} options.url The endpoint that will receive the sent events.
23+
* @param {string} [options.version] The HTTP binding specification version. Default: "1.0"
2224
* @throws {TypeError} if no options.url is provided or an unknown specification version is provided.
2325
*/
24-
constructor(version = SPEC_V1) {
26+
constructor({ url, version = SPEC_V1 } = {}) {
2527
if (version !== SPEC_V03 && version !== SPEC_V1) {
2628
throw new TypeError(
2729
`Unknown CloudEvent specification version: ${version}`);
2830
}
31+
if (!url) {
32+
throw new TypeError("A default endpoint URL is required for a CloudEvent emitter");
33+
}
2934
this.binary = new BinaryHTTPEmitter(version);
3035
this.structured = new StructuredEmitter();
36+
this.url = url;
3137
}
3238

3339
/**
3440
* Sends the {CloudEvent} to an event receiver over HTTP POST
3541
*
36-
* @param {Object} options The configuration options for this event. Options
42+
* @param {CloudEvent} event the CloudEvent to be sent
43+
* @param {Object} [options] The configuration options for this event. Options
3744
* provided will be passed along to Node.js `http.request()`.
3845
* https://nodejs.org/api/http.html#http_http_request_options_callback
39-
* @param {URL} options.url The HTTP/S url that should receive this event
40-
* @param {CloudEvent} event the CloudEvent to be sent
41-
* @param {string} [mode] the message mode for sending this event.
46+
* @param {URL} [options.url] The HTTP/S url that should receive this event.
47+
* The URL is optional if one was provided when this emitter was constructed.
48+
* In that case, it will be used as the recipient endpoint. The endpoint can
49+
* be overridden by providing a URL here.
50+
* @param {string} [options.mode] the message mode for sending this event.
4251
* Possible values are "binary" and "structured". Default: structured
4352
* @returns {Promise} Promise with an eventual response from the receiver
4453
*/
45-
send(options, event, mode = "binary") {
54+
send(event, { url, mode = "binary", ...httpOpts } = {}) {
55+
if (!url) { url = this.url; }
56+
httpOpts.url = url;
4657
if (mode === "binary") {
47-
return this.binary.emit(options, event);
58+
return this.binary.emit(httpOpts, event);
4859
} else if (mode === "structured") {
49-
return this.structured.emit(options, event);
60+
return this.structured.emit(httpOpts, event);
5061
}
5162
throw new TypeError(`Unknown transport mode ${mode}.`);
5263
}

test/bindings/http/http_emitter_test.js

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
4545
});
4646

4747
describe("V1", () => {
48-
const emitter = new HTTPEmitter();
48+
const emitter = new HTTPEmitter({ url: receiver });
4949
const event = new CloudEvent(V1Spec)
5050
.type(type)
5151
.source(source)
@@ -55,7 +55,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
5555
.addExtension(ext2Name, ext2Value);
5656

5757
it("Sends a binary 1.0 CloudEvent by default", () => {
58-
emitter.send({ url: receiver }, event)
58+
emitter.send(event)
5959
.then((response) => {
6060
// A binary message will have a ce-id header
6161
expect(response.data[BINARY_HEADERS_1.ID]).to.equal(event.getId());
@@ -65,8 +65,36 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
6565
}).catch(expect.fail);
6666
});
6767

68-
it("Sends a structured 1.0 CloudEvent if created that way", () => {
69-
emitter.send({ url: receiver }, event, "structured")
68+
it("Sends a structured 1.0 CloudEvent if specified", () => {
69+
emitter.send(event, { mode: "structured" })
70+
.then((response) => {
71+
// A structured message will have a cloud event content type
72+
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
73+
// Ensure other CE headers don't exist - just testing for ID
74+
expect(response.data[BINARY_HEADERS_1.ID]).to.equal(undefined);
75+
// The spec version would have been specified in the body
76+
expect(response.data.specversion).to.equal(SPEC_V1);
77+
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
78+
}).catch(expect.fail);
79+
});
80+
81+
it("Sends to an alternate URL if specified", () => {
82+
nock(receiver)
83+
.post("/alternate")
84+
.reply(function(uri, requestBody) {
85+
// return the request body and the headers so they can be
86+
// examined in the test
87+
if (typeof requestBody === "string") {
88+
requestBody = JSON.parse(requestBody);
89+
}
90+
const returnBody = { ...requestBody, ...this.req.headers };
91+
return [
92+
201,
93+
returnBody
94+
];
95+
});
96+
97+
emitter.send(event, { mode: "structured", url: `${receiver}alternate` })
7098
.then((response) => {
7199
// A structured message will have a cloud event content type
72100
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
@@ -80,7 +108,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
80108
});
81109

82110
describe("V03", () => {
83-
const emitter = new HTTPEmitter(SPEC_V03);
111+
const emitter = new HTTPEmitter({ url: receiver, version: SPEC_V03 });
84112
const event = new CloudEvent(V03Spec)
85113
.type(type)
86114
.source(source)
@@ -90,7 +118,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
90118
.addExtension(ext2Name, ext2Value);
91119

92120
it("Sends a binary 0.3 CloudEvent", () => {
93-
emitter.send({ url: receiver }, event)
121+
emitter.send(event)
94122
.then((response) => {
95123
// A binary message will have a ce-id header
96124
expect(response.data[BINARY_HEADERS_03.ID]).to.equal(event.getId());
@@ -100,8 +128,35 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
100128
}).catch(expect.fail);
101129
});
102130

103-
it("Sends a structured 0.3 CloudEvent", () => {
104-
emitter.send({ url: receiver }, event, "structured")
131+
it("Sends a structured 0.3 CloudEvent if specified", () => {
132+
emitter.send(event, { mode: "structured", foo: "bar" })
133+
.then((response) => {
134+
// A structured message will have a cloud event content type
135+
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
136+
// Ensure other CE headers don't exist - just testing for ID
137+
expect(response.data[BINARY_HEADERS_03.ID]).to.equal(undefined);
138+
// The spec version would have been specified in the body
139+
expect(response.data.specversion).to.equal(SPEC_V03);
140+
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
141+
}).catch(expect.fail);
142+
});
143+
it("Sends to an alternate URL if specified", () => {
144+
nock(receiver)
145+
.post("/alternate")
146+
.reply(function(uri, requestBody) {
147+
// return the request body and the headers so they can be
148+
// examined in the test
149+
if (typeof requestBody === "string") {
150+
requestBody = JSON.parse(requestBody);
151+
}
152+
const returnBody = { ...requestBody, ...this.req.headers };
153+
return [
154+
201,
155+
returnBody
156+
];
157+
});
158+
159+
emitter.send(event, { mode: "structured", url: `${receiver}alternate` })
105160
.then((response) => {
106161
// A structured message will have a cloud event content type
107162
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);

test/sdk_test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ describe("The SDK Requirements", () => {
1919
});
2020

2121
it("should expose an HTTPEmitter type", () => {
22-
const emitter = new HTTPEmitter();
22+
const emitter = new HTTPEmitter({
23+
url: "http://example.com"
24+
});
2325
expect(emitter instanceof HTTPEmitter).to.equal(true);
2426
});
2527

0 commit comments

Comments
 (0)