Http receiver binary for spec 1.0
Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
parent
7d8ef84365
commit
645001af0f
|
@ -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;
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue