You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ol...@apache.org on 2017/03/29 13:57:45 UTC
[37/67] [abbrv] ambari git commit: AMBARI-20541. Rename
ambari-logsearch-solr-client module to ambari-infra-solr-client (oleewere)
AMBARI-20541. Rename ambari-logsearch-solr-client module to ambari-infra-solr-client (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c5ccb1ab
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c5ccb1ab
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c5ccb1ab
Branch: refs/heads/branch-dev-logsearch
Commit: c5ccb1ab7f09762db0e9a812770e3c3fbe1e848d
Parents: b0f1e34
Author: oleewere <ol...@gmail.com>
Authored: Thu Mar 23 13:26:48 2017 +0100
Committer: oleewere <ol...@gmail.com>
Committed: Mon Mar 27 21:13:39 2017 +0200
----------------------------------------------------------------------
.../ambari-infra-solr-client/build.xml | 56 ++
.../ambari-infra-solr-client/pom.xml | 125 ++++
.../ambari/infra/solr/AmbariSolrCloudCLI.java | 565 +++++++++++++++++++
.../infra/solr/AmbariSolrCloudClient.java | 334 +++++++++++
.../solr/AmbariSolrCloudClientBuilder.java | 215 +++++++
.../solr/AmbariSolrCloudClientException.java | 28 +
.../solr/commands/AbstractRetryCommand.java | 58 ++
.../solr/commands/AbstractSolrRetryCommand.java | 53 ++
.../commands/AbstractStateFileZkCommand.java | 42 ++
.../AbstractZookeeperConfigCommand.java | 44 ++
.../commands/AbstractZookeeperRetryCommand.java | 40 ++
.../solr/commands/CheckConfigZkCommand.java | 34 ++
.../solr/commands/CheckZnodeZkCommand.java | 45 ++
.../solr/commands/CreateCollectionCommand.java | 62 ++
.../infra/solr/commands/CreateShardCommand.java | 51 ++
.../solr/commands/CreateSolrZnodeZkCommand.java | 42 ++
.../solr/commands/DownloadConfigZkCommand.java | 47 ++
.../EnableKerberosPluginSolrZkCommand.java | 88 +++
.../infra/solr/commands/GetShardsCommand.java | 39 ++
.../solr/commands/GetSolrHostsCommand.java | 53 ++
.../solr/commands/GetStateFileZkCommand.java | 43 ++
.../solr/commands/ListCollectionCommand.java | 49 ++
.../solr/commands/SecureSolrZNodeZkCommand.java | 86 +++
.../solr/commands/SecureZNodeZkCommand.java | 49 ++
.../commands/SetClusterPropertyZkCommand.java | 40 ++
.../solr/commands/UpdateStateFileZkCommand.java | 84 +++
.../solr/commands/UploadConfigZkCommand.java | 41 ++
.../infra/solr/domain/AmbariSolrState.java | 26 +
.../apache/ambari/infra/solr/util/AclUtils.java | 85 +++
.../ambari/infra/solr/util/ShardUtils.java | 71 +++
.../src/main/resources/log4j.properties | 31 +
.../src/main/resources/solrCloudCli.sh | 20 +
.../infra/solr/AmbariSolrCloudClientTest.java | 134 +++++
.../ambari-logsearch-assembly/pom.xml | 6 +-
ambari-logsearch/ambari-logsearch-it/pom.xml | 2 +-
.../ambari-logsearch-solr-client/build.xml | 56 --
.../ambari-logsearch-solr-client/pom.xml | 125 ----
.../logsearch/solr/AmbariSolrCloudCLI.java | 565 -------------------
.../logsearch/solr/AmbariSolrCloudClient.java | 334 -----------
.../solr/AmbariSolrCloudClientBuilder.java | 215 -------
.../solr/AmbariSolrCloudClientException.java | 28 -
.../solr/commands/AbstractRetryCommand.java | 58 --
.../solr/commands/AbstractSolrRetryCommand.java | 53 --
.../commands/AbstractStateFileZkCommand.java | 42 --
.../AbstractZookeeperConfigCommand.java | 44 --
.../commands/AbstractZookeeperRetryCommand.java | 40 --
.../solr/commands/CheckConfigZkCommand.java | 34 --
.../solr/commands/CheckZnodeZkCommand.java | 45 --
.../solr/commands/CreateCollectionCommand.java | 62 --
.../solr/commands/CreateShardCommand.java | 51 --
.../solr/commands/CreateSolrZnodeZkCommand.java | 42 --
.../solr/commands/DownloadConfigZkCommand.java | 47 --
.../EnableKerberosPluginSolrZkCommand.java | 88 ---
.../solr/commands/GetShardsCommand.java | 39 --
.../solr/commands/GetSolrHostsCommand.java | 53 --
.../solr/commands/GetStateFileZkCommand.java | 43 --
.../solr/commands/ListCollectionCommand.java | 49 --
.../solr/commands/SecureSolrZNodeZkCommand.java | 87 ---
.../solr/commands/SecureZNodeZkCommand.java | 49 --
.../commands/SetClusterPropertyZkCommand.java | 40 --
.../solr/commands/UpdateStateFileZkCommand.java | 84 ---
.../solr/commands/UploadConfigZkCommand.java | 42 --
.../logsearch/solr/domain/AmbariSolrState.java | 26 -
.../ambari/logsearch/solr/util/AclUtils.java | 87 ---
.../ambari/logsearch/solr/util/ShardUtils.java | 71 ---
.../src/main/resources/log4j.properties | 31 -
.../src/main/resources/solrCloudCli.sh | 20 -
.../solr/AmbariSolrCloudClientTest.java | 134 -----
ambari-logsearch/docker/Dockerfile | 4 +-
ambari-logsearch/pom.xml | 2 +-
70 files changed, 2787 insertions(+), 2791 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/build.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/build.xml b/ambari-logsearch/ambari-infra-solr-client/build.xml
new file mode 100644
index 0000000..a54e336
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/build.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project basedir="." default="build" name="logsearch">
+ <property environment="env"/>
+ <property name="debuglevel" value="source,lines,vars"/>
+ <dirname property="builddir" file="build.xml"/>
+ <property name="target" value="1.7"/>
+ <property name="source" value="1.7"/>
+ <target name="init">
+ </target>
+ <target name="build"/>
+
+ <target name="package">
+ <delete dir="target/package"/>
+ <copy todir="target/package/libs" includeEmptyDirs="no">
+ <fileset dir="target/libs"/>
+ </copy>
+ <copy todir="target/package/libs" includeEmptyDirs="no">
+ <fileset file="target/*.jar"/>
+ </copy>
+ <copy todir="target/package" includeEmptyDirs="no">
+ <fileset file="src/main/resources/solrCloudCli.sh"/>
+ </copy>
+ <copy todir="target/package" includeEmptyDirs="no">
+ <fileset file="src/main/resources/log4j.properties"/>
+ </copy>
+ <chmod file="target/package/*.sh" perm="755"/>
+ <tar compression="gzip" destfile="target/ambari-infra-solr-client.tar.gz">
+ <tarfileset mode="755" dir="target/package">
+ <include name="*.sh"/>
+ </tarfileset>
+ <tarfileset mode="664" dir="target/package">
+ <exclude name="*.sh"/>
+ </tarfileset>
+ </tar>
+
+ </target>
+
+ <target description="Build all projects which reference this project. Useful to propagate changes."
+ name="build-refprojects"/>
+</project>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/pom.xml b/ambari-logsearch/ambari-infra-solr-client/pom.xml
new file mode 100644
index 0000000..228d969
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>ambari-logsearch</artifactId>
+ <groupId>org.apache.ambari</groupId>
+ <version>2.0.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://maven.apache.org</url>
+ <name>Ambari Infra Solr Client</name>
+
+ <artifactId>ambari-infra-solr-client</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.solr</groupId>
+ <artifactId>solr-solrj</artifactId>
+ <version>${solr.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>3.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.8</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
+ <outputDirectory>${basedir}/target/libs</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>false</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.7</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <ant antfile="build.xml">
+ <target name="package"/>
+ </ant>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudCLI.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudCLI.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudCLI.java
new file mode 100644
index 0000000..5cde9ea
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudCLI.java
@@ -0,0 +1,565 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ambari.infra.solr;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class AmbariSolrCloudCLI {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AmbariSolrCloudCLI.class);
+
+ private static final int ZK_CLIENT_TIMEOUT = 15000;
+ private static final int ZK_CLIENT_CONNECT_TIMEOUT = 15000;
+ private static final String CREATE_COLLECTION_COMMAND = "create-collection";
+ private static final String UPLOAD_CONFIG_COMMAND = "upload-config";
+ private static final String DOWNLOAD_CONFIG_COMMAND = "download-config";
+ private static final String CONFIG_CHECK_COMMAND = "check-config";
+ private static final String CREATE_SHARD_COMMAND = "create-shard";
+ private static final String CREATE_ZNODE = "create-znode";
+ private static final String SET_CLUSTER_PROP = "cluster-prop";
+ private static final String SETUP_KERBEROS_PLUGIN = "setup-kerberos-plugin";
+ private static final String CHECK_ZNODE = "check-znode";
+ private static final String SECURE_ZNODE_COMMAND = "secure-znode";
+ private static final String SECURE_SOLR_ZNODE_COMMAND = "secure-solr-znode";
+ private static final String SECURITY_JSON_LOCATION = "security-json-location";
+ private static final String CMD_LINE_SYNTAX =
+ "\n./solrCloudCli.sh --create-collection -z host1:2181,host2:2181/ambari-solr -c collection -cs conf_set"
+ + "\n./solrCloudCli.sh --upload-config -z host1:2181,host2:2181/ambari-solr -d /tmp/myconfig_dir -cs config_set"
+ + "\n./solrCloudCli.sh --download-config -z host1:2181,host2:2181/ambari-solr -cs config_set -d /tmp/myonfig_dir"
+ + "\n./solrCloudCli.sh --check-config -z host1:2181,host2:2181/ambari-solr -cs config_set"
+ + "\n./solrCloudCli.sh --create-shard -z host1:2181,host2:2181/ambari-solr -c collection -sn myshard"
+ + "\n./solrCloudCli.sh --create-znode -z host1:2181,host2:2181 -zn /ambari-solr"
+ + "\n./solrCloudCli.sh --check-znode -z host1:2181,host2:2181 -zn /ambari-solr"
+ + "\n./solrCloudCli.sh --cluster-prop -z host1:2181,host2:2181/ambari-solr -cpn urlScheme -cpn http"
+ + "\n./solrCloudCli.sh --secure-znode -z host1:2181,host2:2181 -zn /ambari-solr -su logsearch,atlas,ranger --jaas-file /etc/myconf/jaas_file"
+ + "\n./solrCloudCli.sh --secure-solr-znode -z host1:2181,host2:2181 -zn /ambari-solr -su logsearch,atlas,ranger --jaas-file /etc/myconf/jaas_file"
+ + "\n./solrCloudCli.sh --setup-kerberos-plugin -z host1:2181,host2:2181 -zn /ambari-solr --security-json-location /etc/infra-solr/conf/security.json\n";
+
+ public static void main(String[] args) {
+ Options options = new Options();
+ HelpFormatter helpFormatter = new HelpFormatter();
+ helpFormatter.setDescPadding(10);
+ helpFormatter.setWidth(200);
+
+ final Option helpOption = Option.builder("h")
+ .longOpt("help")
+ .desc("Print commands")
+ .build();
+
+ final Option createCollectionOption = Option.builder("cc")
+ .longOpt(CREATE_COLLECTION_COMMAND)
+ .desc("Create collection in Solr (command)")
+ .build();
+
+ final Option uploadConfigurationOption = Option.builder("uc")
+ .longOpt(UPLOAD_CONFIG_COMMAND)
+ .desc("Upload configuration set to Zookeeper (command)")
+ .build();
+
+ final Option downloadConfigOption = Option.builder("dc")
+ .longOpt(DOWNLOAD_CONFIG_COMMAND)
+ .desc("Download configuration set from Zookeeper (command)")
+ .build();
+
+ final Option checkConfigOption = Option.builder("chc")
+ .longOpt(CONFIG_CHECK_COMMAND)
+ .desc("Check configuration exists in Zookeeper (command)")
+ .build();
+
+ final Option checkZnodeOption = Option.builder("chz")
+ .longOpt(CHECK_ZNODE)
+ .desc("Check znode exists in Zookeeper (command)")
+ .build();
+
+ final Option createShardOption = Option.builder("csh")
+ .longOpt(CREATE_SHARD_COMMAND)
+ .desc("Create shard in Solr (command)")
+ .build();
+
+ final Option setClusterPropOption = Option.builder("cp")
+ .longOpt(SET_CLUSTER_PROP)
+ .desc("Set cluster property (command)")
+ .build();
+
+ final Option createZnodeOption = Option.builder("cz")
+ .longOpt(CREATE_ZNODE)
+ .desc("Create Znode (command)")
+ .build();
+
+ final Option setupKerberosPluginOption = Option.builder("skp")
+ .longOpt(SETUP_KERBEROS_PLUGIN)
+ .desc("Setup kerberos plugin in security.json (command)")
+ .build();
+
+ final Option secureSolrZnodeOption = Option.builder("ssz")
+ .longOpt(SECURE_SOLR_ZNODE_COMMAND)
+ .desc("Set acls for solr znode")
+ .build();
+
+ final Option secureZnodeOption = Option.builder("sz")
+ .longOpt(SECURE_ZNODE_COMMAND)
+ .desc("Set acls for znode")
+ .build();
+
+ final Option shardNameOption = Option.builder("sn")
+ .longOpt("shard-name")
+ .desc("Name of the shard for create-shard command")
+ .numberOfArgs(1)
+ .argName("my_new_shard")
+ .build();
+
+ final Option disableShardingOption = Option.builder("ns")
+ .longOpt("no-sharding")
+ .desc("Sharding not used when creating collection")
+ .build();
+
+ final Option zkConnectStringOption = Option.builder("z")
+ .longOpt("zookeeper-connect-string")
+ .desc("Zookeeper quorum [and Znode (optional)]")
+ .numberOfArgs(1)
+ .argName("host:port,host:port[/ambari-solr]")
+ .build();
+
+ final Option znodeOption = Option.builder("zn")
+ .longOpt("znode")
+ .desc("Zookeeper ZNode")
+ .numberOfArgs(1)
+ .argName("/ambari-solr")
+ .build();
+
+ final Option collectionOption = Option.builder("c")
+ .longOpt("collection")
+ .desc("Collection name")
+ .numberOfArgs(1)
+ .argName("collection name")
+ .build();
+
+ final Option configSetOption = Option.builder("cs")
+ .longOpt("config-set")
+ .desc("Configuration set")
+ .numberOfArgs(1)
+ .argName("config_set")
+ .build();
+
+ final Option configDirOption = Option.builder("d")
+ .longOpt("config-dir")
+ .desc("Configuration directory")
+ .numberOfArgs(1)
+ .argName("config_dir")
+ .build();
+
+ final Option shardsOption = Option.builder("s")
+ .longOpt("shards")
+ .desc("Number of shards")
+ .numberOfArgs(1)
+ .argName("shard number")
+ .type(Integer.class)
+ .build();
+
+ final Option replicationOption = Option.builder("r")
+ .longOpt("replication")
+ .desc("Replication factor")
+ .numberOfArgs(1)
+ .argName("replication factor")
+ .type(Integer.class)
+ .build();
+
+ final Option retryOption = Option.builder("rt")
+ .longOpt("retry")
+ .desc("Number of retries for access Solr [default:10]")
+ .numberOfArgs(1)
+ .argName("number of retries")
+ .type(Integer.class)
+ .build();
+
+ final Option intervalOption = Option.builder("i")
+ .longOpt("interval")
+ .desc("Interval for retry logic in sec [default:5]")
+ .numberOfArgs(1)
+ .argName("interval")
+ .type(Integer.class)
+ .build();
+
+ final Option maxShardsOption = Option.builder("m")
+ .longOpt("max-shards")
+ .desc("Max number of shards per node (default: replication * shards)")
+ .numberOfArgs(1)
+ .argName("max number of shards")
+ .build();
+
+ final Option routerNameOption = Option.builder("rn")
+ .longOpt("router-name")
+ .desc("Router name for collection [default:implicit]")
+ .numberOfArgs(1)
+ .argName("router_name")
+ .build();
+
+ final Option routerFieldOption = Option.builder("rf")
+ .longOpt("router-field")
+ .desc("Router field for collection [default:_router_field_]")
+ .numberOfArgs(1)
+ .argName("router_field")
+ .build();
+
+ final Option jaasFileOption = Option.builder("jf")
+ .longOpt("jaas-file")
+ .desc("Location of the jaas-file to communicate with kerberized Solr")
+ .numberOfArgs(1)
+ .argName("jaas_file")
+ .build();
+
+ final Option keyStoreLocationOption = Option.builder("ksl")
+ .longOpt("key-store-location")
+ .desc("Location of the key store used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("key store location")
+ .build();
+
+ final Option keyStorePasswordOption = Option.builder("ksp")
+ .longOpt("key-store-password")
+ .desc("Key store password used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("key store password")
+ .build();
+
+ final Option keyStoreTypeOption = Option.builder("kst")
+ .longOpt("key-store-type")
+ .desc("Type of the key store used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("key store type")
+ .build();
+
+ final Option trustStoreLocationOption = Option.builder("tsl")
+ .longOpt("trust-store-location")
+ .desc("Location of the trust store used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("trust store location")
+ .build();
+
+ final Option trustStorePasswordOption = Option.builder("tsp")
+ .longOpt("trust-store-password")
+ .desc("Trust store password used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("trust store password")
+ .build();
+
+ final Option trustStoreTypeOption = Option.builder("tst")
+ .longOpt("trust-store-type")
+ .desc("Type of the trust store used to communicate with Solr using SSL")
+ .numberOfArgs(1)
+ .argName("trust store type")
+ .build();
+
+ final Option propNameOption = Option.builder("cpn")
+ .longOpt("property-name")
+ .desc("Cluster property name")
+ .numberOfArgs(1)
+ .argName("cluster prop name")
+ .build();
+
+ final Option propValueOption = Option.builder("cpv")
+ .longOpt("property-value")
+ .desc("Cluster property value")
+ .numberOfArgs(1)
+ .argName("cluster prop value")
+ .build();
+
+ final Option copyFromZnodeOption = Option.builder("cfz")
+ .longOpt("copy-from-znode")
+ .desc("Copy-from-znode")
+ .numberOfArgs(1)
+ .argName("/ambari-solr-secure")
+ .build();
+
+ final Option saslUsersOption = Option.builder("su")
+ .longOpt("sasl-users")
+ .desc("Sasl users (comma separated list)")
+ .numberOfArgs(1)
+ .argName("atlas,ranger,logsearch-solr")
+ .build();
+
+ final Option securityJsonLocationOption = Option.builder("sjl")
+ .longOpt(SECURITY_JSON_LOCATION)
+ .desc("Local security.json path")
+ .numberOfArgs(1)
+ .argName("security.json location")
+ .build();
+
+ final Option secureOption = Option.builder("sec")
+ .longOpt("secure")
+ .desc("Flag for enable/disable kerberos (with --setup-kerberos or --setup-kerberos-plugin)")
+ .build();
+
+ options.addOption(helpOption);
+ options.addOption(retryOption);
+ options.addOption(intervalOption);
+ options.addOption(zkConnectStringOption);
+ options.addOption(configSetOption);
+ options.addOption(configDirOption);
+ options.addOption(collectionOption);
+ options.addOption(secureZnodeOption);
+ options.addOption(secureSolrZnodeOption);
+ options.addOption(shardsOption);
+ options.addOption(replicationOption);
+ options.addOption(maxShardsOption);
+ options.addOption(routerNameOption);
+ options.addOption(routerFieldOption);
+ options.addOption(shardNameOption);
+ options.addOption(disableShardingOption);
+ options.addOption(createCollectionOption);
+ options.addOption(downloadConfigOption);
+ options.addOption(uploadConfigurationOption);
+ options.addOption(checkConfigOption);
+ options.addOption(createShardOption);
+ options.addOption(jaasFileOption);
+ options.addOption(keyStoreLocationOption);
+ options.addOption(keyStorePasswordOption);
+ options.addOption(keyStoreTypeOption);
+ options.addOption(trustStoreLocationOption);
+ options.addOption(trustStorePasswordOption);
+ options.addOption(trustStoreTypeOption);
+ options.addOption(setClusterPropOption);
+ options.addOption(propNameOption);
+ options.addOption(propValueOption);
+ options.addOption(createZnodeOption);
+ options.addOption(znodeOption);
+ options.addOption(secureOption);
+ options.addOption(copyFromZnodeOption);
+ options.addOption(saslUsersOption);
+ options.addOption(checkZnodeOption);
+ options.addOption(setupKerberosPluginOption);
+ options.addOption(securityJsonLocationOption);
+
+ AmbariSolrCloudClient solrCloudClient = null;
+
+ try {
+ CommandLineParser cmdLineParser = new DefaultParser();
+ CommandLine cli = cmdLineParser.parse(options, args);
+
+ if(cli.hasOption('h')) {
+ helpFormatter.printHelp("sample", options);
+ exit(0, null);
+ }
+ String command = "";
+ if (cli.hasOption("cc")) {
+ command = CREATE_COLLECTION_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, collectionOption, configSetOption);
+ } else if (cli.hasOption("uc")) {
+ command = UPLOAD_CONFIG_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, configSetOption, configDirOption);
+ } else if (cli.hasOption("dc")) {
+ command = DOWNLOAD_CONFIG_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, configSetOption, configDirOption);
+ } else if (cli.hasOption("csh")) {
+ command = CREATE_SHARD_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, collectionOption, shardNameOption);
+ } else if (cli.hasOption("chc")) {
+ command = CONFIG_CHECK_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, configSetOption);
+ } else if (cli.hasOption("cp")) {
+ command = SET_CLUSTER_PROP;
+ validateRequiredOptions(cli, command, zkConnectStringOption, propNameOption, propValueOption);
+ } else if (cli.hasOption("cz")) {
+ command = CREATE_ZNODE;
+ validateRequiredOptions(cli, command, zkConnectStringOption, znodeOption);
+ } else if (cli.hasOption("chz")){
+ command = CHECK_ZNODE;
+ validateRequiredOptions(cli, command, zkConnectStringOption, znodeOption);
+ } else if (cli.hasOption("skp")) {
+ command = SETUP_KERBEROS_PLUGIN;
+ validateRequiredOptions(cli, command, zkConnectStringOption, znodeOption);
+ } else if (cli.hasOption("sz")) {
+ command = SECURE_ZNODE_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, znodeOption, jaasFileOption, saslUsersOption);
+ } else if (cli.hasOption("ssz")) {
+ command = SECURE_SOLR_ZNODE_COMMAND;
+ validateRequiredOptions(cli, command, zkConnectStringOption, znodeOption, jaasFileOption, saslUsersOption);
+ } else {
+ List<String> commands = Arrays.asList(CREATE_COLLECTION_COMMAND, CREATE_SHARD_COMMAND, UPLOAD_CONFIG_COMMAND,
+ DOWNLOAD_CONFIG_COMMAND, CONFIG_CHECK_COMMAND, SET_CLUSTER_PROP, CREATE_ZNODE, SECURE_ZNODE_COMMAND,
+ SECURE_SOLR_ZNODE_COMMAND, CHECK_ZNODE, SETUP_KERBEROS_PLUGIN);
+ helpFormatter.printHelp(CMD_LINE_SYNTAX, options);
+ exit(1, String.format("One of the supported commands is required (%s)", StringUtils.join(commands, "|")));
+ }
+
+ String zkConnectString = cli.getOptionValue('z');
+ String collection = cli.getOptionValue('c');
+ String configSet = cli.getOptionValue("cs");
+ String configDir = cli.getOptionValue("d");
+ int shards = cli.hasOption('s') ? Integer.parseInt(cli.getOptionValue('s')) : 1;
+ int replication = cli.hasOption('r') ? Integer.parseInt(cli.getOptionValue('r')) : 1;
+ int retry = cli.hasOption("rt") ? Integer.parseInt(cli.getOptionValue("rt")) : 5;
+ int interval = cli.hasOption('i') ? Integer.parseInt(cli.getOptionValue('i')) : 10;
+ int maxShards = cli.hasOption('m') ? Integer.parseInt(cli.getOptionValue('m')) : shards * replication;
+ String routerName = cli.hasOption("rn") ? cli.getOptionValue("rn") : null;
+ String routerField = cli.hasOption("rf") ? cli.getOptionValue("rf") : null;
+ String shardName = cli.hasOption("sn") ? cli.getOptionValue("sn") : null;
+ boolean isSplitting = !cli.hasOption("ns");
+ String jaasFile = cli.hasOption("jf") ? cli.getOptionValue("jf") : null;
+ String keyStoreLocation = cli.hasOption("ksl") ? cli.getOptionValue("ksl") : null;
+ String keyStorePassword = cli.hasOption("ksp") ? cli.getOptionValue("ksp") : null;
+ String keyStoreType = cli.hasOption("kst") ? cli.getOptionValue("kst") : null;
+ String trustStoreLocation = cli.hasOption("tsl") ? cli.getOptionValue("tsl") : null;
+ String trustStorePassword = cli.hasOption("tsp") ? cli.getOptionValue("tsp") : null;
+ String trustStoreType = cli.hasOption("tst") ? cli.getOptionValue("tst") : null;
+ String clusterPropName = cli.hasOption("cpn") ? cli.getOptionValue("cpn") : null;
+ String clusterPropValue = cli.hasOption("cpv") ? cli.getOptionValue("cpv") : null;
+ String znode = cli.hasOption("zn") ? cli.getOptionValue("zn") : null;
+ boolean isSecure = cli.hasOption("sec");
+ String saslUsers = cli.hasOption("su") ? cli.getOptionValue("su") : "";
+ String securityJsonLocation = cli.hasOption("sjl") ? cli.getOptionValue("sjl") : "";
+
+ AmbariSolrCloudClientBuilder clientBuilder = new AmbariSolrCloudClientBuilder()
+ .withZkConnectString(zkConnectString)
+ .withCollection(collection)
+ .withConfigSet(configSet)
+ .withShards(shards)
+ .withReplication(replication)
+ .withMaxShardsPerNode(maxShards)
+ .withRetry(retry)
+ .withInterval(interval)
+ .withRouterName(routerName)
+ .withRouterField(routerField)
+ .withJaasFile(jaasFile) // call before creating SolrClient
+ .withSplitting(isSplitting)
+ .withSolrZkClient(ZK_CLIENT_TIMEOUT, ZK_CLIENT_CONNECT_TIMEOUT)
+ .withKeyStoreLocation(keyStoreLocation)
+ .withKeyStorePassword(keyStorePassword)
+ .withKeyStoreType(keyStoreType)
+ .withTrustStoreLocation(trustStoreLocation)
+ .withTrustStorePassword(trustStorePassword)
+ .withTrustStoreType(trustStoreType)
+ .withClusterPropName(clusterPropName)
+ .withClusterPropValue(clusterPropValue)
+ .withSecurityJsonLocation(securityJsonLocation)
+ .withZnode(znode)
+ .withSecure(isSecure)
+ .withSaslUsers(saslUsers);
+
+ switch (command) {
+ case CREATE_COLLECTION_COMMAND:
+ solrCloudClient = clientBuilder
+ .withSolrCloudClient()
+ .build();
+ solrCloudClient.createCollection();
+ break;
+ case UPLOAD_CONFIG_COMMAND:
+ solrCloudClient = clientBuilder
+ .withConfigDir(configDir)
+ .build();
+ solrCloudClient.uploadConfiguration();
+ break;
+ case DOWNLOAD_CONFIG_COMMAND:
+ solrCloudClient = clientBuilder
+ .withConfigDir(configDir)
+ .build();
+ solrCloudClient.downloadConfiguration();
+ break;
+ case CONFIG_CHECK_COMMAND:
+ solrCloudClient = clientBuilder.build();
+ boolean configExists = solrCloudClient.configurationExists();
+ if (!configExists) {
+ exit(1, null);
+ }
+ break;
+ case CREATE_SHARD_COMMAND:
+ solrCloudClient = clientBuilder
+ .withSolrCloudClient()
+ .build();
+ solrCloudClient.createShard(shardName);
+ break;
+ case SET_CLUSTER_PROP:
+ solrCloudClient = clientBuilder.build();
+ solrCloudClient.setClusterProp();
+ break;
+ case CREATE_ZNODE:
+ solrCloudClient = clientBuilder.build();
+ solrCloudClient.createZnode();
+ break;
+ case CHECK_ZNODE:
+ solrCloudClient = clientBuilder.build();
+ boolean znodeExists = solrCloudClient.isZnodeExists(znode);
+ if (!znodeExists) {
+ exit(1, String.format("'%s' znode does not exist. Solr is responsible to create the ZNode, " +
+ "check Solr started successfully or not", znode));
+ }
+ break;
+ case SETUP_KERBEROS_PLUGIN:
+ solrCloudClient = clientBuilder.build();
+ solrCloudClient.setupKerberosPlugin();
+ break;
+ case SECURE_ZNODE_COMMAND:
+ solrCloudClient = clientBuilder.build();
+ solrCloudClient.secureZnode();
+ break;
+ case SECURE_SOLR_ZNODE_COMMAND:
+ solrCloudClient = clientBuilder.build();
+ solrCloudClient.secureSolrZnode();
+ break;
+ default:
+ throw new AmbariSolrCloudClientException(String.format("Not found command: '%s'", command));
+ }
+ } catch (Exception e) {
+ helpFormatter.printHelp(
+ CMD_LINE_SYNTAX, options);
+ exit(1, e.getMessage());
+ } finally {
+ if (solrCloudClient != null && solrCloudClient.getSolrZkClient() != null) {
+ solrCloudClient.getSolrZkClient().close();
+ }
+ }
+ exit(0, null);
+ }
+
+ private static void validateRequiredOptions(CommandLine cli, String command, Option... optionsToValidate)
+ throws AmbariSolrCloudClientException {
+ List<String> requiredOptions = new ArrayList<>();
+ for (Option opt : optionsToValidate) {
+ if (!cli.hasOption(opt.getOpt())) {
+ requiredOptions.add(opt.getOpt());
+ }
+ }
+ if (!requiredOptions.isEmpty()) {
+ throw new AmbariSolrCloudClientException(
+ String.format("The following options required for '%s' : %s",
+ command, StringUtils.join(requiredOptions, ",")));
+ }
+ }
+
+ private static void exit(int exitCode, String message) {
+ if (message != null){
+ LOG.error(message);
+ }
+ LOG.info("Return code: {}", exitCode);
+ System.exit(exitCode);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClient.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClient.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClient.java
new file mode 100644
index 0000000..ff28664
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClient.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr;
+
+import org.apache.ambari.infra.solr.commands.CheckConfigZkCommand;
+import org.apache.ambari.infra.solr.commands.CreateCollectionCommand;
+import org.apache.ambari.infra.solr.commands.CreateShardCommand;
+import org.apache.ambari.infra.solr.commands.CreateSolrZnodeZkCommand;
+import org.apache.ambari.infra.solr.commands.DownloadConfigZkCommand;
+import org.apache.ambari.infra.solr.commands.EnableKerberosPluginSolrZkCommand;
+import org.apache.ambari.infra.solr.commands.GetShardsCommand;
+import org.apache.ambari.infra.solr.commands.GetSolrHostsCommand;
+import org.apache.ambari.infra.solr.commands.ListCollectionCommand;
+import org.apache.ambari.infra.solr.commands.SecureSolrZNodeZkCommand;
+import org.apache.ambari.infra.solr.commands.SecureZNodeZkCommand;
+import org.apache.ambari.infra.solr.commands.SetClusterPropertyZkCommand;
+import org.apache.ambari.infra.solr.commands.UploadConfigZkCommand;
+import org.apache.ambari.infra.solr.commands.CheckZnodeZkCommand;
+import org.apache.ambari.infra.solr.util.ShardUtils;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Client for communicate with Solr (and Zookeeper)
+ */
+public class AmbariSolrCloudClient {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AmbariSolrCloudClient.class);
+
+ private final String zkConnectString;
+ private final String collection;
+ private final String configSet;
+ private final String configDir;
+ private final int shards;
+ private final int replication;
+ private final int retryTimes;
+ private final int interval;
+ private final CloudSolrClient solrCloudClient;
+ private final SolrZkClient solrZkClient;
+ private final int maxShardsPerNode;
+ private final String routerName;
+ private final String routerField;
+ private final boolean splitting;
+ private final String jaasFile;
+ private final String znode;
+ private final String saslUsers;
+ private final String propName;
+ private final String propValue;
+ private final String securityJsonLocation;
+ private final boolean secure;
+
+ public AmbariSolrCloudClient(AmbariSolrCloudClientBuilder builder) {
+ this.zkConnectString = builder.zkConnectString;
+ this.collection = builder.collection;
+ this.configSet = builder.configSet;
+ this.configDir = builder.configDir;
+ this.shards = builder.shards;
+ this.replication = builder.replication;
+ this.retryTimes = builder.retryTimes;
+ this.interval = builder.interval;
+ this.jaasFile = builder.jaasFile;
+ this.solrCloudClient = builder.solrCloudClient;
+ this.solrZkClient = builder.solrZkClient;
+ this.maxShardsPerNode = builder.maxShardsPerNode;
+ this.routerName = builder.routerName;
+ this.routerField = builder.routerField;
+ this.splitting = builder.splitting;
+ this.znode = builder.znode;
+ this.saslUsers = builder.saslUsers;
+ this.propName = builder.propName;
+ this.propValue = builder.propValue;
+ this.securityJsonLocation = builder.securityJsonLocation;
+ this.secure = builder.secure;
+ }
+
+ /**
+ * Get Solr collections
+ */
+ public List<String> listCollections() throws Exception {
+ return new ListCollectionCommand(getRetryTimes(), getInterval()).run(this);
+ }
+
+ /**
+ * Create Solr collection if exists
+ */
+ public String createCollection() throws Exception {
+ List<String> collections = listCollections();
+ if (!collections.contains(getCollection())) {
+ String collection = new CreateCollectionCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("Collection '{}' created.", collection);
+ } else {
+ LOG.info("Collection '{}' already exits.", getCollection());
+ if (this.isSplitting()) {
+ createShard(null);
+ }
+ }
+ return getCollection();
+ }
+
+ /**
+ * Set cluster property in clusterprops.json.
+ */
+ public void setClusterProp() throws Exception {
+ LOG.info("Set cluster prop: '{}'", this.getPropName());
+ String newPropValue = new SetClusterPropertyZkCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("Set cluster prop '{}' successfully to '{}'", this.getPropName(), newPropValue);
+ }
+
+ /**
+ * Create a znode only if it does not exist. Return 0 code if it exists.
+ */
+ public void createZnode() throws Exception {
+ boolean znodeExists = isZnodeExists(this.znode);
+ if (znodeExists) {
+ LOG.info("Znode '{}' already exists.", this.znode);
+ } else {
+ LOG.info("Znode '{}' does not exist. Creating...", this.znode);
+ String newZnode = new CreateSolrZnodeZkCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("Znode '{}' is created successfully.", newZnode);
+ }
+ }
+
+ /**
+ * Check znode exists or not based on the zookeeper connect string.
+ * E.g.: localhost:2181 and znode: /ambari-solr, checks existance of localhost:2181/ambari-solr
+ */
+ public boolean isZnodeExists(String znode) throws Exception {
+ LOG.info("Check '{}' znode exists or not", znode);
+ boolean result = new CheckZnodeZkCommand(getRetryTimes(), getInterval(), znode).run(this);
+ if (result) {
+ LOG.info("'{}' znode exists", znode);
+ } else {
+ LOG.info("'{}' znode does not exist", znode);
+ }
+ return result;
+ }
+
+ public void setupKerberosPlugin() throws Exception {
+ LOG.info("Setup kerberos plugin in security.json");
+ new EnableKerberosPluginSolrZkCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("KerberosPlugin is set in security.json");
+ }
+
+ /**
+ * Secure solr znode
+ */
+ public void secureSolrZnode() throws Exception {
+ new SecureSolrZNodeZkCommand(getRetryTimes(), getInterval()).run(this);
+ }
+
+ /**
+ * Secure znode
+ */
+ public void secureZnode() throws Exception {
+ new SecureZNodeZkCommand(getRetryTimes(), getInterval()).run(this);
+ }
+
+ /**
+ * Upload config set to zookeeper
+ */
+ public String uploadConfiguration() throws Exception {
+ String configSet = new UploadConfigZkCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("'{}' is uploaded to zookeeper.", configSet);
+ return configSet;
+ }
+
+ /**
+ * Download config set from zookeeper
+ */
+ public String downloadConfiguration() throws Exception {
+ String configDir = new DownloadConfigZkCommand(getRetryTimes(), getInterval()).run(this);
+ LOG.info("Config set is download from zookeeper. ({})", configDir);
+ return configDir;
+ }
+
+ /**
+ * Get configuration if exists in zookeeper
+ */
+ public boolean configurationExists() throws Exception {
+ boolean configExits = new CheckConfigZkCommand(getRetryTimes(), getInterval()).run(this);
+ if (configExits) {
+ LOG.info("Config {} exits", configSet);
+ } else {
+ LOG.info("Configuration '{}' does not exist", configSet);
+ }
+ return configExits;
+ }
+
+ /**
+ * Create shard in collection - create a new one if shard name specified, if
+ * not create based on the number of shards logic (with shard_# suffix)
+ *
+ * @param shard
+ * name of the created shard
+ */
+ public Collection<String> createShard(String shard) throws Exception {
+ Collection<String> existingShards = getShardNames();
+ if (shard != null) {
+ new CreateShardCommand(shard, getRetryTimes(), getInterval()).run(this);
+ existingShards.add(shard);
+ } else {
+ List<String> shardList = ShardUtils.generateShardList(getMaxShardsPerNode());
+ for (String shardName : shardList) {
+ if (!existingShards.contains(shardName)) {
+ new CreateShardCommand(shardName, getRetryTimes(), getInterval()).run(this);
+ LOG.info("New shard added to collection '{}': {}", getCollection(), shardName);
+ existingShards.add(shardName);
+ }
+ }
+ }
+ return existingShards;
+ }
+
+ /**
+ * Get shard names
+ */
+ public Collection<String> getShardNames() throws Exception {
+ Collection<Slice> slices = new GetShardsCommand(getRetryTimes(), getInterval()).run(this);
+ return ShardUtils.getShardNamesFromSlices(slices, this.getCollection());
+ }
+
+ /**
+ * Get Solr Hosts
+ */
+ public Collection<String> getSolrHosts() throws Exception {
+ return new GetSolrHostsCommand(getRetryTimes(), getInterval()).run(this);
+ }
+
+ public String getZkConnectString() {
+ return zkConnectString;
+ }
+
+ public String getCollection() {
+ return collection;
+ }
+
+ public String getConfigSet() {
+ return configSet;
+ }
+
+ public String getConfigDir() {
+ return configDir;
+ }
+
+ public int getShards() {
+ return shards;
+ }
+
+ public int getReplication() {
+ return replication;
+ }
+
+ public int getRetryTimes() {
+ return retryTimes;
+ }
+
+ public int getInterval() {
+ return interval;
+ }
+
+ public CloudSolrClient getSolrCloudClient() {
+ return solrCloudClient;
+ }
+
+ public SolrZkClient getSolrZkClient() {
+ return solrZkClient;
+ }
+
+ public int getMaxShardsPerNode() {
+ return maxShardsPerNode;
+ }
+
+ public String getRouterName() {
+ return routerName;
+ }
+
+ public String getRouterField() {
+ return routerField;
+ }
+
+ public boolean isSplitting() {
+ return splitting;
+ }
+
+ public String getJaasFile() {
+ return jaasFile;
+ }
+
+ public String getSaslUsers() {
+ return saslUsers;
+ }
+
+ public String getZnode() {
+ return znode;
+ }
+
+ public String getPropName() {
+ return propName;
+ }
+
+ public String getPropValue() {
+ return propValue;
+ }
+
+ public boolean isSecure() {
+ return secure;
+ }
+
+ public String getSecurityJsonLocation() {
+ return securityJsonLocation;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientBuilder.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientBuilder.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientBuilder.java
new file mode 100644
index 0000000..54c4ae3
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientBuilder.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ambari.infra.solr;
+
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
+import org.apache.solr.client.solrj.impl.Krb5HttpClientConfigurer;
+import org.apache.solr.common.cloud.SolrZkClient;
+
+public class AmbariSolrCloudClientBuilder {
+ private static final String KEYSTORE_LOCATION_ARG = "javax.net.ssl.keyStore";
+ private static final String KEYSTORE_PASSWORD_ARG = "javax.net.ssl.keyStorePassword";
+ private static final String KEYSTORE_TYPE_ARG = "javax.net.ssl.keyStoreType";
+ private static final String TRUSTSTORE_LOCATION_ARG = "javax.net.ssl.trustStore";
+ private static final String TRUSTSTORE_PASSWORD_ARG = "javax.net.ssl.trustStorePassword";
+ private static final String TRUSTSTORE_TYPE_ARG = "javax.net.ssl.trustStoreType";
+
+ String zkConnectString;
+ String collection;
+ String configSet;
+ String configDir;
+ int shards = 1;
+ int replication = 1;
+ int retryTimes = 10;
+ int interval = 5;
+ int maxShardsPerNode = replication * shards;
+ String routerName = "implicit";
+ String routerField = "_router_field_";
+ CloudSolrClient solrCloudClient;
+ SolrZkClient solrZkClient;
+ boolean splitting;
+ String jaasFile;
+ String znode;
+ String saslUsers;
+ String propName;
+ String propValue;
+ String securityJsonLocation;
+ boolean secure;
+
+ public AmbariSolrCloudClient build() {
+ return new AmbariSolrCloudClient(this);
+ }
+
+ public AmbariSolrCloudClientBuilder withZkConnectString(String zkConnectString) {
+ this.zkConnectString = zkConnectString;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withCollection(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withConfigSet(String configSet) {
+ this.configSet = configSet;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withConfigDir(String configDir) {
+ this.configDir = configDir;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withShards(int shards) {
+ this.shards = shards;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withReplication(int replication) {
+ this.replication = replication;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withRetry(int retryTimes) {
+ this.retryTimes = retryTimes;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withInterval(int interval) {
+ this.interval = interval;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withMaxShardsPerNode(int maxShardsPerNode) {
+ this.maxShardsPerNode = maxShardsPerNode;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withRouterName(String routerName) {
+ this.routerName = routerName;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withRouterField(String routerField) {
+ this.routerField = routerField;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSplitting(boolean splitting) {
+ this.splitting = splitting;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withJaasFile(String jaasFile) {
+ this.jaasFile = jaasFile;
+ setupSecurity(jaasFile);
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSolrCloudClient() {
+ this.solrCloudClient = new CloudSolrClient(this.zkConnectString);
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSolrZkClient(int zkClientTimeout, int zkClientConnectTimeout) {
+ this.solrZkClient = new SolrZkClient(this.zkConnectString, zkClientTimeout, zkClientConnectTimeout);
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withKeyStoreLocation(String keyStoreLocation) {
+ if (keyStoreLocation != null) {
+ System.setProperty(KEYSTORE_LOCATION_ARG, keyStoreLocation);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withKeyStorePassword(String keyStorePassword) {
+ if (keyStorePassword != null) {
+ System.setProperty(KEYSTORE_PASSWORD_ARG, keyStorePassword);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withKeyStoreType(String keyStoreType) {
+ if (keyStoreType != null) {
+ System.setProperty(KEYSTORE_TYPE_ARG, keyStoreType);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withTrustStoreLocation(String trustStoreLocation) {
+ if (trustStoreLocation != null) {
+ System.setProperty(TRUSTSTORE_LOCATION_ARG, trustStoreLocation);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withTrustStorePassword(String trustStorePassword) {
+ if (trustStorePassword != null) {
+ System.setProperty(TRUSTSTORE_PASSWORD_ARG, trustStorePassword);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withTrustStoreType(String trustStoreType) {
+ if (trustStoreType != null) {
+ System.setProperty(TRUSTSTORE_TYPE_ARG, trustStoreType);
+ }
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSaslUsers(String saslUsers) {
+ this.saslUsers = saslUsers;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withZnode(String znode) {
+ this.znode = znode;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withClusterPropName(String clusterPropName) {
+ this.propName = clusterPropName;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withClusterPropValue(String clusterPropValue) {
+ this.propValue = clusterPropValue;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSecurityJsonLocation(String securityJson) {
+ this.securityJsonLocation = securityJson;
+ return this;
+ }
+
+ public AmbariSolrCloudClientBuilder withSecure(boolean isSecure) {
+ this.secure = isSecure;
+ return this;
+ }
+
+ private void setupSecurity(String jaasFile) {
+ if (jaasFile != null) {
+ System.setProperty("java.security.auth.login.config", jaasFile);
+ HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientException.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientException.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientException.java
new file mode 100644
index 0000000..d339a77
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientException.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr;
+
+public class AmbariSolrCloudClientException extends Exception{
+ public AmbariSolrCloudClientException(String message) {
+ super(message);
+ }
+ public AmbariSolrCloudClientException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractRetryCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractRetryCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractRetryCommand.java
new file mode 100644
index 0000000..5e87859
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractRetryCommand.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.AmbariSolrCloudClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractRetryCommand<RESPONSE> {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractRetryCommand.class);
+
+ private final int interval;
+ private final int maxRetries;
+
+ public AbstractRetryCommand(int maxRetries, int interval) {
+ this.maxRetries = maxRetries;
+ this.interval = interval;
+ }
+
+ public abstract RESPONSE createAndProcessRequest(AmbariSolrCloudClient solrCloudClient) throws Exception;
+
+ public RESPONSE run(AmbariSolrCloudClient solrCloudClient) throws Exception {
+ return retry(0, solrCloudClient);
+ }
+
+ private RESPONSE retry(int tries, AmbariSolrCloudClient solrCloudClient) throws Exception {
+ try {
+ return createAndProcessRequest(solrCloudClient);
+ } catch (Exception ex) {
+ LOG.error(ex.getMessage(), ex);
+ tries++;
+ LOG.info("Command failed, tries again (tries: {})", tries);
+ if (maxRetries == tries) {
+ throw new AmbariSolrCloudClientException(String.format("Maximum retries exceeded: %d", tries), ex);
+ } else {
+ Thread.sleep(interval * 1000);
+ return retry(tries, solrCloudClient);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractSolrRetryCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractSolrRetryCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractSolrRetryCommand.java
new file mode 100644
index 0000000..fdf26a7
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractSolrRetryCommand.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.AmbariSolrCloudClientException;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+import org.apache.solr.client.solrj.response.SolrResponseBase;
+
+public abstract class AbstractSolrRetryCommand<REQUEST extends CollectionAdminRequest, RESPONSE>
+ extends AbstractRetryCommand<RESPONSE> {
+
+ public AbstractSolrRetryCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ public abstract RESPONSE handleResponse(CollectionAdminResponse response, AmbariSolrCloudClient client) throws Exception;
+
+ public abstract REQUEST createRequest(AmbariSolrCloudClient client);
+
+ public abstract String errorMessage(AmbariSolrCloudClient client);
+
+ @Override
+ public RESPONSE createAndProcessRequest(AmbariSolrCloudClient client) throws Exception {
+ REQUEST request = createRequest(client);
+ CollectionAdminResponse response = (CollectionAdminResponse) request.process(client.getSolrCloudClient());
+ handleErrorIfExists(response, errorMessage(client));
+ return handleResponse(response, client);
+ }
+
+ private void handleErrorIfExists(SolrResponseBase response, String message) throws AmbariSolrCloudClientException {
+ if (response.getStatus() != 0) {
+ throw new AmbariSolrCloudClientException(message);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractStateFileZkCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractStateFileZkCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractStateFileZkCommand.java
new file mode 100644
index 0000000..b4872e2
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractStateFileZkCommand.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.domain.AmbariSolrState;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+
+public abstract class AbstractStateFileZkCommand extends AbstractZookeeperRetryCommand<AmbariSolrState>{
+
+ public static final String STATE_FILE = "ambari-solr-state.json";
+ public static final String STATE_FIELD = "ambari_solr_security_state";
+
+ public AbstractStateFileZkCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ public AmbariSolrState getStateFromJson(AmbariSolrCloudClient client, String fileName) throws Exception {
+ byte[] data = client.getSolrZkClient().getData(fileName, null, null, true);
+ String input = new String(data);
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode rootNode = mapper.readValue(input.getBytes(), JsonNode.class);
+ return AmbariSolrState.valueOf(rootNode.get(STATE_FIELD).asText());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperConfigCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperConfigCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperConfigCommand.java
new file mode 100644
index 0000000..dec34f1
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperConfigCommand.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.solr.common.cloud.ZkConfigManager;
+
+public abstract class AbstractZookeeperConfigCommand<RESPONSE> extends AbstractZookeeperRetryCommand<RESPONSE> {
+
+ public AbstractZookeeperConfigCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ protected abstract RESPONSE executeZkConfigCommand(ZkConfigManager zkConfigManager, AmbariSolrCloudClient client)
+ throws Exception;
+
+ @Override
+ protected RESPONSE executeZkCommand(AmbariSolrCloudClient client, SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+ ZkConfigManager zkConfigManager = createZkConfigManager(zkClient);
+ return executeZkConfigCommand(zkConfigManager, client);
+ }
+
+ protected ZkConfigManager createZkConfigManager(SolrZkClient zkClient) {
+ return new ZkConfigManager(zkClient);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperRetryCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperRetryCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperRetryCommand.java
new file mode 100644
index 0000000..e37088d
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/AbstractZookeeperRetryCommand.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+
+public abstract class AbstractZookeeperRetryCommand<RESPONSE> extends AbstractRetryCommand<RESPONSE> {
+
+ public AbstractZookeeperRetryCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ protected abstract RESPONSE executeZkCommand(AmbariSolrCloudClient client, SolrZkClient zkClient, SolrZooKeeper solrZooKeeper)
+ throws Exception;
+
+ @Override
+ public RESPONSE createAndProcessRequest(AmbariSolrCloudClient client) throws Exception {
+ SolrZkClient zkClient = client.getSolrZkClient();
+ SolrZooKeeper solrZooKeeper = zkClient.getSolrZooKeeper();
+ return executeZkCommand(client, zkClient, solrZooKeeper);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckConfigZkCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckConfigZkCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckConfigZkCommand.java
new file mode 100644
index 0000000..0a03a65
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckConfigZkCommand.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.solr.common.cloud.ZkConfigManager;
+
+public class CheckConfigZkCommand extends AbstractZookeeperConfigCommand<Boolean> {
+
+ public CheckConfigZkCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ @Override
+ protected Boolean executeZkConfigCommand(ZkConfigManager zkConfigManager, AmbariSolrCloudClient client) throws Exception {
+ return zkConfigManager.configExists(client.getConfigSet());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckZnodeZkCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckZnodeZkCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckZnodeZkCommand.java
new file mode 100644
index 0000000..93eb478
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CheckZnodeZkCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.AmbariSolrCloudClientException;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.KeeperException;
+
+public class CheckZnodeZkCommand extends AbstractZookeeperRetryCommand<Boolean> {
+
+ private String znode;
+
+ public CheckZnodeZkCommand(int maxRetries, int interval, String znode) {
+ super(maxRetries, interval);
+ this.znode = znode;
+ }
+
+ @Override
+ protected Boolean executeZkCommand(AmbariSolrCloudClient client, SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+ try {
+ return zkClient.exists(this.znode, false);
+ } catch (KeeperException e) {
+ throw new AmbariSolrCloudClientException("Exception during checking znode, " +
+ "Check zookeeper servers are running (n+1/2) or zookeeper quorum has established or not.", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateCollectionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateCollectionCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateCollectionCommand.java
new file mode 100644
index 0000000..53e96fd
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateCollectionCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.util.ShardUtils;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CreateCollectionCommand extends AbstractSolrRetryCommand<CollectionAdminRequest.Create ,String> {
+
+ public CreateCollectionCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ @Override
+ public String handleResponse(CollectionAdminResponse response, AmbariSolrCloudClient client) throws Exception {
+ return client.getCollection();
+ }
+
+ @Override
+ public CollectionAdminRequest.Create createRequest(AmbariSolrCloudClient client) {
+ CollectionAdminRequest.Create request = new CollectionAdminRequest.Create();
+ request.setConfigName(client.getConfigSet());
+ request.setCollectionName(client.getCollection());
+ request.setNumShards(client.getShards());
+ request.setReplicationFactor(client.getReplication());
+ request.setMaxShardsPerNode(client.getMaxShardsPerNode());
+ if (client.getRouterField() != null && client.getRouterName()!= null) {
+ request.setRouterName(client.getRouterName());
+ request.setRouterField(client.getRouterField());
+ }
+ if (client.isSplitting()) {
+ request.setShards(ShardUtils.generateShardListStr(client.getMaxShardsPerNode()));
+ }
+ return request;
+ }
+
+ @Override
+ public String errorMessage(AmbariSolrCloudClient client) {
+ return String.format("Cannot create collection: '%s'", client.getCollection());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateShardCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateShardCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateShardCommand.java
new file mode 100644
index 0000000..9b57827
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateShardCommand.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+
+public class CreateShardCommand extends AbstractSolrRetryCommand<CollectionAdminRequest.CreateShard, String> {
+
+ private final String shardName;
+
+ public CreateShardCommand(String shardName, int maxRetries, int interval) {
+ super(maxRetries, interval);
+ this.shardName = shardName;
+ }
+
+ @Override
+ public String handleResponse(CollectionAdminResponse response, AmbariSolrCloudClient client) throws Exception {
+ return shardName;
+ }
+
+ @Override
+ public CollectionAdminRequest.CreateShard createRequest(AmbariSolrCloudClient client) {
+ CollectionAdminRequest.CreateShard createShardRequest = new CollectionAdminRequest.CreateShard();
+ createShardRequest.setCollectionName(client.getCollection());
+ createShardRequest.setShardName(shardName);
+ return createShardRequest;
+ }
+
+ @Override
+ public String errorMessage(AmbariSolrCloudClient client) {
+ return String.format("Cannot add shard to collection '%s'", client.getCollection());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateSolrZnodeZkCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateSolrZnodeZkCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateSolrZnodeZkCommand.java
new file mode 100644
index 0000000..1460a84
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/CreateSolrZnodeZkCommand.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.AmbariSolrCloudClientException;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.KeeperException;
+
+public class CreateSolrZnodeZkCommand extends AbstractZookeeperRetryCommand<String> {
+
+ public CreateSolrZnodeZkCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ @Override
+ protected String executeZkCommand(AmbariSolrCloudClient client, SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+ try {
+ zkClient.makePath(client.getZnode(), true);
+ return client.getZnode();
+ } catch (KeeperException e) {
+ throw new AmbariSolrCloudClientException("Cannot create ZNode, check zookeeper servers are running (n+1/2), or zookeeper quorum has established or not.",e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/DownloadConfigZkCommand.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/DownloadConfigZkCommand.java b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/DownloadConfigZkCommand.java
new file mode 100644
index 0000000..990c3c3
--- /dev/null
+++ b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/DownloadConfigZkCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ambari.infra.solr.commands;
+
+import org.apache.ambari.infra.solr.AmbariSolrCloudClient;
+import org.apache.ambari.infra.solr.AmbariSolrCloudClientException;
+import org.apache.solr.common.cloud.ZkConfigManager;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class DownloadConfigZkCommand extends AbstractZookeeperConfigCommand<String> {
+
+ public DownloadConfigZkCommand(int maxRetries, int interval) {
+ super(maxRetries, interval);
+ }
+
+ @Override
+ protected String executeZkConfigCommand(ZkConfigManager zkConfigManager, AmbariSolrCloudClient client) throws Exception {
+ Path configDir = Paths.get(client.getConfigDir());
+ String configSet = client.getConfigSet();
+ try {
+ zkConfigManager.downloadConfigDir(configSet, configDir);
+ return configDir.toString();
+ } catch (IOException e){
+ throw new AmbariSolrCloudClientException("Error downloading configuration set, check Solr Znode has started or not " +
+ "(starting Solr (for Log Search) is responsible to create the Znode)" ,e);
+ }
+ }
+}