Skip to content

Commit

Permalink
Merge branch 'feature/grpc-server-package-definition' of https://gith…
Browse files Browse the repository at this point in the history
…ub.com/krugi/nest into krugi-feature/grpc-server-package-definition
  • Loading branch information
kamilmysliwiec committed Dec 18, 2023
2 parents 202dfbf + 7de2ff2 commit 0a6853c
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 22 deletions.
16 changes: 6 additions & 10 deletions packages/microservices/client/client-grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ClientGrpc, GrpcOptions } from '../interfaces';
import { ClientProxy } from './client-proxy';
import { GRPC_CANCELLED } from './constants';
import { ChannelOptions } from '../external/grpc-options.interface';
import { getGrpcPackageDefinition } from '../helpers';

let grpcPackage: any = {};
let grpcProtoLoaderPackage: any = {};
Expand Down Expand Up @@ -300,16 +301,11 @@ export class ClientGrpcProxy extends ClientProxy implements ClientGrpc {

public loadProto(): any {
try {
const file = this.getOptionsProp(this.options, 'protoPath');
const loader = this.getOptionsProp(this.options, 'loader');

const packageDefinition =
this.getOptionsProp(this.options, 'packageDefinition') ||
grpcProtoLoaderPackage.loadSync(file, loader);

const packageObject =
grpcPackage.loadPackageDefinition(packageDefinition);
return packageObject;
const packageDefinition = getGrpcPackageDefinition(
this.options,
grpcProtoLoaderPackage,
);
return grpcPackage.loadPackageDefinition(packageDefinition);
} catch (err) {
const invalidProtoError = new InvalidProtoDefinitionException(err.path);
const message =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { RuntimeException } from '@nestjs/core/errors/exceptions/runtime.exception';

export class InvalidGrpcPackageDefinitionMissingPacakgeDefinitionException extends RuntimeException {
constructor() {
super('protoPath or packageDefinition must be defined');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { RuntimeException } from '@nestjs/core/errors/exceptions/runtime.exception';

export class InvalidGrpcPackageDefinitionMutexException extends RuntimeException {
constructor() {
super(
'Both protoPath and packageDefinition were provided, but only one can be defined',
);
}
}
24 changes: 24 additions & 0 deletions packages/microservices/helpers/grpc-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { GrpcOptions } from '../interfaces';
import { InvalidGrpcPackageDefinitionMutexException } from '../errors/invalid-grpc-package-definition-mutex.exception';
import { InvalidGrpcPackageDefinitionMissingPacakgeDefinitionException } from '../errors/invalid-grpc-package-definition-missing-package-definition.exception';

export function getGrpcPackageDefinition(
options: GrpcOptions['options'],
grpcProtoLoaderPackage: any,
) {
const file = options['protoPath'];
const packageDefinition = options['packageDefinition'];

if ([file, packageDefinition].every(x => x != undefined)) {
throw new InvalidGrpcPackageDefinitionMutexException();
}

if ([file, packageDefinition].every(x => x == undefined)) {
throw new InvalidGrpcPackageDefinitionMissingPacakgeDefinitionException();
}

return (
packageDefinition ||
grpcProtoLoaderPackage.loadSync(file, options['loader'])
);
}
1 change: 1 addition & 0 deletions packages/microservices/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './kafka-logger';
export * from './kafka-parser';
export * from './kafka-reply-partition-assigner';
export * from './tcp-socket';
export * from './grpc-helpers';
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface GrpcOptions {
};
channelOptions?: ChannelOptions;
credentials?: any;
protoPath: string | string[];
protoPath?: string | string[];
package: string | string[];
protoLoader?: string;
packageDefinition?: any;
Expand Down
15 changes: 7 additions & 8 deletions packages/microservices/server/server-grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ChannelOptions } from '../external/grpc-options.interface';
import { CustomTransportStrategy, MessageHandler } from '../interfaces';
import { GrpcOptions } from '../interfaces/microservice-configuration.interface';
import { Server } from './server';
import { getGrpcPackageDefinition } from '../helpers';

let grpcPackage: any = {};
let grpcProtoLoaderPackage: any = {};
Expand Down Expand Up @@ -501,20 +502,18 @@ export class ServerGrpc extends Server implements CustomTransportStrategy {

public loadProto(): any {
try {
const file = this.getOptionsProp(this.options, 'protoPath');
const loader = this.getOptionsProp(this.options, 'loader');

const packageDefinition = grpcProtoLoaderPackage.loadSync(file, loader);
const packageObject =
grpcPackage.loadPackageDefinition(packageDefinition);
return packageObject;
const packageDefinition = getGrpcPackageDefinition(
this.options,
grpcProtoLoaderPackage,
);
return grpcPackage.loadPackageDefinition(packageDefinition);
} catch (err) {
const invalidProtoError = new InvalidProtoDefinitionException(err.path);
const message =
err && err.message ? err.message : invalidProtoError.message;

this.logger.error(message, invalidProtoError.stack);
throw err;
throw invalidProtoError;
}
}

Expand Down
10 changes: 8 additions & 2 deletions packages/microservices/test/client/client-grpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { expect } from 'chai';
import { join } from 'path';
import { Observable, Subject } from 'rxjs';
import * as sinon from 'sinon';
import { ClientGrpcProxy } from '../../client/client-grpc';
import { ClientGrpcProxy } from '../../client';
import { InvalidGrpcPackageException } from '../../errors/invalid-grpc-package.exception';
import { InvalidGrpcServiceException } from '../../errors/invalid-grpc-service.exception';
import { InvalidProtoDefinitionException } from '../../errors/invalid-proto-definition.exception';
import * as grpcHelpers from '../../helpers/grpc-helpers';

class NoopLogger extends Logger {
log(message: any, context?: string): void {}
Expand Down Expand Up @@ -443,13 +444,18 @@ describe('ClientGrpcProxy', () => {
describe('loadProto', () => {
describe('when proto is invalid', () => {
it('should throw InvalidProtoDefinitionException', () => {
sinon.stub(client, 'getOptionsProp' as any).callsFake(() => {
const getPackageDefinitionStub = sinon.stub(
grpcHelpers,
'getGrpcPackageDefinition' as any,
);
getPackageDefinitionStub.callsFake(() => {
throw new Error();
});
(client as any).logger = new NoopLogger();
expect(() => client.loadProto()).to.throws(
InvalidProtoDefinitionException,
);
getPackageDefinitionStub.restore();
});
});
});
Expand Down
56 changes: 56 additions & 0 deletions packages/microservices/test/helpers/grpc-helpers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { expect } from 'chai';
import { getGrpcPackageDefinition } from '../../helpers/grpc-helpers';
import { InvalidGrpcPackageDefinitionMutexException } from '../../errors/invalid-grpc-package-definition-mutex.exception';
import { InvalidGrpcPackageDefinitionMissingPacakgeDefinitionException } from '../../errors/invalid-grpc-package-definition-missing-package-definition.exception';

const grpcProtoLoaderPackage = { loadSync: (a, b) => 'withLoader' };

describe('getGrpcPackageDefinition', () => {
it('missing both protoPath and packageDefinition', () => {
expect(() =>
getGrpcPackageDefinition(
{
package: 'somePackage',
},
grpcProtoLoaderPackage,
),
).to.throw(InvalidGrpcPackageDefinitionMissingPacakgeDefinitionException);
});

it('got both protoPath and packageDefinition', () => {
expect(() =>
getGrpcPackageDefinition(
{
package: 'somePackage',
protoPath: 'some/path',
packageDefinition: {},
},
grpcProtoLoaderPackage,
),
).to.throw(InvalidGrpcPackageDefinitionMutexException);
});

it('success with protoPath', () => {
expect(() =>
getGrpcPackageDefinition(
{
package: 'somePackage',
protoPath: 'some/path',
},
grpcProtoLoaderPackage,
),
).to.not.throw(Error);
});

it('success with packageDef', () => {
expect(() =>
getGrpcPackageDefinition(
{
package: 'somePackage',
packageDefinition: {},
},
grpcProtoLoaderPackage,
),
).to.not.throw(Error);
});
});
23 changes: 22 additions & 1 deletion packages/microservices/test/server/server-grpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import * as sinon from 'sinon';
import { CANCEL_EVENT } from '../../constants';
import { InvalidGrpcPackageException } from '../../errors/invalid-grpc-package.exception';
import { GrpcMethodStreamingType } from '../../index';
import { ServerGrpc } from '../../server/server-grpc';
import { ServerGrpc } from '../../server';
import { InvalidProtoDefinitionException } from '../../errors/invalid-proto-definition.exception';
import * as grpcHelpers from '../../helpers/grpc-helpers';

class NoopLogger extends Logger {
log(message: any, context?: string): void {}
Expand Down Expand Up @@ -777,6 +779,25 @@ describe('ServerGrpc', () => {
});
});

describe('loadProto', () => {
describe('when proto is invalid', () => {
it('should throw InvalidProtoDefinitionException', () => {
const getPackageDefinitionStub = sinon.stub(
grpcHelpers,
'getGrpcPackageDefinition' as any,
);
getPackageDefinitionStub.callsFake(() => {
throw new Error();
});
(server as any).logger = new NoopLogger();
expect(() => server.loadProto()).to.throws(
InvalidProtoDefinitionException,
);
getPackageDefinitionStub.restore();
});
});
});

describe('close', () => {
it('should call "forceShutdown" by default', async () => {
const grpcClient = {
Expand Down

0 comments on commit 0a6853c

Please sign in to comment.