feat(events-backend,events-node): improve parser interface
Signed-off-by: Rogerio Angeliski <angeliski@hotmail.com>
This commit is contained in:
@@ -209,7 +209,7 @@ describe('HttpPostIngressEventPublisher', () => {
|
||||
expect.objectContaining({
|
||||
error: {
|
||||
message:
|
||||
'Unsupported media type: text/plain. You need to provide a custom body parser for this media type using events extension.',
|
||||
'Unsupported media type: text/plain. You need to provide a custom body parser for this media type using the EventsExtensionPoint.',
|
||||
name: 'UnsupportedMediaTypeError',
|
||||
statusCode: 415,
|
||||
},
|
||||
@@ -259,6 +259,47 @@ describe('HttpPostIngressEventPublisher', () => {
|
||||
expect(response.status).toBe(202);
|
||||
});
|
||||
|
||||
it('with a invalid media type', async () => {
|
||||
const config = new ConfigReader({
|
||||
events: {
|
||||
http: {
|
||||
topics: ['testA'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const router = Router();
|
||||
const app = express().use(router);
|
||||
const events = new TestEventsService();
|
||||
|
||||
const publisher = HttpPostIngressEventPublisher.fromConfig({
|
||||
config,
|
||||
events,
|
||||
logger,
|
||||
});
|
||||
publisher.bind(router);
|
||||
router.use(middleware.error());
|
||||
|
||||
const response = await request(app)
|
||||
.post('/http/testA')
|
||||
.type('not-valid-content/plain')
|
||||
.timeout(1000)
|
||||
.send('Textual information');
|
||||
expect(response.status).toBe(415);
|
||||
expect(response.body).toEqual(
|
||||
expect.objectContaining({
|
||||
error: {
|
||||
message:
|
||||
'Unsupported media type: not-valid-content/plain. You need to provide a custom body parser for this media type using the EventsExtensionPoint.',
|
||||
name: 'UnsupportedMediaTypeError',
|
||||
statusCode: 415,
|
||||
},
|
||||
request: { method: 'POST', url: '/http/testA' },
|
||||
response: { statusCode: 415 },
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('with a custom application/json body parser implementation', async () => {
|
||||
const config = new ConfigReader({
|
||||
events: {
|
||||
@@ -273,7 +314,11 @@ describe('HttpPostIngressEventPublisher', () => {
|
||||
const events = new TestEventsService();
|
||||
const customParse = jest.fn();
|
||||
|
||||
const bodyParser: HttpBodyParser = async (req, _topic) => {
|
||||
const bodyParser: HttpBodyParser = async (
|
||||
req,
|
||||
_parsedMediaType,
|
||||
_topic,
|
||||
) => {
|
||||
customParse();
|
||||
return {
|
||||
bodyParsed: JSON.parse(req.body.toString('utf-8')),
|
||||
|
||||
@@ -103,7 +103,7 @@ export class HttpPostIngressEventPublisher {
|
||||
|
||||
router.post(path, async (request, response) => {
|
||||
const requestContentType = contentType.parse(request);
|
||||
const bodyParser = this.bodyParsers[requestContentType.type];
|
||||
const bodyParser = this.bodyParsers[requestContentType.type ?? ''];
|
||||
|
||||
if (!bodyParser) {
|
||||
throw new UnsupportedMediaTypeError(requestContentType.type);
|
||||
@@ -111,6 +111,7 @@ export class HttpPostIngressEventPublisher {
|
||||
|
||||
const { bodyParsed, bodyBuffer, encoding } = await bodyParser(
|
||||
request,
|
||||
requestContentType,
|
||||
topic,
|
||||
);
|
||||
|
||||
|
||||
+3
-4
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { HttpBodyParser } from '@backstage/plugin-events-node';
|
||||
import contentType from 'content-type';
|
||||
import { UnsupportedCharsetError } from '../errors';
|
||||
|
||||
export const HttpApplicationJsonBodyParser: HttpBodyParser = async (
|
||||
request,
|
||||
parsedMediaType,
|
||||
topic,
|
||||
) => {
|
||||
const requestBody = request.body;
|
||||
@@ -29,16 +29,15 @@ export const HttpApplicationJsonBodyParser: HttpBodyParser = async (
|
||||
}
|
||||
|
||||
const bodyBuffer: Buffer = requestBody;
|
||||
const parsedContentType = contentType.parse(request);
|
||||
|
||||
const encoding = parsedContentType.parameters.charset ?? 'utf-8';
|
||||
const encoding = parsedMediaType.parameters.charset ?? 'utf-8';
|
||||
if (!Buffer.isEncoding(encoding)) {
|
||||
throw new UnsupportedCharsetError(encoding);
|
||||
}
|
||||
|
||||
const bodyString = bodyBuffer.toString(encoding);
|
||||
const bodyParsed =
|
||||
parsedContentType.type === 'application/json'
|
||||
parsedMediaType.type === 'application/json'
|
||||
? JSON.parse(bodyString)
|
||||
: bodyString;
|
||||
return { bodyParsed, bodyBuffer, encoding };
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@types/express": "^4.17.6",
|
||||
"content-type": "^1.0.5",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"express": "^4.17.1",
|
||||
"uri-template": "^2.0.0"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
import { LifecycleService } from '@backstage/backend-plugin-api';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { ParsedMediaType } from 'content-type';
|
||||
import { Request as Request_2 } from 'express';
|
||||
import { RootConfigService } from '@backstage/backend-plugin-api';
|
||||
import { ServiceFactory } from '@backstage/backend-plugin-api';
|
||||
@@ -122,6 +123,7 @@ export type HttpBodyParsed = {
|
||||
// @public (undocumented)
|
||||
export type HttpBodyParser = (
|
||||
request: Request_2,
|
||||
parsedMediaType: ParsedMediaType,
|
||||
topic: string,
|
||||
) => Promise<HttpBodyParsed>;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Request } from 'express';
|
||||
import { ParsedMediaType } from 'content-type';
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@@ -29,5 +30,6 @@ export type HttpBodyParsed = {
|
||||
*/
|
||||
export type HttpBodyParser = (
|
||||
request: Request,
|
||||
parsedMediaType: ParsedMediaType,
|
||||
topic: string,
|
||||
) => Promise<HttpBodyParsed>;
|
||||
|
||||
Reference in New Issue
Block a user