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

ISSUE:195 Provide SSL support to SchemaRegistryClient #221

Merged
merged 1 commit into from
Aug 9, 2017

Conversation

raju-saravanan
Copy link
Collaborator

This PR contains the following changes :

@raju-saravanan raju-saravanan force-pushed the ssl branch 2 times, most recently from 8e38b58 to a6c156a Compare August 7, 2017 11:41
Copy link
Contributor

@satishd satishd left a comment

Choose a reason for hiding this comment

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

@raju-saravanan Overall LGTM, left few comments which you may want to address.

.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE)
.build();
.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);
if(conf.containsKey("schema.registry.client.ssl")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

schema.registry.client.ssl can be extracted as constant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

if(conf.containsKey("schema.registry.client.ssl")) {
Map<String,String> sslConfigurations = (Map<String, String>) conf.get("schema.registry.client.ssl");
clientBuilder.sslContext(createSSLContext(sslConfigurations));
if(sslConfigurations.containsKey("hostnameVerifierClass")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

hostnameVerifierClass can be extracted as constant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

String defaultPropertyValue = null;
SslConfigurator sslConfigurator = SslConfigurator.newInstance();
sslConfigurator.keyStoreType(sslConfigurations.getOrDefault("keyStoreType",defaultPropertyValue))
.keyStoreFile(sslConfigurations.getOrDefault("keyStorePath",defaultPropertyValue))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we have defaultValue as null for all these properties?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if any of these properties is set to null, then the SSLConfigurator would use a default value for the property.

Copy link
Contributor

@satishd satishd Aug 8, 2017

Choose a reason for hiding this comment

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

Invoking sslConfigurations.getOrDefault("keyStorePath",defaultPropertyValue) with defaultPropertyValue as null is equivalent to calling sslConfigurations.get("keyStorePath") as that returns null if the value for the given key does not exist as mentioned here.

-- updated with the right link

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, I will replace getOrDefault() with get() here.


protected final String rootUrl = String.format("http://localhost:%d/api/v1", DROPWIZARD_APP_RULE.getLocalPort());
protected final Map<String, String> SCHEMA_REGISTRY_CLIENT_CONF = Collections.singletonMap(SchemaRegistryClient.Configuration.SCHEMA_REGISTRY_URL.name(), rootUrl);
protected static LocalSchemaRegistryServer localSchemaRegistryServer;
Copy link
Contributor

Choose a reason for hiding this comment

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

This class should not really be abstract class now as it has static methods which are shared with derived classes. It is better to use composition than extending this class. You can remove static fields and use this class instance wherever this class is extended and respective methods can be used with that instance.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should we convert this class to a Util class, as all the functions in the class are stateless?

Copy link
Contributor

Choose a reason for hiding this comment

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

All static fields should be made instance fields and they maintain state for the given SchemaRegistryTestProfileType. So, it is better to have constructor which takes SchemaRegistryTestProfileType and you can also have respective close method which can have the same logic as current teardown method.

Other methods which are generating avro payloads for different avro schemas can be extracted into avro generator class for the given schemas.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

private final String v1APIPath = "api/v1";

public SchemaRegistryTestConfiguration(SchemaRegistryTestProfileType testProfileType) {
switch (testProfileType) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic should be out of constructor and it could be pulled into a factory method like below.

    private SchemaRegistryTestConfiguration(String serverYAMLPath, String clientYAMLPath) {
        this.serverYAMLPath = serverYAMLPath;
        this.clientYAMLPath = clientYAMLPath;
    }
    public static SchemaRegistryTestConfiguration forProfileType(SchemaRegistryTestProfileType testProfileType) {
        String serverYAMLPath;
        String clientYAMLPath;
        switch (testProfileType) {
            case DEFAULT:
                serverYAMLPath = "schema-registry-test.yaml";
                clientYAMLPath = "schema-registry-client.yaml";
                break;
            case SSL:
                serverYAMLPath = "ssl-schema-registry-test.yaml";
                clientYAMLPath = "ssl-schema-registry-client.yaml";
                break;
            case DEFAULT_HA:
                serverYAMLPath = "schema-registry-test-ha.yaml";
                clientYAMLPath = null;
                break;
            case SSL_HA:
                serverYAMLPath = "ssl-schema-registry-test-ha.yaml";
                clientYAMLPath = "ssl-schema-registry-client.yaml";
                break;
            default:
                throw new IllegalArgumentException("Unrecognized SchemaRegistryTestProfileType : " + testProfileType);
        }

        return new SchemaRegistryTestConfiguration(serverYAMLPath, clientYAMLPath);
    }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

public class SchemaRegistryTestConfiguration {
private String serverYAMLPath;
private String clientYAMLPath;
private final String v1APIPath = "api/v1";
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a constant and it can be moved to SchemaRegistryClientUtil where this is used.

@@ -0,0 +1,242 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure about licensing issues with EPL when we copy the code in ASL based sources like here. You may need to put their license(EPL) here and other classes where junit's code is copied.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Copy link
Collaborator

@michaelandrepearce michaelandrepearce Aug 8, 2017

Choose a reason for hiding this comment

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

@satishd on the note of licenses i note the code base has a lot of glassfish dependencies which is GPL afaik, as this project is ASL is it not maybe better to look at apache projects for equiv replacements which also will be ASL.

Copy link
Contributor

Choose a reason for hiding this comment

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

@michaelandrepearce We are not modifying any of the glassfish sources, but we are using those classes as libraries in classpath. AFAIK, it comes under "GPL Classpath Exception" and it is safe to use as library here.

Copy link
Contributor

@satishd satishd left a comment

Choose a reason for hiding this comment

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

@raju-saravanan left few minor nits which you may want to address.

public void setup() throws IOException {
schemaRegistryClient = new SchemaRegistryClient(SCHEMA_REGISTRY_CLIENT_CONF);
}
public class AvroSchemaRegistryClientUtil {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: it can be made final and have private constructor so that this can never be instantiated or extended.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@@ -171,6 +174,9 @@
private final SchemaMetadataCache schemaMetadataCache;
private final Cache<SchemaDigestEntry, SchemaIdVersion> schemaTextCache;

private final String SSL_CONFIGURATION_KEY = "schema.registry.client.ssl";
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: better to keep it as constant, add static.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@@ -171,6 +174,9 @@
private final SchemaMetadataCache schemaMetadataCache;
private final Cache<SchemaDigestEntry, SchemaIdVersion> schemaTextCache;

private final String SSL_CONFIGURATION_KEY = "schema.registry.client.ssl";
private final String HOSTNAME_VERIFIER_CLASS_KEY = "hostnameVerifierClass";
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: better to keep it as constant, add static.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done


private static final String INVALID_SCHEMA_PROVIDER_TYPE = "invalid-schema-provider-type";
private static SchemaRegistryClient schemaRegistryClient;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done


private static final String INVALID_SCHEMA_PROVIDER_TYPE = "invalid-schema-provider-type";
private static SchemaRegistryClient schemaRegistryClient;
private static SchemaRegistryTestServerClientWrapper schemaRegistryTestServerClientWrapper;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

public class KafkaAvroSerDesTest extends AbstractAvroSchemaRegistryCientTest {
public class KafkaAvroSerDesTest {

private static SchemaRegistryTestServerClientWrapper schemaRegistryTestServerClientWrapper;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

private static final Logger LOG = LoggerFactory.getLogger(KafkaAvroSerDesWithKafkaServerTest.class);
private static EmbeddedKafkaCluster CLUSTER;
private static SchemaRegistryTestServerClientWrapper schemaRegistryTestServerClientWrapper;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

public class LocalRegistryServerHATest {
private static SchemaRegistryTestConfiguration schemaRegistryTestConfiguration;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

public class LocalRegistryServerTest {

private static SchemaRegistryTestConfiguration schemaRegistryTestConfiguration;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have capitals like other static fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done


private LocalSchemaRegistryServer localSchemaRegistryServer;
private SchemaRegistryTestConfiguration schemaRegistryTestConfiguration;
private Map<String, Object> CLIENT_CONF;
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: you may want to have camelCase like other instance fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@satishd satishd left a comment

Choose a reason for hiding this comment

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

+1 Thanks @raju-saravanan for addressing the review comments.

@satishd
Copy link
Contributor

satishd commented Aug 9, 2017

Closes #195

@hortonjenkins hortonjenkins merged commit ec5933c into hortonworks:master Aug 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants