@@ -14,28 +14,39 @@ public sealed class ApiKeyEvents : INotificationHandler<ApiKeyAuthenticated>,
14
14
{
15
15
private readonly IdentityContext _context ;
16
16
private readonly ICustomAttributeService _customAttributes ;
17
+ private readonly IMediator _mediator ;
17
18
18
- public ApiKeyEvents ( IdentityContext context , ICustomAttributeService customAttributes )
19
+ public ApiKeyEvents ( IdentityContext context , ICustomAttributeService customAttributes , IMediator mediator )
19
20
{
20
21
_context = context ;
21
22
_customAttributes = customAttributes ;
23
+ _mediator = mediator ;
22
24
}
23
25
24
26
public async Task Handle ( ApiKeyAuthenticated @event , CancellationToken cancellationToken )
25
27
{
26
- ApiKeyEntity apiKey = await _context . ApiKeys
27
- . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken )
28
- ?? throw new InvalidOperationException ( $ "The API key entity 'StreamId={ @event . StreamId } ' could not be found.") ;
28
+ ApiKeyEntity ? apiKey = await _context . ApiKeys
29
+ . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
29
30
30
- apiKey . Authenticate ( @event ) ;
31
+ if ( apiKey == null || apiKey . Version != ( @event . Version - 1 ) )
32
+ {
33
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
34
+ }
35
+ else
36
+ {
37
+ apiKey . Authenticate ( @event ) ;
31
38
32
- await _context . SaveChangesAsync ( cancellationToken ) ;
39
+ await _context . SaveChangesAsync ( cancellationToken ) ;
40
+
41
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
42
+ }
33
43
}
34
44
35
45
public async Task Handle ( ApiKeyCreated @event , CancellationToken cancellationToken )
36
46
{
37
47
ApiKeyEntity ? apiKey = await _context . ApiKeys . AsNoTracking ( )
38
48
. SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
49
+
39
50
if ( apiKey == null )
40
51
{
41
52
apiKey = new ( @event ) ;
@@ -44,61 +55,98 @@ public async Task Handle(ApiKeyCreated @event, CancellationToken cancellationTok
44
55
45
56
await SaveActorAsync ( apiKey , cancellationToken ) ;
46
57
await _context . SaveChangesAsync ( cancellationToken ) ;
58
+
59
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
60
+ }
61
+ else
62
+ {
63
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
47
64
}
48
65
}
49
66
50
67
public async Task Handle ( ApiKeyDeleted @event , CancellationToken cancellationToken )
51
68
{
52
69
ApiKeyEntity ? apiKey = await _context . ApiKeys
53
70
. SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
54
- if ( apiKey != null )
71
+
72
+ if ( apiKey == null )
73
+ {
74
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
75
+ }
76
+ else
55
77
{
56
78
_context . ApiKeys . Remove ( apiKey ) ;
57
79
58
80
await DeleteActorAsync ( apiKey , cancellationToken ) ;
59
81
await _customAttributes . RemoveAsync ( EntityType . ApiKey , apiKey . ApiKeyId , cancellationToken ) ;
60
82
await _context . SaveChangesAsync ( cancellationToken ) ;
83
+
84
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
61
85
}
62
86
}
63
87
64
88
public async Task Handle ( ApiKeyRoleAdded @event , CancellationToken cancellationToken )
65
89
{
66
- ApiKeyEntity apiKey = await _context . ApiKeys
67
- . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken )
68
- ?? throw new InvalidOperationException ( $ "The API key entity 'StreamId={ @event . StreamId } ' could not be found.") ;
90
+ ApiKeyEntity ? apiKey = await _context . ApiKeys
91
+ . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
92
+
93
+ if ( apiKey == null || apiKey . Version != ( @event . Version - 1 ) )
94
+ {
95
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
96
+ }
97
+ else
98
+ {
99
+ RoleEntity role = await _context . Roles
100
+ . SingleOrDefaultAsync ( x => x . StreamId == @event . RoleId . Value , cancellationToken )
101
+ ?? throw new InvalidOperationException ( $ "The role entity 'StreamId={ @event . RoleId } ' could not be found.") ;
69
102
70
- RoleEntity role = await _context . Roles
71
- . SingleOrDefaultAsync ( x => x . StreamId == @event . RoleId . Value , cancellationToken )
72
- ?? throw new InvalidOperationException ( $ "The role entity 'StreamId={ @event . RoleId } ' could not be found.") ;
103
+ apiKey . AddRole ( role , @event ) ;
73
104
74
- apiKey . AddRole ( role , @event ) ;
105
+ await _context . SaveChangesAsync ( cancellationToken ) ;
75
106
76
- await _context . SaveChangesAsync ( cancellationToken ) ;
107
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
108
+ }
77
109
}
78
110
79
111
public async Task Handle ( ApiKeyRoleRemoved @event , CancellationToken cancellationToken )
80
112
{
81
- ApiKeyEntity apiKey = await _context . ApiKeys
113
+ ApiKeyEntity ? apiKey = await _context . ApiKeys
82
114
. Include ( x => x . Roles )
83
- . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken )
84
- ?? throw new InvalidOperationException ( $ "The API key entity 'StreamId={ @event . StreamId } ' could not be found.") ;
115
+ . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
85
116
86
- apiKey . RemoveRole ( @event ) ;
117
+ if ( apiKey == null || apiKey . Version != ( @event . Version - 1 ) )
118
+ {
119
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
120
+ }
121
+ else
122
+ {
123
+ apiKey . RemoveRole ( @event ) ;
124
+
125
+ await _context . SaveChangesAsync ( cancellationToken ) ;
87
126
88
- await _context . SaveChangesAsync ( cancellationToken ) ;
127
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
128
+ }
89
129
}
90
130
91
131
public async Task Handle ( ApiKeyUpdated @event , CancellationToken cancellationToken )
92
132
{
93
- ApiKeyEntity apiKey = await _context . ApiKeys
94
- . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken )
95
- ?? throw new InvalidOperationException ( $ "The API key entity 'StreamId={ @event . StreamId } ' could not be found.") ;
133
+ ApiKeyEntity ? apiKey = await _context . ApiKeys
134
+ . SingleOrDefaultAsync ( x => x . StreamId == @event . StreamId . Value , cancellationToken ) ;
135
+
136
+ if ( apiKey == null || apiKey . Version != ( @event . Version - 1 ) )
137
+ {
138
+ await _mediator . Publish ( new EventNotHandled ( @event , apiKey ) , cancellationToken ) ;
139
+ }
140
+ else
141
+ {
142
+ apiKey . Update ( @event ) ;
96
143
97
- apiKey . Update ( @event ) ;
144
+ await SaveActorAsync ( apiKey , cancellationToken ) ;
145
+ await _customAttributes . UpdateAsync ( EntityType . ApiKey , apiKey . ApiKeyId , @event . CustomAttributes , cancellationToken ) ;
146
+ await _context . SaveChangesAsync ( cancellationToken ) ;
98
147
99
- await SaveActorAsync ( apiKey , cancellationToken ) ;
100
- await _customAttributes . UpdateAsync ( EntityType . ApiKey , apiKey . ApiKeyId , @event . CustomAttributes , cancellationToken ) ;
101
- await _context . SaveChangesAsync ( cancellationToken ) ;
148
+ await _mediator . Publish ( new EventHandled ( @event ) , cancellationToken ) ;
149
+ }
102
150
}
103
151
104
152
private async Task DeleteActorAsync ( ApiKeyEntity apiKey , CancellationToken cancellationToken )
0 commit comments