Skip to content

Commit 8babcd3

Browse files
committed
Introduce AuthenticationEventMulticaster interface.
Closes gh-816
1 parent 693f9cd commit 8babcd3

File tree

5 files changed

+167
-45
lines changed

5 files changed

+167
-45
lines changed

spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationEventPublisher.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.vault.authentication.event.AuthenticationErrorEvent;
2323
import org.springframework.vault.authentication.event.AuthenticationErrorListener;
2424
import org.springframework.vault.authentication.event.AuthenticationEvent;
25+
import org.springframework.vault.authentication.event.AuthenticationEventMulticaster;
2526
import org.springframework.vault.authentication.event.AuthenticationListener;
2627

2728
/**
@@ -31,13 +32,13 @@
3132
* {@link AuthenticationErrorListener}.
3233
*
3334
* @author Mark Paluch
34-
* @since 2.2
3535
* @see AuthenticationEvent
3636
* @see AuthenticationErrorEvent
3737
* @see AuthenticationListener
3838
* @see AuthenticationErrorListener
39+
* @since 2.2
3940
*/
40-
public abstract class AuthenticationEventPublisher {
41+
public abstract class AuthenticationEventPublisher implements AuthenticationEventMulticaster {
4142

4243
private final Set<AuthenticationListener> listeners = new CopyOnWriteArraySet<>();
4344

@@ -46,8 +47,9 @@ public abstract class AuthenticationEventPublisher {
4647
/**
4748
* Add a {@link AuthenticationListener}. The listener starts receiving events as soon
4849
* as possible.
49-
* @param listener lease listener, must not be {@literal null}.
50+
* @param listener the listener, must not be {@literal null}.
5051
*/
52+
@Override
5153
public void addAuthenticationListener(AuthenticationListener listener) {
5254

5355
Assert.notNull(listener, "AuthenticationEventListener must not be null");
@@ -57,17 +59,19 @@ public void addAuthenticationListener(AuthenticationListener listener) {
5759

5860
/**
5961
* Remove a {@link AuthenticationListener}.
60-
* @param listener must not be {@literal null}.
62+
* @param listener the listener, must not be {@literal null}.
6163
*/
64+
@Override
6265
public void removeAuthenticationListener(AuthenticationListener listener) {
6366
this.listeners.remove(listener);
6467
}
6568

6669
/**
6770
* Add a {@link AuthenticationErrorListener}. The listener starts receiving events as
6871
* soon as possible.
69-
* @param listener lease listener, must not be {@literal null}.
72+
* @param listener the listener, must not be {@literal null}.
7073
*/
74+
@Override
7175
public void addErrorListener(AuthenticationErrorListener listener) {
7276

7377
Assert.notNull(listener, "AuthenticationEventErrorListener must not be null");
@@ -77,31 +81,24 @@ public void addErrorListener(AuthenticationErrorListener listener) {
7781

7882
/**
7983
* Remove a {@link AuthenticationErrorListener}.
80-
* @param listener must not be {@literal null}.
84+
* @param listener the listener, must not be {@literal null}.
8185
*/
86+
@Override
8287
public void removeErrorListener(AuthenticationErrorListener listener) {
8388
this.errorListeners.remove(listener);
8489
}
8590

86-
/**
87-
* Dispatch the event to all {@link AuthenticationListener}s.
88-
* @param authenticationEvent the event to dispatch.
89-
*/
90-
void dispatch(AuthenticationEvent authenticationEvent) {
91-
91+
@Override
92+
public void multicastEvent(AuthenticationEvent event) {
9293
for (AuthenticationListener listener : this.listeners) {
93-
listener.onAuthenticationEvent(authenticationEvent);
94+
listener.onAuthenticationEvent(event);
9495
}
9596
}
9697

97-
/**
98-
* Dispatch the event to all {@link AuthenticationErrorListener}s.
99-
* @param authenticationEvent the event to dispatch.
100-
*/
101-
void dispatch(AuthenticationErrorEvent authenticationEvent) {
102-
98+
@Override
99+
public void multicastEvent(AuthenticationErrorEvent event) {
103100
for (AuthenticationErrorListener listener : this.errorListeners) {
104-
listener.onAuthenticationError(authenticationEvent);
101+
listener.onAuthenticationError(event);
105102
}
106103
}
107104

spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,10 @@ public void revoke() {
169169
protected void revoke(VaultToken token) {
170170

171171
try {
172-
dispatch(new BeforeLoginTokenRevocationEvent(token));
172+
multicastEvent(new BeforeLoginTokenRevocationEvent(token));
173173
this.restOperations.postForObject("auth/token/revoke-self", new HttpEntity<>(VaultHttpHeaders.from(token)),
174174
Map.class);
175-
dispatch(new AfterLoginTokenRevocationEvent(token));
175+
multicastEvent(new AfterLoginTokenRevocationEvent(token));
176176
}
177177
catch (RuntimeException e) {
178178
if (LoginToken.hasAccessor(token)) {
@@ -183,7 +183,7 @@ protected void revoke(VaultToken token) {
183183
else {
184184
this.logger.warn("Cannot revoke VaultToken", e);
185185
}
186-
dispatch(new LoginTokenRevocationFailedEvent(token, e));
186+
multicastEvent(new LoginTokenRevocationFailedEvent(token, e));
187187
}
188188
}
189189

@@ -229,14 +229,14 @@ private RenewOutcome tryRenewToken() {
229229
this.logger.warn(exception.getMessage());
230230
}
231231

232-
dispatch(new LoginTokenRenewalFailedEvent(tokenWrapper.getToken(), exception));
232+
multicastEvent(new LoginTokenRenewalFailedEvent(tokenWrapper.getToken(), exception));
233233
return shouldDrop ? RenewOutcome.TERMINAL_ERROR : RenewOutcome.RENEWABLE_ERROR;
234234
}
235235
}
236236

237237
private RenewOutcome doRenew(TokenWrapper wrapper) {
238238

239-
dispatch(new BeforeLoginTokenRenewedEvent(wrapper.getToken()));
239+
multicastEvent(new BeforeLoginTokenRenewedEvent(wrapper.getToken()));
240240
VaultResponse vaultResponse = this.restOperations.postForObject("auth/token/renew-self",
241241
new HttpEntity<>(VaultHttpHeaders.from(wrapper.token)), VaultResponse.class);
242242

@@ -254,12 +254,12 @@ private RenewOutcome doRenew(TokenWrapper wrapper) {
254254
}
255255

256256
setToken(Optional.empty());
257-
dispatch(new LoginTokenExpiredEvent(renewed));
257+
multicastEvent(new LoginTokenExpiredEvent(renewed));
258258
return RenewOutcome.TERMINAL_ERROR;
259259
}
260260

261261
setToken(Optional.of(new TokenWrapper(renewed, wrapper.revocable)));
262-
dispatch(new AfterLoginTokenRenewedEvent(renewed));
262+
multicastEvent(new AfterLoginTokenRenewedEvent(renewed));
263263

264264
return RenewOutcome.SUCCESS;
265265
}
@@ -292,7 +292,7 @@ private void doGetSessionToken() {
292292
token = this.clientAuthentication.login();
293293
}
294294
catch (VaultException e) {
295-
dispatch(new LoginFailedEvent(this.clientAuthentication, e));
295+
multicastEvent(new LoginFailedEvent(this.clientAuthentication, e));
296296
throw e;
297297
}
298298

@@ -305,12 +305,12 @@ private void doGetSessionToken() {
305305
}
306306
catch (VaultTokenLookupException e) {
307307
this.logger.warn(String.format("Cannot enhance VaultToken to a LoginToken: %s", e.getMessage()));
308-
dispatch(new AuthenticationErrorEvent(token, e));
308+
multicastEvent(new AuthenticationErrorEvent(token, e));
309309
}
310310
}
311311

312312
setToken(Optional.of(wrapper));
313-
dispatch(new AfterLoginEvent(token));
313+
multicastEvent(new AfterLoginEvent(token));
314314

315315
if (isTokenRenewable()) {
316316
scheduleRenewal();
@@ -356,7 +356,7 @@ private void scheduleRenewal() {
356356
}
357357
catch (Exception e) {
358358
this.logger.error("Cannot renew VaultToken", e);
359-
dispatch(new LoginTokenRenewalFailedEvent(token, e));
359+
multicastEvent(new LoginTokenRenewalFailedEvent(token, e));
360360
}
361361
};
362362

spring-vault-core/src/main/java/org/springframework/vault/authentication/ReactiveLifecycleAwareSessionManager.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ protected Mono<Void> revoke(VaultToken token) {
185185
})
186186
.retrieve()
187187
.bodyToMono(String.class)
188-
.doOnSubscribe(ignore -> dispatch(new BeforeLoginTokenRevocationEvent(token)))
189-
.doOnNext(ignore -> dispatch(new AfterLoginTokenRevocationEvent(token)))
188+
.doOnSubscribe(ignore -> multicastEvent(new BeforeLoginTokenRevocationEvent(token)))
189+
.doOnNext(ignore -> multicastEvent(new AfterLoginTokenRevocationEvent(token)))
190190
.onErrorResume(WebClientResponseException.class, e -> onRevokeFailed(token, e))
191191
.onErrorResume(Exception.class, e -> onRevokeFailed(token, e))
192192
.then();
@@ -202,7 +202,7 @@ private Mono<String> onRevokeFailed(VaultToken token, Throwable e) {
202202
this.logger.warn("Cannot revoke VaultToken", e);
203203
}
204204

205-
dispatch(new LoginTokenRevocationFailedEvent(token, e));
205+
multicastEvent(new LoginTokenRevocationFailedEvent(token, e));
206206

207207
return Mono.empty();
208208
}
@@ -251,7 +251,7 @@ private Mono<TokenWrapper> doRenewToken(TokenWrapper wrapper) {
251251
this.logger.warn(exception.getMessage());
252252
}
253253

254-
dispatch(new LoginTokenRenewalFailedEvent(wrapper.getToken(), exception));
254+
multicastEvent(new LoginTokenRenewalFailedEvent(wrapper.getToken(), exception));
255255
return shouldDrop ? EMPTY : Mono.just(wrapper);
256256
});
257257
}
@@ -264,14 +264,15 @@ private Mono<TokenWrapper> doRenew(TokenWrapper tokenWrapper) {
264264
.retrieve()
265265
.bodyToMono(VaultResponse.class);
266266

267-
return exchange.doOnSubscribe(ignore -> dispatch(new BeforeLoginTokenRenewedEvent(tokenWrapper.getToken())))
267+
return exchange
268+
.doOnSubscribe(ignore -> multicastEvent(new BeforeLoginTokenRenewedEvent(tokenWrapper.getToken())))
268269
.handle((response, sink) -> {
269270

270271
LoginToken renewed = LoginTokenUtil.from(response.getRequiredAuth());
271272

272273
if (!isExpired(renewed)) {
273274
sink.next(new TokenWrapper(renewed, tokenWrapper.revocable));
274-
dispatch(new AfterLoginTokenRenewedEvent(renewed));
275+
multicastEvent(new AfterLoginTokenRenewedEvent(renewed));
275276
return;
276277
}
277278

@@ -287,7 +288,7 @@ private Mono<TokenWrapper> doRenew(TokenWrapper tokenWrapper) {
287288
}
288289

289290
dropCurrentToken();
290-
dispatch(new LoginTokenExpiredEvent(renewed));
291+
multicastEvent(new LoginTokenExpiredEvent(renewed));
291292
});
292293
}
293294

@@ -310,7 +311,7 @@ public Mono<VaultToken> getVaultToken() throws VaultException {
310311
Mono<TokenWrapper> obtainToken = this.clientAuthentication.getVaultToken()
311312
.flatMap(this::doSelfLookup) //
312313
.onErrorMap(it -> {
313-
dispatch(new LoginFailedEvent(this.clientAuthentication, it));
314+
multicastEvent(new LoginFailedEvent(this.clientAuthentication, it));
314315
return it;
315316
})
316317
.doOnNext(it -> {
@@ -319,7 +320,7 @@ public Mono<VaultToken> getVaultToken() throws VaultException {
319320
scheduleRenewal(it.getToken());
320321
}
321322

322-
dispatch(new AfterLoginEvent(it.getToken()));
323+
multicastEvent(new AfterLoginEvent(it.getToken()));
323324
});
324325

325326
this.token.compareAndSet(tokenWrapper, obtainToken.cache());
@@ -339,7 +340,7 @@ private Mono<TokenWrapper> doSelfLookup(VaultToken token) {
339340
return loginTokenMono.onErrorResume(e -> {
340341

341342
this.logger.warn(String.format("Cannot enhance VaultToken to a LoginToken: %s", e.getMessage()));
342-
dispatch(new AuthenticationErrorEvent(token, e));
343+
multicastEvent(new AuthenticationErrorEvent(token, e));
343344
return Mono.just(token);
344345
}).map(it -> new TokenWrapper(it, false));
345346
}
@@ -379,13 +380,13 @@ private void scheduleRenewal(VaultToken token) {
379380
if (isTokenRenewable(token)) {
380381
renewToken().subscribe(this::scheduleRenewal, e -> {
381382
this.logger.error("Cannot renew VaultToken", e);
382-
dispatch(new LoginTokenRenewalFailedEvent(token, e));
383+
multicastEvent(new LoginTokenRenewalFailedEvent(token, e));
383384
});
384385
}
385386
}
386387
catch (Exception e) {
387388
this.logger.error("Cannot renew VaultToken", e);
388-
dispatch(new LoginTokenRenewalFailedEvent(token, e));
389+
multicastEvent(new LoginTokenRenewalFailedEvent(token, e));
389390
}
390391
};
391392

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.vault.authentication.event;
17+
18+
/**
19+
* Interface to be implemented by objects that can manage a number of
20+
* {@link AuthenticationEvent} and {@link AuthenticationErrorEvent} objects and publish
21+
* events to them.
22+
* <p>
23+
* An {@link org.springframework.vault.authentication.AuthenticationEventPublisher},
24+
* typically a lifecycle-aware
25+
* {@link org.springframework.vault.authentication.SessionManager}, can use an
26+
* {@code AuthenticationEventMulticaster} as a delegate for actually publishing events.
27+
*
28+
* @author Mark Paluch
29+
* @see AuthenticationListener
30+
* @see AuthenticationErrorListener
31+
* @since 3.1
32+
*/
33+
public interface AuthenticationEventMulticaster {
34+
35+
/**
36+
* Add a {@link AuthenticationListener}.
37+
* @param listener the listener, must not be {@literal null}.
38+
*/
39+
void addAuthenticationListener(AuthenticationListener listener);
40+
41+
/**
42+
* Remove a {@link AuthenticationListener}.
43+
* @param listener the listener, must not be {@literal null}.
44+
*/
45+
void removeAuthenticationListener(AuthenticationListener listener);
46+
47+
/**
48+
* Add a {@link AuthenticationErrorListener}.
49+
* @param listener the listener, must not be {@literal null}.
50+
*/
51+
void addErrorListener(AuthenticationErrorListener listener);
52+
53+
/**
54+
* Remove a {@link AuthenticationErrorListener}.
55+
* @param listener the listener, must not be {@literal null}.
56+
*/
57+
void removeErrorListener(AuthenticationErrorListener listener);
58+
59+
/**
60+
* Multicast the given application event to appropriate listeners.
61+
* @param event the event to multicast.
62+
*/
63+
void multicastEvent(AuthenticationEvent event);
64+
65+
/**
66+
* Multicast the given application event to appropriate listeners.
67+
* @param event the event to multicast.
68+
*/
69+
void multicastEvent(AuthenticationErrorEvent event);
70+
71+
}

0 commit comments

Comments
 (0)