Skip to content

Commit e554547

Browse files
committed
Revert Map constructor for InMemoryReactiveClientRegistrationRepository
This commit reverts f6414e9 and partial revert of e1b095d. NOTE: InMemoryReactiveClientRegistrationRepository should not expose a Map constructor as it would allow the caller to pass in a 'distributed' (remote) Map, which would result in a blocking I/O operation.
1 parent 23d61d4 commit e554547

File tree

4 files changed

+47
-68
lines changed

4 files changed

+47
-68
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepository.java

+14-13
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
import org.springframework.util.Assert;
1919

2020
import java.util.Arrays;
21-
import java.util.Collection;
2221
import java.util.Collections;
2322
import java.util.Iterator;
2423
import java.util.List;
2524
import java.util.Map;
25+
import java.util.concurrent.ConcurrentMap;
2626
import java.util.function.Function;
27-
import java.util.stream.Collectors;
27+
import java.util.stream.Collector;
28+
29+
import static java.util.stream.Collectors.collectingAndThen;
30+
import static java.util.stream.Collectors.toConcurrentMap;
2831

2932
/**
3033
* A {@link ClientRegistrationRepository} that stores {@link ClientRegistration}(s) in-memory.
@@ -37,7 +40,6 @@
3740
* @see ClientRegistration
3841
*/
3942
public final class InMemoryClientRegistrationRepository implements ClientRegistrationRepository, Iterable<ClientRegistration> {
40-
4143
private final Map<String, ClientRegistration> registrations;
4244

4345
/**
@@ -46,8 +48,7 @@ public final class InMemoryClientRegistrationRepository implements ClientRegistr
4648
* @param registrations the client registration(s)
4749
*/
4850
public InMemoryClientRegistrationRepository(ClientRegistration... registrations) {
49-
Assert.notEmpty(registrations, "registrations cannot be empty");
50-
this.registrations = createClientRegistrationIdToClientRegistration(Arrays.asList(registrations));
51+
this(Arrays.asList(registrations));
5152
}
5253

5354
/**
@@ -56,7 +57,14 @@ public InMemoryClientRegistrationRepository(ClientRegistration... registrations)
5657
* @param registrations the client registration(s)
5758
*/
5859
public InMemoryClientRegistrationRepository(List<ClientRegistration> registrations) {
59-
this(createClientRegistrationIdToClientRegistration(registrations));
60+
this(createRegistrationsMap(registrations));
61+
}
62+
63+
private static Map<String, ClientRegistration> createRegistrationsMap(List<ClientRegistration> registrations) {
64+
Assert.notEmpty(registrations, "registrations cannot be empty");
65+
Collector<ClientRegistration, ?, ConcurrentMap<String, ClientRegistration>> collector =
66+
toConcurrentMap(ClientRegistration::getRegistrationId, Function.identity());
67+
return registrations.stream().collect(collectingAndThen(collector, Collections::unmodifiableMap));
6068
}
6169

6270
/**
@@ -71,13 +79,6 @@ public InMemoryClientRegistrationRepository(Map<String, ClientRegistration> regi
7179
this.registrations = registrations;
7280
}
7381

74-
private static Map<String, ClientRegistration> createClientRegistrationIdToClientRegistration(Collection<ClientRegistration> registrations) {
75-
Assert.notNull(registrations, "registrations cannot be null");
76-
return Collections.unmodifiableMap(registrations.stream()
77-
.peek(registration -> Assert.notNull(registration, "registrations cannot contain null values"))
78-
.collect(Collectors.toMap(ClientRegistration::getRegistrationId, Function.identity())));
79-
}
80-
8182
@Override
8283
public ClientRegistration findByRegistrationId(String registrationId) {
8384
Assert.hasText(registrationId, "registrationId cannot be empty");

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java

+18-18
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,39 @@
1818
import java.util.Iterator;
1919
import java.util.List;
2020
import java.util.Map;
21+
import java.util.function.Function;
22+
import java.util.stream.Collectors;
23+
24+
import org.springframework.util.Assert;
25+
import org.springframework.util.ConcurrentReferenceHashMap;
2126

2227
import reactor.core.publisher.Mono;
2328

2429
/**
2530
* A Reactive {@link ClientRegistrationRepository} that stores {@link ClientRegistration}(s) in-memory.
2631
*
2732
* @author Rob Winch
28-
* @author Vedran Pavic
2933
* @since 5.1
3034
* @see ClientRegistrationRepository
3135
* @see ClientRegistration
3236
*/
3337
public final class InMemoryReactiveClientRegistrationRepository
3438
implements ReactiveClientRegistrationRepository, Iterable<ClientRegistration> {
3539

36-
private final InMemoryClientRegistrationRepository delegate;
40+
private final Map<String, ClientRegistration> clientIdToClientRegistration;
3741

3842
/**
3943
* Constructs an {@code InMemoryReactiveClientRegistrationRepository} using the provided parameters.
4044
*
4145
* @param registrations the client registration(s)
4246
*/
4347
public InMemoryReactiveClientRegistrationRepository(ClientRegistration... registrations) {
44-
this.delegate = new InMemoryClientRegistrationRepository(registrations);
48+
Assert.notEmpty(registrations, "registrations cannot be empty");
49+
this.clientIdToClientRegistration = new ConcurrentReferenceHashMap<>();
50+
for (ClientRegistration registration : registrations) {
51+
Assert.notNull(registration, "registrations cannot contain null values");
52+
this.clientIdToClientRegistration.put(registration.getRegistrationId(), registration);
53+
}
4554
}
4655

4756
/**
@@ -50,24 +59,15 @@ public InMemoryReactiveClientRegistrationRepository(ClientRegistration... regist
5059
* @param registrations the client registration(s)
5160
*/
5261
public InMemoryReactiveClientRegistrationRepository(List<ClientRegistration> registrations) {
53-
this.delegate = new InMemoryClientRegistrationRepository(registrations);
62+
Assert.notEmpty(registrations, "registrations cannot be null or empty");
63+
this.clientIdToClientRegistration = registrations.stream()
64+
.collect(Collectors.toConcurrentMap(ClientRegistration::getRegistrationId, Function.identity()));
5465
}
5566

56-
/**
57-
* Constructs an {@code InMemoryReactiveClientRegistrationRepository} using the provided {@code Map}
58-
* of {@link ClientRegistration#getRegistrationId() registration id} to {@link ClientRegistration}.
59-
* <b>NOTE:</b> The supplied {@code Map} must be a non-blocking {@code Map}.
60-
*
61-
* @since 5.2
62-
* @param registrations the {@code Map} of client registration(s)
63-
*/
64-
public InMemoryReactiveClientRegistrationRepository(
65-
Map<String, ClientRegistration> registrations) {
66-
this.delegate = new InMemoryClientRegistrationRepository(registrations);
67-
}
6867

68+
@Override
6969
public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
70-
return Mono.justOrEmpty(this.delegate.findByRegistrationId(registrationId));
70+
return Mono.justOrEmpty(this.clientIdToClientRegistration.get(registrationId));
7171
}
7272

7373
/**
@@ -77,6 +77,6 @@ public Mono<ClientRegistration> findByRegistrationId(String registrationId) {
7777
*/
7878
@Override
7979
public Iterator<ClientRegistration> iterator() {
80-
return delegate.iterator();
80+
return this.clientIdToClientRegistration.values().iterator();
8181
}
8282
}

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/InMemoryClientRegistrationRepositoryTests.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Test;
2020

2121
import java.util.Arrays;
22+
import java.util.Collections;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
@@ -38,14 +39,14 @@ public class InMemoryClientRegistrationRepositoryTests {
3839
private InMemoryClientRegistrationRepository clients = new InMemoryClientRegistrationRepository(this.registration);
3940

4041
@Test(expected = IllegalArgumentException.class)
41-
public void constructorVarArgsListClientRegistrationWhenNullThenIllegalArgumentException() {
42-
ClientRegistration nullRegistration = null;
43-
new InMemoryClientRegistrationRepository(nullRegistration);
42+
public void constructorListClientRegistrationWhenNullThenIllegalArgumentException() {
43+
List<ClientRegistration> registrations = null;
44+
new InMemoryClientRegistrationRepository(registrations);
4445
}
4546

4647
@Test(expected = IllegalArgumentException.class)
47-
public void constructorListClientRegistrationWhenNullThenIllegalArgumentException() {
48-
List<ClientRegistration> registrations = null;
48+
public void constructorListClientRegistrationWhenEmptyThenIllegalArgumentException() {
49+
List<ClientRegistration> registrations = Collections.emptyList();
4950
new InMemoryClientRegistrationRepository(registrations);
5051
}
5152

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepositoryTests.java

+9-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,21 +16,18 @@
1616

1717
package org.springframework.security.oauth2.client.registration;
1818

19-
import org.junit.Before;
20-
import org.junit.Test;
21-
import reactor.test.StepVerifier;
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2221

23-
import java.util.Arrays;
24-
import java.util.HashMap;
2522
import java.util.List;
26-
import java.util.Map;
2723

28-
import static org.assertj.core.api.Assertions.assertThat;
29-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
24+
import org.junit.Before;
25+
import org.junit.Test;
26+
27+
import reactor.test.StepVerifier;
3028

3129
/**
3230
* @author Rob Winch
33-
* @author Vedran Pavic
3431
* @since 5.1
3532
*/
3633
public class InMemoryReactiveClientRegistrationRepositoryTests {
@@ -64,33 +61,13 @@ public void constructorWhenClientRegistrationListThenIllegalArgumentException()
6461
.isInstanceOf(IllegalArgumentException.class);
6562
}
6663

67-
@Test
68-
public void constructorWhenClientRegistrationListHasNullThenIllegalArgumentException() {
69-
List<ClientRegistration> registrations = Arrays.asList(null, registration);
70-
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registrations))
71-
.isInstanceOf(IllegalArgumentException.class);
72-
}
73-
7464
@Test
7565
public void constructorWhenClientRegistrationIsNullThenIllegalArgumentException() {
76-
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registration, null))
77-
.isInstanceOf(IllegalArgumentException.class);
78-
}
79-
80-
@Test
81-
public void constructorWhenClientRegistrationMapIsNullThenIllegalArgumentException() {
82-
Map<String, ClientRegistration> registrations = null;
83-
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registrations))
66+
ClientRegistration registration = null;
67+
assertThatThrownBy(() -> new InMemoryReactiveClientRegistrationRepository(registration))
8468
.isInstanceOf(IllegalArgumentException.class);
8569
}
8670

87-
@Test
88-
public void constructorWhenClientRegistrationMapIsEmptyThenRepositoryIsEmpty() {
89-
InMemoryReactiveClientRegistrationRepository repository = new InMemoryReactiveClientRegistrationRepository(
90-
new HashMap<>());
91-
assertThat(repository).isEmpty();
92-
}
93-
9471
@Test
9572
public void findByRegistrationIdWhenValidIdThenFound() {
9673
StepVerifier.create(this.repository.findByRegistrationId(this.registration.getRegistrationId()))

0 commit comments

Comments
 (0)