File tree Expand file tree Collapse file tree 10 files changed +76
-27
lines changed
CoursesCounter/application/Increment
apps/mooc_backend/config/dependency-injection/Shared
Contexts/Shared/infrastructure
apps/mooc_backend/features/step_definitions Expand file tree Collapse file tree 10 files changed +76
-27
lines changed Original file line number Diff line number Diff line change @@ -13,9 +13,9 @@ export class CourseCreatedDomainEvent extends DomainEvent {
13
13
14
14
constructor ( {
15
15
id,
16
- eventId,
17
- duration,
18
16
name,
17
+ duration,
18
+ eventId,
19
19
occurredOn
20
20
} : {
21
21
id : string ;
@@ -42,7 +42,7 @@ export class CourseCreatedDomainEvent extends DomainEvent {
42
42
body : CreateCourseDomainEventBody ,
43
43
eventId : string ,
44
44
occurredOn : Date
45
- ) : CourseCreatedDomainEvent {
45
+ ) : DomainEvent {
46
46
return new CourseCreatedDomainEvent ( {
47
47
id : aggregateId ,
48
48
duration : body . duration ,
Original file line number Diff line number Diff line change 1
1
import { DomainEventSubscriber } from '../../../../Shared/domain/DomainEventSubscriber' ;
2
2
import { CourseCreatedDomainEvent } from '../../../Courses/domain/CourseCreatedDomainEvent' ;
3
- import { CoursesCounterIncrementer } from './CoursesCounterIncrementer' ;
4
3
import { CourseId } from '../../../Shared/domain/Courses/CourseId' ;
4
+ import { CoursesCounterIncrementer } from './CoursesCounterIncrementer' ;
5
5
6
6
export class IncrementCoursesCounterOnCourseCreated implements DomainEventSubscriber < CourseCreatedDomainEvent > {
7
7
constructor ( private incrementer : CoursesCounterIncrementer ) { }
8
8
9
- subscribedTo ( ) : string [ ] {
10
- return [ CourseCreatedDomainEvent . EVENT_NAME ] ;
9
+ subscribedTo ( ) : any [ ] {
10
+ return [ CourseCreatedDomainEvent ] ;
11
11
}
12
12
13
13
async on ( domainEvent : CourseCreatedDomainEvent ) {
Original file line number Diff line number Diff line change 1
1
import { DomainEvent } from './DomainEvent' ;
2
2
3
3
export interface DomainEventSubscriber < T extends DomainEvent > {
4
- subscribedTo ( ) : Array < string > ;
4
+ subscribedTo ( ) : Array < any > ;
5
5
6
6
on ( domainEvent : T ) : Promise < void > ;
7
7
}
Original file line number Diff line number Diff line change
1
+ import { DomainEvent } from '../../domain/DomainEvent' ;
2
+ import { DomainEventMapping } from './DomainEventMapping' ;
3
+
4
+ export class DomainEventJsonDeserializer {
5
+ private mapping : DomainEventMapping ;
6
+
7
+ constructor ( mapping : DomainEventMapping ) {
8
+ this . mapping = mapping ;
9
+ }
10
+
11
+ deserialize ( event : string ) : DomainEvent {
12
+ const eventData = JSON . parse ( event ) . data ;
13
+ const eventName = eventData . type ;
14
+ const eventClass = this . mapping . for ( eventName ) ;
15
+
16
+ if ( ! eventClass ) {
17
+ throw new Error ( `The event ${ eventName } doesn't exist or has no subscribers` ) ;
18
+ }
19
+
20
+ return eventClass . fromPrimitives (
21
+ eventData . attributes . id ,
22
+ eventData . attributes ,
23
+ eventData . id ,
24
+ eventData . occurred_on
25
+ ) ;
26
+ }
27
+ }
Original file line number Diff line number Diff line change
1
+ import { DomainEventSubscriber } from '../../domain/DomainEventSubscriber' ;
2
+
3
+ export class DomainEventMapping {
4
+ mapping : any ;
5
+
6
+ constructor ( mapping : any ) {
7
+ this . mapping = mapping . reduce ( ( prev : any , subscriber : DomainEventSubscriber < any > ) => {
8
+ subscriber . subscribedTo ( ) . forEach ( event => {
9
+ prev [ event . EVENT_NAME ] = event ;
10
+ } ) ;
11
+ return prev ;
12
+ } , { } ) ;
13
+ }
14
+
15
+ for ( name : string ) {
16
+ if ( ! this . mapping [ name ] ) {
17
+ throw new Error ( `The Domain Event Class for ${ name } doesn't exists or have no subscribers` ) ;
18
+ }
19
+ return this . mapping [ name ] ;
20
+ }
21
+ }
Original file line number Diff line number Diff line change
1
+ import { EventEmitter } from 'events' ;
1
2
import { DomainEvent } from '../../domain/DomainEvent' ;
2
3
import { DomainEventSubscriber } from '../../domain/DomainEventSubscriber' ;
3
- import { EventEmitter } from 'events' ;
4
4
5
5
export class EventEmitterBus extends EventEmitter {
6
6
constructor ( subscribers : Array < DomainEventSubscriber < DomainEvent > > ) {
@@ -17,7 +17,7 @@ export class EventEmitterBus extends EventEmitter {
17
17
18
18
private registerSubscriber ( subscriber : DomainEventSubscriber < DomainEvent > ) {
19
19
subscriber . subscribedTo ( ) . map ( event => {
20
- this . on ( event , subscriber . on ) ;
20
+ this . on ( event . EVENT_NAME , subscriber . on ) ;
21
21
} ) ;
22
22
}
23
23
Original file line number Diff line number Diff line change 1
- import { EventBus } from '../../domain/EventBus' ;
2
1
import { DomainEvent } from '../../domain/DomainEvent' ;
3
2
import { DomainEventSubscriber } from '../../domain/DomainEventSubscriber' ;
3
+ import { EventBus } from '../../domain/EventBus' ;
4
4
5
5
type Subscription = {
6
6
boundedCallback : Function ;
@@ -27,7 +27,7 @@ export class InMemorySyncEventBus implements EventBus {
27
27
}
28
28
29
29
addSubscribers ( subscribers : Array < DomainEventSubscriber < DomainEvent > > ) {
30
- subscribers . map ( subscriber => subscriber . subscribedTo ( ) . map ( event => this . subscribe ( event , subscriber ) ) ) ;
30
+ subscribers . map ( subscriber => subscriber . subscribedTo ( ) . map ( event => this . subscribe ( event . EVENT_NAME , subscriber ) ) ) ;
31
31
}
32
32
33
33
private subscribe ( topic : string , subscriber : DomainEventSubscriber < DomainEvent > ) : void {
Original file line number Diff line number Diff line change 1
1
services :
2
-
3
2
Mooc.shared.ConnectionManager :
4
3
factory :
5
4
class : ../../../../../Contexts/Shared/infrastructure/persistence/mongo/MongoClientFactory
@@ -13,3 +12,11 @@ services:
13
12
Mooc.shared.EventBus :
14
13
class : ../../../../../Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus
15
14
arguments : []
15
+
16
+ Mooc.shared.EventBus.DomainEventMapping :
17
+ class : ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventMapping
18
+ arguments : ['!tagged domainEventSubscriber']
19
+
20
+ Mooc.shared.EventBus.DomainEventJsonDeserializer :
21
+ class : ../../../../../Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer
22
+ arguments : ['@Mooc.shared.EventBus.DomainEventMapping']
Original file line number Diff line number Diff line change 1
- import { InMemoryAsyncEventBus } from '../../../../src/Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus' ;
2
- import { DomainEventSubscriber } from '../../../../src/Contexts/Shared/domain/DomainEventSubscriber' ;
3
1
import { DomainEvent } from '../../../../src/Contexts/Shared/domain/DomainEvent' ;
2
+ import { DomainEventSubscriber } from '../../../../src/Contexts/Shared/domain/DomainEventSubscriber' ;
4
3
import { Uuid } from '../../../../src/Contexts/Shared/domain/value-object/Uuid' ;
4
+ import { InMemoryAsyncEventBus } from '../../../../src/Contexts/Shared/infrastructure/EventBus/InMemoryAsyncEventBus' ;
5
5
6
6
describe ( 'InMemoryAsyncEventBus' , ( ) => {
7
7
let subscriber : DomainEventSubscriberDummy ;
@@ -35,8 +35,8 @@ class DummyEvent extends DomainEvent {
35
35
}
36
36
37
37
class DomainEventSubscriberDummy implements DomainEventSubscriber < DummyEvent > {
38
- subscribedTo ( ) : string [ ] {
39
- return [ DummyEvent . EVENT_NAME ] ;
38
+ subscribedTo ( ) : any [ ] {
39
+ return [ DummyEvent ] ;
40
40
}
41
41
42
42
async on ( domainEvent : DummyEvent ) {
Original file line number Diff line number Diff line change 1
1
import { Given } from 'cucumber' ;
2
2
import container from '../../../../../src/apps/mooc_backend/config/dependency-injection' ;
3
3
import { EventBus } from '../../../../../src/Contexts/Shared/domain/EventBus' ;
4
- import { CourseCreatedDomainEvent } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseCreatedDomainEvent ' ;
4
+ import { DomainEventJsonDeserializer } from '../../../../../src/Contexts/Shared/infrastructure/EventBus/DomainEventJsonDeserializer ' ;
5
5
6
- Given ( 'I send an event to the event bus:' , async ( event : any ) => {
7
- const eventBus = container . get ( 'Mooc.shared.EventBus' ) as EventBus ;
8
- const jsonEvent = JSON . parse ( event ) . data ;
6
+ const eventBus = container . get ( 'Mooc.shared.EventBus' ) as EventBus ;
7
+ const deserializer = container . get ( 'Mooc.shared.EventBus.DomainEventJsonDeserializer' ) as DomainEventJsonDeserializer ;
9
8
10
- const domainEvent = CourseCreatedDomainEvent . fromPrimitives (
11
- jsonEvent . attributes . id ,
12
- jsonEvent . attributes ,
13
- jsonEvent . id ,
14
- jsonEvent . occurred_on
15
- ) ;
9
+ Given ( 'I send an event to the event bus:' , async ( event : any ) => {
10
+ const domainEvent = deserializer . deserialize ( event ) ;
16
11
17
12
await eventBus . publish ( [ domainEvent ] ) ;
18
13
} ) ;
19
-
You can’t perform that action at this time.
0 commit comments