From 5794ba96d67dfb9207dddf43bb4610c111c255ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabio=20Jos=C3=A9?= Date: Thu, 6 Jun 2019 22:46:29 -0300 Subject: [PATCH] Starting the binding impl to receive events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabio José --- lib/bindings/http/receiver_binary_0_2.js | 102 +++++++++++++++++++++ test/http_binding_0_2.js | 111 ++++++++++++++++++++++- 2 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 lib/bindings/http/receiver_binary_0_2.js diff --git a/lib/bindings/http/receiver_binary_0_2.js b/lib/bindings/http/receiver_binary_0_2.js new file mode 100644 index 0000000..19b6aac --- /dev/null +++ b/lib/bindings/http/receiver_binary_0_2.js @@ -0,0 +1,102 @@ +var http = require("http"); +var Spec02 = require("../../specs/spec_0_2.js") +var spec02 = new Spec02(); + +const allowedContentTypes = []; +allowedContentTypes.push("application/cloudevents+json; charset=utf-8"); + +function is_http_request_valid(req, res, config) { + var valid = true; + + if(req.url === config.path + && req.method.toLowerCase() + === config.method.toLowerCase()) { + + if(!req.headers["content-type"] + || !allowedContentTypes.includes( + req.headers["content-type"].toLowerCase())){ + res.statusCode = 400; + res.end("Bad Request"); + + valid = false; + } + + } else if(req.url !== config.path) { + res.statusCode = 404; + res.end("Not Found"); + + valid = false; + } else { + res.statusCode = 405; + res.end("Method Not Allowed"); + + valid = false; + } + + return valid; +} + +function HTTPBinary(configuration){ + this.config = configuration; + + this.config["headers"] = { + "content-type":"application/cloudevents+json; charset=utf-8" + }; + + if(!this.config["path"]){ + this.config["path"] = "/"; + } + + if(!this.config["method"]){ + this.config["method"] = "POST"; + } +} + +HTTPBinary.prototype.receive = function(){ + this.server; + var self = this; + + return new Promise((resolve, reject) => { + self.server = + http.createServer((request, res) => { + if(is_http_request_valid(request, res, this.config)){ + var body = []; + request.on("error", err => { + console.error(err); + }) + .on("data", chunk => { + // accumulate the chunks + body.push(chunk); + }) + .on("end", () => { + body = Buffer.concat(body).toString(); + var jsonBody = JSON.parse(body); + + try { + // Process/validate the body + spec02.check(jsonBody); + + res.statusCode = 201; + res.end("Event Accepted"); + }catch(e) { + res.statusCode = 400; + res.end(JSON.stringify(e)); + } + }); + } + }); + + self.server.listen(this.config.port, (err) => { + if(err){ + console.error(err); + reject(err); + } + }); + }); +} + +HTTPBinary.prototype.stop = function() { + this.server.close(); +} + +module.exports = HTTPBinary; diff --git a/test/http_binding_0_2.js b/test/http_binding_0_2.js index 5684952..6bd5046 100644 --- a/test/http_binding_0_2.js +++ b/test/http_binding_0_2.js @@ -1,6 +1,10 @@ -var expect = require("chai").expect; -var Cloudevent = require("../index.js"); -var nock = require("nock"); +var expect = require("chai").expect; +var Cloudevent = require("../index.js"); +var nock = require("nock"); +var ReceiverBinary01 = require("../lib/bindings/http/receiver_binary_0_2.js"); +var http = require("http"); +var request = require("request"); +var Spec02 = require("../lib/specs/spec_0_2.js"); const type = "com.github.pull.create"; const source = "urn:event:from:myapi/resourse/123"; @@ -20,10 +24,16 @@ const ext1Value = "foobar"; const ext2Name = "extension2"; const ext2Value = "acme"; +const receiverConfig = { + path : "/events", + port : 10300, + method : "POST" +}; + const Structured02 = Cloudevent.bindings["http-structured0.2"]; const Binary02 = Cloudevent.bindings["http-binary0.2"]; -var cloudevent = +var cloudevent = new Cloudevent() .type(type) .source(source) @@ -145,5 +155,98 @@ describe("HTTP Transport Binding - Version 0.2", () => { }); }); }); + + describe("Receiver", () => { + var receiver; + before(() => { + // setup + receiver = new ReceiverBinary01(receiverConfig); + receiver.receive() + .then(response => { + console.log(response); + }) + .catch(err => { + console.error(err); + }); + }); + + after(() => { + receiver.stop(); + }); + + it("Should return 404 when path is wrong", () => { + // act + request.post("http://localhost:" + receiverConfig.port + "/foobar", + (err, res, body) => { + // assert + expect(res.statusCode).to.equal(404); + }); + }); + + it("Should return 405 when method is wrong", () => { + // act + request.get("http://localhost:" + receiverConfig.port + + receiverConfig.path, + (err, res, body) => { + // assert + expect(res.statusCode).to.equal(405); + }); + }); + + it("Should return 400 when Content-Type is wrong", () => { + // act + request.post("http://localhost:" + receiverConfig.port + + receiverConfig.path, + (err, res, body) => { + // assert + expect(res.statusCode).to.equal(400); + }); + }); + + it("Should return 400 when is not a cloudevent", () => { + // setup + var requestOptions = { + url : "http://localhost:" + receiverConfig.port + + receiverConfig.path, + method : "POST", + headers : { + "Content-Type":"application/cloudevents+json; charset=utf-8" + }, + body : JSON.stringify({"foo": "bar"}) + }; + + // act + request(requestOptions, + (err, res, body) => { + // assert + expect(res.statusCode).to.equal(400); + }); + }); + + it("Should return 201 when accepts the event", () => { + // setup + var ce_spec02 = new Spec02(); + ce_spec02 + .type(type) + .source(source); + + var requestOptions = { + url : "http://localhost:" + receiverConfig.port + + receiverConfig.path, + method : "POST", + headers : { + "Content-Type":"application/cloudevents+json; charset=utf-8" + }, + body : JSON.stringify(ce_spec02.payload) + }; + + // act + request(requestOptions, + (err, res, body) => { + // assert + expect(res.statusCode).to.equal(201); + }); + }); + }); }); });