Skip to content

Commit

Permalink
ISSUE 608 : Support one way SSL in schema registry client. (#609)
Browse files Browse the repository at this point in the history
*  ISSUE 608 : Support server auth only SSL in schema registry client.

*   Minor refactoring in Schema Registry Client

*   Make trust store mandatory in schema registry client
  • Loading branch information
raju-saravanan authored Oct 21, 2019
1 parent 2af3a91 commit 21f73ec
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ public class SchemaRegistryClient implements ISchemaRegistryClient {
private static Login login;
private static final long KERBEROS_SYNCHRONIZATION_TIMEOUT_MS = 180000;

private static final String SSL_KEY_PASSWORD = "keyPassword";
private static final String SSL_KEY_STORE_PATH = "keyStorePath";

static {
String jaasConfigFile = System.getProperty("java.security.auth.login.config");
if (jaasConfigFile != null && !jaasConfigFile.trim().isEmpty()) {
Expand Down Expand Up @@ -273,22 +276,28 @@ public SchemaVersionInfo retrieveSchemaVersion(SchemaIdVersion key) throws Schem

protected SSLContext createSSLContext(Map<String, String> sslConfigurations) {
SslConfigurator sslConfigurator = SslConfigurator.newInstance();
String keyPassword = "keyPassword";
sslConfigurator.keyStoreType(sslConfigurations.get("keyStoreType"))
.keyStoreFile(sslConfigurations.get("keyStorePath"))
.keyStorePassword(sslConfigurations.get("keyStorePassword"))
.trustStoreType(sslConfigurations.get("trustStoreType"))
if (sslConfigurations.containsKey(SSL_KEY_STORE_PATH)) {
sslConfigurator.keyStoreType(sslConfigurations.get("keyStoreType"))
.keyStoreFile(sslConfigurations.get(SSL_KEY_STORE_PATH))
.keyStorePassword(sslConfigurations.get("keyStorePassword"))
.keyStoreProvider(sslConfigurations.get("keyStoreProvider"))
.keyManagerFactoryAlgorithm(sslConfigurations.get("keyManagerFactoryAlgorithm"))
.keyManagerFactoryProvider(sslConfigurations.get("keyManagerFactoryProvider"));
if (sslConfigurations.containsKey(SSL_KEY_PASSWORD)) {
sslConfigurator.keyPassword(sslConfigurations.get(SSL_KEY_PASSWORD));
}
}


sslConfigurator.trustStoreType(sslConfigurations.get("trustStoreType"))
.trustStoreFile(sslConfigurations.get("trustStorePath"))
.trustStorePassword(sslConfigurations.get("trustStorePassword"))
.keyStoreProvider(sslConfigurations.get("keyStoreProvider"))
.trustStoreProvider(sslConfigurations.get("trustStoreProvider"))
.keyManagerFactoryAlgorithm(sslConfigurations.get("keyManagerFactoryAlgorithm"))
.keyManagerFactoryProvider(sslConfigurations.get("keyManagerFactoryProvider"))
.trustManagerFactoryAlgorithm(sslConfigurations.get("trustManagerFactoryAlgorithm"))
.trustManagerFactoryProvider(sslConfigurations.get("trustManagerFactoryProvider"))
.securityProtocol(sslConfigurations.get("protocol"));
if (sslConfigurations.containsKey(keyPassword))
sslConfigurator.keyPassword(sslConfigurations.get(keyPassword));
.trustManagerFactoryProvider(sslConfigurations.get("trustManagerFactoryProvider"));

sslConfigurator.securityProtocol(sslConfigurations.get("protocol"));

return sslConfigurator.createSSLContext();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ public class AvroSchemaRegistryClientTest {

@CustomParameterizedRunner.Parameters
public static Iterable<SchemaRegistryTestProfileType> profiles() {
return Arrays.asList(SchemaRegistryTestProfileType.DEFAULT, SchemaRegistryTestProfileType.SSL);
return Arrays.asList(SchemaRegistryTestProfileType.DEFAULT,
SchemaRegistryTestProfileType.SSL,
SchemaRegistryTestProfileType.ONE_WAY_SSL);
}

@CustomParameterizedRunner.BeforeParam
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class ConfluentProtocolCompatibleTest {

@Test
public void testConfluentProduceRegistryConsume() throws Exception {
String configPath = new File(Resources.getResource("schema-registry-test.yaml").toURI()).getAbsolutePath();
String configPath = new File(Resources.getResource("schema-registry.yaml").toURI()).getAbsolutePath();
LocalSchemaRegistryServer localSchemaRegistryServer = new LocalSchemaRegistryServer(configPath);
try {
localSchemaRegistryServer.start();
Expand Down Expand Up @@ -99,7 +99,7 @@ public void testConfluentProduceRegistryConsume() throws Exception {

@Test
public void testRegistryProduceConfluentConsume() throws Exception {
String configPath = new File(Resources.getResource("schema-registry-test.yaml").toURI()).getAbsolutePath();
String configPath = new File(Resources.getResource("schema-registry.yaml").toURI()).getAbsolutePath();
LocalSchemaRegistryServer localSchemaRegistryServer = new LocalSchemaRegistryServer(configPath);
try {
localSchemaRegistryServer.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class ConfluentRegistryCompatibleResourceTest {

@Before
public void setup() throws Exception {
String configPath = new File(Resources.getResource("schema-registry-test.yaml").toURI()).getAbsolutePath();
String configPath = new File(Resources.getResource("schema-registry.yaml").toURI()).getAbsolutePath();
localSchemaRegistryServer = new LocalSchemaRegistryServer(configPath);
localSchemaRegistryServer.start();
String rootUrl = String.format("http://localhost:%d/api/v1/confluent", localSchemaRegistryServer.getLocalPort());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,25 @@ public static SchemaRegistryTestConfiguration forProfileType(SchemaRegistryTestP
String clientYAMLFileName;
switch (testProfileType) {
case DEFAULT:
serverYAMLFileName = "schema-registry-test.yaml";
serverYAMLFileName = "schema-registry.yaml";
clientYAMLFileName = "schema-registry-client.yaml";
break;
case SSL:
serverYAMLFileName = "ssl-schema-registry-test.yaml";
serverYAMLFileName = "ssl-schema-registry.yaml";
clientYAMLFileName = "ssl-schema-registry-client.yaml";
break;
case DEFAULT_HA:
serverYAMLFileName = "schema-registry-test-ha.yaml";
serverYAMLFileName = "schema-registry-ha.yaml";
clientYAMLFileName = null;
break;
case SSL_HA:
serverYAMLFileName = "ssl-schema-registry-test-ha.yaml";
serverYAMLFileName = "ssl-schema-registry-ha.yaml";
clientYAMLFileName = "ssl-schema-registry-client.yaml";
break;
case ONE_WAY_SSL:
serverYAMLFileName = "one-way-ssl-schema-registry.yaml";
clientYAMLFileName = "one-way-ssl-schema-registry-client.yaml";
break;
default:
throw new IllegalArgumentException("Unrecognized SchemaRegistryTestProfileType : " + testProfileType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public enum SchemaRegistryTestProfileType {
DEFAULT,
SSL,
DEFAULT_HA,
SSL_HA;
SSL_HA,
ONE_WAY_SSL;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
schema.registry.url : "__registry_url"
schema.registry.client.local.jars.path : "/tmp/schema-registry/local-jars"
schema.registry.client.class.loader.cache.size : 1024
schema.registry.client.class.loader.cache.expiry.interval : 3600
schema.registry.client.schema.version.cache.size : 1024
schema.registry.client.schema.version.cache.expiry.interval : 300
schema.registry.client.schema.metadata.cache.expiry.interval : 300
schema.registry.client.schema.text.cache.size : 1024
schema.registry.client.schema.text.cache.expiry.interval : 300
schema.registry.client.url.selector : "com.hortonworks.registries.schemaregistry.client.FailoverUrlSelector"

schema.registry.client.ssl:
protocol: SSL
hostnameVerifierClass: com.hortonworks.registries.schemaregistry.avro.util.AcceptAllHostnameVerifier
# keyStoreType: JKS
# keyStorePath: ./src/test/resources/jks/client.jks
# keyStorePassword: clientpwd
# keyPassword:
# keyStoreProvider:
# keyManagerFactoryProvider:
# keyManagerFactoryAlgorithm:
trustStoreType: JKS
trustStorePath: ./src/test/resources/jks/client.jks
trustStorePassword: clientpwd
# trustStoreProvider:
# trustManagerFactoryProvider:
# trustManagerFactoryAlgorithm:
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# registries configuration
modules:
# - name: tag-registry
# className: com.hortonworks.iotas.registries.tag.service.TagRegistryModule
- name: schema-registry
className: com.hortonworks.registries.schemaregistry.webservice.SchemaRegistryModule
config:
schemaProviders:
- providerClass: "com.hortonworks.registries.schemaregistry.avro.AvroSchemaProvider"
defaultSerializerClass: "com.hortonworks.registries.schemaregistry.serdes.avro.AvroSnapshotSerializer"
defaultDeserializerClass: "com.hortonworks.registries.schemaregistry.serdes.avro.AvroSnapshotDeserializer"
# schema cache properties
# inmemory schema versions cache size
schemaCacheSize: 10000
# inmemory schema version cache entry expiry interval after access
schemaCacheExpiryInterval: 3600


servletFilters:
# - className: "com.hortonworks.registries.auth.server.AuthenticationFilter"
# params:
# type: "kerberos"
# kerberos.principal: "HTTP/streamline-ui-host.com"
# kerberos.keytab: "/vagrant/keytabs/http.keytab"
# kerberos.name.rules: "RULE:[2:$1@$0]([jt]t@.*EXAMPLE.COM)s/.*/$MAPRED_USER/ RULE:[2:$1@$0]([nd]n@.*EXAMPLE.COM)s/.*/$HDFS_USER/DEFAULT"
- className: "com.hortonworks.registries.schemaregistry.webservice.RewriteUriFilter"
params:
# value format is [<targetpath>,<paths-should-be-redirected-to>,*|]*
# below /subjects and /schemas/ids are forwarded to /api/v1/confluent
forwardPaths: "/api/v1/confluent,/subjects/*,/schemas/ids/*"
redirectPaths: "/ui/,/"

# HA configuration
#haConfig:
# className: com.hortonworks.registries.ha.zk.ZKLeadershipParticipant
# config:
# # This url is a list of ZK servers separated by ,
# connect.url: "localhost:2181"
# # root node prefix in ZK for this instance
# root: "/registry"
# session.timeout.ms: 30000
# connection.timeout.ms: 20000
# retry.limit: 5
# retry.base.sleep.time.ms: 1000
# retry.max.sleep.time.ms: 5000

fileStorageConfiguration:
className: "com.hortonworks.registries.common.util.LocalFileSystemStorage"
properties:
directory: "/tmp/storage"

# storage provider configuration
# providerClass can be inmemory and jdbc.
#
# Example configuration for inmemory is:
#storageProviderConfiguration:
# providerClass: "com.hortonworks.registries.storage.impl.memory.InMemoryStorageManager"
#
# Example configuration for phoenix based JDBC driver
#storageProviderConfiguration:
# providerClass: "com.hortonworks.registries.storage.impl.jdbc.JdbcStorageManager"
# properties:
# db.type: "phoenix"
# queryTimeoutInSecs: 30
# db.properties:
# jdbcDriverClass: "com.hortonworks.phoenix.jdbc.PhoenixDriver"
# jdbcUrl: "jdbc:phoenix:localhost:2181"
#
# MySQL based jdbc provider configuration is:
#storageProviderConfiguration:
# providerClass: "com.hortonworks.registries.storage.impl.jdbc.JdbcStorageManager"
# properties:
# db.type: "mysql"
# queryTimeoutInSecs: 30
# db.properties:
# dataSourceClassName: "com.mysql.cj.jdbc.MysqlDataSource"
# dataSource.url: "jdbc:mysql://localhost:3307/test"

storageProviderConfiguration:
providerClass: "com.hortonworks.registries.storage.impl.memory.InMemoryStorageManager"

#enable CORS, may want to disable in production
enableCors: true

## swagger configuration
swagger:
resourcePackage: com.hortonworks.registries.schemaregistry.webservice

# use the simple server factory if you only want to run on a single port
#server:
# type: simple
# connector:
# type: http
# port: 8080

server:
applicationConnectors:
- type: https
port: 0
keyStorePath: ./src/test/resources/jks/server.jks
keyStorePassword: serverpwd
trustStorePath: ./src/test/resources/jks/client.jks
trustStorePassword: clientpwd
needClientAuth: false
validateCerts: false
validatePeers: false
adminConnectors:
- type: https
port: 0
keyStorePath: ./src/test/resources/jks/server.jks
keyStorePassword: serverpwd
trustStorePath: ./src/test/resources/jks/client.jks
trustStorePassword: clientpwd
needClientAuth: false
validateCerts: false
validatePeers: false

# Logging settings.
logging:

# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
level: INFO

# Logger-specific levels.
loggers:

# Sets the level for 'com.example.app' to DEBUG.
com.hortonworks.registries: DEBUG


appenders:
- type: console
# - type: file
# threshold: DEBUG
# logFormat: "%-6level [%d{HH:mm:ss.SSS}] [%t] %logger{5} - %X{code} %msg %n"
# currentLogFilename: /tmp/application.log
# archivedLogFilenamePattern: /tmp/application-%d{yyyy-MM-dd}-%i.log.gz
# archivedFileCount: 7
# timeZone: UTC
# maxFileSize: 10MB

#jerseyClient:
# minThreads: 1
# maxThreads: 16
# workQueueSize: 1000
# gzipEnabled: true
# gzipEnabledForRequests: true
# chunkedEncodingEnabled: true
# timeout: 1000ms
# connectionTimeout: 1000ms
# timeToLive: 1h
# cookiesEnabled: false
# maxConnections: 10
# maxConnectionsPerRoute: 1024
# keepAlive: 0ms
# retries: 10
# userAgent: Storm-Client

0 comments on commit 21f73ec

Please sign in to comment.