This is an automated email from the ASF dual-hosted git repository. pradeep pushed a commit to branch RANGER-5029_master in repository https://gitbox.apache.org/repos/asf/ranger.git
commit ff4bbd7b9099efb8b5eb928c155e67e01c4e3d42 Author: Pradeep AgrawaL <[email protected]> AuthorDate: Sun Dec 29 18:22:28 2024 +0530 RANGER-5029: embeddedwebserver module: update for code readability improvement --- embeddedwebserver/pom.xml | 5 + .../tomcat/ElasticSearchIndexBootStrapper.java | 461 ++++----- .../ranger/server/tomcat/EmbeddedServer.java | 1058 ++++++++++---------- .../tomcat/EmbeddedServerMetricsCollector.java | 49 +- .../ranger/server/tomcat/EmbeddedServerUtil.java | 207 ++-- .../server/tomcat/SolrCollectionBootstrapper.java | 761 +++++++------- .../ranger/server/tomcat/StopEmbeddedServer.java | 20 +- 7 files changed, 1197 insertions(+), 1364 deletions(-) diff --git a/embeddedwebserver/pom.xml b/embeddedwebserver/pom.xml index 5c1fa833c..b3f20b123 100644 --- a/embeddedwebserver/pom.xml +++ b/embeddedwebserver/pom.xml @@ -27,6 +27,11 @@ <packaging>jar</packaging> <name>Embedded Web Server Invoker</name> <description>Embedded Web Server Invoker</description> + <properties> + <checkstyle.failOnViolation>true</checkstyle.failOnViolation> + <checkstyle.skip>false</checkstyle.skip> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> <dependencies> <dependency> <groupId>ch.qos.logback</groupId> diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/ElasticSearchIndexBootStrapper.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/ElasticSearchIndexBootStrapper.java index 15a16e41f..9aefb015d 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/ElasticSearchIndexBootStrapper.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/ElasticSearchIndexBootStrapper.java @@ -16,21 +16,8 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.ranger.server.tomcat; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.KeyStore; -import java.util.Locale; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Logger; - import org.apache.commons.lang.StringUtils; import org.apache.http.HttpHost; import org.apache.http.auth.AuthSchemeProvider; @@ -53,248 +40,234 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.util.Locale; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Logger; public class ElasticSearchIndexBootStrapper extends Thread { + private static final Logger LOG = Logger.getLogger(ElasticSearchIndexBootStrapper.class.getName()); + private static final String ES_CONFIG_USERNAME = "ranger.audit.elasticsearch.user"; + private static final String ES_CONFIG_PASSWORD = "ranger.audit.elasticsearch.password"; + private static final String ES_CONFIG_URLS = "ranger.audit.elasticsearch.urls"; + private static final String ES_CONFIG_PORT = "ranger.audit.elasticsearch.port"; + private static final String ES_CONFIG_PROTOCOL = "ranger.audit.elasticsearch.protocol"; + private static final String ES_CONFIG_INDEX = "ranger.audit.elasticsearch.index"; + private static final String ES_TIME_INTERVAL = "ranger.audit.elasticsearch.time.interval"; + private static final String ES_NO_SHARDS = "ranger.audit.elasticsearch.no.shards"; + private static final String ES_NO_REPLICA = "ranger.audit.elasticsearch.no.replica"; + private static final String ES_CREDENTIAL_PROVIDER_PATH = "ranger.credential.provider.path"; + private static final String ES_CREDENTIAL_ALIAS = "ranger.audit.elasticsearch.credential.alias"; + private static final String ES_BOOTSTRAP_MAX_RETRY = "ranger.audit.elasticsearch.max.retry"; + private static final String DEFAULT_INDEX_NAME = "ranger_audits"; + private static final String ES_RANGER_AUDIT_SCHEMA_FILE = "ranger_es_schema.json"; + private static final long DEFAULT_ES_TIME_INTERVAL_MS = 60000L; + private static final int TRY_UNTIL_SUCCESS = -1; + private static final int DEFAULT_ES_BOOTSTRAP_MAX_RETRY = 30; + private final AtomicLong lastLoggedAt = new AtomicLong(0); + private volatile RestHighLevelClient client; + private Long timeInterval; - private static final Logger LOG = Logger.getLogger(ElasticSearchIndexBootStrapper.class.getName()); - - private static final String ES_CONFIG_USERNAME = "ranger.audit.elasticsearch.user"; - private static final String ES_CONFIG_PASSWORD = "ranger.audit.elasticsearch.password"; - private static final String ES_CONFIG_URLS = "ranger.audit.elasticsearch.urls"; - private static final String ES_CONFIG_PORT = "ranger.audit.elasticsearch.port"; - private static final String ES_CONFIG_PROTOCOL = "ranger.audit.elasticsearch.protocol"; - private static final String ES_CONFIG_INDEX = "ranger.audit.elasticsearch.index"; - private static final String ES_TIME_INTERVAL = "ranger.audit.elasticsearch.time.interval"; - private static final String ES_NO_SHARDS = "ranger.audit.elasticsearch.no.shards"; - private static final String ES_NO_REPLICA = "ranger.audit.elasticsearch.no.replica"; - private static final String ES_CREDENTIAL_PROVIDER_PATH = "ranger.credential.provider.path"; - private static final String ES_CREDENTIAL_ALIAS = "ranger.audit.elasticsearch.credential.alias"; - private static final String ES_BOOTSTRAP_MAX_RETRY = "ranger.audit.elasticsearch.max.retry"; - - private static final String DEFAULT_INDEX_NAME = "ranger_audits"; - private static final String ES_RANGER_AUDIT_SCHEMA_FILE = "ranger_es_schema.json"; - - private static final long DEFAULT_ES_TIME_INTERVAL_MS = 60000L; - private static final int TRY_UNTIL_SUCCESS = -1; - private static final int DEFAULT_ES_BOOTSTRAP_MAX_RETRY = 30; - - private final AtomicLong lastLoggedAt = new AtomicLong(0); - private volatile RestHighLevelClient client = null; - private Long time_interval; - - private String user; - private String password; - private String hosts; - private String protocol; - private String index; - private String es_ranger_audit_schema_json; - - private int port; - private int max_retry; - private int retry_counter = 0; - private int no_of_replicas; - private int no_of_shards; - private boolean is_completed = false; - - public ElasticSearchIndexBootStrapper() throws IOException { - LOG.info("Starting Ranger audit schema setup in ElasticSearch."); - time_interval = EmbeddedServerUtil.getLongConfig(ES_TIME_INTERVAL, DEFAULT_ES_TIME_INTERVAL_MS); - user = EmbeddedServerUtil.getConfig(ES_CONFIG_USERNAME); - hosts = EmbeddedServerUtil.getHosts(EmbeddedServerUtil.getConfig(ES_CONFIG_URLS)); - port = EmbeddedServerUtil.getIntConfig(ES_CONFIG_PORT, 9200); - protocol = EmbeddedServerUtil.getConfig(ES_CONFIG_PROTOCOL, "http"); - index = EmbeddedServerUtil.getConfig(ES_CONFIG_INDEX, DEFAULT_INDEX_NAME); - password = EmbeddedServerUtil.getConfig(ES_CONFIG_PASSWORD); + private String user; + private String password; + private String hosts; + private String protocol; + private String index; + private String esRangerAuditSchemaJson; - no_of_replicas = EmbeddedServerUtil.getIntConfig(ES_NO_REPLICA, 1); - no_of_shards = EmbeddedServerUtil.getIntConfig(ES_NO_SHARDS, 1); - max_retry = EmbeddedServerUtil.getIntConfig(ES_BOOTSTRAP_MAX_RETRY, DEFAULT_ES_BOOTSTRAP_MAX_RETRY); - String jarLocation = null; - try { - jarLocation = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); - } catch (Exception ex) { - LOG.severe("Error finding base location:" + ex.toString()); - } - String rangerHomeDir = new File(jarLocation).getParentFile().getParentFile().getParentFile().getPath(); - Path es_schema_path = Paths.get(rangerHomeDir, "contrib", "elasticsearch_for_audit_setup", "conf", - ES_RANGER_AUDIT_SCHEMA_FILE); - es_ranger_audit_schema_json = new String(Files.readAllBytes(es_schema_path), StandardCharsets.UTF_8); + private int port; + private int maxRetry; + private int retryCounter; + private int noOfReplicas; + private int noOfShards; + private boolean isCompleted; - String providerPath = EmbeddedServerUtil.getConfig(ES_CREDENTIAL_PROVIDER_PATH); - String credentialAlias = EmbeddedServerUtil.getConfig(ES_CREDENTIAL_ALIAS, ES_CONFIG_PASSWORD); - String keyStoreFileType = EmbeddedServerUtil.getConfig("ranger.keystore.file.type", KeyStore.getDefaultType()); - if (providerPath != null && credentialAlias != null) { - password = CredentialReader.getDecryptedString(providerPath.trim(), credentialAlias.trim(), keyStoreFileType); - if (StringUtils.isBlank(password) || "none".equalsIgnoreCase(password.trim())) { - password = EmbeddedServerUtil.getConfig(ES_CONFIG_PASSWORD); - } - } - } + public ElasticSearchIndexBootStrapper() throws IOException { + LOG.info("Starting Ranger audit schema setup in ElasticSearch."); + timeInterval = EmbeddedServerUtil.getLongConfig(ES_TIME_INTERVAL, DEFAULT_ES_TIME_INTERVAL_MS); + user = EmbeddedServerUtil.getConfig(ES_CONFIG_USERNAME); + hosts = EmbeddedServerUtil.getHosts(EmbeddedServerUtil.getConfig(ES_CONFIG_URLS)); + port = EmbeddedServerUtil.getIntConfig(ES_CONFIG_PORT, 9200); + protocol = EmbeddedServerUtil.getConfig(ES_CONFIG_PROTOCOL, "http"); + index = EmbeddedServerUtil.getConfig(ES_CONFIG_INDEX, DEFAULT_INDEX_NAME); + password = EmbeddedServerUtil.getConfig(ES_CONFIG_PASSWORD); - private String connectionString() { - return String.format(Locale.ROOT,"User:%s, %s://%s:%s/%s", user, protocol, hosts, port, index); - } + noOfReplicas = EmbeddedServerUtil.getIntConfig(ES_NO_REPLICA, 1); + noOfShards = EmbeddedServerUtil.getIntConfig(ES_NO_SHARDS, 1); + maxRetry = EmbeddedServerUtil.getIntConfig(ES_BOOTSTRAP_MAX_RETRY, DEFAULT_ES_BOOTSTRAP_MAX_RETRY); + String jarLocation = null; + try { + jarLocation = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); + } catch (Exception ex) { + LOG.severe("Error finding base location:" + ex); + } + String rangerHomeDir = new File(jarLocation).getParentFile().getParentFile().getParentFile().getPath(); + Path esSchemaPath = Paths.get(rangerHomeDir, "contrib", "elasticsearch_for_audit_setup", "conf", ES_RANGER_AUDIT_SCHEMA_FILE); + esRangerAuditSchemaJson = new String(Files.readAllBytes(esSchemaPath), StandardCharsets.UTF_8); - public void run() { - LOG.info("Started run method"); - if (StringUtils.isNotBlank(hosts)) { - LOG.info("Elastic search hosts=" + hosts + ", index=" + index); - while (!is_completed && (max_retry == TRY_UNTIL_SUCCESS || retry_counter < max_retry)) { - try { - LOG.info("Trying to acquire elastic search connection"); - if (connect()) { - LOG.info("Connection to elastic search established successfully"); - if (createIndex()) { - is_completed = true; - break; - } else { - logErrorMessageAndWait("Error while performing operations on elasticsearch. ", null); - } - } else { - logErrorMessageAndWait( - "Cannot connect to elasticsearch kindly check the elasticsearch related configs. ", - null); - } - } catch (Exception ex) { - logErrorMessageAndWait("Error while validating elasticsearch index ", ex); - } - } - } else { - LOG.severe("elasticsearch hosts values are empty. Please set property " + ES_CONFIG_URLS); - } + String providerPath = EmbeddedServerUtil.getConfig(ES_CREDENTIAL_PROVIDER_PATH); + String credentialAlias = EmbeddedServerUtil.getConfig(ES_CREDENTIAL_ALIAS, ES_CONFIG_PASSWORD); + String keyStoreFileType = EmbeddedServerUtil.getConfig("ranger.keystore.file.type", KeyStore.getDefaultType()); + if (providerPath != null && credentialAlias != null) { + password = CredentialReader.getDecryptedString(providerPath.trim(), credentialAlias.trim(), keyStoreFileType); + if (StringUtils.isBlank(password) || "none".equalsIgnoreCase(password.trim())) { + password = EmbeddedServerUtil.getConfig(ES_CONFIG_PASSWORD); + } + } + } - } + public static RestClientBuilder getRestClientBuilder(String urls, String protocol, String user, String password, int port) { + RestClientBuilder restClientBuilder = RestClient.builder(EmbeddedServerUtil.toArray(urls, ",").stream().map(x -> new HttpHost(x, port, protocol)).<HttpHost>toArray(i -> new HttpHost[i])); + if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(password) && !user.equalsIgnoreCase("NONE") && !password.equalsIgnoreCase("NONE")) { + if (password.contains("keytab") && new File(password).exists()) { + final KerberosCredentialsProvider credentialsProvider = CredentialsProviderUtil.getKerberosCredentials(user, password); + Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory()).build(); + restClientBuilder.setHttpClientConfigCallback(clientBuilder -> { + clientBuilder.setDefaultCredentialsProvider(credentialsProvider); + clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry); + return clientBuilder; + }); + } else { + final CredentialsProvider credentialsProvider = CredentialsProviderUtil.getBasicCredentials(user, password); + restClientBuilder.setHttpClientConfigCallback(clientBuilder -> clientBuilder.setDefaultCredentialsProvider(credentialsProvider)); + } + } else { + LOG.severe("ElasticSearch Credentials not provided!!"); + final CredentialsProvider credentialsProvider = null; + restClientBuilder.setHttpClientConfigCallback(clientBuilder -> clientBuilder.setDefaultCredentialsProvider(credentialsProvider)); + } + return restClientBuilder; + } - private synchronized boolean connect() { - if (client == null) { - synchronized (ElasticSearchIndexBootStrapper.class) { - if (client == null) { - try { - createClient(); - } catch (Exception ex) { - LOG.severe("Can't connect to elasticsearch server. host=" + hosts + ", index=" + index + ex); - } - } - } - } - return client != null ? true : false; - } + public void run() { + LOG.info("Started run method"); + if (StringUtils.isNotBlank(hosts)) { + LOG.info("Elastic search hosts=" + hosts + ", index=" + index); + while (!isCompleted && (maxRetry == TRY_UNTIL_SUCCESS || retryCounter < maxRetry)) { + try { + LOG.info("Trying to acquire elastic search connection"); + if (connect()) { + LOG.info("Connection to elastic search established successfully"); + if (createIndex()) { + isCompleted = true; + break; + } else { + logErrorMessageAndWait("Error while performing operations on elasticsearch. ", null); + } + } else { + logErrorMessageAndWait("Cannot connect to elasticsearch kindly check the elasticsearch related configs. ", null); + } + } catch (Exception ex) { + logErrorMessageAndWait("Error while validating elasticsearch index ", ex); + } + } + } else { + LOG.severe("elasticsearch hosts values are empty. Please set property " + ES_CONFIG_URLS); + } + } - private void createClient() { - try { - RestClientBuilder restClientBuilder = - getRestClientBuilder(hosts, protocol, user, password, port); - client = new RestHighLevelClient(restClientBuilder); - } catch (Throwable t) { - lastLoggedAt.updateAndGet(lastLoggedAt -> { - long now = System.currentTimeMillis(); - long elapsed = now - lastLoggedAt; - if (elapsed > TimeUnit.MINUTES.toMillis(1)) { - LOG.severe("Can't connect to ElasticSearch server: " + connectionString() + t); - return now; - } else { - return lastLoggedAt; - } - }); - } - } + private String connectionString() { + return String.format(Locale.ROOT, "User:%s, %s://%s:%s/%s", user, protocol, hosts, port, index); + } - public static RestClientBuilder getRestClientBuilder(String urls, String protocol, String user, String password, int port) { - RestClientBuilder restClientBuilder = RestClient.builder( - EmbeddedServerUtil.toArray(urls, ",").stream() - .map(x -> new HttpHost(x, port, protocol)) - .<HttpHost>toArray(i -> new HttpHost[i]) - ); - if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(password) && !user.equalsIgnoreCase("NONE") && !password.equalsIgnoreCase("NONE")) { - if (password.contains("keytab") && new File(password).exists()) { - final KerberosCredentialsProvider credentialsProvider = - CredentialsProviderUtil.getKerberosCredentials(user, password); - Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create() - .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory()).build(); - restClientBuilder.setHttpClientConfigCallback(clientBuilder -> { - clientBuilder.setDefaultCredentialsProvider(credentialsProvider); - clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry); - return clientBuilder; - }); - } else { - final CredentialsProvider credentialsProvider = - CredentialsProviderUtil.getBasicCredentials(user, password); - restClientBuilder.setHttpClientConfigCallback(clientBuilder -> - clientBuilder.setDefaultCredentialsProvider(credentialsProvider)); - } - } else { - LOG.severe("ElasticSearch Credentials not provided!!"); - final CredentialsProvider credentialsProvider = null; - restClientBuilder.setHttpClientConfigCallback(clientBuilder -> - clientBuilder.setDefaultCredentialsProvider(credentialsProvider)); - } - return restClientBuilder; - } + private synchronized boolean connect() { + if (client == null) { + synchronized (ElasticSearchIndexBootStrapper.class) { + if (client == null) { + try { + createClient(); + } catch (Exception ex) { + LOG.severe("Can't connect to elasticsearch server. host=" + hosts + ", index=" + index + ex); + } + } + } + } + return client != null; + } - private boolean createIndex() { - boolean exits = false; - if (client == null) { - connect(); - } - if (client != null) { - try { - exits = client.indices().open(new OpenIndexRequest(this.index), RequestOptions.DEFAULT) - .isShardsAcknowledged(); - } catch (Exception e) { - LOG.info("Index " + this.index + " not available."); - } - if (!exits) { - LOG.info("Index does not exist. Attempting to create index:" + this.index); - CreateIndexRequest request = new CreateIndexRequest(this.index); - if (this.no_of_shards >= 0 && this.no_of_replicas >= 0) { - request.settings(Settings.builder().put("index.number_of_shards", this.no_of_shards) - .put("index.number_of_replicas", this.no_of_replicas)); - } - request.mapping(es_ranger_audit_schema_json, XContentType.JSON); - request.setMasterTimeout(TimeValue.timeValueMinutes(1)); - request.setTimeout(TimeValue.timeValueMinutes(2)); - try { - CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT); - if (createIndexResponse != null) { - exits = client.indices().open(new OpenIndexRequest(this.index), RequestOptions.DEFAULT) - .isShardsAcknowledged(); - if (exits) { - LOG.info("Index " + this.index + " created successfully."); - } - } - } catch (Exception e) { - LOG.severe("Unable to create Index. Reason:" + e.toString()); - e.printStackTrace(); - } - } else { - LOG.info("Index " + this.index + " is already created."); - } - } - return exits; - } + private void createClient() { + try { + RestClientBuilder restClientBuilder = getRestClientBuilder(hosts, protocol, user, password, port); + client = new RestHighLevelClient(restClientBuilder); + } catch (Throwable t) { + lastLoggedAt.updateAndGet(lastLoggedAt -> { + long now = System.currentTimeMillis(); + long elapsed = now - lastLoggedAt; + if (elapsed > TimeUnit.MINUTES.toMillis(1)) { + LOG.severe("Can't connect to ElasticSearch server: " + connectionString() + t); + return now; + } else { + return lastLoggedAt; + } + }); + } + } - private void logErrorMessageAndWait(String msg, Exception exception) { - retry_counter++; - String attemptMessage; - if (max_retry != TRY_UNTIL_SUCCESS) { - attemptMessage = (retry_counter == max_retry) ? ("Maximum attempts reached for setting up elasticsearch.") - : ("[retrying after " + time_interval + " ms]. No. of attempts left : " - + (max_retry - retry_counter) + " . Maximum attempts : " + max_retry); - } else { - attemptMessage = "[retrying after " + time_interval + " ms]"; - } - StringBuilder errorBuilder = new StringBuilder(); - errorBuilder.append(msg); - if (exception != null) { - errorBuilder.append("Error : ".concat(exception.getMessage() + ". ")); - } - errorBuilder.append(attemptMessage); - LOG.severe(errorBuilder.toString()); - try { - Thread.sleep(time_interval); - } catch (InterruptedException ex) { - LOG.info("sleep interrupted: " + ex.getMessage()); - } - } + private boolean createIndex() { + boolean exits = false; + if (client == null) { + connect(); + } + if (client != null) { + try { + exits = client.indices().open(new OpenIndexRequest(this.index), RequestOptions.DEFAULT).isShardsAcknowledged(); + } catch (Exception e) { + LOG.info("Index " + this.index + " not available."); + } + if (!exits) { + LOG.info("Index does not exist. Attempting to create index:" + this.index); + CreateIndexRequest request = new CreateIndexRequest(this.index); + if (this.noOfShards >= 0 && this.noOfShards >= 0) { + request.settings(Settings.builder().put("index.number_of_shards", this.noOfShards).put("index.number_of_replicas", this.noOfShards)); + } + request.mapping(esRangerAuditSchemaJson, XContentType.JSON); + request.setMasterTimeout(TimeValue.timeValueMinutes(1)); + request.setTimeout(TimeValue.timeValueMinutes(2)); + try { + CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT); + if (createIndexResponse != null) { + exits = client.indices().open(new OpenIndexRequest(this.index), RequestOptions.DEFAULT).isShardsAcknowledged(); + if (exits) { + LOG.info("Index " + this.index + " created successfully."); + } + } + } catch (Exception e) { + LOG.severe("Unable to create Index. Reason:" + e); + e.printStackTrace(); + } + } else { + LOG.info("Index " + this.index + " is already created."); + } + } + return exits; + } -} \ No newline at end of file + private void logErrorMessageAndWait(String msg, Exception exception) { + retryCounter++; + String attemptMessage; + if (maxRetry != TRY_UNTIL_SUCCESS) { + attemptMessage = (retryCounter == maxRetry) ? ("Maximum attempts reached for setting up elasticsearch.") : ("[retrying after " + timeInterval + " ms]. No. of attempts left : " + (maxRetry - retryCounter) + " . Maximum attempts : " + maxRetry); + } else { + attemptMessage = "[retrying after " + timeInterval + " ms]"; + } + StringBuilder errorBuilder = new StringBuilder(); + errorBuilder.append(msg); + if (exception != null) { + errorBuilder.append("Error : ".concat(exception.getMessage() + ". ")); + } + errorBuilder.append(attemptMessage); + LOG.severe(errorBuilder.toString()); + try { + Thread.sleep(timeInterval); + } catch (InterruptedException ex) { + LOG.info("sleep interrupted: " + ex.getMessage()); + } + } +} diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java index f1e2bafe2..4ede6fadc 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java @@ -19,6 +19,23 @@ package org.apache.ranger.server.tomcat; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.valves.AccessLogValve; +import org.apache.catalina.valves.ErrorReportValve; +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.security.SecureClientLogin; +import org.apache.ranger.credentialapi.CredentialReader; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.security.auth.Subject; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -37,555 +54,496 @@ import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardContext; -import org.apache.catalina.startup.Tomcat; -import org.apache.catalina.valves.AccessLogValve; -import org.apache.catalina.valves.ErrorReportValve; -import org.apache.commons.lang.StringUtils; -import org.apache.hadoop.security.SecureClientLogin; - -import org.apache.ranger.credentialapi.CredentialReader; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.security.auth.Subject; - public class EmbeddedServer { - - private static final Logger LOG = Logger.getLogger(EmbeddedServer.class - .getName()); - private static final String DEFAULT_NAME_RULE = "DEFAULT"; - private static final String DEFAULT_WEBAPPS_ROOT_FOLDER = "webapps"; - private static String configFile = "ranger-admin-site.xml"; - private static final String AUTH_TYPE_KERBEROS = "kerberos"; - private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication"; - private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal"; - private static final String AUDIT_SOURCE_TYPE = "ranger.audit.source.type"; - private static final String AUDIT_SOURCE_SOLR = "solr"; - private static final String AUDIT_SOURCE_ES = "elasticsearch"; - private static final String SOLR_BOOTSTRAP_ENABLED = "ranger.audit.solr.bootstrap.enabled"; - private static final String ES_BOOTSTRAP_ENABLED = "ranger.audit.elasticsearch.bootstrap.enabled"; - private static final String ADMIN_USER_KEYTAB = "ranger.admin.kerberos.keytab"; - - private static final String ADMIN_NAME_RULES = "hadoop.security.auth_to_local"; - private static final String ADMIN_SERVER_NAME = "rangeradmin"; - private static final String KMS_SERVER_NAME = "rangerkms"; - private static final String ACCESS_LOG_ENABLED = "ranger.accesslog.enabled"; - private static final String ACCESS_LOG_PREFIX = "ranger.accesslog.prefix"; - private static final String ACCESS_LOG_DATE_FORMAT = "ranger.accesslog.dateformat"; - private static final String ACCESS_LOG_PATTERN = "ranger.accesslog.pattern"; - private static final String ACCESS_LOG_ROTATE_ENABLED = "ranger.accesslog.rotate.enabled"; - private static final String ACCESS_LOG_ROTATE_MAX_DAYS = "ranger.accesslog.rotate.max_days"; - private static final String ACCESS_LOG_ROTATE_RENAME_ON_ROTATE = "ranger.accesslog.rotate.rename_on_rotate"; - public static final String RANGER_KEYSTORE_FILE_TYPE_DEFAULT = KeyStore.getDefaultType(); - public static final String RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT = KeyStore.getDefaultType(); - public static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "TLSv1.2"; - public static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = KeyManagerFactory.getDefaultAlgorithm(); - public static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = TrustManagerFactory.getDefaultAlgorithm(); - - - private static EmbeddedServerMetricsCollector serverMetricsCollector; - - public static void main(String[] args) { - new EmbeddedServer(args).start(); - } - - public EmbeddedServer(String[] args) { - if (args.length > 0) { - configFile = args[0]; - } - - EmbeddedServerUtil.loadRangerConfigProperties(configFile); - } - - public static int DEFAULT_SHUTDOWN_PORT = 6185; - public static String DEFAULT_SHUTDOWN_COMMAND = "SHUTDOWN"; - - public void start() { - SSLContext sslContext = getSSLContext(); - if (sslContext != null) { - SSLContext.setDefault(sslContext); - } - final Tomcat server = new Tomcat(); - - String logDir = null; - logDir = EmbeddedServerUtil.getConfig("logdir"); - if (logDir == null) { - logDir = EmbeddedServerUtil.getConfig("kms.log.dir"); - } - String servername = EmbeddedServerUtil.getConfig("servername"); - String hostName = EmbeddedServerUtil.getConfig("ranger.service.host"); - int serverPort = EmbeddedServerUtil.getIntConfig("ranger.service.http.port", 6181); - int sslPort = EmbeddedServerUtil.getIntConfig("ranger.service.https.port", -1); - int shutdownPort = EmbeddedServerUtil.getIntConfig("ranger.service.shutdown.port", DEFAULT_SHUTDOWN_PORT); - String shutdownCommand = EmbeddedServerUtil.getConfig("ranger.service.shutdown.command", DEFAULT_SHUTDOWN_COMMAND); - - server.setHostname(hostName); - server.setPort(serverPort); - server.getServer().setPort(shutdownPort); - server.getServer().setShutdown(shutdownCommand); - - boolean isHttpsEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.enabled", "false")); - boolean ajpEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig("ajp.enabled", "false")); - - if (ajpEnabled) { - - Connector ajpConnector = new Connector( - "org.apache.coyote.ajp.AjpNioProtocol"); - ajpConnector.setPort(serverPort); - ajpConnector.setProperty("protocol", "AJP/1.3"); - - server.getService().addConnector(ajpConnector); - - // Making this as a default connector - server.setConnector(ajpConnector); - LOG.info("Created AJP Connector"); - } else if ((sslPort > 0) && isHttpsEnabled) { - Connector ssl = new Connector(); - ssl.setPort(sslPort); - ssl.setSecure(true); - ssl.setScheme("https"); - ssl.setAttribute("SSLEnabled", "true"); - ssl.setAttribute("sslProtocol", EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.protocol", "TLSv1.2")); - ssl.setAttribute("keystoreType", EmbeddedServerUtil.getConfig("ranger.keystore.file.type", RANGER_KEYSTORE_FILE_TYPE_DEFAULT)); - ssl.setAttribute("truststoreType", EmbeddedServerUtil.getConfig("ranger.truststore.file.type", RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT)); - String clientAuth = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.clientAuth", "false"); - if("false".equalsIgnoreCase(clientAuth)){ - clientAuth = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.client.auth", "want"); - } - ssl.setAttribute("clientAuth",clientAuth); - String providerPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); - String keyAlias = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.credential.alias", "keyStoreCredentialAlias"); - String keystorePass=null; - if(providerPath!=null && keyAlias!=null){ - keystorePass = CredentialReader.getDecryptedString(providerPath.trim(), keyAlias.trim(), EmbeddedServerUtil.getConfig("ranger.keystore.file.type", RANGER_KEYSTORE_FILE_TYPE_DEFAULT)); - if (StringUtils.isBlank(keystorePass) || "none".equalsIgnoreCase(keystorePass.trim())) { - keystorePass = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.pass"); - } - } - ssl.setAttribute("keyAlias", EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.keyalias", "rangeradmin")); - ssl.setAttribute("keystorePass", keystorePass); - ssl.setAttribute("keystoreFile", getKeystoreFile()); - - String defaultEnabledProtocols = "TLSv1.2"; - String enabledProtocols = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.enabled.protocols", defaultEnabledProtocols); - ssl.setAttribute("sslEnabledProtocols", enabledProtocols); - String ciphers = EmbeddedServerUtil.getConfig("ranger.tomcat.ciphers"); - if (StringUtils.isNotBlank(ciphers)) { - ssl.setAttribute("ciphers", ciphers); - } - server.getService().addConnector(ssl); - - // - // Making this as a default connector - // - server.setConnector(ssl); - - } - updateHttpConnectorAttribConfig(server); - - File logDirectory = new File(logDir); - if (!logDirectory.exists()) { - logDirectory.mkdirs(); - } - - AccessLogValve valve = new AccessLogValve(); - valve.setRotatable(true); - valve.setAsyncSupported(true); - valve.setBuffered(false); - valve.setEnabled(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ENABLED, true)); - valve.setPrefix(EmbeddedServerUtil.getConfig(ACCESS_LOG_PREFIX,"access-" + hostName)); - valve.setFileDateFormat(EmbeddedServerUtil.getConfig(ACCESS_LOG_DATE_FORMAT, "-yyyy-MM-dd.HH")); - valve.setDirectory(logDirectory.getAbsolutePath()); - valve.setSuffix(".log"); - valve.setRotatable(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ROTATE_ENABLED, true)); - valve.setMaxDays(EmbeddedServerUtil.getIntConfig(ACCESS_LOG_ROTATE_MAX_DAYS,15)); - valve.setRenameOnRotate(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ROTATE_RENAME_ON_ROTATE, false)); - - String defaultAccessLogPattern = servername.equalsIgnoreCase(KMS_SERVER_NAME) ? "%h %l %u %t \"%m %U\" %s %b %D" : "%h %l %u %t \"%r\" %s %b %D"; - String logPattern = EmbeddedServerUtil.getConfig(ACCESS_LOG_PATTERN, defaultAccessLogPattern); - valve.setPattern(logPattern); - - server.getHost().getPipeline().addValve(valve); - - ErrorReportValve errorReportValve = new ErrorReportValve(); - boolean showServerinfo = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.valve.errorreportvalve.showserverinfo", "true")); - boolean showReport = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.valve.errorreportvalve.showreport", "true")); - errorReportValve.setShowServerInfo(showServerinfo); - errorReportValve.setShowReport(showReport); - server.getHost().getPipeline().addValve(errorReportValve); - - try { - String webapp_dir = EmbeddedServerUtil.getConfig("xa.webapp.dir"); - if (StringUtils.isBlank(webapp_dir)) { - // If webapp location property is not set, then let's derive - // from catalina_base - String catalina_base = EmbeddedServerUtil.getConfig("catalina.base"); - if (StringUtils.isBlank(catalina_base)) { - LOG.severe("Tomcat Server failed to start: catalina.base and/or xa.webapp.dir is not set"); - System.exit(1); - } - webapp_dir = catalina_base + File.separator + "webapp"; - LOG.info("Deriving webapp folder from catalina.base property. folder=" - + webapp_dir); - } - - //String webContextName = getConfig("xa.webapp.contextName", "/"); - String webContextName = EmbeddedServerUtil.getConfig("ranger.contextName", "/"); - if (webContextName == null) { - webContextName = "/"; - } else if (!webContextName.startsWith("/")) { - LOG.info("Context Name [" + webContextName - + "] is being loaded as [ /" + webContextName + "]"); - webContextName = "/" + webContextName; - } - - File wad = new File(webapp_dir); - if (wad.isDirectory()) { - LOG.info("Webapp file =" + webapp_dir + ", webAppName = " - + webContextName); - } else if (wad.isFile()) { - File webAppDir = new File(DEFAULT_WEBAPPS_ROOT_FOLDER); - if (!webAppDir.exists()) { - webAppDir.mkdirs(); - } - LOG.info("Webapp file =" + webapp_dir + ", webAppName = " - + webContextName); - } - LOG.info("Adding webapp [" + webContextName + "] = path [" - + webapp_dir + "] ....."); - StandardContext webappCtx = (StandardContext) server.addWebapp(webContextName, new File( - webapp_dir).getAbsolutePath()); - String workDirPath = EmbeddedServerUtil.getConfig("ranger.tomcat.work.dir", ""); - if (!workDirPath.isEmpty() && new File(workDirPath).exists()) { - webappCtx.setWorkDir(workDirPath); - } else { - if (LOG.isLoggable(Level.FINE)) { - LOG.fine("Skipping to set tomcat server work directory, '" + workDirPath + - "', as it is blank or directory does not exist."); - } - } - webappCtx.init(); - LOG.info("Finished init of webapp [" + webContextName - + "] = path [" + webapp_dir + "]."); - } catch (LifecycleException lce) { - LOG.severe("Tomcat Server failed to start webapp:" + lce.toString()); - lce.printStackTrace(); - } - - if (servername.equalsIgnoreCase(ADMIN_SERVER_NAME)) { - String keytab = EmbeddedServerUtil.getConfig(ADMIN_USER_KEYTAB); - String principal = null; - try { - principal = SecureClientLogin.getPrincipal(EmbeddedServerUtil.getConfig(ADMIN_USER_PRINCIPAL), hostName); - } catch (IOException ignored) { - LOG.warning("Failed to get ranger.admin.kerberos.principal. Reason: " + ignored.toString()); - } - String nameRules = EmbeddedServerUtil.getConfig(ADMIN_NAME_RULES); - if (StringUtils.isBlank(nameRules)) { - LOG.info("Name is empty. Setting Name Rule as 'DEFAULT'"); - nameRules = DEFAULT_NAME_RULE; - } - if (EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE) != null - && EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE).trim().equalsIgnoreCase(AUTH_TYPE_KERBEROS) - && SecureClientLogin.isKerberosCredentialExists(principal,keytab)) { - try{ - LOG.info("Provided Kerberos Credential : Principal = " - + principal + " and Keytab = " + keytab); - Subject sub = SecureClientLogin.loginUserFromKeytab(principal, keytab, nameRules); - Subject.doAs(sub, new PrivilegedAction<Void>() { - @Override - public Void run() { - LOG.info("Starting Server using kerberos credential"); - startServer(server); - return null; - } - }); - } catch (Exception e) { - LOG.severe("Tomcat Server failed to start:" + e.toString()); - e.printStackTrace(); - } - } else { - startServer(server); - } - } else { - startServer(server); - } - } - - private void startServer(final Tomcat server) { - try { - String servername = EmbeddedServerUtil.getConfig("servername"); - LOG.info("Server Name : " + servername); - if (servername.equalsIgnoreCase(ADMIN_SERVER_NAME)) { - String auditSourceType = EmbeddedServerUtil.getConfig(AUDIT_SOURCE_TYPE, "db"); - if (AUDIT_SOURCE_SOLR.equalsIgnoreCase(auditSourceType)) { - boolean solrBootstrapEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig(SOLR_BOOTSTRAP_ENABLED, "true")); - if (solrBootstrapEnabled) { - try { - SolrCollectionBootstrapper solrSetup = new SolrCollectionBootstrapper(); - solrSetup.start(); - } catch (Exception e) { - LOG.severe("Error while setting solr " + e); - } - } - } else if (AUDIT_SOURCE_ES.equalsIgnoreCase(auditSourceType)) { - boolean esBootstrapEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig(ES_BOOTSTRAP_ENABLED, "true")); - if (esBootstrapEnabled) { - try { - ElasticSearchIndexBootStrapper esSchemaSetup = new ElasticSearchIndexBootStrapper(); - esSchemaSetup.start(); - } catch (Exception e) { - LOG.severe("Error while setting elasticsearch " + e); - } - } - } - } - - serverMetricsCollector = new EmbeddedServerMetricsCollector(server); - server.start(); - server.getServer().await(); - shutdownServer(); - } catch (LifecycleException e) { - LOG.severe("Tomcat Server failed to start:" + e.toString()); - e.printStackTrace(); - } catch (Exception e) { - LOG.severe("Tomcat Server failed to start:" + e.toString()); - e.printStackTrace(); - } - } - - private String getKeystoreFile() { - String keystoreFile = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.file"); - if (StringUtils.isBlank(keystoreFile)) { - // new property not configured, lets use the old property - keystoreFile = EmbeddedServerUtil.getConfig("ranger.https.attrib.keystore.file"); - } - return keystoreFile; - } - - public void shutdownServer() { - int timeWaitForShutdownInSeconds = EmbeddedServerUtil.getIntConfig( - "service.waitTimeForForceShutdownInSeconds", 0); - if (timeWaitForShutdownInSeconds > 0) { - long endTime = System.currentTimeMillis() - + (timeWaitForShutdownInSeconds * 1000L); - LOG.info("Will wait for all threads to shutdown gracefully. Final shutdown Time: " - + new Date(endTime)); - while (System.currentTimeMillis() < endTime) { - int activeCount = Thread.activeCount(); - if (activeCount == 0) { - LOG.info("Number of active threads = " + activeCount + "."); - break; - } else { - LOG.info("Number of active threads = " + activeCount - + ". Waiting for all threads to shutdown ..."); - try { - Thread.sleep(5000L); - } catch (InterruptedException e) { - LOG.warning("shutdownServer process is interrupted with exception: " - + e); - break; - } - } - } - } - LOG.info("Shuting down the Server."); - System.exit(0); - } - - public void updateHttpConnectorAttribConfig(Tomcat server) { - server.getConnector().setAllowTrace(Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.allowTrace", "false"))); - server.getConnector().setAsyncTimeout(EmbeddedServerUtil.getLongConfig("ranger.service.http.connector.attrib.asyncTimeout", 10000L)); - server.getConnector().setEnableLookups(Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.enableLookups", "false"))); - server.getConnector().setMaxParameterCount(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxParameterCount", 10000)); - server.getConnector().setMaxPostSize(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxPostSize", 2097152)); - server.getConnector().setMaxSavePostSize(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxSavePostSize", 4096)); - server.getConnector().setParseBodyMethods(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.methods", "POST")); - server.getConnector().setURIEncoding(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.URIEncoding", "UTF-8")); - server.getConnector().setXpoweredBy(false); - server.getConnector().setAttribute("server", "Apache Ranger"); - server.getConnector().setProperty("sendReasonPhrase",EmbeddedServerUtil.getConfig("ranger.service.http.connector.property.sendReasonPhrase", "true")); - Iterator<Object> iterator = EmbeddedServerUtil.getRangerConfigProperties().keySet().iterator(); - String key = null; - String property = null; - while (iterator.hasNext()){ - key = iterator.next().toString(); - if(key != null && key.startsWith("ranger.service.http.connector.property.")){ - property = key.replace("ranger.service.http.connector.property.",""); - server.getConnector().setProperty(property, EmbeddedServerUtil.getConfig(key)); - LOG.info(property + ":" + server.getConnector().getProperty(property)); - } - } - } - - private SSLContext getSSLContext() { - KeyManager[] kmList = getKeyManagers(); - TrustManager[] tmList = getTrustManagers(); - SSLContext sslContext = null; - if (tmList != null) { - try { - sslContext = SSLContext.getInstance(RANGER_SSL_CONTEXT_ALGO_TYPE); - sslContext.init(kmList, tmList, new SecureRandom()); - } catch (NoSuchAlgorithmException e) { - LOG.severe("SSL algorithm is not available in the environment. Reason: " + e.toString()); - } catch (KeyManagementException e) { - LOG.severe("Unable to initials the SSLContext. Reason: " + e.toString()); - } - } - return sslContext; - } - - private KeyManager[] getKeyManagers() { - KeyManager[] kmList = null; - String keyStoreFile = EmbeddedServerUtil.getConfig("ranger.keystore.file"); - String keyStoreAlias = EmbeddedServerUtil.getConfig("ranger.keystore.alias", "keyStoreCredentialAlias"); - if (StringUtils.isBlank(keyStoreFile)) { - keyStoreFile = getKeystoreFile(); - keyStoreAlias = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.credential.alias", "keyStoreCredentialAlias"); - } - String keyStoreFileType = EmbeddedServerUtil.getConfig("ranger.keystore.file.type",RANGER_KEYSTORE_FILE_TYPE_DEFAULT); - String credentialProviderPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); - String keyStoreFilepwd = CredentialReader.getDecryptedString(credentialProviderPath, keyStoreAlias, keyStoreFileType); - - if (StringUtils.isNotEmpty(keyStoreFile) && StringUtils.isNotEmpty(keyStoreFilepwd)) { - InputStream in = null; - - try { - in = getFileInputStream(keyStoreFile); - - if (in != null) { - KeyStore keyStore = KeyStore.getInstance(keyStoreFileType); - - keyStore.load(in, keyStoreFilepwd.toCharArray()); - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - - keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); - - kmList = keyManagerFactory.getKeyManagers(); - } else { - LOG.severe("Unable to obtain keystore from file [" + keyStoreFile + "]"); - } - } catch (KeyStoreException e) { - LOG.log(Level.SEVERE, "Unable to obtain from KeyStore :" + e.getMessage(), e); - } catch (NoSuchAlgorithmException e) { - LOG.log(Level.SEVERE, "SSL algorithm is NOT available in the environment", e); - } catch (CertificateException e) { - LOG.log(Level.SEVERE, "Unable to obtain the requested certification ", e); - } catch (FileNotFoundException e) { - LOG.log(Level.SEVERE, "Unable to find the necessary SSL Keystore Files", e); - } catch (IOException e) { - LOG.log(Level.SEVERE, "Unable to read the necessary SSL Keystore Files", e); - } catch (UnrecoverableKeyException e) { - LOG.log(Level.SEVERE, "Unable to recover the key from keystore", e); - } finally { - close(in, keyStoreFile); - } - } else { - if (StringUtils.isBlank(keyStoreFile)) { - LOG.warning("Config 'ranger.keystore.file' or 'ranger.service.https.attrib.keystore.file' is not found or contains blank value"); - } else if (StringUtils.isBlank(keyStoreAlias)) { - LOG.warning("Config 'ranger.keystore.alias' or 'ranger.service.https.attrib.keystore.credential.alias' is not found or contains blank value"); - } else if (StringUtils.isBlank(credentialProviderPath)) { - LOG.warning("Config 'ranger.credential.provider.path' is not found or contains blank value"); - } else if (StringUtils.isBlank(keyStoreFilepwd)) { - LOG.warning("Unable to read credential from credential store file ["+ credentialProviderPath + "] for given alias:"+keyStoreAlias); - } - } - return kmList; - } - - private TrustManager[] getTrustManagers() { - TrustManager[] tmList = null; - String truststoreFile = EmbeddedServerUtil.getConfig("ranger.truststore.file"); - String truststoreAlias = EmbeddedServerUtil.getConfig("ranger.truststore.alias"); - String credentialProviderPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); - String truststoreFileType = EmbeddedServerUtil.getConfig("ranger.truststore.file.type",RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT); - String trustStoreFilepwd = CredentialReader.getDecryptedString(credentialProviderPath, truststoreAlias, truststoreFileType); - - if (StringUtils.isNotEmpty(truststoreFile) && StringUtils.isNotEmpty(trustStoreFilepwd)) { - InputStream in = null; - - try { - in = getFileInputStream(truststoreFile); - - if (in != null) { - KeyStore trustStore = KeyStore.getInstance(truststoreFileType); - - trustStore.load(in, trustStoreFilepwd.toCharArray()); - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(RANGER_SSL_TRUSTMANAGER_ALGO_TYPE); - - trustManagerFactory.init(trustStore); - - tmList = trustManagerFactory.getTrustManagers(); - } else { - LOG.log(Level.SEVERE, "Unable to obtain truststore from file [" + truststoreFile + "]"); - } - } catch (KeyStoreException e) { - LOG.log(Level.SEVERE, "Unable to obtain from KeyStore", e); - } catch (NoSuchAlgorithmException e) { - LOG.log(Level.SEVERE, "SSL algorithm is NOT available in the environment :" + e.getMessage(), e); - } catch (CertificateException e) { - LOG.log(Level.SEVERE, "Unable to obtain the requested certification :" + e.getMessage(), e); - } catch (FileNotFoundException e) { - LOG.log(Level.SEVERE, "Unable to find the necessary SSL TrustStore File:" + truststoreFile, e); - } catch (IOException e) { - LOG.log(Level.SEVERE, "Unable to read the necessary SSL TrustStore Files :" + truststoreFile, e); - } finally { - close(in, truststoreFile); - } - } else { - if (StringUtils.isBlank(truststoreFile)) { - LOG.warning("Config 'ranger.truststore.file' is not found or contains blank value!"); - } else if (StringUtils.isBlank(truststoreAlias)) { - LOG.warning("Config 'ranger.truststore.alias' is not found or contains blank value!"); - } else if (StringUtils.isBlank(credentialProviderPath)) { - LOG.warning("Config 'ranger.credential.provider.path' is not found or contains blank value!"); - } else if (StringUtils.isBlank(trustStoreFilepwd)) { - LOG.warning("Unable to read credential from credential store file ["+ credentialProviderPath + "] for given alias:"+truststoreAlias); - } - } - - return tmList; - } - - private InputStream getFileInputStream(String fileName) throws IOException { - InputStream in = null; - if (StringUtils.isNotEmpty(fileName)) { - File f = new File(fileName); - if (f.exists()) { - in = new FileInputStream(f); - } else { - in = ClassLoader.getSystemResourceAsStream(fileName); - } - } - return in; - } - - private void close(InputStream str, String filename) { - if (str != null) { - try { - str.close(); - } catch (IOException excp) { - LOG.log(Level.SEVERE, "Error while closing file: [" + filename + "]", excp); - } - } - } - - public static EmbeddedServerMetricsCollector getServerMetricsCollector(){ - - EmbeddedServerMetricsCollector embeddedServerMetricsCollector = EmbeddedServer.serverMetricsCollector; - if( null != embeddedServerMetricsCollector ){ - LOG.info("Selected Tomcat protocolHandler: "+ embeddedServerMetricsCollector.getProtocolHandlerName()); - } - return embeddedServerMetricsCollector; - } - + private static final Logger LOG = Logger.getLogger(EmbeddedServer.class.getName()); + public static final String RANGER_KEYSTORE_FILE_TYPE_DEFAULT = KeyStore.getDefaultType(); + public static final String RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT = KeyStore.getDefaultType(); + public static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "TLSv1.2"; + public static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = KeyManagerFactory.getDefaultAlgorithm(); + public static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = TrustManagerFactory.getDefaultAlgorithm(); + private static final String DEFAULT_NAME_RULE = "DEFAULT"; + private static final String DEFAULT_WEBAPPS_ROOT_FOLDER = "webapps"; + private static final String AUTH_TYPE_KERBEROS = "kerberos"; + private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication"; + private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal"; + private static final String AUDIT_SOURCE_TYPE = "ranger.audit.source.type"; + private static final String AUDIT_SOURCE_SOLR = "solr"; + private static final String AUDIT_SOURCE_ES = "elasticsearch"; + private static final String SOLR_BOOTSTRAP_ENABLED = "ranger.audit.solr.bootstrap.enabled"; + private static final String ES_BOOTSTRAP_ENABLED = "ranger.audit.elasticsearch.bootstrap.enabled"; + private static final String ADMIN_USER_KEYTAB = "ranger.admin.kerberos.keytab"; + private static final String ADMIN_NAME_RULES = "hadoop.security.auth_to_local"; + private static final String ADMIN_SERVER_NAME = "rangeradmin"; + private static final String KMS_SERVER_NAME = "rangerkms"; + private static final String ACCESS_LOG_ENABLED = "ranger.accesslog.enabled"; + private static final String ACCESS_LOG_PREFIX = "ranger.accesslog.prefix"; + private static final String ACCESS_LOG_DATE_FORMAT = "ranger.accesslog.dateformat"; + private static final String ACCESS_LOG_PATTERN = "ranger.accesslog.pattern"; + private static final String ACCESS_LOG_ROTATE_ENABLED = "ranger.accesslog.rotate.enabled"; + private static final String ACCESS_LOG_ROTATE_MAX_DAYS = "ranger.accesslog.rotate.max_days"; + private static final String ACCESS_LOG_ROTATE_RENAME_ON_ROTATE = "ranger.accesslog.rotate.rename_on_rotate"; + public static String defaultShutdownCommand = "SHUTDOWN"; + private static String configFile = "ranger-admin-site.xml"; + public static int defaultShutdownPort = 6185; + private static EmbeddedServerMetricsCollector serverMetricsCollector; + + public EmbeddedServer(String[] args) { + if (args.length > 0) { + configFile = args[0]; + } + EmbeddedServerUtil.loadRangerConfigProperties(configFile); + } + + public static void main(String[] args) { + new EmbeddedServer(args).start(); + } + + public static EmbeddedServerMetricsCollector getServerMetricsCollector() { + EmbeddedServerMetricsCollector embeddedServerMetricsCollector = EmbeddedServer.serverMetricsCollector; + if (null != embeddedServerMetricsCollector) { + LOG.info("Selected Tomcat protocolHandler: " + embeddedServerMetricsCollector.getProtocolHandlerName()); + } + return embeddedServerMetricsCollector; + } + + public void start() { + SSLContext sslContext = getSSLContext(); + if (sslContext != null) { + SSLContext.setDefault(sslContext); + } + final Tomcat server = new Tomcat(); + + String logDir = null; + logDir = EmbeddedServerUtil.getConfig("logdir"); + if (logDir == null) { + logDir = EmbeddedServerUtil.getConfig("kms.log.dir"); + } + String servername = EmbeddedServerUtil.getConfig("servername"); + String hostName = EmbeddedServerUtil.getConfig("ranger.service.host"); + int serverPort = EmbeddedServerUtil.getIntConfig("ranger.service.http.port", 6181); + int sslPort = EmbeddedServerUtil.getIntConfig("ranger.service.https.port", -1); + int shutdownPort = EmbeddedServerUtil.getIntConfig("ranger.service.shutdown.port", defaultShutdownPort); + String shutdownCommand = EmbeddedServerUtil.getConfig("ranger.service.shutdown.command", defaultShutdownCommand); + + server.setHostname(hostName); + server.setPort(serverPort); + server.getServer().setPort(shutdownPort); + server.getServer().setShutdown(shutdownCommand); + + boolean isHttpsEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.enabled", "false")); + boolean ajpEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig("ajp.enabled", "false")); + + if (ajpEnabled) { + Connector ajpConnector = new Connector("org.apache.coyote.ajp.AjpNioProtocol"); + ajpConnector.setPort(serverPort); + ajpConnector.setProperty("protocol", "AJP/1.3"); + + server.getService().addConnector(ajpConnector); + + // Making this as a default connector + server.setConnector(ajpConnector); + LOG.info("Created AJP Connector"); + } else if ((sslPort > 0) && isHttpsEnabled) { + Connector ssl = new Connector(); + ssl.setPort(sslPort); + ssl.setSecure(true); + ssl.setScheme("https"); + ssl.setAttribute("SSLEnabled", "true"); + ssl.setAttribute("sslProtocol", EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.protocol", "TLSv1.2")); + ssl.setAttribute("keystoreType", EmbeddedServerUtil.getConfig("ranger.keystore.file.type", RANGER_KEYSTORE_FILE_TYPE_DEFAULT)); + ssl.setAttribute("truststoreType", EmbeddedServerUtil.getConfig("ranger.truststore.file.type", RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT)); + String clientAuth = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.clientAuth", "false"); + if ("false".equalsIgnoreCase(clientAuth)) { + clientAuth = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.client.auth", "want"); + } + ssl.setAttribute("clientAuth", clientAuth); + String providerPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); + String keyAlias = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.credential.alias", "keyStoreCredentialAlias"); + String keystorePass = null; + if (providerPath != null && keyAlias != null) { + keystorePass = CredentialReader.getDecryptedString(providerPath.trim(), keyAlias.trim(), EmbeddedServerUtil.getConfig("ranger.keystore.file.type", RANGER_KEYSTORE_FILE_TYPE_DEFAULT)); + if (StringUtils.isBlank(keystorePass) || "none".equalsIgnoreCase(keystorePass.trim())) { + keystorePass = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.pass"); + } + } + ssl.setAttribute("keyAlias", EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.keyalias", "rangeradmin")); + ssl.setAttribute("keystorePass", keystorePass); + ssl.setAttribute("keystoreFile", getKeystoreFile()); + + String defaultEnabledProtocols = "TLSv1.2"; + String enabledProtocols = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.ssl.enabled.protocols", defaultEnabledProtocols); + ssl.setAttribute("sslEnabledProtocols", enabledProtocols); + String ciphers = EmbeddedServerUtil.getConfig("ranger.tomcat.ciphers"); + if (StringUtils.isNotBlank(ciphers)) { + ssl.setAttribute("ciphers", ciphers); + } + server.getService().addConnector(ssl); + // + // Making this as a default connector + // + server.setConnector(ssl); + } + updateHttpConnectorAttribConfig(server); + + File logDirectory = new File(logDir); + if (!logDirectory.exists()) { + logDirectory.mkdirs(); + } + + AccessLogValve valve = new AccessLogValve(); + valve.setRotatable(true); + valve.setAsyncSupported(true); + valve.setBuffered(false); + valve.setEnabled(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ENABLED, true)); + valve.setPrefix(EmbeddedServerUtil.getConfig(ACCESS_LOG_PREFIX, "access-" + hostName)); + valve.setFileDateFormat(EmbeddedServerUtil.getConfig(ACCESS_LOG_DATE_FORMAT, "-yyyy-MM-dd.HH")); + valve.setDirectory(logDirectory.getAbsolutePath()); + valve.setSuffix(".log"); + valve.setRotatable(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ROTATE_ENABLED, true)); + valve.setMaxDays(EmbeddedServerUtil.getIntConfig(ACCESS_LOG_ROTATE_MAX_DAYS, 15)); + valve.setRenameOnRotate(EmbeddedServerUtil.getBooleanConfig(ACCESS_LOG_ROTATE_RENAME_ON_ROTATE, false)); + + String defaultAccessLogPattern = servername.equalsIgnoreCase(KMS_SERVER_NAME) ? "%h %l %u %t \"%m %U\" %s %b %D" : "%h %l %u %t \"%r\" %s %b %D"; + String logPattern = EmbeddedServerUtil.getConfig(ACCESS_LOG_PATTERN, defaultAccessLogPattern); + valve.setPattern(logPattern); + + server.getHost().getPipeline().addValve(valve); + + ErrorReportValve errorReportValve = new ErrorReportValve(); + boolean showServerinfo = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.valve.errorreportvalve.showserverinfo", "true")); + boolean showReport = Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.valve.errorreportvalve.showreport", "true")); + errorReportValve.setShowServerInfo(showServerinfo); + errorReportValve.setShowReport(showReport); + server.getHost().getPipeline().addValve(errorReportValve); + + try { + String webappDir = EmbeddedServerUtil.getConfig("xa.webapp.dir"); + if (StringUtils.isBlank(webappDir)) { + // If webapp location property is not set, then let's derive + // from catalina_base + String catalinaBaseDir = EmbeddedServerUtil.getConfig("catalina.base"); + if (StringUtils.isBlank(catalinaBaseDir)) { + LOG.severe("Tomcat Server failed to start: catalina.base and/or xa.webapp.dir is not set"); + System.exit(1); + } + webappDir = catalinaBaseDir + File.separator + "webapp"; + LOG.info("Deriving webapp folder from catalina.base property. folder=" + webappDir); + } + + //String webContextName = getConfig("xa.webapp.contextName", "/"); + String webContextName = EmbeddedServerUtil.getConfig("ranger.contextName", "/"); + if (webContextName == null) { + webContextName = "/"; + } else if (!webContextName.startsWith("/")) { + LOG.info("Context Name [" + webContextName + "] is being loaded as [ /" + webContextName + "]"); + webContextName = "/" + webContextName; + } + + File wad = new File(webappDir); + if (wad.isDirectory()) { + LOG.info("Webapp file =" + webappDir + ", webAppName = " + webContextName); + } else if (wad.isFile()) { + File webAppDir = new File(DEFAULT_WEBAPPS_ROOT_FOLDER); + if (!webAppDir.exists()) { + webAppDir.mkdirs(); + } + LOG.info("Webapp file =" + webappDir + ", webAppName = " + webContextName); + } + LOG.info("Adding webapp [" + webContextName + "] = path [" + webappDir + "] ....."); + StandardContext webappCtx = (StandardContext) server.addWebapp(webContextName, new File(webappDir).getAbsolutePath()); + String workDirPath = EmbeddedServerUtil.getConfig("ranger.tomcat.work.dir", ""); + if (!workDirPath.isEmpty() && new File(workDirPath).exists()) { + webappCtx.setWorkDir(workDirPath); + } else { + if (LOG.isLoggable(Level.FINE)) { + LOG.fine("Skipping to set tomcat server work directory, '" + workDirPath + "', as it is blank or directory does not exist."); + } + } + webappCtx.init(); + LOG.info("Finished init of webapp [" + webContextName + "] = path [" + webappDir + "]."); + } catch (LifecycleException lce) { + LOG.severe("Tomcat Server failed to start webapp:" + lce); + lce.printStackTrace(); + } + + if (servername.equalsIgnoreCase(ADMIN_SERVER_NAME)) { + String keytab = EmbeddedServerUtil.getConfig(ADMIN_USER_KEYTAB); + String principal = null; + try { + principal = SecureClientLogin.getPrincipal(EmbeddedServerUtil.getConfig(ADMIN_USER_PRINCIPAL), hostName); + } catch (IOException ignored) { + LOG.warning("Failed to get ranger.admin.kerberos.principal. Reason: " + ignored); + } + String nameRules = EmbeddedServerUtil.getConfig(ADMIN_NAME_RULES); + if (StringUtils.isBlank(nameRules)) { + LOG.info("Name is empty. Setting Name Rule as 'DEFAULT'"); + nameRules = DEFAULT_NAME_RULE; + } + if (EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE) != null && EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE).trim().equalsIgnoreCase(AUTH_TYPE_KERBEROS) && SecureClientLogin.isKerberosCredentialExists(principal, keytab)) { + try { + LOG.info("Provided Kerberos Credential : Principal = " + principal + " and Keytab = " + keytab); + Subject sub = SecureClientLogin.loginUserFromKeytab(principal, keytab, nameRules); + Subject.doAs(sub, new PrivilegedAction<Void>() { + @Override + public Void run() { + LOG.info("Starting Server using kerberos credential"); + startServer(server); + return null; + } + }); + } catch (Exception e) { + LOG.severe("Tomcat Server failed to start:" + e); + e.printStackTrace(); + } + } else { + startServer(server); + } + } else { + startServer(server); + } + } + + public void shutdownServer() { + int timeWaitForShutdownInSeconds = EmbeddedServerUtil.getIntConfig("service.waitTimeForForceShutdownInSeconds", 0); + if (timeWaitForShutdownInSeconds > 0) { + long endTime = System.currentTimeMillis() + (timeWaitForShutdownInSeconds * 1000L); + LOG.info("Will wait for all threads to shutdown gracefully. Final shutdown Time: " + new Date(endTime)); + while (System.currentTimeMillis() < endTime) { + int activeCount = Thread.activeCount(); + if (activeCount == 0) { + LOG.info("Number of active threads = " + activeCount + "."); + break; + } else { + LOG.info("Number of active threads = " + activeCount + ". Waiting for all threads to shutdown ..."); + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + LOG.warning("shutdownServer process is interrupted with exception: " + e); + break; + } + } + } + } + LOG.info("Shuting down the Server."); + System.exit(0); + } + + public void updateHttpConnectorAttribConfig(Tomcat server) { + server.getConnector().setAllowTrace(Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.allowTrace", "false"))); + server.getConnector().setAsyncTimeout(EmbeddedServerUtil.getLongConfig("ranger.service.http.connector.attrib.asyncTimeout", 10000L)); + server.getConnector().setEnableLookups(Boolean.valueOf(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.enableLookups", "false"))); + server.getConnector().setMaxParameterCount(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxParameterCount", 10000)); + server.getConnector().setMaxPostSize(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxPostSize", 2097152)); + server.getConnector().setMaxSavePostSize(EmbeddedServerUtil.getIntConfig("ranger.service.http.connector.attrib.maxSavePostSize", 4096)); + server.getConnector().setParseBodyMethods(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.methods", "POST")); + server.getConnector().setURIEncoding(EmbeddedServerUtil.getConfig("ranger.service.http.connector.attrib.URIEncoding", "UTF-8")); + server.getConnector().setXpoweredBy(false); + server.getConnector().setAttribute("server", "Apache Ranger"); + server.getConnector().setProperty("sendReasonPhrase", EmbeddedServerUtil.getConfig("ranger.service.http.connector.property.sendReasonPhrase", "true")); + Iterator<Object> iterator = EmbeddedServerUtil.getRangerConfigProperties().keySet().iterator(); + String key = null; + String property = null; + while (iterator.hasNext()) { + key = iterator.next().toString(); + if (key != null && key.startsWith("ranger.service.http.connector.property.")) { + property = key.replace("ranger.service.http.connector.property.", ""); + server.getConnector().setProperty(property, EmbeddedServerUtil.getConfig(key)); + LOG.info(property + ":" + server.getConnector().getProperty(property)); + } + } + } + + private void startServer(final Tomcat server) { + try { + String servername = EmbeddedServerUtil.getConfig("servername"); + LOG.info("Server Name : " + servername); + if (servername.equalsIgnoreCase(ADMIN_SERVER_NAME)) { + String auditSourceType = EmbeddedServerUtil.getConfig(AUDIT_SOURCE_TYPE, "db"); + if (AUDIT_SOURCE_SOLR.equalsIgnoreCase(auditSourceType)) { + boolean solrBootstrapEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig(SOLR_BOOTSTRAP_ENABLED, "true")); + if (solrBootstrapEnabled) { + try { + SolrCollectionBootstrapper solrSetup = new SolrCollectionBootstrapper(); + solrSetup.start(); + } catch (Exception e) { + LOG.severe("Error while setting solr " + e); + } + } + } else if (AUDIT_SOURCE_ES.equalsIgnoreCase(auditSourceType)) { + boolean esBootstrapEnabled = Boolean.valueOf(EmbeddedServerUtil.getConfig(ES_BOOTSTRAP_ENABLED, "true")); + if (esBootstrapEnabled) { + try { + ElasticSearchIndexBootStrapper esSchemaSetup = new ElasticSearchIndexBootStrapper(); + esSchemaSetup.start(); + } catch (Exception e) { + LOG.severe("Error while setting elasticsearch " + e); + } + } + } + } + + serverMetricsCollector = new EmbeddedServerMetricsCollector(server); + server.start(); + server.getServer().await(); + shutdownServer(); + } catch (LifecycleException e) { + LOG.severe("Tomcat Server failed to start:" + e); + e.printStackTrace(); + } catch (Exception e) { + LOG.severe("Tomcat Server failed to start:" + e); + e.printStackTrace(); + } + } + + private String getKeystoreFile() { + String keystoreFile = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.file"); + if (StringUtils.isBlank(keystoreFile)) { + // new property not configured, lets use the old property + keystoreFile = EmbeddedServerUtil.getConfig("ranger.https.attrib.keystore.file"); + } + return keystoreFile; + } + + private SSLContext getSSLContext() { + KeyManager[] kmList = getKeyManagers(); + TrustManager[] tmList = getTrustManagers(); + SSLContext sslContext = null; + if (tmList != null) { + try { + sslContext = SSLContext.getInstance(RANGER_SSL_CONTEXT_ALGO_TYPE); + sslContext.init(kmList, tmList, new SecureRandom()); + } catch (NoSuchAlgorithmException e) { + LOG.severe("SSL algorithm is not available in the environment. Reason: " + e); + } catch (KeyManagementException e) { + LOG.severe("Unable to initials the SSLContext. Reason: " + e); + } + } + return sslContext; + } + + private KeyManager[] getKeyManagers() { + KeyManager[] kmList = null; + String keyStoreFile = EmbeddedServerUtil.getConfig("ranger.keystore.file"); + String keyStoreAlias = EmbeddedServerUtil.getConfig("ranger.keystore.alias", "keyStoreCredentialAlias"); + if (StringUtils.isBlank(keyStoreFile)) { + keyStoreFile = getKeystoreFile(); + keyStoreAlias = EmbeddedServerUtil.getConfig("ranger.service.https.attrib.keystore.credential.alias", "keyStoreCredentialAlias"); + } + String keyStoreFileType = EmbeddedServerUtil.getConfig("ranger.keystore.file.type", RANGER_KEYSTORE_FILE_TYPE_DEFAULT); + String credentialProviderPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); + String keyStoreFilepwd = CredentialReader.getDecryptedString(credentialProviderPath, keyStoreAlias, keyStoreFileType); + + if (StringUtils.isNotEmpty(keyStoreFile) && StringUtils.isNotEmpty(keyStoreFilepwd)) { + InputStream in = null; + try { + in = getFileInputStream(keyStoreFile); + if (in != null) { + KeyStore keyStore = KeyStore.getInstance(keyStoreFileType); + keyStore.load(in, keyStoreFilepwd.toCharArray()); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); + kmList = keyManagerFactory.getKeyManagers(); + } else { + LOG.severe("Unable to obtain keystore from file [" + keyStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.log(Level.SEVERE, "Unable to obtain from KeyStore :" + e.getMessage(), e); + } catch (NoSuchAlgorithmException e) { + LOG.log(Level.SEVERE, "SSL algorithm is NOT available in the environment", e); + } catch (CertificateException e) { + LOG.log(Level.SEVERE, "Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.log(Level.SEVERE, "Unable to find the necessary SSL Keystore Files", e); + } catch (IOException e) { + LOG.log(Level.SEVERE, "Unable to read the necessary SSL Keystore Files", e); + } catch (UnrecoverableKeyException e) { + LOG.log(Level.SEVERE, "Unable to recover the key from keystore", e); + } finally { + close(in, keyStoreFile); + } + } else { + if (StringUtils.isBlank(keyStoreFile)) { + LOG.warning("Config 'ranger.keystore.file' or 'ranger.service.https.attrib.keystore.file' is not found or contains blank value"); + } else if (StringUtils.isBlank(keyStoreAlias)) { + LOG.warning("Config 'ranger.keystore.alias' or 'ranger.service.https.attrib.keystore.credential.alias' is not found or contains blank value"); + } else if (StringUtils.isBlank(credentialProviderPath)) { + LOG.warning("Config 'ranger.credential.provider.path' is not found or contains blank value"); + } else if (StringUtils.isBlank(keyStoreFilepwd)) { + LOG.warning("Unable to read credential from credential store file [" + credentialProviderPath + "] for given alias:" + keyStoreAlias); + } + } + return kmList; + } + + private TrustManager[] getTrustManagers() { + TrustManager[] tmList = null; + String truststoreFile = EmbeddedServerUtil.getConfig("ranger.truststore.file"); + String truststoreAlias = EmbeddedServerUtil.getConfig("ranger.truststore.alias"); + String credentialProviderPath = EmbeddedServerUtil.getConfig("ranger.credential.provider.path"); + String truststoreFileType = EmbeddedServerUtil.getConfig("ranger.truststore.file.type", RANGER_TRUSTSTORE_FILE_TYPE_DEFAULT); + String trustStoreFilepwd = CredentialReader.getDecryptedString(credentialProviderPath, truststoreAlias, truststoreFileType); + + if (StringUtils.isNotEmpty(truststoreFile) && StringUtils.isNotEmpty(trustStoreFilepwd)) { + InputStream in = null; + try { + in = getFileInputStream(truststoreFile); + if (in != null) { + KeyStore trustStore = KeyStore.getInstance(truststoreFileType); + trustStore.load(in, trustStoreFilepwd.toCharArray()); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(RANGER_SSL_TRUSTMANAGER_ALGO_TYPE); + trustManagerFactory.init(trustStore); + tmList = trustManagerFactory.getTrustManagers(); + } else { + LOG.log(Level.SEVERE, "Unable to obtain truststore from file [" + truststoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.log(Level.SEVERE, "Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.log(Level.SEVERE, "SSL algorithm is NOT available in the environment :" + e.getMessage(), e); + } catch (CertificateException e) { + LOG.log(Level.SEVERE, "Unable to obtain the requested certification :" + e.getMessage(), e); + } catch (FileNotFoundException e) { + LOG.log(Level.SEVERE, "Unable to find the necessary SSL TrustStore File:" + truststoreFile, e); + } catch (IOException e) { + LOG.log(Level.SEVERE, "Unable to read the necessary SSL TrustStore Files :" + truststoreFile, e); + } finally { + close(in, truststoreFile); + } + } else { + if (StringUtils.isBlank(truststoreFile)) { + LOG.warning("Config 'ranger.truststore.file' is not found or contains blank value!"); + } else if (StringUtils.isBlank(truststoreAlias)) { + LOG.warning("Config 'ranger.truststore.alias' is not found or contains blank value!"); + } else if (StringUtils.isBlank(credentialProviderPath)) { + LOG.warning("Config 'ranger.credential.provider.path' is not found or contains blank value!"); + } else if (StringUtils.isBlank(trustStoreFilepwd)) { + LOG.warning("Unable to read credential from credential store file [" + credentialProviderPath + "] for given alias:" + truststoreAlias); + } + } + + return tmList; + } + + private InputStream getFileInputStream(String fileName) throws IOException { + InputStream in = null; + if (StringUtils.isNotEmpty(fileName)) { + File f = new File(fileName); + if (f.exists()) { + in = new FileInputStream(f); + } else { + in = ClassLoader.getSystemResourceAsStream(fileName); + } + } + return in; + } + + private void close(InputStream str, String filename) { + if (str != null) { + try { + str.close(); + } catch (IOException excp) { + LOG.log(Level.SEVERE, "Error while closing file: [" + filename + "]", excp); + } + } + } } diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerMetricsCollector.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerMetricsCollector.java index 90617f456..9c3332b05 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerMetricsCollector.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerMetricsCollector.java @@ -22,89 +22,74 @@ package org.apache.ranger.server.tomcat; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; import org.apache.coyote.AbstractProtocol; +import org.apache.tomcat.util.threads.ThreadPoolExecutor; import java.util.concurrent.Executor; -import org.apache.tomcat.util.threads.ThreadPoolExecutor; public class EmbeddedServerMetricsCollector { - - private final Connector connector; + private final Connector connector; private final AbstractProtocol protocolHandler; - EmbeddedServerMetricsCollector( Tomcat server){ - this.connector = server.getConnector(); + EmbeddedServerMetricsCollector(Tomcat server) { + this.connector = server.getConnector(); this.protocolHandler = (AbstractProtocol) this.connector.getProtocolHandler(); } /** - * * @return: maxConfigured (allowed) connections to be accepted by the server. */ - public long getMaxAllowedConnection(){ - + public long getMaxAllowedConnection() { return this.protocolHandler.getMaxConnections(); } /** - * * @return: Once maxConnection is reached, OS would still accept few more connections in a queue and size of queue is determined by "acceptCount" * By default, it is 100. * Note: These connections will wait in the queue for serverSocket to accept. */ - public int getConnectionAcceptCount(){ + public int getConnectionAcceptCount() { return this.protocolHandler.getAcceptCount(); } /** - * * @return: Returns the active connections count. */ - public long getActiveConnectionCount(){ + public long getActiveConnectionCount() { return this.protocolHandler.getConnectionCount(); } /** - * * @return: Max container threads count */ - public int getMaxContainerThreadsCount(){ + public int getMaxContainerThreadsCount() { return this.protocolHandler.getMaxThreads(); } /** - * * @return: Returns the corePoolSize of threadpool */ - public int getMinSpareContainerThreadsCount(){ + public int getMinSpareContainerThreadsCount() { return this.protocolHandler.getMinSpareThreads(); } /** - * * @return: Returns the current active worked threads count. * Note: {@link ThreadPoolExecutor#getActiveCount()} internally acquires lock, so it could be expensive. */ - public int getActiveContainerThreadsCount(){ + public int getActiveContainerThreadsCount() { Executor executor = this.protocolHandler.getExecutor(); - int activeThreadCount = -1; - - if( executor instanceof ThreadPoolExecutor){ - + if (executor instanceof ThreadPoolExecutor) { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; activeThreadCount = threadPoolExecutor.getActiveCount(); } - return activeThreadCount; } - public int getTotalContainerThreadsCount(){ + public int getTotalContainerThreadsCount() { Executor executor = this.protocolHandler.getExecutor(); - int totalThreadCount = -1; - - if( executor instanceof ThreadPoolExecutor){ - + if (executor instanceof ThreadPoolExecutor) { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; totalThreadCount = threadPoolExecutor.getPoolSize(); } @@ -112,17 +97,15 @@ public class EmbeddedServerMetricsCollector { return totalThreadCount; } - - public String getProtocolHandlerName(){ + public String getProtocolHandlerName() { return this.protocolHandler.getName(); } - public long getConnectionTimeout(){ + public long getConnectionTimeout() { return this.protocolHandler.getConnectionTimeout(); } - public long getKeepAliveTimeout(){ + public long getKeepAliveTimeout() { return this.protocolHandler.getKeepAliveTimeout(); } - } diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerUtil.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerUtil.java index b6c2a94bb..715873f86 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerUtil.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServerUtil.java @@ -19,6 +19,8 @@ package org.apache.ranger.server.tomcat; +import org.apache.commons.lang.StringUtils; +import org.apache.ranger.plugin.util.XMLUtils; import java.util.ArrayList; import java.util.List; @@ -26,110 +28,105 @@ import java.util.Properties; import java.util.StringTokenizer; import java.util.logging.Logger; -import org.apache.commons.lang.StringUtils; -import org.apache.ranger.plugin.util.XMLUtils; - public class EmbeddedServerUtil { - - private static final Logger LOG = Logger.getLogger(EmbeddedServerUtil.class.getName()); - private static final String CONFIG_FILE = "ranger-admin-site.xml"; - private static final String CORE_SITE_CONFIG_FILENAME = "core-site.xml"; - private static final String DEFAULT_CONFIG_FILENAME = "ranger-admin-default-site.xml"; - private static Properties rangerConfigProperties = new Properties(); - - private EmbeddedServerUtil() { - loadRangerConfigProperties(CONFIG_FILE); - } - - public static void loadRangerConfigProperties(String configFile) { - if (CONFIG_FILE.equalsIgnoreCase(configFile)) { - XMLUtils.loadConfig(DEFAULT_CONFIG_FILENAME, rangerConfigProperties); - } - XMLUtils.loadConfig(CORE_SITE_CONFIG_FILENAME, rangerConfigProperties); - XMLUtils.loadConfig(configFile, rangerConfigProperties); - } - - public static Properties getRangerConfigProperties() { - if (rangerConfigProperties.isEmpty()) { - loadRangerConfigProperties(CONFIG_FILE); - } - return rangerConfigProperties; - } - - public static String getConfig(String key, String defaultValue) { - String ret = getConfig(key); - if (ret == null) { - ret = defaultValue; - } - return ret; - } - - public static boolean getBooleanConfig(String key, boolean defaultValue) { - boolean ret = defaultValue; - String retStr = getConfig(key); - try { - if (retStr != null) { - ret = Boolean.parseBoolean(retStr); - } - } catch (Exception err) { - LOG.severe(retStr + " can't be parsed to int. Reason: " + err.toString()); - } - return ret; - } - - public static int getIntConfig(String key, int defaultValue) { - int ret = defaultValue; - String retStr = getConfig(key); - try { - if (retStr != null) { - ret = Integer.parseInt(retStr); - } - } catch (Exception err) { - LOG.severe(retStr + " can't be parsed to int. Reason: " + err.toString()); - } - return ret; - } - - public static Long getLongConfig(String key, Long defaultValue) { - Long ret = defaultValue; - String retStr = getConfig(key); - try { - if (retStr != null) { - ret = Long.parseLong(retStr); - } - } catch (Exception err) { - LOG.severe(retStr + " can't be parsed to long. Reason: " + err.toString()); - } - return ret; - } - - public static String getConfig(String key) { - String value = getRangerConfigProperties().getProperty(key); - if (value == null || value.trim().isEmpty()) { - value = System.getProperty(key); - } - return value; - } - - public static String getHosts(String urls) { - if (urls != null) { - urls = urls.trim(); - if ("NONE".equalsIgnoreCase(urls)) { - urls = null; - } - } - return urls; - } - - public static List<String> toArray(String destListStr, String delim) { - List<String> list = new ArrayList<String>(); - if (StringUtils.isNotBlank(destListStr)) { - StringTokenizer tokenizer = new StringTokenizer(destListStr, delim.trim()); - while (tokenizer.hasMoreTokens()) { - list.add(tokenizer.nextToken()); - } - } - return list; - } - + private static final Logger LOG = Logger.getLogger(EmbeddedServerUtil.class.getName()); + private static final String CONFIG_FILE = "ranger-admin-site.xml"; + private static final String CORE_SITE_CONFIG_FILENAME = "core-site.xml"; + private static final String DEFAULT_CONFIG_FILENAME = "ranger-admin-default-site.xml"; + private static final Properties rangerConfigProperties = new Properties(); + + private EmbeddedServerUtil() { + loadRangerConfigProperties(CONFIG_FILE); + } + + public static void loadRangerConfigProperties(String configFile) { + if (CONFIG_FILE.equalsIgnoreCase(configFile)) { + XMLUtils.loadConfig(DEFAULT_CONFIG_FILENAME, rangerConfigProperties); + } + XMLUtils.loadConfig(CORE_SITE_CONFIG_FILENAME, rangerConfigProperties); + XMLUtils.loadConfig(configFile, rangerConfigProperties); + } + + public static Properties getRangerConfigProperties() { + if (rangerConfigProperties.isEmpty()) { + loadRangerConfigProperties(CONFIG_FILE); + } + return rangerConfigProperties; + } + + public static String getConfig(String key, String defaultValue) { + String ret = getConfig(key); + if (ret == null) { + ret = defaultValue; + } + return ret; + } + + public static boolean getBooleanConfig(String key, boolean defaultValue) { + boolean ret = defaultValue; + String retStr = getConfig(key); + try { + if (retStr != null) { + ret = Boolean.parseBoolean(retStr); + } + } catch (Exception err) { + LOG.severe(retStr + " can't be parsed to int. Reason: " + err); + } + return ret; + } + + public static int getIntConfig(String key, int defaultValue) { + int ret = defaultValue; + String retStr = getConfig(key); + try { + if (retStr != null) { + ret = Integer.parseInt(retStr); + } + } catch (Exception err) { + LOG.severe(retStr + " can't be parsed to int. Reason: " + err); + } + return ret; + } + + public static Long getLongConfig(String key, Long defaultValue) { + Long ret = defaultValue; + String retStr = getConfig(key); + try { + if (retStr != null) { + ret = Long.parseLong(retStr); + } + } catch (Exception err) { + LOG.severe(retStr + " can't be parsed to long. Reason: " + err); + } + return ret; + } + + public static String getConfig(String key) { + String value = getRangerConfigProperties().getProperty(key); + if (value == null || value.trim().isEmpty()) { + value = System.getProperty(key); + } + return value; + } + + public static String getHosts(String urls) { + if (urls != null) { + urls = urls.trim(); + if ("NONE".equalsIgnoreCase(urls)) { + urls = null; + } + } + return urls; + } + + public static List<String> toArray(String destListStr, String delim) { + List<String> list = new ArrayList<String>(); + if (StringUtils.isNotBlank(destListStr)) { + StringTokenizer tokenizer = new StringTokenizer(destListStr, delim.trim()); + while (tokenizer.hasMoreTokens()) { + list.add(tokenizer.nextToken()); + } + } + return list; + } } diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java index 48ee824c4..489e0d6d0 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java @@ -18,24 +18,6 @@ */ package org.apache.ranger.server.tomcat; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.StringReader; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.security.SecureClientLogin; @@ -59,424 +41,361 @@ import org.apache.solr.common.cloud.ZkConfigManager; import org.noggit.JSONParser; import org.noggit.ObjectBuilder; -import com.google.protobuf.TextFormat.ParseException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.StringReader; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; public class SolrCollectionBootstrapper extends Thread { + private static final Logger logger = Logger.getLogger(SolrCollectionBootstrapper.class.getName()); + public static final String DEFAULT_COLLECTION_NAME = "ranger_audits"; + public static final String DEFAULT_CONFIG_NAME = "ranger_audits"; + public static final long DEFAULT_SOLR_TIME_INTERVAL_MS = 60000L; + public static final int DEFAULT_VALUE = 1; + public static final int DEFAULT_SOLR_BOOTSTRP_MAX_RETRY = -1; + static final String SOLR_ZK_HOSTS = "ranger.audit.solr.zookeepers"; + static final String SOLR_COLLECTION_NAME_KEY = "ranger.audit.solr.collection.name"; + static final String SOLR_CONFIG_NAME_KEY = "ranger.audit.solr.config.name"; + static final String CONFIG_SET_LOCATION = "ranger.audit.solr.configset.location"; + static final String SOLR_NO_SHARDS = "ranger.audit.solr.no.shards"; + static final String SOLR_MAX_SHARD_PER_NODE = "ranger.audit.solr.max.shards.per.node"; + static final String SOLR_NO_REPLICA = "ranger.audit.solr.no.replica"; + static final String SOLR_TIME_INTERVAL = "ranger.audit.solr.time.interval"; + static final String SOLR_BOOTSTRP_MAX_RETRY = "ranger.audit.solr.max.retry"; + static final String PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG = "java.security.auth.login.config"; + private static final String AUTH_TYPE_KERBEROS = "kerberos"; + private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication"; + private static final String RANGER_SERVICE_HOSTNAME = "ranger.service.host"; + private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal"; + private static final String SSL_ENABLED_PARAM = "ranger.service.https.attrib.ssl.enabled"; + private static final int TRY_UNTIL_SUCCESS = -1; + private final String customConfigSetLocation; + boolean solrCloudMode; + boolean isCompleted; + boolean isKERBEROS; + String principal; + String hostName; + String keytab; + String nameRules; + String solrCollectionName; + String solrConfigName; + Path pathForCloudMode; + int noOfReplicas; + int maxNodePerShards; + int maxRetry; + int retryCounter; + Long timeInterval; + SolrClient solrClient; + CloudSolrClient solrCloudClient; + SolrZooKeeper solrZookeeper; + SolrZkClient zkClient; + private File configSetFolder; + private boolean isSSLEnabled; + + public SolrCollectionBootstrapper() throws IOException { + logger.info("Starting Solr Setup"); + + logger.info("AUTHENTICATION_TYPE : " + EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE)); + if (EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE) != null && EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE).trim().equalsIgnoreCase(AUTH_TYPE_KERBEROS)) { + isKERBEROS = true; + hostName = EmbeddedServerUtil.getConfig(RANGER_SERVICE_HOSTNAME); + try { + principal = SecureClientLogin.getPrincipal(EmbeddedServerUtil.getConfig(ADMIN_USER_PRINCIPAL), hostName); + } catch (IOException ignored) { + logger.warning("Failed to get ranger.admin.kerberos.principal. Reason: " + ignored); + } + } + + solrCollectionName = EmbeddedServerUtil.getConfig(SOLR_COLLECTION_NAME_KEY, DEFAULT_COLLECTION_NAME); + logger.info("Solr Collection name provided is : " + solrCollectionName); + solrConfigName = EmbeddedServerUtil.getConfig(SOLR_CONFIG_NAME_KEY, DEFAULT_CONFIG_NAME); + logger.info("Solr Config name provided is : " + solrConfigName); + noOfReplicas = EmbeddedServerUtil.getIntConfig(SOLR_NO_REPLICA, DEFAULT_VALUE); + logger.info("No. of replicas provided is : " + noOfReplicas); + + maxNodePerShards = EmbeddedServerUtil.getIntConfig(SOLR_MAX_SHARD_PER_NODE, DEFAULT_VALUE); + logger.info("Max no of nodes per shards provided is : " + maxNodePerShards); + + timeInterval = EmbeddedServerUtil.getLongConfig(SOLR_TIME_INTERVAL, DEFAULT_SOLR_TIME_INTERVAL_MS); + logger.info("Solr time interval provided is : " + timeInterval); + + maxRetry = EmbeddedServerUtil.getIntConfig(SOLR_BOOTSTRP_MAX_RETRY, DEFAULT_SOLR_BOOTSTRP_MAX_RETRY); + if (System.getProperty(PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG) == null) { + System.setProperty(PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG, "/dev/null"); + } + + String basedir = new File(".").getCanonicalPath(); + String solrFileDir = new File(basedir).getParent(); + + this.customConfigSetLocation = EmbeddedServerUtil.getConfig(CONFIG_SET_LOCATION); + logger.info("Provided custom configSet location : " + this.customConfigSetLocation); + if (StringUtils.isNotEmpty(this.customConfigSetLocation)) { + this.configSetFolder = new File(this.customConfigSetLocation); + } else { + pathForCloudMode = Paths.get(solrFileDir, "contrib", "solr_for_audit_setup", "conf"); + configSetFolder = pathForCloudMode.toFile(); + } + String sslEnabledProp = EmbeddedServerUtil.getConfig(SSL_ENABLED_PARAM); + isSSLEnabled = ("true".equalsIgnoreCase(sslEnabledProp)); + } - private static final Logger logger = Logger - .getLogger(SolrCollectionBootstrapper.class.getName()); - final static String SOLR_ZK_HOSTS = "ranger.audit.solr.zookeepers"; - final static String SOLR_COLLECTION_NAME_KEY = "ranger.audit.solr.collection.name"; - final static String SOLR_CONFIG_NAME_KEY = "ranger.audit.solr.config.name"; - final static String CONFIG_SET_LOCATION = "ranger.audit.solr.configset.location"; - final static String SOLR_NO_SHARDS = "ranger.audit.solr.no.shards"; - final static String SOLR_MAX_SHARD_PER_NODE = "ranger.audit.solr.max.shards.per.node"; - final static String SOLR_NO_REPLICA = "ranger.audit.solr.no.replica"; - final static String SOLR_TIME_INTERVAL = "ranger.audit.solr.time.interval"; - final static String SOLR_BOOTSTRP_MAX_RETRY = "ranger.audit.solr.max.retry"; - final static String PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG = "java.security.auth.login.config"; - public static final String DEFAULT_COLLECTION_NAME = "ranger_audits"; - public static final String DEFAULT_CONFIG_NAME = "ranger_audits"; - public static final int DEFAULT_VALUE = 1; - public static final long DEFAULT_SOLR_TIME_INTERVAL_MS = 60000L; - private static final int TRY_UNTIL_SUCCESS = -1; - public static final int DEFAULT_SOLR_BOOTSTRP_MAX_RETRY = TRY_UNTIL_SUCCESS; - private static final String AUTH_TYPE_KERBEROS = "kerberos"; - private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication"; - private static final String RANGER_SERVICE_HOSTNAME = "ranger.service.host"; - private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal"; - private static final String SSL_ENABLED_PARAM = "ranger.service.https.attrib.ssl.enabled"; - private File configSetFolder = null; - - boolean solr_cloud_mode = false; - boolean is_completed = false; - boolean isKERBEROS = false; - private boolean isSSLEnabled = false; - String principal = null; - String hostName; - String keytab; - String nameRules; - String solr_collection_name; - String solr_config_name; - private String customConfigSetLocation; - Path path_for_cloud_mode; - int no_of_replicas; - int max_node_per_shards; - int max_retry; - int retry_counter = 0; - Long time_interval; - SolrClient solrClient = null; - CloudSolrClient solrCloudClient = null; - SolrZooKeeper solrZookeeper = null; - SolrZkClient zkClient = null; - - public SolrCollectionBootstrapper() throws IOException { - logger.info("Starting Solr Setup"); - - logger.info("AUTHENTICATION_TYPE : " + EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE)); - if (EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE) != null - && EmbeddedServerUtil.getConfig(AUTHENTICATION_TYPE).trim().equalsIgnoreCase( - AUTH_TYPE_KERBEROS)) { - isKERBEROS = true; - hostName = EmbeddedServerUtil.getConfig(RANGER_SERVICE_HOSTNAME); - try { - principal = SecureClientLogin.getPrincipal( - EmbeddedServerUtil.getConfig(ADMIN_USER_PRINCIPAL), hostName); - } catch (IOException ignored) { - logger.warning("Failed to get ranger.admin.kerberos.principal. Reason: " - + ignored.toString()); - } - } - - solr_collection_name = EmbeddedServerUtil.getConfig(SOLR_COLLECTION_NAME_KEY, - DEFAULT_COLLECTION_NAME); - logger.info("Solr Collection name provided is : " - + solr_collection_name); - solr_config_name = EmbeddedServerUtil.getConfig(SOLR_CONFIG_NAME_KEY, DEFAULT_CONFIG_NAME); - logger.info("Solr Config name provided is : " + solr_config_name); - no_of_replicas = EmbeddedServerUtil.getIntConfig(SOLR_NO_REPLICA, DEFAULT_VALUE); - logger.info("No. of replicas provided is : " + no_of_replicas); - - max_node_per_shards = EmbeddedServerUtil.getIntConfig(SOLR_MAX_SHARD_PER_NODE, DEFAULT_VALUE); - logger.info("Max no of nodes per shards provided is : " - + max_node_per_shards); - - time_interval = EmbeddedServerUtil.getLongConfig(SOLR_TIME_INTERVAL, - DEFAULT_SOLR_TIME_INTERVAL_MS); - logger.info("Solr time interval provided is : " + time_interval); - - max_retry = EmbeddedServerUtil.getIntConfig(SOLR_BOOTSTRP_MAX_RETRY, DEFAULT_SOLR_BOOTSTRP_MAX_RETRY); - if (System.getProperty(PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG) == null) { - System.setProperty(PROP_JAVA_SECURITY_AUTH_LOGIN_CONFIG, - "/dev/null"); - } - - String basedir = new File(".").getCanonicalPath(); - String solrFileDir = new File(basedir).getParent(); - - this.customConfigSetLocation = EmbeddedServerUtil.getConfig(CONFIG_SET_LOCATION); - logger.info("Provided custom configSet location : " + this.customConfigSetLocation); - if (StringUtils.isNotEmpty(this.customConfigSetLocation)) { - this.configSetFolder = new File(this.customConfigSetLocation); - } else { - path_for_cloud_mode = Paths.get(solrFileDir, "contrib", "solr_for_audit_setup", "conf"); - configSetFolder = path_for_cloud_mode.toFile(); - } - String sslEnabledProp = EmbeddedServerUtil.getConfig(SSL_ENABLED_PARAM); - isSSLEnabled = ("true".equalsIgnoreCase(sslEnabledProp)); - } - - public void run() { - logger.info("Started run method"); - List<String> zookeeperHosts = getZkHosts(); - if (zookeeperHosts != null - && !zookeeperHosts.isEmpty() - && zookeeperHosts.stream().noneMatch( - h -> h.equalsIgnoreCase("none"))) { - logger.info("Solr zkHosts=" + zookeeperHosts + ", collectionName=" - + solr_collection_name); - while (!is_completed && (max_retry == TRY_UNTIL_SUCCESS || retry_counter < max_retry)) { - try { - if (connect(zookeeperHosts)) { - if (solr_cloud_mode) { - if (uploadConfiguration() && createCollection() - ) { - is_completed = true; - break; - } else { - logErrorMessageAndWait( - "Error while performing operations on solr. ", - null); - } - } - - } else { - logErrorMessageAndWait( - "Cannot connect to solr kindly check the solr related configs. ", - null); - } - } catch (Exception ex) { - logErrorMessageAndWait("Error while configuring solr. ", ex); - } - - try { - if (solrCloudClient != null) { - solrCloudClient.close(); - } - } catch (Exception ex) { - logger.log(Level.WARNING, "Error while closing the solr client. ", ex); - } - - } - - } else { - logger.severe("Solr ZKHosts for Audit are empty. Please set property " - + SOLR_ZK_HOSTS); - } - - } - - private boolean connect(List<String> zookeeperHosts) { - try { - logger.info("Solr is in Cloud mode"); - if (isKERBEROS) { - setHttpClientBuilderForKrb(); - } - solrCloudClient = new CloudSolrClient.Builder(zookeeperHosts, - Optional.empty()).build(); - solrCloudClient.setDefaultCollection(solr_collection_name); - solrCloudClient.connect(); - zkClient = solrCloudClient.getZkStateReader().getZkClient(); - solrClient = solrCloudClient; - solr_cloud_mode = true; - - return true; - } catch (Exception ex) { - logger.severe("Can't connect to Solr server. ZooKeepers=" - + zookeeperHosts + ", collection=" + solr_collection_name - + ex); - return false; - } - } - - private void setHttpClientBuilderForKrb() { - try (Krb5HttpClientBuilder krbBuild = new Krb5HttpClientBuilder()) { - SolrHttpClientBuilder kb = krbBuild.getBuilder(); - HttpClientUtil.setHttpClientBuilder(kb); - } - } + public static Map postDataAndGetResponse(CloudSolrClient cloudClient, String uri, ByteBuffer bytarr) throws IOException { + HttpPost httpPost = null; + HttpEntity entity; + String response = null; + Map m = null; + try { + httpPost = new HttpPost(uri); + + httpPost.setHeader("Content-Type", "application/octet-stream"); + + httpPost.setEntity(new ByteArrayEntity(bytarr.array(), bytarr.arrayOffset(), bytarr.limit())); + entity = cloudClient.getLbClient().getHttpClient().execute(httpPost).getEntity(); + try { + response = EntityUtils.toString(entity, StandardCharsets.UTF_8); + m = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response))); + } catch (JSONParser.ParseException e) { + logger.severe("Error response: " + response); + } + } finally { + httpPost.releaseConnection(); + } + return m; + } - public static Map postDataAndGetResponse(CloudSolrClient cloudClient, - String uri, ByteBuffer bytarr) throws IOException { - HttpPost httpPost = null; - HttpEntity entity; - String response = null; - Map m = null; - try { - httpPost = new HttpPost(uri); + public void run() { + logger.info("Started run method"); + List<String> zookeeperHosts = getZkHosts(); + if (zookeeperHosts != null && !zookeeperHosts.isEmpty() && zookeeperHosts.stream().noneMatch(h -> h.equalsIgnoreCase("none"))) { + logger.info("Solr zkHosts=" + zookeeperHosts + ", collectionName=" + solrCollectionName); + while (!isCompleted && (maxRetry == TRY_UNTIL_SUCCESS || retryCounter < maxRetry)) { + try { + if (connect(zookeeperHosts)) { + if (solrCloudMode) { + if (uploadConfiguration() && createCollection()) { + isCompleted = true; + break; + } else { + logErrorMessageAndWait("Error while performing operations on solr. ", null); + } + } + } else { + logErrorMessageAndWait("Cannot connect to solr kindly check the solr related configs. ", null); + } + } catch (Exception ex) { + logErrorMessageAndWait("Error while configuring solr. ", ex); + } - httpPost.setHeader("Content-Type", "application/octet-stream"); + try { + if (solrCloudClient != null) { + solrCloudClient.close(); + } + } catch (Exception ex) { + logger.log(Level.WARNING, "Error while closing the solr client. ", ex); + } + } + } else { + logger.severe("Solr ZKHosts for Audit are empty. Please set property " + SOLR_ZK_HOSTS); + } + } - httpPost.setEntity(new ByteArrayEntity(bytarr.array(), bytarr - .arrayOffset(), bytarr.limit())); - entity = cloudClient.getLbClient().getHttpClient().execute(httpPost) - .getEntity(); - try { - response = EntityUtils.toString(entity, StandardCharsets.UTF_8); - m = (Map) ObjectBuilder.getVal(new JSONParser( - new StringReader(response))); - } catch (JSONParser.ParseException e) { - logger.severe("Error response: " + response); - } - }finally { - httpPost.releaseConnection(); - } - return m; - } + private boolean connect(List<String> zookeeperHosts) { + try { + logger.info("Solr is in Cloud mode"); + if (isKERBEROS) { + setHttpClientBuilderForKrb(); + } + solrCloudClient = new CloudSolrClient.Builder(zookeeperHosts, Optional.empty()).build(); + solrCloudClient.setDefaultCollection(solrCollectionName); + solrCloudClient.connect(); + zkClient = solrCloudClient.getZkStateReader().getZkClient(); + solrClient = solrCloudClient; + solrCloudMode = true; + return true; + } catch (Exception ex) { + logger.severe("Can't connect to Solr server. ZooKeepers=" + zookeeperHosts + ", collection=" + solrCollectionName + ex); + return false; + } + } - private boolean uploadConfiguration() { - try { - if (zkClient != null) { - ZkConfigManager zkConfigManager = new ZkConfigManager(zkClient); + private void setHttpClientBuilderForKrb() { + try (Krb5HttpClientBuilder krbBuild = new Krb5HttpClientBuilder()) { + SolrHttpClientBuilder kb = krbBuild.getBuilder(); + HttpClientUtil.setHttpClientBuilder(kb); + } + } - boolean configExists = zkConfigManager.configExists(solr_config_name); + private boolean uploadConfiguration() { + try { + if (zkClient != null) { + ZkConfigManager zkConfigManager = new ZkConfigManager(zkClient); + boolean configExists = zkConfigManager.configExists(solrConfigName); if (!configExists) { - try { - logger.info("Config does not exist with name " + solr_config_name); - String zipOfConfigs = null; - if (this.configSetFolder.exists() && this.configSetFolder.isFile()) { - zipOfConfigs = this.configSetFolder.getAbsolutePath(); - } else { - String[] files = this.configSetFolder.list(); - if (files != null) { - for (String aFile : files) { - if (aFile != null) { - if (aFile.equals("solr_audit_conf.zip")) { - zipOfConfigs = this.configSetFolder + "/" + aFile; - break; - } - } - } - } - } - if (zipOfConfigs == null) { - throw new FileNotFoundException( - "Could Not Find Configs Zip File : " + getConfigSetFolder()); - } - File file = new File(zipOfConfigs); - byte[] arrByte = Files.readAllBytes(file.toPath()); - ByteBuffer byteBuffer = ByteBuffer.wrap(arrByte); - String baseUrl = getBaseUrl(); - String protocol = isSSLEnabled ? "https" : "http"; - String uploadConfigsUrl = String.format("%s://%s/admin/configs?action=UPLOAD&name=%s", protocol, - baseUrl.toString(), solr_config_name); - postDataAndGetResponse(solrCloudClient, uploadConfigsUrl, byteBuffer); - return true; - } catch (Exception ex) { - logger.log(Level.SEVERE, "Error while uploading configs : ", ex); - return false; - } - } - else { - logger.info("Config already exists with name " + solr_config_name ); - return true; + try { + logger.info("Config does not exist with name " + solrConfigName); + String zipOfConfigs = null; + if (this.configSetFolder.exists() && this.configSetFolder.isFile()) { + zipOfConfigs = this.configSetFolder.getAbsolutePath(); + } else { + String[] files = this.configSetFolder.list(); + if (files != null) { + for (String aFile : files) { + if (aFile != null) { + if (aFile.equals("solr_audit_conf.zip")) { + zipOfConfigs = this.configSetFolder + "/" + aFile; + break; + } + } + } + } + } + if (zipOfConfigs == null) { + throw new FileNotFoundException("Could Not Find Configs Zip File : " + getConfigSetFolder()); + } + File file = new File(zipOfConfigs); + byte[] arrByte = Files.readAllBytes(file.toPath()); + ByteBuffer byteBuffer = ByteBuffer.wrap(arrByte); + String baseUrl = getBaseUrl(); + String protocol = isSSLEnabled ? "https" : "http"; + String uploadConfigsUrl = String.format("%s://%s/admin/configs?action=UPLOAD&name=%s", protocol, baseUrl, solrConfigName); + postDataAndGetResponse(solrCloudClient, uploadConfigsUrl, byteBuffer); + return true; + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error while uploading configs : ", ex); + return false; + } + } else { + logger.info("Config already exists with name " + solrConfigName); + return true; } - } else { - logger.severe("Solr is in cloud mode and could not find the zookeeper client for performing upload operations. "); - return false; - } - } catch (Exception ex) { - logger.severe("Error while uploading configuration : " + ex); - return false; - } + } else { + logger.severe("Solr is in cloud mode and could not find the zookeeper client for performing upload operations. "); + return false; + } + } catch (Exception ex) { + logger.severe("Error while uploading configuration : " + ex); + return false; + } } - private void logErrorMessageAndWait(String msg, Exception exception) { - retry_counter++; - String attempMessage; - if (max_retry != TRY_UNTIL_SUCCESS) { - attempMessage = (retry_counter == max_retry) ? ("Maximum attempts reached for setting up Solr.") - : ("[retrying after " + time_interval + " ms]. No. of attempts left : " - + (max_retry - retry_counter) + " . Maximum attempts : " + max_retry); - } else { - attempMessage = "[retrying after " + time_interval + " ms]"; - } - StringBuilder errorBuilder = new StringBuilder(); - errorBuilder.append(msg); - if (exception != null) { - errorBuilder.append("Error : ".concat(exception.getMessage() + ". ")); - } - errorBuilder.append(attempMessage); - logger.severe(errorBuilder.toString()); - try { - Thread.sleep(time_interval); - } catch (InterruptedException ex) { - logger.info("sleep interrupted: " + ex.getMessage()); - } - } - - private boolean createCollection() { - try { - List<String> allCollectionList = getCollections(); - if (allCollectionList != null) { - if (!allCollectionList.contains(solr_collection_name)) { - - int shardsCalculation = solrCloudClient != null - ? solrCloudClient.getClusterStateProvider().getLiveNodes().size() - : DEFAULT_VALUE; - int no_of_shards = EmbeddedServerUtil.getIntConfig(SOLR_NO_SHARDS, shardsCalculation); - logger.info("No. of shards provided is : " + no_of_shards); - - CollectionAdminRequest.Create createCollection = CollectionAdminRequest - .createCollection(solr_collection_name, - solr_config_name, no_of_shards, - no_of_replicas); - createCollection.setMaxShardsPerNode(max_node_per_shards); - CollectionAdminResponse createResponse = createCollection - .process(solrClient); - if (createResponse.getStatus() != 0) { - logger.severe("Error creating collection. collectionName=" - + solr_collection_name - + " , solr config name = " - + solr_config_name - + " , replicas = " - + no_of_replicas - + ", shards=" - + no_of_shards - + " , max node per shards = " - + max_node_per_shards - + ", response=" - + createResponse); - return false; - } else { - allCollectionList = getCollections(); - if (allCollectionList != null) { - if(allCollectionList.contains(solr_collection_name)){ - logger.info("Created collection " - + solr_collection_name + " with config name " - + solr_config_name + " replicas = " - + no_of_replicas + " Shards = " + no_of_shards - + " max node per shards = " - + max_node_per_shards); - return true; - } else { - logger.severe("Collection does not exist. collectionName=" - + solr_collection_name - + " , solr config name = " - + solr_config_name - + " , replicas = " - + no_of_replicas - + ", shards=" - + no_of_shards - + " , max node per shards = " - + max_node_per_shards - + ", response=" - + createResponse); - return false; - } - } else { - logger.severe("Error while getting collection list after creating collection"); - return false; - } - } - } else { - logger.info("Collection already exists with name " - + solr_collection_name); - return true; - } - } else { - logger.severe("Error while connecting to solr "); - return false; - } - } catch (Exception ex) { - logger.severe("Error while creating collection in solr : " + ex); - return false; - } - } - - @SuppressWarnings("unchecked") - private List<String> getCollections() throws IOException, ParseException { - try { - CollectionAdminRequest.List colListReq = new CollectionAdminRequest.List(); - CollectionAdminResponse response = colListReq.process(solrClient); - if (response.getStatus() != 0) { - logger.severe("Error getting collection list from solr. response=" - + response); - return null; - } - return (List<String>) response.getResponse().get("collections"); - } catch (SolrException e) { - logger.severe("getCollections() operation failed : " + e); - return null; - } catch (SolrServerException e) { - logger.severe("getCollections() operation failed : " + e); - return null; - } + private void logErrorMessageAndWait(String msg, Exception exception) { + retryCounter++; + String attempMessage; + if (maxRetry != TRY_UNTIL_SUCCESS) { + attempMessage = (retryCounter == maxRetry) ? ("Maximum attempts reached for setting up Solr.") : ("[retrying after " + timeInterval + " ms]. No. of attempts left : " + (maxRetry - retryCounter) + " . Maximum attempts : " + maxRetry); + } else { + attempMessage = "[retrying after " + timeInterval + " ms]"; + } + StringBuilder errorBuilder = new StringBuilder(); + errorBuilder.append(msg); + if (exception != null) { + errorBuilder.append("Error : ".concat(exception.getMessage() + ". ")); + } + errorBuilder.append(attempMessage); + logger.severe(errorBuilder.toString()); + try { + Thread.sleep(timeInterval); + } catch (InterruptedException ex) { + logger.info("sleep interrupted: " + ex.getMessage()); + } + } - } + private boolean createCollection() { + try { + List<String> allCollectionList = getCollections(); + if (allCollectionList != null) { + if (!allCollectionList.contains(solrCollectionName)) { + int shardsCalculation = solrCloudClient != null ? solrCloudClient.getClusterStateProvider().getLiveNodes().size() : DEFAULT_VALUE; + int noOfShards = EmbeddedServerUtil.getIntConfig(SOLR_NO_SHARDS, shardsCalculation); + logger.info("No. of shards provided is : " + noOfShards); + CollectionAdminRequest.Create createCollection = CollectionAdminRequest.createCollection(solrCollectionName, solrConfigName, noOfShards, noOfReplicas); + createCollection.setMaxShardsPerNode(maxNodePerShards); + CollectionAdminResponse createResponse = createCollection.process(solrClient); + if (createResponse.getStatus() != 0) { + logger.severe("Error creating collection. collectionName=" + solrCollectionName + " , solr config name = " + solrConfigName + " , replicas = " + noOfReplicas + ", shards=" + noOfShards + " , max node per shards = " + maxNodePerShards + ", response=" + createResponse); + return false; + } else { + allCollectionList = getCollections(); + if (allCollectionList != null) { + if (allCollectionList.contains(solrCollectionName)) { + logger.info("Created collection " + solrCollectionName + " with config name " + solrConfigName + " replicas = " + noOfReplicas + " Shards = " + noOfShards + " max node per shards = " + maxNodePerShards); + return true; + } else { + logger.severe("Collection does not exist. collectionName=" + solrCollectionName + " , solr config name = " + solrConfigName + " , replicas = " + noOfReplicas + ", shards=" + noOfShards + " , max node per shards = " + maxNodePerShards + ", response=" + createResponse); + return false; + } + } else { + logger.severe("Error while getting collection list after creating collection"); + return false; + } + } + } else { + logger.info("Collection already exists with name " + solrCollectionName); + return true; + } + } else { + logger.severe("Error while connecting to solr "); + return false; + } + } catch (Exception ex) { + logger.severe("Error while creating collection in solr : " + ex); + return false; + } + } - private File getConfigSetFolder() { - return configSetFolder; - } + @SuppressWarnings("unchecked") + private List<String> getCollections() throws IOException { + try { + CollectionAdminRequest.List colListReq = new CollectionAdminRequest.List(); + CollectionAdminResponse response = colListReq.process(solrClient); + if (response.getStatus() != 0) { + logger.severe("Error getting collection list from solr. response=" + response); + return null; + } + return (List<String>) response.getResponse().get("collections"); + } catch (SolrException e) { + logger.severe("getCollections() operation failed : " + e); + return null; + } catch (SolrServerException e) { + logger.severe("getCollections() operation failed : " + e); + return null; + } + } - private static List<String> getZkHosts() { - String zkHosts = ""; - List<String> zookeeperHosts = null; - if (!StringUtil.isEmpty(EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS))) { - zkHosts = EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS).trim(); - zookeeperHosts = new ArrayList<String>(Arrays.asList(zkHosts.split(","))); - } - return zookeeperHosts; - } + private File getConfigSetFolder() { + return configSetFolder; + } - private String getBaseUrl() throws Exception { - Set<String> nodes = solrCloudClient.getClusterStateProvider().getLiveNodes(); - if (CollectionUtils.isEmpty(nodes)) { - throw new Exception("No live SolrServers available"); - } - String[] nodeArr = nodes.toArray(new String[0]); - // getting nodes URL as 'port_solr', so converting it to 'port/solr' - return nodeArr[0].replaceAll("_", "/"); - } + private static List<String> getZkHosts() { + String zkHosts = ""; + List<String> zookeeperHosts = null; + if (!StringUtil.isEmpty(EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS))) { + zkHosts = EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS).trim(); + zookeeperHosts = new ArrayList<String>(Arrays.asList(zkHosts.split(","))); + } + return zookeeperHosts; + } + private String getBaseUrl() throws Exception { + Set<String> nodes = solrCloudClient.getClusterStateProvider().getLiveNodes(); + if (CollectionUtils.isEmpty(nodes)) { + throw new Exception("No live SolrServers available"); + } + String[] nodeArr = nodes.toArray(new String[0]); + // getting nodes URL as 'port_solr', so converting it to 'port/solr' + return nodeArr[0].replaceAll("_", "/"); + } } diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/StopEmbeddedServer.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/StopEmbeddedServer.java index d838b09dc..6e3cfbbc7 100644 --- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/StopEmbeddedServer.java +++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/StopEmbeddedServer.java @@ -23,24 +23,23 @@ import java.io.PrintWriter; import java.net.Socket; public class StopEmbeddedServer extends EmbeddedServer { - private static final String SHUTDOWN_HOSTNAME = "localhost"; - public static void main(String[] args) { - new StopEmbeddedServer(args).stop(); - } - public StopEmbeddedServer(String[] args) { super(args); } - public void stop() { + public static void main(String[] args) { + new StopEmbeddedServer(args).stop(); + } - int shutdownPort = EmbeddedServerUtil.getIntConfig("ranger.service.shutdown.port", DEFAULT_SHUTDOWN_PORT); - String shutdownCommand = EmbeddedServerUtil.getConfig("ranger.service.shutdown.command", DEFAULT_SHUTDOWN_COMMAND); + public void stop() { + int shutdownPort = EmbeddedServerUtil.getIntConfig("ranger.service.shutdown.port", defaultShutdownPort); + String shutdownCommand = EmbeddedServerUtil.getConfig("ranger.service.shutdown.command", defaultShutdownCommand); - try (Socket sock = new Socket(SHUTDOWN_HOSTNAME, shutdownPort); - PrintWriter out = new PrintWriter(sock.getOutputStream(), true)) { + try { + Socket sock = new Socket(SHUTDOWN_HOSTNAME, shutdownPort); + PrintWriter out = new PrintWriter(sock.getOutputStream(), true); out.println(shutdownCommand); out.flush(); } catch (Throwable t) { @@ -48,5 +47,4 @@ public class StopEmbeddedServer extends EmbeddedServer { System.exit(1); } } - }
