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 608 : Support one way SSL in schema registry client. #609

Merged
merged 3 commits into from
Oct 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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