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

Parse authParamsString on plugin side #721

Merged
merged 1 commit into from
Sep 14, 2017

Conversation

tkb77
Copy link
Contributor

@tkb77 tkb77 commented Aug 29, 2017

Motivation

#671

  • Parse authParamsString on plugin side

Modifications

I added EncodedAuthenticationParameterSupport interface to parse authParamsString on plugin side.

  1. If EncodedAuthenticationParameterSupport is implemented, parse authParamsString on plugin side.
  2. If EncodedAuthenticationParameterSupport is not implemented, use default parsing logic(separated by “:” and “,”) on AuthenticationFactory.

Result

  • We can parse authParamsString on plugins side by overriding configure(String authParamsString) in EncodedAuthenticationParameterSupport interface.

*/
default void configure(String authParams) {
Map<String, String> authParamsMap = new HashMap<>();
Logger LOG = LoggerFactory.getLogger(Authentication.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger should be declared as private static final at the class scope

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private static final can not be declared at the class scope because Authentication.java is an interface.
https://stackoverflow.com/questions/31452118/why-private-static-field-is-not-allowed-in-java-8-interface

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, though instead of having the parsing logic here in the interface, we could have it in a different place and then call it. eg:

default void configure(String authParamsStr) {
   Map<String, String> authParams = AuthenticationUtil.configureFromJsonString(authParamsStr);
   configure(authParams);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to have the two lines here? If we move parsing logic to somewhere else, we can deprecate the old interface and will have this only one universal configure interface eventually, which is more beautiful API I think.

Copy link
Contributor

@merlimat merlimat Aug 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the intention for using default method was to avoid breaking the Authentication API. I think we could as well break it right now, since I'm not aware of any 3rd party Authentication implementations at this point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so, but probably we can achieve the both, keeping compatibility and having one configure (and deprecated old one) if we introduce an interface I wrote on the issue.

authParamsMap = jsonMapper.readValue(authParams, new TypeReference<HashMap<String, String>>() {});
} catch (JsonParseException e) {
// If authParams is not JSON, separate by “:” and “,” for compatibility
LOG.warn("Authentication config parameter should be JSON: {}", e.getMessage());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to support both comma separated and Json, we shouldn't print a warning here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that comma separated should be deleted in the future.
What do you think that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case the deprecation should be at the interface level, not by having WARN message in log.

if (isNotBlank(authPluginClassName)) {
Class<?> authClass = Class.forName(authPluginClassName);
Authentication auth = (Authentication) authClass.newInstance();
auth.configure(authParamsString);
Copy link
Contributor

@rdhabalia rdhabalia Aug 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel configure(Map<String, String> authParams) is generic-enough and parsing/preparation of authParams-map can be done by AuthenticationFactory because in future, if we decide yaml format then we can adapt it without changing interface-definition.

a quick thought on implementation:
Rather adding void configure(String authParams) method in Authentication.java and doing parsing, instead can we do parsing here in AuthenticationFactory?

  1. First try to parse given auth-param into json and prepare Map<String,String> from json and call configure(map)
    Map<String, String> authParamsMap = jsonMapper.readValue(authParamsString, new TypeReference<HashMap<String, String>>() {});
  2. If fails then try to parse in existing way with : and ; delimiters, and prepare config-map

any thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think rdhabalia's suggestion is good enough since what we want to do here is to allow String containing ":" or "," (such as URL) as a parameter.

Introducing new interface sounds nice, however, I think we should do that when we really need plugin-specific parsing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the new interface may be YAGNI. However, I still don't understand why you guys want limitations.

  • Maybe Map<String, String> is enough, maybe not. Who knows?
  • colon-comma, JSON, YAML... What's next? Can we auto-detect all formats?
  • When we finally agreed on having new interface, is it still easy to migrate? How many plugins exists?

What will we lose instead of freedom if we introduce the new one now?

In my opinion, we should maximize API capability and do smart things on top of it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will we lose instead of freedom if we introduce the new one now?

Sure, I will be fine with new api as well. 👍

@tkb77 tkb77 force-pushed the parse_authParamsString_on_plugin_side branch from ed1ef85 to 8aa7e91 Compare September 4, 2017 09:27
@tkb77
Copy link
Contributor Author

tkb77 commented Sep 4, 2017

I added AuthParamsStringConfigurable interface to parse authParamsString on plugin side.

  1. If AuthParamsStringConfigurable is implemented, parse authParamsString on plugin side.
  2. If authParamsString is JSON, parse JSON on AuthenticationFactory.
  3. If authParamsString is not JSON, use current parsing logic(separated by “:” and “,”) on AuthenticationFactory.

@maskit
Copy link
Member

maskit commented Sep 4, 2017

@tkb77 Can you explain why we should parse JSON in AuthenticationFactory in spite of the fact that plugins can easily do that in the new configure? It would be just a line.

Map<String, String> authParams = AuthenticationUtil.configureFromJsonString(authParamsStr);

I don't see pros keeping the old configure interface and supporting new format in it. I think it should be left just for compatibility.

Also, format auto-detecting is not so easy.

"abc":"x,y,z"}

Note that { is missing. This string would be parsed as a colon-comma format string, which means that abc would not be set without any errors. This is unsafe.

@tkb77 tkb77 force-pushed the parse_authParamsString_on_plugin_side branch from 8aa7e91 to c633e60 Compare September 5, 2017 07:15
@tkb77
Copy link
Contributor Author

tkb77 commented Sep 5, 2017

@maskit
I can not explain the clear reason.
I try to parse authParamsString on plugin side without changing current parsing logic.
I will only add AuthParamsStringConfigurable interface and enable AuthenticationFactory to use it in this pull request.
I will implement original parsing logic on the plugin side at the next pull request.

@tkb77
Copy link
Contributor Author

tkb77 commented Sep 7, 2017

retest this please

@nkurihar
Copy link
Contributor

nkurihar commented Sep 7, 2017

LGTM

Copy link
Member

@maskit maskit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outline looks good.

  • AuthParamsStringConfigurable -- The name might be unclear.
  • Old configure -- Should be deprecated
  • New configure -- Future plan should be explained on Javadoc

I don't think they are blockers but would be better to change at this time.

@maskit
Copy link
Member

maskit commented Sep 7, 2017

If I understand you all correctly, our consensus here is:

  • Replace configure(Map<String, String> with configure(String)
  • Provide a separated interface to manage compatibility
  • Add support for JSON to Athens plugin (or provide an utility class and use it from plugins)

and I think we should:

  • Deprecate the old configure in 1.20 (or 1.21), and remove it in 2.0
  • Integrate the new configure into Authentication and deprecate the separated interface in 2.0

@tkb77 @merlimat @rdhabalia Makes sense?

@tkb77
Copy link
Contributor Author

tkb77 commented Sep 8, 2017

@ maskit
Thank you for your comments.

AuthParamsStringConfigurable -- The name might be unclear.

What did you feel unclear about the name?
Please tell me if there is an idea or suggestion.

Old configure -- Should be deprecated

Does the old interface need to be deprecated?
When deleting the old interface, it is inconvenient because we have to give all settings as a string.

New configure -- Future plan should be explained on Javadoc

I will add javadoc for the new interface.

@maskit
Copy link
Member

maskit commented Sep 8, 2017

@tkb77

What did you feel unclear about the name?
Please tell me if there is an idea or suggestion.

I can understand the name because we have been talking about it but I'm not confident with that plugin developers easily understand what it is for. The name you suggested doesn't add any context (the same thing is already written as the method name and the parameter name). As I wrote on the issue, I'd suggest EncodedAuthenticationParameterSupport. I'm also fine with Pulsar2AuthenticationInterface if we agreed on marking the old one deprecated.

Does the old interface need to be deprecated?
When deleting the old interface, it is inconvenient because we have to give all settings as a string.

Yes, I think it need to be deprecated because it makes API simple and solid, and it indicates that we are not going to add support for other formats on configure. As I wrote above, plugin developers can parse the string with just one line if we provide an utility class.

Honestly, I'd not write configuration values directly in authParams if I wrote a plugin which requires many and/or complex configurations. I'd write just an external filename or an URL instead. Even if the format was JSON, one line JSON is hard to read / write.

@tkb77 tkb77 force-pushed the parse_authParamsString_on_plugin_side branch from c633e60 to 48831a8 Compare September 11, 2017 08:14
@tkb77
Copy link
Contributor Author

tkb77 commented Sep 11, 2017

@maskit
Thank you for advising me.
I fixed as follows.

  • Add Javadoc
  • Set deprecated to the old configure
  • Rename the new interface EncodedAuthenticationParameterSupport

@merlimat
Copy link
Contributor

LGTM. @maskit can you do a final check on this?

@merlimat merlimat added area/client type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages labels Sep 14, 2017
@merlimat merlimat added this to the 1.20.0-incubating milestone Sep 14, 2017
Copy link
Member

@maskit maskit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@merlimat merlimat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/client type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants