http://git-wip-us.apache.org/repos/asf/knox/blob/e5fd0622/gateway-server/src/test/java/org/apache/knox/gateway/topology/monitor/ZooKeeperConfigurationMonitorTest.java
----------------------------------------------------------------------
diff --cc 
gateway-server/src/test/java/org/apache/knox/gateway/topology/monitor/ZooKeeperConfigurationMonitorTest.java
index 75cd5d0,0000000..2e753f1
mode 100644,000000..100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/topology/monitor/ZooKeeperConfigurationMonitorTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/topology/monitor/ZooKeeperConfigurationMonitorTest.java
@@@ -1,355 -1,0 +1,368 @@@
 +/**
 + * 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
 + * <p>
 + * http://www.apache.org/licenses/LICENSE-2.0
 + * <p>
 + * 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.knox.gateway.topology.monitor;
 +
 +import org.apache.commons.io.FileUtils;
 +import org.apache.curator.framework.CuratorFramework;
 +import org.apache.curator.framework.CuratorFrameworkFactory;
 +import org.apache.curator.retry.ExponentialBackoffRetry;
 +import org.apache.curator.test.InstanceSpec;
 +import org.apache.curator.test.TestingCluster;
 +import org.apache.knox.gateway.config.GatewayConfig;
 +import 
org.apache.knox.gateway.service.config.remote.zk.ZooKeeperClientService;
 +import 
org.apache.knox.gateway.service.config.remote.zk.ZooKeeperClientServiceProvider;
 +import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
 +import org.apache.knox.gateway.services.security.AliasService;
 +import org.apache.knox.test.TestUtils;
 +import org.apache.zookeeper.CreateMode;
 +import org.apache.zookeeper.ZooDefs;
 +import org.apache.zookeeper.data.ACL;
 +import org.easymock.EasyMock;
 +import org.junit.AfterClass;
 +import org.junit.BeforeClass;
 +import org.junit.Test;
 +
 +import java.io.File;
 +import java.util.ArrayList;
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +/**
 + * Test the ZooKeeperConfigMonitor WITHOUT SASL configured or znode ACLs 
applied.
 + * The implementation of the monitor is the same regardless, since the ACLs 
are defined by the ZooKeeper znode
 + * creator, and the SASL config is purely JAAS (and external to the 
implementation).
 + */
 +public class ZooKeeperConfigurationMonitorTest {
 +
 +    private static final String PATH_KNOX = "/knox";
 +    private static final String PATH_KNOX_CONFIG = PATH_KNOX + "/config";
 +    private static final String PATH_KNOX_PROVIDERS = PATH_KNOX_CONFIG + 
"/shared-providers";
 +    private static final String PATH_KNOX_DESCRIPTORS = PATH_KNOX_CONFIG + 
"/descriptors";
 +
 +    private static File testTmp;
 +    private static File providersDir;
 +    private static File descriptorsDir;
 +
 +    private static TestingCluster zkCluster;
 +
 +    private static CuratorFramework client;
 +
 +    private GatewayConfig gc;
 +
 +
 +    @BeforeClass
 +    public static void setupSuite() throws Exception {
 +        testTmp = 
TestUtils.createTempDir(ZooKeeperConfigurationMonitorTest.class.getName());
 +        File confDir   = TestUtils.createTempDir(testTmp + "/conf");
 +        providersDir   = TestUtils.createTempDir(confDir + 
"/shared-providers");
 +        descriptorsDir = TestUtils.createTempDir(confDir + "/descriptors");
 +
 +        configureAndStartZKCluster();
 +    }
 +
 +    private static void configureAndStartZKCluster() throws Exception {
 +        // Configure security for the ZK cluster instances
 +        Map<String, Object> customInstanceSpecProps = new HashMap<>();
 +        customInstanceSpecProps.put("authProvider.1", 
"org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
 +        customInstanceSpecProps.put("requireClientAuthScheme", "sasl");
 +
 +        // Define the test cluster
 +        List<InstanceSpec> instanceSpecs = new ArrayList<>();
 +        for (int i = 0 ; i < 3 ; i++) {
 +            InstanceSpec is = new InstanceSpec(null, -1, -1, -1, false, 
(i+1), -1, -1, customInstanceSpecProps);
 +            instanceSpecs.add(is);
 +        }
 +        zkCluster = new TestingCluster(instanceSpecs);
 +
 +        // Start the cluster
 +        zkCluster.start();
 +
 +        // Create the client for the test cluster
 +        client = CuratorFrameworkFactory.builder()
 +                                        
.connectString(zkCluster.getConnectString())
 +                                        .retryPolicy(new 
ExponentialBackoffRetry(100, 3))
 +                                        .build();
 +        assertNotNull(client);
 +        client.start();
 +
 +        // Create the knox config paths with an ACL for the sasl user 
configured for the client
 +        List<ACL> acls = new ArrayList<>();
 +        acls.add(new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.ANYONE_ID_UNSAFE));
 +
 +        
client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).withACL(acls).forPath(PATH_KNOX_DESCRIPTORS);
 +        assertNotNull("Failed to create node:" + PATH_KNOX_DESCRIPTORS,
-                 client.checkExists().forPath(PATH_KNOX_DESCRIPTORS));
++                      client.checkExists().forPath(PATH_KNOX_DESCRIPTORS));
 +        
client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).withACL(acls).forPath(PATH_KNOX_PROVIDERS);
 +        assertNotNull("Failed to create node:" + PATH_KNOX_PROVIDERS,
-                 client.checkExists().forPath(PATH_KNOX_PROVIDERS));
++                      client.checkExists().forPath(PATH_KNOX_PROVIDERS));
 +    }
 +
 +    @AfterClass
 +    public static void tearDownSuite() throws Exception {
 +        // Clean up the ZK nodes, and close the client
 +        if (client != null) {
 +            client.delete().deletingChildrenIfNeeded().forPath(PATH_KNOX);
 +            client.close();
 +        }
 +
 +        // Shutdown the ZK cluster
 +        zkCluster.close();
 +
 +        // Delete the working dir
 +        testTmp.delete();
 +    }
 +
 +    @Test
 +    public void testZooKeeperConfigMonitor() throws Exception {
 +        String configMonitorName = "remoteConfigMonitorClient";
 +
 +        // Setup the base GatewayConfig mock
 +        gc = EasyMock.createNiceMock(GatewayConfig.class);
 +        
EasyMock.expect(gc.getGatewayProvidersConfigDir()).andReturn(providersDir.getAbsolutePath()).anyTimes();
 +        
EasyMock.expect(gc.getGatewayDescriptorsDir()).andReturn(descriptorsDir.getAbsolutePath()).anyTimes();
 +        EasyMock.expect(gc.getRemoteRegistryConfigurationNames())
 +                .andReturn(Collections.singletonList(configMonitorName))
 +                .anyTimes();
 +        final String registryConfig =
 +                                GatewayConfig.REMOTE_CONFIG_REGISTRY_TYPE + 
"=" + ZooKeeperClientService.TYPE + ";" +
 +                                GatewayConfig.REMOTE_CONFIG_REGISTRY_ADDRESS 
+ "=" + zkCluster.getConnectString();
 +        EasyMock.expect(gc.getRemoteRegistryConfiguration(configMonitorName))
 +                .andReturn(registryConfig)
 +                .anyTimes();
 +        
EasyMock.expect(gc.getRemoteConfigurationMonitorClientName()).andReturn(configMonitorName).anyTimes();
 +        EasyMock.replay(gc);
 +
 +        AliasService aliasService = 
EasyMock.createNiceMock(AliasService.class);
 +        EasyMock.replay(aliasService);
 +
 +        RemoteConfigurationRegistryClientService clientService = (new 
ZooKeeperClientServiceProvider()).newInstance();
 +        clientService.setAliasService(aliasService);
 +        clientService.init(gc, Collections.emptyMap());
 +        clientService.start();
 +
 +        DefaultRemoteConfigurationMonitor cm = new 
DefaultRemoteConfigurationMonitor(gc, clientService);
 +
++        // Create a provider configuration in the test ZK, prior to starting 
the monitor, to make sure that the monitor
++        // will download existing entries upon starting.
++        final String preExistingProviderConfig = 
getProviderPath("pre-existing-providers.xml");
++        
client.create().withMode(CreateMode.PERSISTENT).forPath(preExistingProviderConfig,
++                                                                
TEST_PROVIDERS_CONFIG_1.getBytes());
++        File preExistingProviderConfigLocalFile = new File(providersDir, 
"pre-existing-providers.xml");
++        assertFalse("This file should not exist locally prior to monitor 
starting.",
++                    preExistingProviderConfigLocalFile.exists());
++
 +        try {
 +            cm.start();
 +        } catch (Exception e) {
 +            fail("Failed to start monitor: " + e.getMessage());
 +        }
 +
++        assertTrue("This file should exist locally immediately after monitor 
starting.",
++                    preExistingProviderConfigLocalFile.exists());
++
++
 +        try {
 +            final String pc_one_znode = 
getProviderPath("providers-config1.xml");
 +            final File pc_one         = new File(providersDir, 
"providers-config1.xml");
 +            final String pc_two_znode = 
getProviderPath("providers-config2.xml");
 +            final File pc_two         = new File(providersDir, 
"providers-config2.xml");
 +
 +            
client.create().withMode(CreateMode.PERSISTENT).forPath(pc_one_znode, 
TEST_PROVIDERS_CONFIG_1.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(pc_one.exists());
 +            assertEquals(TEST_PROVIDERS_CONFIG_1, 
FileUtils.readFileToString(pc_one));
 +
 +            
client.create().withMode(CreateMode.PERSISTENT).forPath(getProviderPath("providers-config2.xml"),
 TEST_PROVIDERS_CONFIG_2.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(pc_two.exists());
 +            assertEquals(TEST_PROVIDERS_CONFIG_2, 
FileUtils.readFileToString(pc_two));
 +
 +            client.setData().forPath(pc_two_znode, 
TEST_PROVIDERS_CONFIG_1.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(pc_two.exists());
 +            assertEquals(TEST_PROVIDERS_CONFIG_1, 
FileUtils.readFileToString(pc_two));
 +
 +            client.delete().forPath(pc_two_znode);
 +            Thread.sleep(100);
 +            assertFalse(pc_two.exists());
 +
 +            client.delete().forPath(pc_one_znode);
 +            Thread.sleep(100);
 +            assertFalse(pc_one.exists());
 +
 +            final String desc_one_znode   = getDescriptorPath("test1.json");
 +            final String desc_two_znode   = getDescriptorPath("test2.json");
 +            final String desc_three_znode = getDescriptorPath("test3.json");
 +            final File desc_one           = new File(descriptorsDir, 
"test1.json");
 +            final File desc_two           = new File(descriptorsDir, 
"test2.json");
 +            final File desc_three         = new File(descriptorsDir, 
"test3.json");
 +
 +            
client.create().withMode(CreateMode.PERSISTENT).forPath(desc_one_znode, 
TEST_DESCRIPTOR_1.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(desc_one.exists());
 +            assertEquals(TEST_DESCRIPTOR_1, 
FileUtils.readFileToString(desc_one));
 +
 +            
client.create().withMode(CreateMode.PERSISTENT).forPath(desc_two_znode, 
TEST_DESCRIPTOR_1.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(desc_two.exists());
 +            assertEquals(TEST_DESCRIPTOR_1, 
FileUtils.readFileToString(desc_two));
 +
 +            client.setData().forPath(desc_two_znode, 
TEST_DESCRIPTOR_2.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(desc_two.exists());
 +            assertEquals(TEST_DESCRIPTOR_2, 
FileUtils.readFileToString(desc_two));
 +
 +            
client.create().withMode(CreateMode.PERSISTENT).forPath(desc_three_znode, 
TEST_DESCRIPTOR_1.getBytes());
 +            Thread.sleep(100);
 +            assertTrue(desc_three.exists());
 +            assertEquals(TEST_DESCRIPTOR_1, 
FileUtils.readFileToString(desc_three));
 +
 +            client.delete().forPath(desc_two_znode);
 +            Thread.sleep(100);
 +            assertFalse("Expected test2.json to have been deleted.", 
desc_two.exists());
 +
 +            client.delete().forPath(desc_three_znode);
 +            Thread.sleep(100);
 +            assertFalse(desc_three.exists());
 +
 +            client.delete().forPath(desc_one_znode);
 +            Thread.sleep(100);
 +            assertFalse(desc_one.exists());
 +        } finally {
 +            cm.stop();
 +        }
 +    }
 +
 +    private static String getDescriptorPath(String descriptorName) {
 +        return PATH_KNOX_DESCRIPTORS + "/" + descriptorName;
 +    }
 +
 +    private static String getProviderPath(String providerConfigName) {
 +        return PATH_KNOX_PROVIDERS + "/" + providerConfigName;
 +    }
 +
 +
 +    private static final String TEST_PROVIDERS_CONFIG_1 =
 +            "<gateway>\n" +
 +            "    <provider>\n" +
 +            "        <role>identity-assertion</role>\n" +
 +            "        <name>Default</name>\n" +
 +            "        <enabled>true</enabled>\n" +
 +            "    </provider>\n" +
 +            "    <provider>\n" +
 +            "        <role>hostmap</role>\n" +
 +            "        <name>static</name>\n" +
 +            "        <enabled>true</enabled>\n" +
 +            "        
<param><name>localhost</name><value>sandbox,sandbox.hortonworks.com</value></param>\n"
 +
 +            "    </provider>\n" +
 +            "</gateway>\n";
 +
 +    private static final String TEST_PROVIDERS_CONFIG_2 =
 +            "<gateway>\n" +
 +            "    <provider>\n" +
 +            "        <role>authentication</role>\n" +
 +            "        <name>ShiroProvider</name>\n" +
 +            "        <enabled>true</enabled>\n" +
 +            "        <param>\n" +
 +            "            <name>sessionTimeout</name>\n" +
 +            "            <value>30</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>main.ldapRealm</name>\n" +
 +            "            
<value>org.apache.knox.gateway.shirorealm.KnoxLdapRealm</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>main.ldapContextFactory</name>\n" +
 +            "            
<value>org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>main.ldapRealm.contextFactory</name>\n" +
 +            "            <value>$ldapContextFactory</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>main.ldapRealm.userDnTemplate</name>\n" +
 +            "            
<value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>main.ldapRealm.contextFactory.url</name>\n" +
 +            "            <value>ldap://localhost:33389</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            
<name>main.ldapRealm.contextFactory.authenticationMechanism</name>\n" +
 +            "            <value>simple</value>\n" +
 +            "        </param>\n" +
 +            "        <param>\n" +
 +            "            <name>urls./**</name>\n" +
 +            "            <value>authcBasic</value>\n" +
 +            "        </param>\n" +
 +            "    </provider>\n" +
 +            "</gateway>\n";
 +
 +    private static final String TEST_DESCRIPTOR_1 =
 +            "{\n" +
 +            "  \"discovery-type\":\"AMBARI\",\n" +
 +            "  
\"discovery-address\":\"http://sandbox.hortonworks.com:8080\",\n"; +
 +            "  \"discovery-user\":\"maria_dev\",\n" +
 +            "  
\"discovery-pwd-alias\":\"sandbox.ambari.discovery.password\",\n" +
 +            "  \"provider-config-ref\":\"sandbox-providers.xml\",\n" +
 +            "  \"cluster\":\"Sandbox\",\n" +
 +            "  \"services\":[\n" +
 +            "    {\"name\":\"NODEUI\"},\n" +
 +            "    {\"name\":\"YARNUI\"},\n" +
 +            "    {\"name\":\"HDFSUI\"},\n" +
 +            "    {\"name\":\"OOZIEUI\"},\n" +
 +            "    {\"name\":\"HBASEUI\"},\n" +
 +            "    {\"name\":\"NAMENODE\"},\n" +
 +            "    {\"name\":\"JOBTRACKER\"},\n" +
 +            "    {\"name\":\"WEBHDFS\"},\n" +
 +            "    {\"name\":\"WEBHCAT\"},\n" +
 +            "    {\"name\":\"OOZIE\"},\n" +
 +            "    {\"name\":\"WEBHBASE\"},\n" +
 +            "    {\"name\":\"RESOURCEMANAGER\"},\n" +
 +            "    {\"name\":\"AMBARI\", 
\"urls\":[\"http://c6401.ambari.apache.org:8080\"]},\n"; +
 +            "    {\"name\":\"AMBARIUI\", 
\"urls\":[\"http://c6401.ambari.apache.org:8080\"]}\n"; +
 +            "  ]\n" +
 +            "}\n";
 +
 +    private static final String TEST_DESCRIPTOR_2 =
 +            "{\n" +
 +            "  \"discovery-type\":\"AMBARI\",\n" +
 +            "  
\"discovery-address\":\"http://sandbox.hortonworks.com:8080\",\n"; +
 +            "  \"discovery-user\":\"maria_dev\",\n" +
 +            "  
\"discovery-pwd-alias\":\"sandbox.ambari.discovery.password\",\n" +
 +            "  \"provider-config-ref\":\"sandbox-providers.xml\",\n" +
 +            "  \"cluster\":\"Sandbox\",\n" +
 +            "  \"services\":[\n" +
 +            "    {\"name\":\"NAMENODE\"},\n" +
 +            "    {\"name\":\"JOBTRACKER\"},\n" +
 +            "    {\"name\":\"WEBHDFS\"},\n" +
 +            "    {\"name\":\"WEBHCAT\"},\n" +
 +            "    {\"name\":\"OOZIE\"},\n" +
 +            "    {\"name\":\"WEBHBASE\"},\n" +
 +            "    {\"name\":\"RESOURCEMANAGER\"}\n" +
 +            "  ]\n" +
 +            "}\n";
 +
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/e5fd0622/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
----------------------------------------------------------------------
diff --cc 
gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
index b768937,0000000..116b8dd
mode 100644,000000..100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
@@@ -1,1032 -1,0 +1,1048 @@@
 +/**
 + * 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.knox.gateway.util;
 +
 +import com.mycila.xmltool.XMLDoc;
 +import com.mycila.xmltool.XMLTag;
 +import org.apache.commons.io.FileUtils;
 +import org.apache.hadoop.conf.Configuration;
 +import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
 +import org.apache.knox.gateway.services.GatewayServices;
 +import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClient;
 +import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
 +import org.apache.knox.gateway.services.security.AliasService;
 +import org.apache.knox.gateway.services.security.MasterService;
 +import org.apache.knox.test.TestUtils;
 +import org.junit.Before;
 +import org.junit.Test;
 +
 +import java.io.ByteArrayOutputStream;
 +import java.io.File;
 +import java.io.FileOutputStream;
 +import java.io.IOException;
 +import java.io.PrintStream;
 +import java.net.URL;
 +import java.util.UUID;
 +
 +import static org.hamcrest.CoreMatchers.containsString;
 +import static org.hamcrest.CoreMatchers.is;
 +import static org.hamcrest.CoreMatchers.not;
 +import static org.hamcrest.CoreMatchers.notNullValue;
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertNull;
 +import static org.junit.Assert.assertThat;
 +import static org.junit.Assert.assertTrue;
 +
 +/**
 + * @author larry
 + *
 + */
 +public class KnoxCLITest {
 +  private final ByteArrayOutputStream outContent = new 
ByteArrayOutputStream();
 +  private final ByteArrayOutputStream errContent = new 
ByteArrayOutputStream();
 +
 +  @Before
 +  public void setup() throws Exception {
 +    System.setOut(new PrintStream(outContent));
 +    System.setErr(new PrintStream(errContent));
 +  }
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryClientService() throws Exception 
{
 +    outContent.reset();
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    Configuration config = new GatewayConfigImpl();
 +    // Configure a client for the test local filesystem registry 
implementation
 +    config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=/test");
 +    cli.setConf(config);
 +
 +    // This is only to get the gateway services initialized
 +    cli.run(new String[]{"version"});
 +
 +    RemoteConfigurationRegistryClientService service =
 +                                   
cli.getGatewayServices().getService(GatewayServices.REMOTE_REGISTRY_CLIENT_SERVICE);
 +    assertNotNull(service);
 +    RemoteConfigurationRegistryClient client = service.get("test_client");
 +    assertNotNull(client);
 +
 +    assertNull(service.get("bogus"));
 +  }
 +
 +  @Test
 +  public void testListRemoteConfigurationRegistryClients() throws Exception {
 +    outContent.reset();
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    String[] args = { "list-registry-clients", "--master","master" };
 +
 +    Configuration config = new GatewayConfigImpl();
 +    cli.setConf(config);
 +
 +    // Test with no registry clients configured
 +    int rc = cli.run(args);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().isEmpty());
 +
 +    // Test with a single client configured
 +    // Configure a client for the test local filesystem registry 
implementation
 +    config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=/test1");
 +    cli.setConf(config);
 +    outContent.reset();
 +    rc = cli.run(args);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("test_client"));
 +
 +    // Configure another client for the test local filesystem registry 
implementation
 +    config.set("gateway.remote.config.registry.another_client", 
"type=LocalFileSystem;address=/test2");
 +    cli.setConf(config);
 +    outContent.reset();
 +    rc = cli.run(args);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("test_client"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("another_client"));
 +  }
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryGetACLs() throws Exception {
 +    outContent.reset();
 +
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +
 +      final String providerConfigName = "my-provider-config.xml";
 +      final String providerConfigContent = "<gateway/>\n";
 +      final File testProviderConfig = new File(testRoot, providerConfigName);
 +      final String[] uploadArgs = {"upload-provider-config", 
testProviderConfig.getAbsolutePath(),
 +                                   "--registry-client", "test_client",
 +                                   "--master", "master"};
 +      FileUtils.writeStringToFile(testProviderConfig, providerConfigContent);
 +
 +
 +      final String[] args = {"get-registry-acl", 
"/knox/config/shared-providers",
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      int rc = cli.run(uploadArgs);
 +      assertEquals(0, rc);
 +
 +      // Run the test command
 +      rc = cli.run(args);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
 +      String result = outContent.toString();
 +      assertEquals(result, 3, result.split("\n").length);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryUploadProviderConfig() throws 
Exception {
 +    outContent.reset();
 +
 +    final String providerConfigName = "my-provider-config.xml";
 +    final String providerConfigContent = "<gateway/>\n";
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testProviderConfig = new File(testRoot, providerConfigName);
 +
 +      final String[] args = {"upload-provider-config", 
testProviderConfig.getAbsolutePath(),
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testProviderConfig, providerConfigContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(args);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
++
++      outContent.reset();
++      final String[] listArgs = {"list-provider-configs", 
"--registry-client", "test_client"};
++      cli.run(listArgs);
++      String outStr =  outContent.toString().trim();
++      assertTrue(outStr.startsWith("Provider Configurations"));
++      assertTrue(outStr.endsWith(")\n"+providerConfigName));
++
 +      File registryFile = new File(testRegistry, 
"knox/config/shared-providers/" + providerConfigName);
 +      assertTrue(registryFile.exists());
 +      assertEquals(FileUtils.readFileToString(registryFile), 
providerConfigContent);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +
 +  @Test
 +  public void 
testRemoteConfigurationRegistryUploadProviderConfigWithDestinationOverride() 
throws Exception {
 +    outContent.reset();
 +
 +    final String providerConfigName = "my-provider-config.xml";
 +    final String entryName = "my-providers.xml";
 +    final String providerConfigContent = "<gateway/>\n";
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testProviderConfig = new File(testRoot, providerConfigName);
 +
 +      final String[] args = {"upload-provider-config", 
testProviderConfig.getAbsolutePath(),
 +                             "--entry-name", entryName,
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testProviderConfig, providerConfigContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(args);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
 +      assertFalse((new File(testRegistry, "knox/config/shared-providers/" + 
providerConfigName)).exists());
 +      File registryFile = new File(testRegistry, 
"knox/config/shared-providers/" + entryName);
 +      assertTrue(registryFile.exists());
 +      assertEquals(FileUtils.readFileToString(registryFile), 
providerConfigContent);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryUploadDescriptor() throws 
Exception {
 +    outContent.reset();
 +
 +    final String descriptorName = "my-topology.json";
 +    final String descriptorContent = testDescriptorContentJSON;
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testDescriptor = new File(testRoot, descriptorName);
 +
 +      final String[] args = {"upload-descriptor", 
testDescriptor.getAbsolutePath(),
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testDescriptor, descriptorContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(args);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
++
++      outContent.reset();
++      final String[] listArgs = {"list-descriptors", "--registry-client", 
"test_client"};
++      cli.run(listArgs);
++      String outStr =  outContent.toString().trim();
++      assertTrue(outStr.startsWith("Descriptors"));
++      assertTrue(outStr.endsWith(")\n"+descriptorName));
++
 +      File registryFile = new File(testRegistry, "knox/config/descriptors/" + 
descriptorName);
 +      assertTrue(registryFile.exists());
 +      assertEquals(FileUtils.readFileToString(registryFile), 
descriptorContent);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +  @Test
 +  public void 
testRemoteConfigurationRegistryUploadDescriptorWithDestinationOverride() throws 
Exception {
 +    outContent.reset();
 +
 +    final String descriptorName = "my-topology.json";
 +    final String entryName = "different-topology.json";
 +    final String descriptorContent = testDescriptorContentJSON;
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testDescriptor = new File(testRoot, descriptorName);
 +
 +      final String[] args = {"upload-descriptor", 
testDescriptor.getAbsolutePath(),
 +                             "--entry-name", entryName,
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testDescriptor, descriptorContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(args);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
 +      assertFalse((new File(testRegistry, "knox/config/descriptors/" + 
descriptorName)).exists());
 +      File registryFile = new File(testRegistry, "knox/config/descriptors/" + 
entryName);
 +      assertTrue(registryFile.exists());
 +      assertEquals(FileUtils.readFileToString(registryFile), 
descriptorContent);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryDeleteProviderConfig() throws 
Exception {
 +    outContent.reset();
 +
 +    // Create a provider config
 +    final String providerConfigName = "my-provider-config.xml";
 +    final String providerConfigContent = "<gateway/>\n";
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testProviderConfig = new File(testRoot, providerConfigName);
 +
 +      final String[] createArgs = {"upload-provider-config", 
testProviderConfig.getAbsolutePath(),
 +                                   "--registry-client", "test_client",
 +                                   "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testProviderConfig, providerConfigContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(createArgs);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
 +      File registryFile = new File(testRegistry, 
"knox/config/shared-providers/" + providerConfigName);
 +      assertTrue(registryFile.exists());
 +
 +      outContent.reset();
 +
 +      // Delete the created provider config
 +      final String[] deleteArgs = {"delete-provider-config", 
providerConfigName,
 +                                   "--registry-client", "test_client",
 +                                   "--master", "master"};
 +      rc = cli.run(deleteArgs);
 +      assertEquals(0, rc);
 +      assertFalse(registryFile.exists());
 +
 +      // Try to delete a provider config that does not exist
 +      rc = cli.run(new String[]{"delete-provider-config", 
"imaginary-providers.xml",
 +                                "--registry-client", "test_client",
 +                                "--master", "master"});
 +      assertEquals(0, rc);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +  @Test
 +  public void testRemoteConfigurationRegistryDeleteDescriptor() throws 
Exception {
 +    outContent.reset();
 +
 +    final String descriptorName = "my-topology.json";
 +    final String descriptorContent = testDescriptorContentJSON;
 +
 +    final File testRoot = TestUtils.createTempDir(this.getClass().getName());
 +    try {
 +      final File testRegistry = new File(testRoot, "registryRoot");
 +      final File testDescriptor = new File(testRoot, descriptorName);
 +
 +      final String[] createArgs = {"upload-descriptor", 
testDescriptor.getAbsolutePath(),
 +                             "--registry-client", "test_client",
 +                             "--master", "master"};
 +
 +      FileUtils.writeStringToFile(testDescriptor, descriptorContent);
 +
 +      KnoxCLI cli = new KnoxCLI();
 +      Configuration config = new GatewayConfigImpl();
 +      // Configure a client for the test local filesystem registry 
implementation
 +      config.set("gateway.remote.config.registry.test_client", 
"type=LocalFileSystem;address=" + testRegistry);
 +      cli.setConf(config);
 +
 +      // Run the test command
 +      int rc = cli.run(createArgs);
 +
 +      // Validate the result
 +      assertEquals(0, rc);
 +      File registryFile = new File(testRegistry, "knox/config/descriptors/" + 
descriptorName);
 +      assertTrue(registryFile.exists());
 +
 +      outContent.reset();
 +
 +      // Delete the created provider config
 +      final String[] deleteArgs = {"delete-descriptor", descriptorName,
 +                                   "--registry-client", "test_client",
 +                                   "--master", "master"};
 +      rc = cli.run(deleteArgs);
 +      assertEquals(0, rc);
 +      assertFalse(registryFile.exists());
 +
 +      // Try to delete a descriptor that does not exist
 +      rc = cli.run(new String[]{"delete-descriptor", "bogus.json",
 +                                "--registry-client", "test_client",
 +                                "--master", "master"});
 +      assertEquals(0, rc);
 +    } finally {
 +      FileUtils.forceDelete(testRoot);
 +    }
 +  }
 +
 +  @Test
 +  public void testSuccessfulAliasLifecycle() throws Exception {
 +    outContent.reset();
 +    String[] args1 = {"create-alias", "alias1", "--value", "testvalue1", 
"--master", "master"};
 +    int rc = 0;
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    rc = cli.run(args1);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias1 
has been successfully " +
 +        "created."));
 +
 +    outContent.reset();
 +    String[] args2 = {"list-alias", "--master", 
 +        "master"};
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("alias1"));
 +
 +    outContent.reset();
 +    String[] args4 = {"delete-alias", "alias1", "--master", 
 +      "master"};
 +    rc = cli.run(args4);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias1 
has been successfully " +
 +        "deleted."));
 +
 +    outContent.reset();
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    assertFalse(outContent.toString(), 
outContent.toString().contains("alias1"));
 +  }
 +  
 +  @Test
 +  public void testListAndDeleteOfAliasForInvalidClusterName() throws 
Exception {
 +    outContent.reset();
 +    String[] args1 =
 +        { "create-alias", "alias1", "--cluster", "cluster1", "--value", 
"testvalue1", "--master",
 +            "master" };
 +    int rc = 0;
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    rc = cli.run(args1);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains(
 +      "alias1 has been successfully " + "created."));
 +
 +    outContent.reset();
 +    String[] args2 = { "list-alias", "--cluster", "Invalidcluster1", 
"--master", "master" };
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    System.out.println(outContent.toString());
 +    assertTrue(outContent.toString(),
 +      outContent.toString().contains("Invalid cluster name provided: 
Invalidcluster1"));
 +
 +    outContent.reset();
 +    String[] args4 =
 +        { "delete-alias", "alias1", "--cluster", "Invalidcluster1", 
"--master", "master" };
 +    rc = cli.run(args4);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(),
 +      outContent.toString().contains("Invalid cluster name provided: 
Invalidcluster1"));
 +
 +  }
 +
 +  @Test
 +  public void testDeleteOfNonExistAliasFromUserDefinedCluster() throws 
Exception {
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    try {
 +      int rc = 0;
 +      outContent.reset();
 +      String[] args1 =
 +          { "create-alias", "alias1", "--cluster", "cluster1", "--value", 
"testvalue1", "--master",
 +              "master" };
 +      cli.run(args1);
 +
 +      // Delete invalid alias from the cluster
 +      outContent.reset();
 +      String[] args2 = { "delete-alias", "alias2", "--cluster", "cluster1", 
"--master", "master" };
 +      rc = cli.run(args2);
 +      assertEquals(0, rc);
 +      assertTrue(outContent.toString().contains("No such alias exists in the 
cluster."));
 +    } finally {
 +      outContent.reset();
 +      String[] args1 = { "delete-alias", "alias1", "--cluster", "cluster1", 
"--master", "master" };
 +      cli.run(args1);
 +    }
 +  }
 +
 +  @Test
 +  public void testDeleteOfNonExistAliasFromDefaultCluster() throws Exception {
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    try {
 +      int rc = 0;
 +      outContent.reset();
 +      String[] args1 = { "create-alias", "alias1", "--value", "testvalue1", 
"--master", "master" };
 +      cli.run(args1);
 +
 +      // Delete invalid alias from the cluster
 +      outContent.reset();
 +      String[] args2 = { "delete-alias", "alias2", "--master", "master" };
 +      rc = cli.run(args2);
 +      assertEquals(0, rc);
 +      assertTrue(outContent.toString().contains("No such alias exists in the 
cluster."));
 +    } finally {
 +      outContent.reset();
 +      String[] args1 = { "delete-alias", "alias1", "--master", "master" };
 +      cli.run(args1);
 +    }
 +  }
 +
 +  @Test
 +  public void testForInvalidArgument() throws Exception {
 +    outContent.reset();
 +    String[] args1 = { "--value", "testvalue1", "--master", "master" };
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    int rc = cli.run(args1);
 +    assertEquals(-2, rc);
 +    assertTrue(outContent.toString().contains("ERROR: Invalid Command"));
 +  }
 +
 +  @Test
 +  public void testListAndDeleteOfAliasForValidClusterName() throws Exception {
 +    outContent.reset();
 +    String[] args1 =
 +        { "create-alias", "alias1", "--cluster", "cluster1", "--value", 
"testvalue1", "--master",
 +            "master" };
 +    int rc = 0;
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(new GatewayConfigImpl());
 +    rc = cli.run(args1);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains(
 +      "alias1 has been successfully " + "created."));
 +
 +    outContent.reset();
 +    String[] args2 = { "list-alias", "--cluster", "cluster1", "--master", 
"master" };
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    System.out.println(outContent.toString());
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("alias1"));
 +
 +    outContent.reset();
 +    String[] args4 =
 +        { "delete-alias", "alias1", "--cluster", "cluster1", "--master", 
"master" };
 +    rc = cli.run(args4);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains(
 +      "alias1 has been successfully " + "deleted."));
 +
 +    outContent.reset();
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    assertFalse(outContent.toString(), 
outContent.toString().contains("alias1"));
 +
 +  }
 +
 +  @Test
 +  public void testGatewayAndClusterStores() throws Exception {
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
 +
 +    outContent.reset();
 +    String[] gwCreateArgs = {"create-alias", "alias1", "--value", 
"testvalue1", "--master", "master"};
 +    int rc = 0;
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    rc = cli.run(gwCreateArgs);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias1 
has been successfully " +
 +        "created."));
 +
 +    AliasService as = 
cli.getGatewayServices().getService(GatewayServices.ALIAS_SERVICE);
 +
 +    outContent.reset();
 +    String[] clusterCreateArgs = {"create-alias", "alias2", "--value", 
"testvalue1", "--cluster", "test", 
 +        "--master", "master"};
 +    cli = new KnoxCLI();
 +    cli.setConf( config );
 +    rc = cli.run(clusterCreateArgs);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias2 
has been successfully " +
 +        "created."));
 +
 +    outContent.reset();
 +    String[] args2 = {"list-alias", "--master", "master"};
 +    cli = new KnoxCLI();
 +    rc = cli.run(args2);
 +    assertEquals(0, rc);
 +    assertFalse(outContent.toString(), 
outContent.toString().contains("alias2"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("alias1"));
 +
 +    char[] passwordChars = as.getPasswordFromAliasForCluster("test", 
"alias2");
 +    assertNotNull(passwordChars);
 +    assertTrue(new String(passwordChars), "testvalue1".equals(new 
String(passwordChars)));
 +
 +    outContent.reset();
 +    String[] args1 = {"list-alias", "--cluster", "test", "--master", 
"master"};
 +    cli = new KnoxCLI();
 +    rc = cli.run(args1);
 +    assertEquals(0, rc);
 +    assertFalse(outContent.toString(), 
outContent.toString().contains("alias1"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("alias2"));
 +
 +    outContent.reset();
 +    String[] args4 = {"delete-alias", "alias1", "--master", "master"};
 +    cli = new KnoxCLI();
 +    rc = cli.run(args4);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias1 
has been successfully " +
 +        "deleted."));
 +    
 +    outContent.reset();
 +    String[] args5 = {"delete-alias", "alias2", "--cluster", "test", 
"--master", "master"};
 +    cli = new KnoxCLI();
 +    rc = cli.run(args5);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("alias2 
has been successfully " +
 +        "deleted."));
 +  }
 +
 +  private void createTestMaster() throws Exception {
 +    outContent.reset();
 +    String[] args = new String[]{ "create-master", "--master", "master", 
"--force" };
 +    KnoxCLI cli = new KnoxCLI();
 +    int rc = cli.run(args);
 +    assertThat( rc, is( 0 ) );
 +    MasterService ms = cli.getGatewayServices().getService("MasterService");
 +    String master = String.copyValueOf( ms.getMasterSecret() );
 +    assertThat( master, is( "master" ) );
 +    assertThat( outContent.toString(), containsString( "Master secret has 
been persisted to disk." ) );
 +  }
 +
 +  @Test
 +  public void testCreateSelfSignedCert() throws Exception {
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
 +    createTestMaster();
 +    outContent.reset();
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    String[] gwCreateArgs = {"create-cert", "--hostname", "hostname1", 
"--master", "master"};
 +    int rc = 0;
 +    rc = cli.run(gwCreateArgs);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("gateway-identity has been successfully " +
 +        "created."));
 +  }
 +
 +  @Test
 +  public void testExportCert() throws Exception {
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
 +    createTestMaster();
 +    outContent.reset();
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    String[] gwCreateArgs = {"create-cert", "--hostname", "hostname1", 
"--master", "master"};
 +    int rc = 0;
 +    rc = cli.run(gwCreateArgs);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("gateway-identity has been successfully " +
 +        "created."));
 +
 +    outContent.reset();
 +    String[] gwCreateArgs2 = {"export-cert", "--type", "PEM"};
 +    rc = 0;
 +    rc = cli.run(gwCreateArgs2);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("Certificate gateway-identity has been 
successfully exported to"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("gateway-identity.pem"));
 +
 +    outContent.reset();
 +    String[] gwCreateArgs2_5 = {"export-cert"};
 +    rc = 0;
 +    rc = cli.run(gwCreateArgs2_5);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("Certificate gateway-identity has been 
successfully exported to"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("gateway-identity.pem"));
 +
 +    outContent.reset();
 +    String[] gwCreateArgs3 = {"export-cert", "--type", "JKS"};
 +    rc = 0;
 +    rc = cli.run(gwCreateArgs3);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("Certificate gateway-identity has been 
successfully exported to"));
 +    assertTrue(outContent.toString(), 
outContent.toString().contains("gateway-client-trust.jks"));
 +
 +    outContent.reset();
 +    String[] gwCreateArgs4 = {"export-cert", "--type", "invalid"};
 +    rc = 0;
 +    rc = cli.run(gwCreateArgs4);
 +    assertEquals(0, rc);
 +    assertTrue(outContent.toString(), outContent.toString().contains("Invalid 
type for export file provided."));
 +  }
 +
 +  @Test
 +  public void testCreateMaster() throws Exception {
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
 +    outContent.reset();
 +    String[] args = {"create-master", "--master", "master"};
 +    int rc = 0;
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    rc = cli.run(args);
 +    assertEquals(0, rc);
 +    MasterService ms = cli.getGatewayServices().getService("MasterService");
 +    // assertTrue(ms.getClass().getName(), 
ms.getClass().getName().equals("kjdfhgjkhfdgjkh"));
 +    assertTrue( new String( ms.getMasterSecret() ), "master".equals( new 
String( ms.getMasterSecret() ) ) );
 +    assertTrue(outContent.toString(), outContent.toString().contains("Master 
secret has been persisted to disk."));
 +  }
 +
 +  @Test
 +  public void testCreateMasterGenerate() throws Exception {
 +    String[] args = {"create-master", "--generate" };
 +    int rc = 0;
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    File masterFile = new File( config.getGatewaySecurityDir(), "master" );
 +
 +    // Need to delete the master file so that the change isn't ignored.
 +    if( masterFile.exists() ) {
 +      assertThat( "Failed to delete existing master file.", 
masterFile.delete(), is( true ) );
 +    }
 +    outContent.reset();
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(config);
 +    rc = cli.run(args);
 +    assertThat( rc, is( 0 ) );
 +    MasterService ms = cli.getGatewayServices().getService("MasterService");
 +    String master = String.copyValueOf( ms.getMasterSecret() );
 +    assertThat( master.length(), is( 36 ) );
 +    assertThat( master.indexOf( '-' ), is( 8 ) );
 +    assertThat( master.indexOf( '-', 9 ), is( 13 ) );
 +    assertThat( master.indexOf( '-', 14 ), is( 18 ) );
 +    assertThat( master.indexOf( '-', 19 ), is( 23 ) );
 +    assertThat( UUID.fromString( master ), notNullValue() );
 +    assertThat( outContent.toString(), containsString( "Master secret has 
been persisted to disk." ) );
 +
 +    // Need to delete the master file so that the change isn't ignored.
 +    if( masterFile.exists() ) {
 +      assertThat( "Failed to delete existing master file.", 
masterFile.delete(), is( true ) );
 +    }
 +    outContent.reset();
 +    cli = new KnoxCLI();
 +    rc = cli.run(args);
 +    ms = cli.getGatewayServices().getService("MasterService");
 +    String master2 = String.copyValueOf( ms.getMasterSecret() );
 +    assertThat( master2.length(), is( 36 ) );
 +    assertThat( UUID.fromString( master2 ), notNullValue() );
 +    assertThat( master2, not( is( master ) ) );
 +    assertThat( rc, is( 0 ) );
 +    assertThat(outContent.toString(), containsString("Master secret has been 
persisted to disk."));
 +  }
 +
 +  @Test
 +  public void testCreateMasterForce() throws Exception {
 +    GatewayConfigImpl config = new GatewayConfigImpl();
 +    File masterFile = new File( config.getGatewaySecurityDir(), "master" );
 +
 +    // Need to delete the master file so that the change isn't ignored.
 +    if( masterFile.exists() ) {
 +      assertThat( "Failed to delete existing master file.", 
masterFile.delete(), is( true ) );
 +    }
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf(config);
 +    MasterService ms;
 +    int rc = 0;
 +    outContent.reset();
 +
 +    String[] args = { "create-master", "--master", "test-master-1" };
 +
 +    rc = cli.run(args);
 +    assertThat( rc, is( 0 ) );
 +    ms = cli.getGatewayServices().getService("MasterService");
 +    String master = String.copyValueOf( ms.getMasterSecret() );
 +    assertThat( master, is( "test-master-1" ) );
 +    assertThat( outContent.toString(), containsString( "Master secret has 
been persisted to disk." ) );
 +
 +    outContent.reset();
 +    rc = cli.run(args);
 +    assertThat( rc, is(0 ) );
 +    assertThat( outContent.toString(), containsString( "Master secret is 
already present on disk." ) );
 +
 +    outContent.reset();
 +    args = new String[]{ "create-master", "--master", "test-master-2", 
"--force" };
 +    rc = cli.run(args);
 +    assertThat( rc, is( 0 ) );
 +    ms = cli.getGatewayServices().getService("MasterService");
 +    master = String.copyValueOf( ms.getMasterSecret() );
 +    assertThat( master, is( "test-master-2" ) );
 +    assertThat( outContent.toString(), containsString( "Master secret has 
been persisted to disk." ) );
 +  }
 +
 +  @Test
 +  public void testListTopology() throws Exception {
 +
 +    GatewayConfigMock config = new GatewayConfigMock();
 +    URL topoURL = 
ClassLoader.getSystemResource("conf-demo/conf/topologies/admin.xml");
 +    config.setConfDir( new 
File(topoURL.getFile()).getParentFile().getParent() );
 +    String args[] = {"list-topologies", "--master", "knox"};
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +
 +    cli.run( args );
 +    assertThat(outContent.toString(), containsString("sandbox"));
 +    assertThat(outContent.toString(), containsString("admin"));
 +  }
 +
 +  private class GatewayConfigMock extends GatewayConfigImpl{
 +    private String confDir;
 +    public void setConfDir(String location) {
 +      confDir = location;
 +    }
 +
 +    @Override
 +    public String getGatewayConfDir(){
 +      return confDir;
 +    }
 +  }
 +
 +  private static XMLTag createBadTopology() {
 +    XMLTag xml = XMLDoc.newDocument(true)
 +        .addRoot( "topology" )
 +        .addTag( "gateway" )
 +
 +        .addTag( "provider" )
 +        .addTag( "role" ).addText( "authentication" )
 +        .addTag( "name" ).addText( "ShiroProvider" )
 +        .addTag( "enabled" ).addText( "123" )
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "" )
 +        .addTag( "value" ).addText( 
"org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" )
 +        .addTag( "value" ).addText( 
"uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" )
 +        .addTag( "value" ).addText( "ldap://localhost:8443"; ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( 
"main.ldapRealm.contextFactory.authenticationMechanism" )
 +        .addTag( "value" ).addText( "simple" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "urls./**" )
 +        .addTag( "value" ).addText( "authcBasic" ).gotoParent().gotoParent()
 +        .addTag( "provider" )
 +        .addTag( "role" ).addText( "identity-assertion" )
 +        .addTag( "enabled" ).addText( "vvv" )
 +        .addTag( "name" ).addText( "Default" ).gotoParent()
 +        .addTag( "provider" )
 +        .gotoRoot()
 +        .addTag( "service" )
 +        .addTag( "role" ).addText( "test-service-role" )
 +        .gotoRoot();
 +    return xml;
 +  }
 +
 +  private static XMLTag createGoodTopology() {
 +    XMLTag xml = XMLDoc.newDocument( true )
 +        .addRoot( "topology" )
 +        .addTag( "gateway" )
 +
 +        .addTag( "provider" )
 +        .addTag( "role" ).addText( "authentication" )
 +        .addTag( "name" ).addText( "ShiroProvider" )
 +        .addTag( "enabled" ).addText( "true" )
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "main.ldapRealm" )
 +        .addTag( "value" ).addText( 
"org.apache.knox.gateway.shirorealm.KnoxLdapRealm" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "main.ldapRealm.userDnTemplate" )
 +        .addTag( "value" ).addText( 
"uid={0},ou=people,dc=hadoop,dc=apache,dc=org" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "main.ldapRealm.contextFactory.url" )
 +        .addTag( "value" ).addText( "ldap://localhost:8443";).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( 
"main.ldapRealm.contextFactory.authenticationMechanism" )
 +        .addTag( "value" ).addText( "simple" ).gotoParent()
 +        .addTag( "param" )
 +        .addTag( "name" ).addText( "urls./**" )
 +        .addTag( "value" ).addText( "authcBasic" ).gotoParent().gotoParent()
 +        .addTag( "provider" )
 +        .addTag( "role" ).addText( "identity-assertion" )
 +        .addTag( "enabled" ).addText( "true" )
 +        .addTag( "name" ).addText( "Default" ).gotoParent()
 +        .addTag( "provider" )
 +        .gotoRoot()
 +        .addTag( "service" )
 +        .addTag( "role" ).addText( "test-service-role" )
 +        .gotoRoot();
 +    return xml;
 +  }
 +
 +  private File writeTestTopology( String name, XMLTag xml ) throws 
IOException {
 +    // Create the test topology.
 +
 +    GatewayConfigMock config = new GatewayConfigMock();
 +    URL topoURL = 
ClassLoader.getSystemResource("conf-demo/conf/topologies/admin.xml");
 +    config.setConfDir( new 
File(topoURL.getFile()).getParentFile().getParent() );
 +
 +    File tempFile = new File( config.getGatewayTopologyDir(), name + ".xml." 
+ UUID.randomUUID() );
 +    FileOutputStream stream = new FileOutputStream( tempFile );
 +    xml.toStream( stream );
 +    stream.close();
 +    File descriptor = new File( config.getGatewayTopologyDir(), name + ".xml" 
);
 +    tempFile.renameTo( descriptor );
 +    return descriptor;
 +  }
 +
 +  @Test
 +  public void testValidateTopology() throws Exception {
 +
 +    GatewayConfigMock config = new GatewayConfigMock();
 +    URL topoURL = 
ClassLoader.getSystemResource("conf-demo/conf/topologies/admin.xml");
 +    config.setConfDir( new 
File(topoURL.getFile()).getParentFile().getParent() );
 +    String args[] = {"validate-topology", "--master", "knox", "--cluster", 
"sandbox"};
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    cli.run( args );
 +
 +    assertThat(outContent.toString(), 
containsString(config.getGatewayTopologyDir()));
 +    assertThat(outContent.toString(), containsString("sandbox"));
 +    assertThat(outContent.toString(), containsString("success"));
 +    outContent.reset();
 +
 +
 +    String args2[] = {"validate-topology", "--master", "knox", "--cluster", 
"NotATopology"};
 +    cli.run(args2);
 +
 +    assertThat(outContent.toString(), containsString("NotATopology"));
 +    assertThat(outContent.toString(), containsString("does not exist"));
 +    outContent.reset();
 +
 +    String args3[] = {"validate-topology", "--master", "knox", "--path", 
config.getGatewayTopologyDir() + "/admin.xml"};
 +    cli.run(args3);
 +
 +    assertThat(outContent.toString(), containsString("admin"));
 +    assertThat(outContent.toString(), containsString("success"));
 +    outContent.reset();
 +
 +    String args4[] = {"validate-topology", "--master", "knox", "--path", 
"not/a/path"};
 +    cli.run(args4);
 +    assertThat(outContent.toString(), containsString("does not exist"));
 +    assertThat(outContent.toString(), containsString("not/a/path"));
 +  }
 +
 +  @Test
 +  public void testValidateTopologyOutput() throws Exception {
 +
 +    File bad = writeTestTopology( "test-cluster-bad", createBadTopology() );
 +    File good = writeTestTopology( "test-cluster-good", createGoodTopology() 
);
 +
 +    GatewayConfigMock config = new GatewayConfigMock();
 +    URL topoURL = 
ClassLoader.getSystemResource("conf-demo/conf/topologies/admin.xml");
 +    config.setConfDir( new 
File(topoURL.getFile()).getParentFile().getParent() );
 +    String args[] = {"validate-topology", "--master", "knox", "--cluster", 
"test-cluster-bad"};
 +
 +    KnoxCLI cli = new KnoxCLI();
 +    cli.setConf( config );
 +    cli.run( args );
 +
 +    assertThat(outContent.toString(), 
containsString(config.getGatewayTopologyDir()));
 +    assertThat(outContent.toString(), containsString("test-cluster-bad"));
 +    assertThat(outContent.toString(), containsString("unsuccessful"));
 +    assertThat(outContent.toString(), containsString("Invalid content"));
 +    assertThat(outContent.toString(), containsString("Line"));
 +
 +
 +    outContent.reset();
 +
 +    String args2[] = {"validate-topology", "--master", "knox", "--cluster", 
"test-cluster-good"};
 +
 +    cli.run(args2);
 +
 +    assertThat(outContent.toString(), 
containsString(config.getGatewayTopologyDir()));
 +    assertThat(outContent.toString(), containsString("success"));
 +    assertThat(outContent.toString(), containsString("test-cluster-good"));
 +
 +
 +  }
 +
 +  private static final String testDescriptorContentJSON = "{\n" +
 +                                                          "  
\"discovery-address\":\"http://localhost:8080\",\n"; +
 +                                                          "  
\"discovery-user\":\"maria_dev\",\n" +
 +                                                          "  
\"discovery-pwd-alias\":\"sandbox.discovery.password\",\n" +
 +                                                          "  
\"provider-config-ref\":\"my-provider-config\",\n" +
 +                                                          "  
\"cluster\":\"Sandbox\",\n" +
 +                                                          "  
\"services\":[\n" +
 +                                                          "    
{\"name\":\"NAMENODE\"},\n" +
 +                                                          "    
{\"name\":\"JOBTRACKER\"},\n" +
 +                                                          "    
{\"name\":\"WEBHDFS\"},\n" +
 +                                                          "    
{\"name\":\"WEBHCAT\"},\n" +
 +                                                          "    
{\"name\":\"OOZIE\"},\n" +
 +                                                          "    
{\"name\":\"WEBHBASE\"},\n" +
 +                                                          "    
{\"name\":\"HIVE\"},\n" +
 +                                                          "    
{\"name\":\"RESOURCEMANAGER\"}\n" +
 +                                                          "  ]\n" +
 +                                                          "}";
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/e5fd0622/pom.xml
----------------------------------------------------------------------

Reply via email to