Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow in-memory client registration repos to be constructed with a map #5918

Closed

Conversation

vpavic
Copy link
Contributor

@vpavic vpavic commented Oct 4, 2018

This would allow to back InMemoryClientRegistrationRepository with a distributed Map, such as Hazelcast's IMap for instance.

Ideally, the implementations should be renamed as well in order to reflect their nature (e.g. to MapClientRegistrationRepository). In that case, to ensure backwards compatibility the InMemoryClientRegistrationRepository that would be provided as an implementation that simply delegates to MapClientRegistrationRepository and is marked as deprecated. Let me know what's your opinion on this, and if accepted should I do it via this PR or another one later on.

@rwinch rwinch requested a review from jgrandja October 4, 2018 15:11
@jgrandja
Copy link
Contributor

jgrandja commented Oct 4, 2018

@vpavic This makes sense to allow InMemoryClientRegistrationRepository to be directly supplied with a Map - that may be a distributed one.

However, I'm not keen on deprecating InMemoryClientRegistrationRepository. Is there a specific reason you are wanting it deprecated? I do agree that InMemoryClientRegistrationRepository should delegate to the proposed new MapClientRegistrationRepository.

Please go ahead and add MapClientRegistrationRepository to this PR.

@jgrandja
Copy link
Contributor

jgrandja commented Oct 4, 2018

Also, what are your thoughts on just adding MapClientRegistrationRepository and leaving InMemoryClientRegistrationRepository as-is?

@vpavic
Copy link
Contributor Author

vpavic commented Oct 6, 2018

Is there a specific reason you are wanting it deprecated?

It is a naming concern. If something can be backed by a distributed map like Hazelcast's IMap, and having in mind that Hazelcast can operate in client-server topology, then it isn't an in-memory implementation anymore. Besides, the term in-memory is vague, as multiple data structures can theoretically be used to fit that description. OTOH MapClientRegistrationRepository is very clear.

Also, what are your thoughts on just adding MapClientRegistrationRepository and leaving InMemoryClientRegistrationRepository as-is?

It sounds like an unnecessary duplication to me. With MapClientRegistrationRepository in, the InMemoryClientRegistrationRepository isn't needed anymore and I'd have it simply delegate to the new MapClientRegistrationRepository.

@jgrandja
Copy link
Contributor

jgrandja commented Oct 9, 2018

Besides, the term in-memory is vague, as multiple data structures can theoretically be used to fit that description.

The naming convention InMemory is pretty clear. The associated in-memory implementation is designed to be non-persistent and backed by an in-memory construct. These implementations are meant to be simple and usually considered default implementations. See also InMemoryOAuth2AuthorizedClientService and InMemoryUserDetailsManager.

It is a naming concern. If something can be backed by a distributed map like Hazelcast's IMap, and having in mind that Hazelcast can operate in client-server topology, then it isn't an in-memory implementation anymore

Agreed that this can be confusing if the user were to implement this way. An alternative implementation the user can do is:

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
	// Obtain registrations from Hazelcast's `IMap`
	final Map<String, ClientRegistration> registrations = getRegistrations();
	return registrationId -> registrations.get(registrationId);
}

OR

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
	// Obtain registrations from Hazelcast's `IMap`
	final Map<String, ClientRegistration> registrations = getRegistrations();
	return new MapClientRegistrationRepository(getRegistrations());
}

private class MapClientRegistrationRepository implements ClientRegistrationRepository, Iterable<ClientRegistration> {
	private Map<String, ClientRegistration> registrations;

	private MapClientRegistrationRepository(Map<String, ClientRegistration> registrations) {
		this.registrations = registrations;
	}

	@Override
	public ClientRegistration findByRegistrationId(String registrationId) {
		return this.registrations.get(registrationId);
	}

	@Override
	public Iterator<ClientRegistration> iterator() {
		return this.registrations.values().iterator();
	}
}

Do you think both of these alternative implementations are straight forward?

@rwinch
Copy link
Member

rwinch commented Oct 10, 2018

Agreed that this can be confusing if the user were to implement this way. An alternative implementation the user can do is:

The issue is that this is not dynamic. The values in Hazelcast may be updated after this initialization is done. Also it may be too large to fit in memory.

I think it makes sense for the deprecation as migration is straight forward.

@jgrandja
Copy link
Contributor

The issue is that this is not dynamic. The values in Hazelcast may be updated after this initialization is done. Also it may be too large to fit in memory.

The sample provided was only to demonstrate how easy it is to create a ClientRegistrationRepository backed by a Map (local or distributed). I understand your points, but the code sample is not making the assumption that the values would be initialized from the remote store and into local storage. It may have been interpreted that way but that was not my intention. You can assume that it's a reference to the external Map.

Either way, I still feel deprecating InMemoryClientRegistrationRepository is not really necessary given that a Map implementation can easily be created by the user with minimal code.

If we were to deprecate, than what do we do with InMemoryOAuth2AuthorizedClientService and InMemoryUserDetailsManager? Wouldn't the same rules apply?

@rwinch
Copy link
Member

rwinch commented Oct 11, 2018

I think we would deprecate on an as needed (requested) basis from users.

@jgrandja
Copy link
Contributor

@vpavic I spoke to @rwinch and we decided to not deprecate at this time. If we were to go that route than we would need to deprecate InMemoryClientRegistrationRepository and InMemoryReactiveClientRegistrationRepository and that would also trigger changes in Boot auto-configuration at a later point in time. It may not be an ideal name when a distributed Map is backed but at the same time it may be a locally backed Map which would be fine.

We did agree that InMemory* naming convention will not be used on a go forward basis.

The PR looks good. I'll get this merged shortly.

@vpavic
Copy link
Contributor Author

vpavic commented Oct 17, 2018

Thanks for the follow up and sorry for my lack activity on this over the past week or so - I was just about to follow up myself.

We did agree that InMemory* naming convention will not be used on a go forward basis.

That's good to hear - hopefully at some later point in the 5.x lifecycle you would consider deprecation in favor of Map*.

@rwinch rwinch added this to the 5.2.0.M1 milestone Oct 17, 2018
@rwinch rwinch added type: enhancement A general enhancement in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) labels Oct 17, 2018
@jgrandja jgrandja closed this in e1b095d Oct 18, 2018
@jgrandja
Copy link
Contributor

Thanks for the PR @vpavic. This is now in master.

@vpavic vpavic deleted the improve-client-registration-repo branch October 18, 2018 18:41
@jgrandja jgrandja modified the milestones: 5.2.0.M1, 5.2.0.RC1 Jul 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants