This repository has been archived by the owner on Nov 7, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(googlePubSub): initial implementation of googlePubSub
- Loading branch information
1 parent
34f71bf
commit b82b842
Showing
13 changed files
with
1,356 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export const GOOGLE_PUB_SUB_PROVIDER = 'GOOGLE_PUB_SUB_PROVIDER'; | ||
export const GOOGLE_PUB_SUB_CONFIG = 'GOOGLE_PUB_SUB_CONFIG'; | ||
|
||
export const GOOGLE_PUB_SUB_TOPIC = 'GOOGLE_PUB_SUB_TOPIC'; | ||
export const GOOGLE_PUB_SUB_SUBSCRIPTION = 'GOOGLE_PUB_SUB_SUBSCRIPTION'; | ||
|
||
export const GOOGLE_PUB_SUB_PUBLISHER_OPTIONS = 'GOOGLE_PUB_SUB_PUBLISHER_OPTIONS'; | ||
export const GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS = 'GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS'; | ||
|
||
export const GOOGLE_PUB_SUB_CONFIG_USE_ENV = Symbol('GOOGLE_PUB_SUB_CONFIG_USE_ENV'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export interface GooglePubSubMessage { | ||
id: string; | ||
ackId: string; | ||
data: string; | ||
attributes: any; | ||
timestamp: Date; | ||
|
||
ack(); | ||
nack(); | ||
|
||
// message.id = ID of the message. | ||
// message.ackId = ID used to acknowledge the message receival. | ||
// message.data = Contents of the message. | ||
// message.attributes = Attributes of the message. | ||
// message.timestamp = Timestamp when Pub/Sub received the message. | ||
|
||
// Ack the message: | ||
// message.ack(); | ||
|
||
// This doesn't ack the message, but allows more messages to be retrieved | ||
// if your limit was hit or if you don't want to ack the message. | ||
// message.nack(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { Global, Module, DynamicModule } from '@nestjs/common'; | ||
import { googlePubSubProviders } from './googlePubSub.providers'; | ||
import * as PubSub from '@google-cloud/pubsub'; | ||
import { | ||
GOOGLE_PUB_SUB_CONFIG, | ||
GOOGLE_PUB_SUB_TOPIC, | ||
GOOGLE_PUB_SUB_PUBLISHER_OPTIONS, | ||
GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS, | ||
GOOGLE_PUB_SUB_SUBSCRIPTION, | ||
GOOGLE_PUB_SUB_CONFIG_USE_ENV, | ||
} from './googlePubSub.constants'; | ||
import { GooglePubSub } from './googlePubSub'; | ||
|
||
@Global() | ||
@Module({ | ||
providers: [ | ||
...googlePubSubProviders, | ||
{ | ||
provide: GOOGLE_PUB_SUB_CONFIG, | ||
useValue: GOOGLE_PUB_SUB_CONFIG_USE_ENV, | ||
}, | ||
], | ||
exports: [ | ||
...googlePubSubProviders, | ||
{ | ||
provide: GOOGLE_PUB_SUB_CONFIG, | ||
useValue: GOOGLE_PUB_SUB_CONFIG_USE_ENV, | ||
}, | ||
], | ||
}) | ||
export class GooglePubSubModule { | ||
static forRoot( | ||
config?: PubSub.GCloudConfiguration, | ||
): DynamicModule { | ||
return { | ||
module: GooglePubSubModule, | ||
providers: [ | ||
{ | ||
provide: GOOGLE_PUB_SUB_CONFIG, | ||
useValue: config, | ||
}, | ||
], | ||
exports: [ | ||
{ | ||
provide: GOOGLE_PUB_SUB_CONFIG, | ||
useValue: config, | ||
}, | ||
], | ||
}; | ||
} | ||
|
||
static forFeature( | ||
topic: string, | ||
subscription: string, | ||
publisherSubscriberConfig: { | ||
publisherOptions?: PubSub.Topic.PublisherOptions, | ||
subscriptionOptions?: PubSub.Topic.SubscriptionOptions, | ||
} = {}, | ||
): DynamicModule { | ||
if (!publisherSubscriberConfig.publisherOptions) { | ||
publisherSubscriberConfig.publisherOptions = {}; | ||
} | ||
if (!publisherSubscriberConfig.subscriptionOptions) { | ||
publisherSubscriberConfig.subscriptionOptions = {}; | ||
} | ||
return { | ||
module: GooglePubSubModule, | ||
providers: [ | ||
{ | ||
provide: GOOGLE_PUB_SUB_TOPIC, | ||
useValue: topic, | ||
}, | ||
{ | ||
provide: GOOGLE_PUB_SUB_SUBSCRIPTION, | ||
useValue: subscription, | ||
}, | ||
{ | ||
provide: GOOGLE_PUB_SUB_PUBLISHER_OPTIONS, | ||
useValue: publisherSubscriberConfig.publisherOptions, | ||
}, | ||
{ | ||
provide: GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS, | ||
useValue: publisherSubscriberConfig.subscriptionOptions, | ||
}, | ||
GooglePubSub, | ||
], | ||
exports: [ | ||
GooglePubSub, | ||
], | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { | ||
GOOGLE_PUB_SUB_PROVIDER, | ||
GOOGLE_PUB_SUB_CONFIG, | ||
GOOGLE_PUB_SUB_CONFIG_USE_ENV, | ||
} from './googlePubSub.constants'; | ||
import * as PubSub from '@google-cloud/pubsub'; | ||
|
||
export const googlePubSubProviders = [ | ||
{ | ||
provide: GOOGLE_PUB_SUB_PROVIDER, | ||
useFactory: ( | ||
googlePubSubConfig?: PubSub.GCloudConfiguration, | ||
) : PubSub.PubSub => { | ||
if (googlePubSubConfig === GOOGLE_PUB_SUB_CONFIG_USE_ENV) { | ||
return PubSub(); | ||
} | ||
return PubSub(googlePubSubConfig); | ||
}, | ||
inject: [GOOGLE_PUB_SUB_CONFIG], | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Injectable, Inject, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; | ||
import { | ||
GOOGLE_PUB_SUB_PROVIDER, | ||
GOOGLE_PUB_SUB_TOPIC, | ||
GOOGLE_PUB_SUB_PUBLISHER_OPTIONS, | ||
GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS, | ||
GOOGLE_PUB_SUB_SUBSCRIPTION, | ||
} from './googlePubSub.constants'; | ||
import { IEventPublisher } from '@nestjs/cqrs/dist/interfaces/events/event-publisher.interface'; | ||
import { IMessageSource } from '@nestjs/cqrs/dist/interfaces/events/message-source.interface'; | ||
import { IEvent } from '@nestjs/cqrs/dist/interfaces/events/event.interface'; | ||
import { Subject } from 'rxjs/Subject'; | ||
import * as PubSub from '@google-cloud/pubsub'; | ||
import { fromEvent } from 'rxjs'; | ||
import { GooglePubSubMessage } from './googlePubSub.interface'; | ||
|
||
@Injectable() | ||
export class GooglePubSub implements IEventPublisher, IMessageSource, OnModuleInit, OnModuleDestroy | ||
{ | ||
|
||
private events: PubSub.Subscription; | ||
|
||
constructor( | ||
@Inject(GOOGLE_PUB_SUB_PROVIDER) | ||
private googlePubSub: PubSub.PubSub, | ||
@Inject(GOOGLE_PUB_SUB_TOPIC) | ||
private topic: string, | ||
@Inject(GOOGLE_PUB_SUB_SUBSCRIPTION) | ||
private subscription: string, | ||
@Inject(GOOGLE_PUB_SUB_PUBLISHER_OPTIONS) | ||
private publisherOptions: PubSub.Topic.PublisherOptions, | ||
@Inject(GOOGLE_PUB_SUB_SUBSCRIBER_OPTIONS) | ||
private subscriberOptions: PubSub.Topic.SubscriptionOptions, | ||
) { | ||
} | ||
|
||
async onModuleInit() { | ||
console.log('GooglePubSub Module initializing!'); | ||
console.log(`Setting up topic: ${this.topic}`); | ||
await this.googlePubSub.createTopic(this.topic); | ||
console.log(`Setting up subscription: ${this.subscription}`); | ||
await this.googlePubSub.createSubscription(this.topic, this.subscription); | ||
} | ||
|
||
onModuleDestroy() { | ||
console.log('GooglePubSub Module destroying!'); | ||
this.events.removeAllListeners(); | ||
} | ||
|
||
// Publisher | ||
publish<T extends IEvent>(event: T) { | ||
const message = Buffer.from(JSON.stringify(event)); | ||
|
||
this.googlePubSub | ||
.topic(this.topic) | ||
.publisher(this.publisherOptions) | ||
.publish(message) | ||
.then((messageId) => { | ||
console.log(`Published message: ${messageId}`); | ||
}) | ||
.catch((err) => { | ||
console.error('Error publishing message!', err); | ||
}); | ||
} | ||
|
||
bridgeEventsTo<T extends IEvent>(subject: Subject<T>) { | ||
// Subscriber | ||
this.events = this.googlePubSub | ||
.topic(this.topic) | ||
.subscription(this.subscription, this.subscriberOptions); | ||
|
||
fromEvent<GooglePubSubMessage>(this.events, 'message') | ||
.subscribe((message) => { | ||
console.log(`Recived message: ${message.id}`); | ||
const event = JSON.parse(message.data); | ||
subject.next(event); | ||
message.ack(); | ||
}); | ||
|
||
fromEvent(this.events, 'error') | ||
.subscribe(error => console.error('Recived error message', error)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.