Http receiver binary for spec 1.0

Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
Fabio José 2019-11-04 09:44:39 -03:00
parent 7d8ef84365
commit 645001af0f
2 changed files with 534 additions and 0 deletions

View File

@ -0,0 +1,106 @@
const Constants = require("./constants.js");
const Spec = require("../../specs/spec_1.js");
const JSONParser = require("../../formats/json/parser.js");
const Base64Parser = require("../../formats/base64.js");
const BinaryHTTPReceiver = require("./receiver_binary.js");
const {
isDefinedOrThrow,
isStringOrObjectOrThrow
} = require("../../utils/fun.js");
const parserByType = {};
parserByType[Constants.MIME_JSON] = new JSONParser();
parserByType[Constants.MIME_OCTET_STREAM] = {
parse(payload) { return payload; }
};
const parsersByEncoding = {};
parsersByEncoding[null] = parserByType;
parsersByEncoding[undefined] = parserByType;
// base64
parsersByEncoding[Constants.ENCODING_BASE64] = {};
parsersByEncoding[Constants.ENCODING_BASE64][Constants.MIME_JSON] =
new JSONParser(new Base64Parser());
parsersByEncoding[Constants.ENCODING_BASE64][Constants.MIME_OCTET_STREAM] = {
parse(payload) { return payload; }
};
const allowedContentTypes = [];
allowedContentTypes.push(Constants.MIME_JSON);
allowedContentTypes.push(Constants.MIME_OCTET_STREAM);
const allowedEncodings = [];
allowedEncodings.push(Constants.ENCODING_BASE64);
const requiredHeaders = [];
requiredHeaders.push(Constants.BINARY_HEADERS_1.TYPE);
requiredHeaders.push(Constants.BINARY_HEADERS_1.SPEC_VERSION);
requiredHeaders.push(Constants.BINARY_HEADERS_1.SOURCE);
requiredHeaders.push(Constants.BINARY_HEADERS_1.ID);
const setterByHeader = {};
setterByHeader[Constants.BINARY_HEADERS_1.TYPE] = {
name : "type",
parser : (v) => v
};
setterByHeader[Constants.BINARY_HEADERS_1.SPEC_VERSION] = {
name : "specversion",
parser : (v) => "1.0"
};
setterByHeader[Constants.BINARY_HEADERS_1.SOURCE] = {
name : "source",
parser: (v) => v
};
setterByHeader[Constants.BINARY_HEADERS_1.ID] = {
name : "id",
parser : (v) => v
};
setterByHeader[Constants.BINARY_HEADERS_1.TIME] = {
name : "time",
parser : (v) => new Date(Date.parse(v))
};
setterByHeader[Constants.BINARY_HEADERS_1.DATA_SCHEMA] = {
name: "dataschema",
parser: (v) => v
};
setterByHeader[Constants.HEADER_CONTENT_TYPE] = {
name: "dataContentType",
parser: (v) => v
};
setterByHeader[Constants.BINARY_HEADERS_1.SUBJECT] = {
name: "subject",
parser: (v) => v
};
function checkDecorator(payload, headers) {
}
function Receiver(configuration) {
this.receiver = new BinaryHTTPReceiver(
parsersByEncoding,
setterByHeader,
allowedContentTypes,
requiredHeaders,
Spec,
Constants.SPEC_V1,
Constants.BINARY_HEADERS_1.EXTENSIONS_PREFIX,
checkDecorator
);
}
Receiver.prototype.check = function(payload, headers) {
this.receiver.check(payload, headers);
};
Receiver.prototype.parse = function(payload, headers) {
// firstly specific local checks
this.check(payload, headers);
return this.receiver.parse(payload, headers);
};
module.exports = Receiver;

View File

@ -0,0 +1,428 @@
var expect = require("chai").expect;
var HTTPBinaryReceiver =
require("../../../lib/bindings/http/receiver_binary_1.js");
var receiver = new HTTPBinaryReceiver();
describe("HTTP Transport Binding Binary Receiver for CloudEvents v1.0", () => {
describe("Check", () => {
it("Throw error when payload arg is null or undefined", () => {
// setup
var payload = null;
var attributes = {};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("payload is null or undefined");
});
it("Throw error when attributes arg is null or undefined", () => {
// setup
var payload = {};
var attributes = null;
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("attributes is null or undefined");
});
it("Throw error when payload is not an object or string", () => {
// setup
var payload = 1.2;
var attributes = {};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("payload must be an object or a string");
});
it("Throw error when headers has no 'ce-type'", () => {
// setup
var payload = {};
var attributes = {
"ce-specversion" : "specversion",
"ce-source" : "source",
"ce-id" : "id",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("header 'ce-type' not found");
});
it("Throw error when headers has no 'ce-specversion'", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-source" : "source",
"ce-id" : "id",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("header 'ce-specversion' not found");
});
it("Throw error when headers has no 'ce-source'", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "specversion",
"ce-id" : "id",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("header 'ce-source' not found");
});
it("Throw error when headers has no 'ce-id'", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "specversion",
"ce-source" : "source",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("header 'ce-id' not found");
});
it("Throw error when spec is not 1.0", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "0.2",
"ce-source" : "source",
"ce-id" : "id",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.parse.bind(receiver, payload, attributes))
.to.throw("invalid spec version");
});
it("Throw error when the content-type is invalid", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "specversion",
"ce-source" : "source",
"ce-id" : "id",
"Content-Type" : "text/html"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.throw("invalid content type");
});
it("No error when all required headers are in place", () => {
// setup
var payload = {};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "source",
"ce-id" : "id",
"Content-Type" : "application/json"
};
// act and assert
expect(receiver.check.bind(receiver, payload, attributes))
.to.not.throw();
});
});
describe("Parse", () => {
it("Cloudevent contains 'type'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getType())
.to.equal("type");
});
it("Cloudevent contains 'specversion'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getSpecversion())
.to.equal("1.0");
});
it("Cloudevent contains 'source'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getSource())
.to.equal("/source");
});
it("Cloudevent contains 'id'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getId())
.to.equal("id");
});
it("Cloudevent contains 'time'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00.000Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getTime())
.to.equal("2019-06-16T11:42:00.000Z");
});
it("Cloudevent contains 'schemaurl'", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getDataschema())
.to.equal("http://schema.registry/v1");
});
it("Cloudevent contains 'contenttype' (application/json)", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getDataContentType())
.to.equal("application/json");
});
it("Cloudevent contains 'contenttype' (application/octet-stream)", () => {
// setup
var payload = "The payload is binary data";
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/octet-stream"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getDataContentType())
.to.equal("application/octet-stream");
});
it("Cloudevent contains 'data' (application/json)", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getData())
.to.deep.equal(payload);
});
it("Cloudevent contains 'data' (application/octet-stream)", () => {
// setup
var payload = "The payload is binary data";
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "/source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/octet-stream"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual.getData())
.to.deep.equal(payload);
});
it("No error when all attributes are in place", () => {
// setup
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json"
};
// act
var actual = receiver.parse(payload, attributes);
// assert
expect(actual)
.to.be.an("object");
expect(actual)
.to.have.property("format");
});
it("Should accept 'extension1'", () => {
// setup
var extension1 = "mycuston-ext1";
var payload = {
"data" : "dataString"
};
var attributes = {
"ce-type" : "type",
"ce-specversion" : "1.0",
"ce-source" : "source",
"ce-id" : "id",
"ce-time" : "2019-06-16T11:42:00Z",
"ce-dataschema" : "http://schema.registry/v1",
"Content-Type" : "application/json",
"ce-extension1" : extension1
};
// act
var actual = receiver.parse(payload, attributes);
var actualExtensions = actual.getExtensions();
// assert
expect(actualExtensions["extension1"])
.to.equal(extension1);
});
});
});