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/EnableKerberosPluginSolrZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/EnableKerberosPluginSolrZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/EnableKerberosPluginSolrZkCommand.java
new file mode 100644
index 0000000..793addd
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/EnableKerberosPluginSolrZkCommand.java
@@ -0,0 +1,88 @@
+/*
+ * 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.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.CreateMode;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+public class EnableKerberosPluginSolrZkCommand extends 
AbstractZookeeperRetryCommand<String> {
+
+  private static final String SECURITY_JSON = "/security.json";
+  private static final String UNSECURE_CONTENT = "{}";
+
+  public EnableKerberosPluginSolrZkCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  protected String executeZkCommand(AmbariSolrCloudClient client, SolrZkClient 
zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    String result = "";
+    String filePath = client.getZnode() + SECURITY_JSON;
+    String fileContent = getFileContentFromZnode(zkClient, filePath);
+    String securityContent = getFileContent(client.getSecurityJsonLocation());
+    if (client.isSecure()) {
+      if (!fileContent.equals(securityContent)) {
+        putFileContent(zkClient, filePath, securityContent);
+      }
+      result = securityContent;
+    } else {
+      if (!fileContent.equals(UNSECURE_CONTENT)) {
+        putFileContent(zkClient, filePath, UNSECURE_CONTENT);
+      }
+      result = UNSECURE_CONTENT;
+    }
+    return result;
+  }
+
+  private void putFileContent(SolrZkClient zkClient, String fileName, String 
content) throws Exception {
+    if (zkClient.exists(fileName, true)) {
+      zkClient.setData(fileName, content.getBytes(StandardCharsets.UTF_8), 
true);
+    } else {
+      zkClient.create(fileName, content.getBytes(StandardCharsets.UTF_8), 
CreateMode.PERSISTENT, true);
+    }
+  }
+
+  private String getFileContentFromZnode(SolrZkClient zkClient, String 
fileName) throws Exception {
+    String result;
+    if (zkClient.exists(fileName, true)) {
+      byte[] data = zkClient.getData(fileName, null, null, true);
+      result = new String(data, StandardCharsets.UTF_8);
+    } else {
+      result = UNSECURE_CONTENT;
+    }
+    return result;
+  }
+
+  private String getFileContent(String fileLocation) throws IOException {
+    File securityJson = new File(fileLocation);
+    if (StringUtils.isNotEmpty(fileLocation) && securityJson.exists()) {
+      return FileUtils.readFileToString(securityJson);
+    } else {
+      return UNSECURE_CONTENT;
+    }
+  }
+}

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/GetShardsCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetShardsCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetShardsCommand.java
new file mode 100644
index 0000000..e49bfec
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetShardsCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+
+import java.util.Collection;
+
+public class GetShardsCommand extends AbstractRetryCommand<Collection<Slice>> {
+
+  public GetShardsCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  public Collection<Slice> createAndProcessRequest(AmbariSolrCloudClient 
solrCloudClient) throws Exception {
+    ZkStateReader zkReader = new 
ZkStateReader(solrCloudClient.getSolrZkClient());
+    zkReader.createClusterStateWatchersAndUpdate();
+    return 
zkReader.getClusterState().getSlices(solrCloudClient.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/GetSolrHostsCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetSolrHostsCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetSolrHostsCommand.java
new file mode 100644
index 0000000..5a14a44
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetSolrHostsCommand.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.zookeeper.ZooKeeper;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class GetSolrHostsCommand extends 
AbstractRetryCommand<Collection<String>> {
+
+  public GetSolrHostsCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  public Collection<String> createAndProcessRequest(AmbariSolrCloudClient 
solrCloudClient) throws Exception {
+    List<String> solrHosts = new ArrayList<>();
+
+    ZooKeeper zk = new ZooKeeper(solrCloudClient.getZkConnectString(), 10000, 
null);
+    List<String> ids = zk.getChildren("/live_nodes", false);
+    for (String id : ids) {
+      if (id.endsWith("_solr")) {
+        String hostAndPort = id.substring(0, id.length() - 5);
+        String[] tokens = hostAndPort.split(":");
+        String host = InetAddress.getByName(tokens[0]).getHostName();
+
+        solrHosts.add(host);
+      }
+    }
+
+    return solrHosts;
+  }
+}

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/GetStateFileZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetStateFileZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetStateFileZkCommand.java
new file mode 100644
index 0000000..10a8daa
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/GetStateFileZkCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+
+public class GetStateFileZkCommand extends AbstractStateFileZkCommand {
+  private String unsecureZnode;
+
+  public GetStateFileZkCommand(int maxRetries, int interval, String 
unsecureZnode) {
+    super(maxRetries, interval);
+    this.unsecureZnode = unsecureZnode;
+  }
+
+  @Override
+  protected AmbariSolrState executeZkCommand(AmbariSolrCloudClient client, 
SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    AmbariSolrState result = AmbariSolrState.UNSECURE;
+    String stateFile = String.format("%s/%s", unsecureZnode, 
AbstractStateFileZkCommand.STATE_FILE);
+    if (zkClient.exists(stateFile, true)) {
+      result = getStateFromJson(client, stateFile);
+    }
+    return result;
+  }
+}

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/ListCollectionCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/ListCollectionCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/ListCollectionCommand.java
new file mode 100644
index 0000000..41094c7
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/ListCollectionCommand.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import java.util.List;
+
+public class ListCollectionCommand extends 
AbstractSolrRetryCommand<CollectionAdminRequest.List, List<String>> {
+
+  public ListCollectionCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  public List<String> handleResponse(CollectionAdminResponse response, 
AmbariSolrCloudClient client) throws Exception {
+    List<String> allCollectionList = (List<String>) response
+      .getResponse().get("collections");
+    return allCollectionList;
+  }
+
+  @Override
+  public CollectionAdminRequest.List createRequest(AmbariSolrCloudClient 
client) {
+    return new CollectionAdminRequest.List();
+  }
+
+  @Override
+  public String errorMessage(AmbariSolrCloudClient client) {
+    return "Cannot get collections.";
+  }
+}

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/SecureSolrZNodeZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureSolrZNodeZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureSolrZNodeZkCommand.java
new file mode 100644
index 0000000..6958623
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureSolrZNodeZkCommand.java
@@ -0,0 +1,86 @@
+/*
+ * 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.AclUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.data.Stat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SecureSolrZNodeZkCommand extends 
AbstractZookeeperRetryCommand<Boolean> {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(SecureSolrZNodeZkCommand.class);
+
+  public SecureSolrZNodeZkCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  protected Boolean executeZkCommand(AmbariSolrCloudClient client, 
SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    String zNode = client.getZnode();
+    List<ACL> newAclList = new ArrayList<>();
+    List<ACL> saslUserList = 
AclUtils.createAclListFromSaslUsers(client.getSaslUsers().split(","));
+    newAclList.addAll(saslUserList);
+    newAclList.add(new ACL(ZooDefs.Perms.READ, new Id("world", "anyone")));
+
+    String configsPath = String.format("%s/%s", zNode, "configs");
+    String collectionsPath = String.format("%s/%s", zNode, "collections");
+    String aliasesPath = String.format("%s/%s", zNode, "aliases.json"); // 
TODO: protect this later somehow
+    List<String> excludePaths = Arrays.asList(configsPath, collectionsPath, 
aliasesPath);
+
+    createZnodeIfNeeded(configsPath, client.getSolrZkClient());
+    createZnodeIfNeeded(collectionsPath, client.getSolrZkClient());
+
+    AclUtils.setRecursivelyOn(client.getSolrZkClient().getSolrZooKeeper(), 
zNode, newAclList, excludePaths);
+
+    List<ACL> commonConfigAcls = new ArrayList<>();
+    commonConfigAcls.addAll(saslUserList);
+    commonConfigAcls.add(new ACL(ZooDefs.Perms.READ | ZooDefs.Perms.CREATE, 
new Id("world", "anyone")));
+
+    LOG.info("Set sasl users for znode '{}' : {}", client.getZnode(), 
StringUtils.join(saslUserList, ","));
+    LOG.info("Skip {}/configs and {}/collections", client.getZnode(), 
client.getZnode());
+    solrZooKeeper.setACL(configsPath, 
AclUtils.mergeAcls(solrZooKeeper.getACL(configsPath, new Stat()), 
commonConfigAcls), -1);
+    solrZooKeeper.setACL(collectionsPath, 
AclUtils.mergeAcls(solrZooKeeper.getACL(collectionsPath, new Stat()), 
commonConfigAcls), -1);
+
+    LOG.info("Set world:anyone to 'cr' on  {}/configs and {}/collections", 
client.getZnode(), client.getZnode());
+    AclUtils.setRecursivelyOn(solrZooKeeper, configsPath, saslUserList);
+    AclUtils.setRecursivelyOn(solrZooKeeper, collectionsPath, saslUserList);
+
+    return true;
+  }
+
+  private void createZnodeIfNeeded(String configsPath, SolrZkClient zkClient) 
throws KeeperException, InterruptedException {
+    if (!zkClient.exists(configsPath, true)) {
+      LOG.info("'{}' does not exist. Creating it ...", configsPath);
+      zkClient.makePath(configsPath, true);
+    }
+  }
+}

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/SecureZNodeZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureZNodeZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureZNodeZkCommand.java
new file mode 100644
index 0000000..a96dc5d
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SecureZNodeZkCommand.java
@@ -0,0 +1,49 @@
+/*
+ * 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.AclUtils;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SecureZNodeZkCommand extends 
AbstractZookeeperRetryCommand<Boolean> {
+
+  public SecureZNodeZkCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  protected Boolean executeZkCommand(AmbariSolrCloudClient client, 
SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    String zNode = client.getZnode();
+    List<ACL> newAclList = new ArrayList<>();
+    List<ACL> saslUserList = 
AclUtils.createAclListFromSaslUsers(client.getSaslUsers().split(","));
+    newAclList.addAll(saslUserList);
+    newAclList.add(new ACL(ZooDefs.Perms.READ, new Id("world", "anyone")));
+    AclUtils.setRecursivelyOn(client.getSolrZkClient().getSolrZooKeeper(), 
zNode, newAclList);
+    return true;
+  }
+
+}

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/SetClusterPropertyZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SetClusterPropertyZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SetClusterPropertyZkCommand.java
new file mode 100644
index 0000000..34597c6
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/SetClusterPropertyZkCommand.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;
+import org.apache.solr.common.cloud.ZkStateReader;
+
+public class SetClusterPropertyZkCommand extends 
AbstractZookeeperRetryCommand<String>{
+
+  public SetClusterPropertyZkCommand(int maxRetries, int interval) {
+    super(maxRetries, interval);
+  }
+
+  @Override
+  protected String executeZkCommand(AmbariSolrCloudClient client, SolrZkClient 
zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    String propertyName = client.getPropName();
+    String propertyValue = client.getPropValue();
+    ZkStateReader reader = new ZkStateReader(zkClient);
+    reader.setClusterProperty(propertyName, propertyValue);
+    return propertyValue;
+  }
+}

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/UpdateStateFileZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UpdateStateFileZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UpdateStateFileZkCommand.java
new file mode 100644
index 0000000..2b360fb
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UpdateStateFileZkCommand.java
@@ -0,0 +1,84 @@
+/*
+ * 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.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.CreateMode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+public class UpdateStateFileZkCommand extends AbstractStateFileZkCommand {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(UpdateStateFileZkCommand.class);
+
+  private String unsecureZnode;
+
+  public UpdateStateFileZkCommand(int maxRetries, int interval, String 
unsecureZnode) {
+    super(maxRetries, interval);
+    this.unsecureZnode = unsecureZnode;
+  }
+
+  @Override
+  protected AmbariSolrState executeZkCommand(AmbariSolrCloudClient client, 
SolrZkClient zkClient, SolrZooKeeper solrZooKeeper) throws Exception {
+    boolean secure = client.isSecure();
+    String stateFile = String.format("%s/%s", unsecureZnode, 
AbstractStateFileZkCommand.STATE_FILE);
+    AmbariSolrState result = null;
+    if (secure) {
+      LOG.info("Update state file in secure mode.");
+      updateStateFile(client, zkClient, AmbariSolrState.SECURE, stateFile);
+      result = AmbariSolrState.SECURE;
+    } else {
+      LOG.info("Update state file in unsecure mode.");
+      updateStateFile(client, zkClient, AmbariSolrState.UNSECURE, stateFile);
+      result = AmbariSolrState.UNSECURE;
+    }
+    return result;
+  }
+
+  private void updateStateFile(AmbariSolrCloudClient client, SolrZkClient 
zkClient, AmbariSolrState stateToUpdate,
+                               String stateFile) throws Exception {
+    if (!zkClient.exists(stateFile, true)) {
+      LOG.info("State file does not exits. Initializing it as '{}'", 
stateToUpdate);
+      zkClient.create(stateFile, 
createStateJson(stateToUpdate).getBytes(StandardCharsets.UTF_8),
+        CreateMode.PERSISTENT, true);
+    } else {
+      AmbariSolrState stateOnSecure = getStateFromJson(client, stateFile);
+      if (stateToUpdate.equals(stateOnSecure)) {
+        LOG.info("State file is in '{}' mode. No update.", stateOnSecure);
+      } else {
+        LOG.info("State file is in '{}' mode. Updating it to '{}'", 
stateOnSecure, stateToUpdate);
+        zkClient.setData(stateFile, 
createStateJson(stateToUpdate).getBytes(StandardCharsets.UTF_8), true);
+      }
+    }
+  }
+
+  private String createStateJson(AmbariSolrState state) throws Exception {
+    Map<String, String> secStateMap = new HashMap<>();
+    secStateMap.put(AbstractStateFileZkCommand.STATE_FIELD, state.toString());
+    return new ObjectMapper().writeValueAsString(secStateMap);
+  }
+}

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/UploadConfigZkCommand.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UploadConfigZkCommand.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UploadConfigZkCommand.java
new file mode 100644
index 0000000..fc7482d
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/commands/UploadConfigZkCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class UploadConfigZkCommand extends 
AbstractZookeeperConfigCommand<String> {
+
+  public UploadConfigZkCommand(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();
+    zkConfigManager.uploadConfigDir(configDir, configSet);
+    return configSet;
+  }
+}

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/domain/AmbariSolrState.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/domain/AmbariSolrState.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/domain/AmbariSolrState.java
new file mode 100644
index 0000000..489d3f1
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/domain/AmbariSolrState.java
@@ -0,0 +1,26 @@
+/*
+ * 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.domain;
+
+/**
+ * Enum state values for storing security status in unsecure znode
+ */
+public enum AmbariSolrState {
+  SECURE, UNSECURE
+}

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/util/AclUtils.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/AclUtils.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/AclUtils.java
new file mode 100644
index 0000000..dd5d6c8
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/AclUtils.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util;
+
+import org.apache.solr.common.cloud.SolrZooKeeper;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.data.Stat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AclUtils {
+
+  public static List<ACL> mergeAcls(List<ACL> originalAcls, List<ACL> 
updateAcls) {
+    Map<String, ACL> aclMap = new HashMap<>();
+    List<ACL> acls = new ArrayList<>();
+    if (originalAcls != null) {
+      for (ACL acl : originalAcls) {
+        aclMap.put(acl.getId().getId(), acl);
+      }
+    }
+
+    if (updateAcls != null) {
+      for (ACL acl : updateAcls) {
+        aclMap.put(acl.getId().getId(), acl);
+      }
+    }
+
+    for (Map.Entry<String, ACL> aclEntry : aclMap.entrySet()) {
+      acls.add(aclEntry.getValue());
+    }
+    return acls;
+  }
+
+  public static List<ACL> createAclListFromSaslUsers(String[] saslUsers) {
+    List<ACL> saslUserList = new ArrayList<>();
+    for (String saslUser : saslUsers) {
+      ACL acl = new ACL();
+      acl.setId(new Id("sasl", saslUser));
+      acl.setPerms(ZooDefs.Perms.ALL);
+      saslUserList.add(acl);
+    }
+    return saslUserList;
+  }
+
+  public static void setRecursivelyOn(SolrZooKeeper solrZooKeeper, String 
node, List<ACL> acls) throws KeeperException, InterruptedException {
+    setRecursivelyOn(solrZooKeeper, node, acls, new ArrayList<String>());
+  }
+
+  public static void setRecursivelyOn(SolrZooKeeper solrZooKeeper, String 
node, List<ACL> acls, List<String> excludePaths)
+    throws KeeperException, InterruptedException {
+    if (!excludePaths.contains(node)) {
+      List<ACL> newAcls = AclUtils.mergeAcls(solrZooKeeper.getACL(node, new 
Stat()), acls);
+      solrZooKeeper.setACL(node, newAcls, -1);
+      for (String child : solrZooKeeper.getChildren(node, null)) {
+        setRecursivelyOn(solrZooKeeper, path(node, child), acls, excludePaths);
+      }
+    }
+  }
+
+  private static String path(String node, String child) {
+    return node.endsWith("/") ? node + child : node + "/" + child;
+  }
+}

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/util/ShardUtils.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/ShardUtils.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/ShardUtils.java
new file mode 100644
index 0000000..f46565b
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/util/ShardUtils.java
@@ -0,0 +1,71 @@
+/*
+ * 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.util;
+
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+public class ShardUtils {
+
+  private static final Logger LOG = LoggerFactory.getLogger(ShardUtils.class);
+
+  public static String generateShardListStr(int maxShardsPerNode) {
+    String shardsListStr = "";
+    for (int i = 0; i < maxShardsPerNode; i++) {
+      if (i != 0) {
+        shardsListStr += ",";
+      }
+      String shard = "shard" + i;
+      shardsListStr += shard;
+    }
+    return shardsListStr;
+  }
+
+  public static List<String> generateShardList(int maxShardsPerNode) {
+    List<String> shardsList = new ArrayList<>();
+    for (int i = 0; i < maxShardsPerNode; i++) {
+      shardsList.add("shard" + i);
+    }
+    return shardsList;
+  }
+
+  public static Collection<String> getShardNamesFromSlices(Collection<Slice> 
slices, String collection) {
+    Collection<String> result = new HashSet<String>();
+    Iterator<Slice> iter = slices.iterator();
+    while (iter.hasNext()) {
+      Slice slice = iter.next();
+      for (Replica replica : slice.getReplicas()) {
+        LOG.info("collectionName=" + collection + ", slice.name="
+          + slice.getName() + ", slice.state=" + slice.getState()
+          + ", replica.core=" + replica.getStr("core")
+          + ", replica.state=" + replica.getStr("state"));
+        result.add(slice.getName());
+      }
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/resources/log4j.properties 
b/ambari-logsearch/ambari-infra-solr-client/src/main/resources/log4j.properties
new file mode 100644
index 0000000..e8dca12
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/resources/log4j.properties
@@ -0,0 +1,31 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
+
+log4j.rootLogger=INFO,stdout,stderr
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Threshold=INFO
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%m%n
+
+log4j.appender.stderr=org.apache.log4j.ConsoleAppender
+log4j.appender.stderr.Threshold=ERROR
+log4j.appender.stderr.Target=System.err
+log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
+log4j.appender.stderr.layout.ConversionPattern=%m%n
\ 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/resources/solrCloudCli.sh
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/main/resources/solrCloudCli.sh 
b/ambari-logsearch/ambari-infra-solr-client/src/main/resources/solrCloudCli.sh
new file mode 100644
index 0000000..cd47f06
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/main/resources/solrCloudCli.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# 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.
+
+JVM="java"
+sdir="`dirname \"$0\"`"
+
+PATH=$JAVA_HOME/bin:$PATH $JVM -classpath "$sdir:$sdir/libs/*" 
org.apache.ambari.logsearch.solr.AmbariSolrCloudCLI ${1+"$@"}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-infra-solr-client/src/test/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-infra-solr-client/src/test/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientTest.java
 
b/ambari-logsearch/ambari-infra-solr-client/src/test/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientTest.java
new file mode 100644
index 0000000..44f3ec5
--- /dev/null
+++ 
b/ambari-logsearch/ambari-infra-solr-client/src/test/java/org/apache/ambari/infra/solr/AmbariSolrCloudClientTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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 static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.util.NamedList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class AmbariSolrCloudClientTest {
+
+  private AmbariSolrCloudClient underTest;
+
+  private CloudSolrClient mockedSolrClient;
+
+  private SolrZkClient mockedSolrZkClient;
+
+  private CollectionAdminResponse mockedResponse;
+
+  @Before
+  public void setUp() {
+    AmbariSolrCloudClientBuilder builder = new AmbariSolrCloudClientBuilder();
+
+    mockedSolrClient = createMock(CloudSolrClient.class);
+    mockedSolrZkClient = createMock(SolrZkClient.class);
+    mockedResponse = createMock(CollectionAdminResponse.class);
+
+    builder.solrCloudClient = mockedSolrClient;
+    builder.solrZkClient = mockedSolrZkClient;
+
+    underTest = builder
+      .withZkConnectString("localhost1:2181,localhost2:2182")
+      .withCollection("collection1")
+      .withConfigSet("configSet")
+      .withShards(1)
+      .withReplication(1)
+      .withMaxShardsPerNode(2)
+      .withInterval(1)
+      .withRetry(2)
+      .withRouterName("routerName")
+      .withRouterField("routerField")
+      .build();
+  }
+
+  @Test
+  public void testCreateCollectionWhenCollectionDoesNotExist() throws 
Exception {
+    // GIVEN
+    NamedList<Object> namedList = new NamedList<>();
+    namedList.add("collections", Arrays.asList("collection1", "collection2"));
+
+    expect(mockedSolrClient.request(anyObject(CollectionAdminRequest.class), 
anyString())).andReturn(namedList).times(1);
+    replay(mockedSolrClient);
+
+    // WHEN
+    String result = underTest.createCollection();
+    // THEN
+    assertEquals("collection1", result);
+    verify(mockedSolrClient);
+  }
+
+  @Test
+  public void testCreateCollectionWhenCollectionExists() throws Exception {
+    // GIVEN
+    NamedList<Object> namedList = new NamedList<>();
+    namedList.add("collections", Arrays.asList("collection2", "collection3"));
+
+    expect(mockedSolrClient.request(anyObject(CollectionAdminRequest.class), 
anyString())).andReturn(namedList).times(2);
+    replay(mockedSolrClient);
+
+    // WHEN
+    String result = underTest.createCollection();
+    // THEN
+    assertEquals("collection1", result);
+    verify(mockedSolrClient);
+  }
+
+  @Test
+  public void testListCollections() throws Exception {
+    // GIVEN
+    NamedList<Object> namedList = new NamedList<>();
+    namedList.add("collections", Arrays.asList("collection1", "collection2"));
+
+    expect(mockedSolrClient.request(anyObject(CollectionAdminRequest.class), 
anyString())).andReturn(namedList);
+
+    replay(mockedSolrClient);
+    // WHEN
+    List<String> result = underTest.listCollections();
+
+    // THEN
+    assertTrue(result.contains("collection1"));
+    assertTrue(result.contains("collection2"));
+    assertEquals(2, result.size());
+  }
+
+  @Test(expected = AmbariSolrCloudClientException.class)
+  public void testRetries() throws Exception {
+    // GIVEN
+    expect(mockedSolrClient.request(anyObject(CollectionAdminRequest.class), 
anyString())).andThrow(new RuntimeException("ex")).times(2);
+    replay(mockedSolrClient);
+    // WHEN
+    underTest.listCollections();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-logsearch-assembly/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-assembly/pom.xml 
b/ambari-logsearch/ambari-logsearch-assembly/pom.xml
index ff6c80e..d286993 100644
--- a/ambari-logsearch/ambari-logsearch-assembly/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-assembly/pom.xml
@@ -33,7 +33,7 @@
     <solr.package.name>ambari-infra-solr</solr.package.name>
     
<solr.client.package.name>ambari-infra-solr-client</solr.client.package.name>
     
<solr.client.mapping.path>${mapping.base.path}/${solr.client.package.name}</solr.client.mapping.path>
-    
<solr.client.dir>${project.basedir}/../ambari-logsearch-solr-client</solr.client.dir>
+    
<solr.client.dir>${project.basedir}/../ambari-infra-solr-client</solr.client.dir>
     
<logsearch.portal.package.name>ambari-logsearch-portal</logsearch.portal.package.name>
     
<logsearch.portal.mapping.path>${mapping.base.path}/ambari-logsearch-portal</logsearch.portal.mapping.path>
     
<logsearch.server.dir>${project.basedir}/../ambari-logsearch-server</logsearch.server.dir>
@@ -363,7 +363,7 @@
                   <skipPOMs>false</skipPOMs>
                   <dataSet>
                     <data>
-                      
<src>${solr.client.dir}/target/ambari-logsearch-solr-client.tar.gz</src>
+                      
<src>${solr.client.dir}/target/ambari-infra-solr-client.tar.gz</src>
                       <type>archive</type>
                       <mapper>
                         <type>perm</type>
@@ -533,7 +533,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.ambari</groupId>
-      <artifactId>ambari-logsearch-solr-client</artifactId>
+      <artifactId>ambari-infra-solr-client</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-logsearch-it/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-it/pom.xml 
b/ambari-logsearch/ambari-logsearch-it/pom.xml
index 373068e..c3188e7 100644
--- a/ambari-logsearch/ambari-logsearch-it/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-it/pom.xml
@@ -54,7 +54,7 @@
     </dependency>
     <dependency>
       <groupId>org.apache.ambari</groupId>
-      <artifactId>ambari-logsearch-solr-client</artifactId>
+      <artifactId>ambari-infra-solr-client</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c5ccb1ab/ambari-logsearch/ambari-logsearch-solr-client/build.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-solr-client/build.xml 
b/ambari-logsearch/ambari-logsearch-solr-client/build.xml
deleted file mode 100644
index 4d1a9c7..0000000
--- a/ambari-logsearch/ambari-logsearch-solr-client/build.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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-logsearch-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-logsearch-solr-client/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-solr-client/pom.xml 
b/ambari-logsearch/ambari-logsearch-solr-client/pom.xml
deleted file mode 100644
index e1bd9a6..0000000
--- a/ambari-logsearch/ambari-logsearch-solr-client/pom.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?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 Logsearch Solr Client</name>
-
-  <artifactId>ambari-logsearch-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-logsearch-solr-client/src/main/java/org/apache/ambari/logsearch/solr/AmbariSolrCloudCLI.java
----------------------------------------------------------------------
diff --git 
a/ambari-logsearch/ambari-logsearch-solr-client/src/main/java/org/apache/ambari/logsearch/solr/AmbariSolrCloudCLI.java
 
b/ambari-logsearch/ambari-logsearch-solr-client/src/main/java/org/apache/ambari/logsearch/solr/AmbariSolrCloudCLI.java
deleted file mode 100644
index be73473..0000000
--- 
a/ambari-logsearch/ambari-logsearch-solr-client/src/main/java/org/apache/ambari/logsearch/solr/AmbariSolrCloudCLI.java
+++ /dev/null
@@ -1,565 +0,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.
- */
-
-package org.apache.ambari.logsearch.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);
-  }
-}

Reply via email to