diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java index 4d2db9d0a6..98ba597c41 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/InMemoryReactiveClientRegistrationRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,22 @@ */ package org.springframework.security.oauth2.client.registration; +import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import reactor.core.publisher.Mono; +import org.springframework.util.Assert; + /** * A Reactive {@link ClientRegistrationRepository} that stores {@link ClientRegistration}(s) in-memory. * * @author Rob Winch + * @author Ebert Toribio * @since 5.1 * @see ClientRegistrationRepository * @see ClientRegistration @@ -31,7 +38,7 @@ import reactor.core.publisher.Mono; public final class InMemoryReactiveClientRegistrationRepository implements ReactiveClientRegistrationRepository, Iterable { - private final InMemoryClientRegistrationRepository delegate; + private final Map clientIdToClientRegistration; /** * Constructs an {@code InMemoryReactiveClientRegistrationRepository} using the provided parameters. @@ -39,7 +46,12 @@ public final class InMemoryReactiveClientRegistrationRepository * @param registrations the client registration(s) */ public InMemoryReactiveClientRegistrationRepository(ClientRegistration... registrations) { - this.delegate = new InMemoryClientRegistrationRepository(registrations); + this(toList(registrations)); + } + + private static List toList(ClientRegistration... registrations) { + Assert.notEmpty(registrations, "registrations cannot be null or empty"); + return Arrays.asList(registrations); } /** @@ -48,12 +60,12 @@ public final class InMemoryReactiveClientRegistrationRepository * @param registrations the client registration(s) */ public InMemoryReactiveClientRegistrationRepository(List registrations) { - this.delegate = new InMemoryClientRegistrationRepository(registrations); + this.clientIdToClientRegistration = toUnmodifiableConcurrentMap(registrations); } @Override public Mono findByRegistrationId(String registrationId) { - return Mono.justOrEmpty(this.delegate.findByRegistrationId(registrationId)); + return Mono.justOrEmpty(this.clientIdToClientRegistration.get(registrationId)); } /** @@ -63,6 +75,20 @@ public final class InMemoryReactiveClientRegistrationRepository */ @Override public Iterator iterator() { - return delegate.iterator(); + return this.clientIdToClientRegistration.values().iterator(); + } + + private static Map toUnmodifiableConcurrentMap(List registrations) { + Assert.notEmpty(registrations, "registrations cannot be null or empty"); + ConcurrentHashMap result = new ConcurrentHashMap<>(); + for (ClientRegistration registration : registrations) { + Assert.notNull(registration, "no registration can be null"); + if (result.containsKey(registration.getRegistrationId())) { + throw new IllegalStateException(String.format("Duplicate key %s", + registration.getRegistrationId())); + } + result.put(registration.getRegistrationId(), registration); + } + return Collections.unmodifiableMap(result); } }