You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2017/11/28 03:04:06 UTC

[05/15] directory-kerby git commit: Change the Maven groupId in HAS folder to org.apache.kerby.

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/TestHasWebServer.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestHasWebServer.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/TestHasWebServer.java
deleted file mode 100644
index 148909f..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestHasWebServer.java
+++ /dev/null
@@ -1,128 +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.hadoop.has.server;
-
-import org.apache.hadoop.fs.FileUtil;
-import org.apache.hadoop.has.common.HasConfig;
-import org.apache.hadoop.has.common.util.URLConnectionFactory;
-import org.apache.hadoop.has.server.web.WebConfigKey;
-import org.apache.hadoop.has.server.web.WebServer;
-import org.apache.hadoop.http.HttpConfig.Policy;
-import org.apache.hadoop.net.NetUtils;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Arrays;
-import java.util.Collection;
-
-@RunWith(value = Parameterized.class)
-public class TestHasWebServer {
-  private static final String KEY_STORE_DIR = TestUtil.getTempPath("keystore");
-  private static File keyStoreDir = new File(KEY_STORE_DIR);
-  private static HasConfig httpsConf;
-  private static URLConnectionFactory connectionFactory;
-
-  @Parameterized.Parameters
-  public static Collection<Object[]> policy() {
-    Object[][] params = new Object[][]{{Policy.HTTP_ONLY},
-        {Policy.HTTPS_ONLY}, {Policy.HTTP_AND_HTTPS}};
-    return Arrays.asList(params);
-  }
-
-  private final Policy policy;
-
-  public TestHasWebServer(Policy policy) {
-    super();
-    this.policy = policy;
-  }
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    httpsConf = new HasConfig();
-    // Create test keystore dir.
-    if (!keyStoreDir.exists()) {
-      if (!keyStoreDir.mkdirs()) {
-        System.err.println("Failed to create keystore-dir.");
-        System.exit(3);
-      }
-    }
-    String sslConfDir = TestUtil.getClasspathDir(TestRestApiBase.class);
-    TestUtil.setupSSLConfig(KEY_STORE_DIR, sslConfDir, httpsConf, false);
-    connectionFactory = URLConnectionFactory.newDefaultURLConnectionFactory(httpsConf);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    FileUtil.fullyDelete(keyStoreDir);
-  }
-
-  @Test
-  public void testHttpPolicy() throws Exception {
-    httpsConf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY, policy.name());
-    httpsConf.setString(WebConfigKey.HAS_HTTP_ADDRESS_KEY, "localhost:11236");
-    httpsConf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, "localhost:19278");
-    httpsConf.setString(WebConfigKey.HAS_AUTHENTICATION_FILTER_AUTH_TYPE, "simple");
-
-    WebServer server = null;
-    try {
-      server = new WebServer(httpsConf);
-      server.start();
-
-      Assert.assertTrue(implies(policy.isHttpEnabled(),
-          canAccess("http", server.getHttpAddress())));
-      Assert.assertTrue(implies(!policy.isHttpEnabled(),
-          server.getHttpAddress() == null));
-
-      Assert.assertTrue(implies(policy.isHttpsEnabled(),
-          canAccess("https", server.getHttpsAddress())));
-      Assert.assertTrue(implies(!policy.isHttpsEnabled(),
-          server.getHttpsAddress() == null));
-    } finally {
-      if (server != null) {
-        server.stop();
-      }
-    }
-  }
-
-  private static boolean canAccess(String scheme, InetSocketAddress address) {
-    if (address == null) {
-      return false;
-    }
-    try {
-      URL url = new URL(scheme + "://" + NetUtils.getHostPortString(address));
-      URLConnection conn = connectionFactory.openConnection(url);
-      conn.connect();
-      conn.getContent();
-    } catch (Exception e) {
-      return false;
-    }
-    return true;
-  }
-
-  private static boolean implies(boolean a, boolean b) {
-    return !a || b;
-  }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/TestRestApiBase.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestRestApiBase.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/TestRestApiBase.java
deleted file mode 100644
index e95382c..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestRestApiBase.java
+++ /dev/null
@@ -1,336 +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.hadoop.has.server;
-
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.client.urlconnection.HTTPSProperties;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
-import org.apache.hadoop.fs.FileUtil;
-import org.apache.hadoop.has.common.HasConfig;
-import org.apache.hadoop.has.common.HasConfigKey;
-import org.apache.hadoop.has.common.HasException;
-import org.apache.hadoop.has.common.spnego.AuthenticationException;
-import org.apache.hadoop.has.common.util.URLConnectionFactory;
-import org.apache.hadoop.has.server.web.WebConfigKey;
-import org.apache.hadoop.has.server.web.WebServer;
-import org.apache.hadoop.http.HttpConfig;
-import org.apache.hadoop.security.ssl.SSLFactory;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.glassfish.jersey.SslConfigurator;
-import org.junit.After;
-import org.junit.Before;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.ws.rs.core.MultivaluedMap;
-import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import static org.junit.Assert.assertEquals;
-
-public class TestRestApiBase {
-    private static String address;
-    protected static File testDir = new File(System.getProperty("test.dir", "target"));
-    private static File testClassDir = new File(testDir, "test-classes");
-    private static File confDir = new File(testClassDir, "conf");
-    private static File workDir = new File(testDir, "work-dir");
-    private static HasServer server = null;
-    private static final String KEY_STORE_DIR = TestUtil.getTempPath("keystore");
-    private static File keyStoreDir = new File(KEY_STORE_DIR);
-    private static HasConfig httpsConf;
-
-    @Before
-    public void startHasServer() throws Exception {
-        // Create test keystoreDir and workDir.
-        if (!keyStoreDir.exists()) {
-            if (!keyStoreDir.mkdirs()) {
-                System.err.println("Failed to create keystore-dir.");
-                System.exit(3);
-            }
-        }
-
-        if (!workDir.exists()) {
-            if (!workDir.mkdirs()) {
-                System.err.println("Failed to create work-dir.");
-                System.exit(3);
-            }
-        }
-
-        // Configure test HAS server.
-        httpsConf = new HasConfig();
-        String sslConfDir = TestUtil.getClasspathDir(TestRestApiBase.class);
-        TestUtil.setupSSLConfig(KEY_STORE_DIR, sslConfDir, httpsConf, false);
-        httpsConf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name());
-        httpsConf.setString(HasConfigKey.FILTER_AUTH_TYPE, "simple");
-
-        // Start test HAS server.
-        int httpsPort = 10000 + (int) (System.currentTimeMillis() % 10000); // Generate test port randomly
-        String host = "localhost";
-        address = host + ":" + httpsPort;
-        httpsConf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, address);
-
-        server = new HasServer(confDir);
-        server.setWebServer(new WebServer(httpsConf));
-        server.setWorkDir(workDir);
-        try {
-            server.startWebServer();
-        } catch (HasException e) {
-            System.err.println("Errors occurred when start HAS server: " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    @After
-    public void stopHasServer() {
-        server.stopWebServer();
-        if (keyStoreDir.exists()) {
-            FileUtil.fullyDelete(keyStoreDir);
-        }
-        if (workDir.exists()) {
-            FileUtil.fullyDelete(workDir);
-        }
-    }
-
-    private void startKdc() {
-        WebResource webResource = getWebResource("kdcstart");
-        String response = webResource.get(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            if (!result.getString("result").equals("success")) {
-                System.err.println("Errors occurred when start HAS KDC server.");
-                System.exit(6);
-            }
-        } catch (JSONException e) {
-            System.err.println("Errors occurred when start HAS KDC server. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected WebResource getWebResource(String restName) {
-        String apiUrl = "https://" + address + "/has/v1/" + restName;
-        HasConfig clientConf = new HasConfig();
-        try {
-            clientConf.addIniConfig(new File(httpsConf.getString(SSLFactory.SSL_CLIENT_CONF_KEY)));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        SslConfigurator sslConfigurator = SslConfigurator.newInstance()
-            .trustStoreFile(clientConf.getString("ssl.client.truststore.location"))
-            .trustStorePassword(clientConf.getString("ssl.client.truststore.password"));
-        sslConfigurator.securityProtocol("SSL");
-        SSLContext sslContext = sslConfigurator.createSSLContext();
-        ClientConfig clientConfig = new DefaultClientConfig();
-        clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
-            new HTTPSProperties(new HostnameVerifier() {
-                @Override
-                public boolean verify(String s, SSLSession sslSession) {
-                    return false;
-                }
-            }, sslContext));
-        Client client = Client.create(clientConfig);
-        return client.resource(apiUrl);
-    }
-
-    protected void getKrb5Conf() {
-        WebResource webResource = getWebResource("getkrb5conf");
-        ClientResponse response = webResource.get(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-    }
-
-    protected void getHasConf() {
-        WebResource webResource = getWebResource("gethasconf");
-        ClientResponse response = webResource.get(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-        File hasConf = new File(confDir, "has-client.conf");
-        if (hasConf.exists()) {
-            if (!hasConf.delete()) {
-                System.err.println("Failed to delete has-client.conf.");
-            }
-        }
-    }
-
-    protected void kdcStart() {
-        WebResource webResource = getWebResource("kdcstart");
-        String response = webResource.get(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException e) {
-            System.err.println("Failed to start HAS KDC server. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected void kdcInit() {
-        startKdc();
-        WebResource webResource = getWebResource("kdcinit");
-        ClientResponse response = webResource.get(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-    }
-
-    protected void createPrincipals() {
-        String webServerUrl = "https://" + address + "/has/v1/";
-        startKdc();
-
-        // Create test host roles json object.
-        JSONObject hostRoles = new JSONObject();
-        try {
-            JSONObject host1 = new JSONObject();
-            host1.put("name", "host1");
-            host1.put("hostRoles", "HDFS,YARN");
-            JSONObject host2 = new JSONObject();
-            host2.put("name", "host2");
-            host2.put("hostRoles", "ZOOKEEPER,HBASE");
-            JSONArray hosts = new JSONArray();
-            hosts.put(host1);
-            hosts.put(host2);
-            hostRoles.put("HOSTS", hosts);
-        } catch (JSONException e) {
-            System.err.println("Failed to create test host roles json object. " + e.toString());
-            System.exit(6);
-        }
-
-        try {
-            URL url = null;
-            try {
-                url = new URL(webServerUrl + "admin/createprincipals");
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-            }
-
-            URLConnectionFactory connectionFactory = URLConnectionFactory.newDefaultURLConnectionFactory(httpsConf);
-            HttpURLConnection httpConn = (HttpURLConnection) connectionFactory.openConnection(url, false, httpsConf);
-            httpConn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
-            httpConn.setRequestMethod("PUT");
-            httpConn.setDoOutput(true);
-            httpConn.setDoInput(true);
-            httpConn.connect();
-
-            OutputStream out = httpConn.getOutputStream();
-            out.write(hostRoles.toString().getBytes());
-            out.flush();
-            out.close();
-
-            assertEquals(200, httpConn.getResponseCode());
-            BufferedReader reader = httpConn.getResponseCode()
-                == HttpURLConnection.HTTP_OK ? new BufferedReader(
-                new InputStreamReader(httpConn.getInputStream(),
-                    "UTF-8")) : new BufferedReader(
-                new InputStreamReader(httpConn.getErrorStream(),
-                    "UTF-8"));
-
-            String response = reader.readLine();
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException | IOException | AuthenticationException e) {
-            System.err.println("Failed to create principals by hostRoles. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected void exportKeytabs() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/exportkeytabs");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("host", "host1");
-        params.add("role", "HDFS");
-        ClientResponse response = webResource.queryParams(params).get(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-    }
-
-    protected void exportKeytab() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/exportkeytab");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("principal", "admin@HADOOP.COM");
-        ClientResponse response = webResource.queryParams(params).get(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-    }
-
-    protected void addPrincipal() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/addprincipal");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("principal", "admin");
-        params.add("password", "123");
-        String response = webResource.queryParams(params).post(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException e) {
-            System.err.println("Failed to add principal. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected void getPrincipals() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/getprincipals");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        String response = webResource.queryParams(params).get(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException e) {
-            System.err.println("Failed to get principals. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected void renamePrincipal() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/renameprincipal");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("oldprincipal", "admin");
-        params.add("newprincipal", "admin2");
-        String response = webResource.queryParams(params).post(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException e) {
-            System.err.println("Failed to rename principal. " + e.toString());
-            System.exit(6);
-        }
-    }
-
-    protected void deletePrincipal() {
-        startKdc();
-        WebResource webResource = getWebResource("admin/deleteprincipal");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("principal", "admin2");
-        String response = webResource.queryParams(params).delete(String.class);
-        try {
-            JSONObject result = new JSONObject(response);
-            assertEquals("success", result.getString("result"));
-        } catch (JSONException e) {
-            System.err.println("Failed to delete principal. " + e.toString());
-            System.exit(6);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/TestUtil.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestUtil.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/TestUtil.java
deleted file mode 100644
index 1ae1a64..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/TestUtil.java
+++ /dev/null
@@ -1,368 +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.hadoop.has.server;
-
-import org.apache.hadoop.has.common.HasConfig;
-import org.apache.hadoop.has.server.web.WebConfigKey;
-import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory;
-import org.apache.hadoop.security.ssl.SSLFactory;
-import org.bouncycastle.x509.X509V1CertificateGenerator;
-
-import javax.security.auth.x500.X500Principal;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.SignatureException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-class TestUtil {
-
-  /**
-   * system property for test data: {@value}
-   */
-  private static final String SYSPROP_TEST_DATA_DIR = "test.build.data";
-
-  /**
-   * The default path for using in Hadoop path references: {@value}
-   */
-  private static final String DEFAULT_TEST_DATA_PATH = "target/";
-
-  /**
-   * Get a temp path. This may or may not be relative; it depends on what the
-   * {@link #SYSPROP_TEST_DATA_DIR} is set to. If unset, it returns a path
-   * under the relative path {@link #DEFAULT_TEST_DATA_PATH}
-   *
-   * @param subPath sub path, with no leading "/" character
-   * @return a string to use in paths
-   */
-  public static String getTempPath(String subPath) {
-    String prop = System.getProperty(SYSPROP_TEST_DATA_DIR, DEFAULT_TEST_DATA_PATH);
-    if (prop.isEmpty()) {
-      // corner case: property is there but empty
-      prop = DEFAULT_TEST_DATA_PATH;
-    }
-    if (!prop.endsWith("/")) {
-      prop = prop + "/";
-    }
-    return prop + subPath;
-  }
-
-  public static String getClasspathDir(Class testClass) throws Exception {
-    String file = testClass.getName();
-    file = file.replace('.', '/') + ".class";
-    URL url = Thread.currentThread().getContextClassLoader().getResource(file);
-    String baseDir = url.toURI().getPath();
-    baseDir = baseDir.substring(0, baseDir.length() - file.length() - 1);
-    return baseDir;
-  }
-
-  @SuppressWarnings("deprecation")
-  /*
-   * Create a self-signed X.509 Certificate.
-   *
-   * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
-   * @param pair the KeyPair
-   * @param days how many days from now the Certificate is valid for
-   * @param algorithm the signing algorithm, eg "SHA1withRSA"
-   * @return the self-signed certificate
-   */
-  private static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
-      throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
-      NoSuchProviderException, NoSuchAlgorithmException, SignatureException {
-
-    Date from = new Date();
-    Date to = new Date(from.getTime() + days * 86400000L);
-    BigInteger sn = new BigInteger(64, new SecureRandom());
-    X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
-    X500Principal dnName = new X500Principal(dn);
-
-    certGen.setSerialNumber(sn);
-    certGen.setIssuerDN(dnName);
-    certGen.setNotBefore(from);
-    certGen.setNotAfter(to);
-    certGen.setSubjectDN(dnName);
-    certGen.setPublicKey(pair.getPublic());
-    certGen.setSignatureAlgorithm(algorithm);
-
-    return certGen.generate(pair.getPrivate());
-  }
-
-  private static KeyPair generateKeyPair(String algorithm) throws NoSuchAlgorithmException {
-    KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
-    keyGen.initialize(1024);
-    return keyGen.genKeyPair();
-  }
-
-  private static KeyStore createEmptyKeyStore() throws GeneralSecurityException, IOException {
-    KeyStore ks = KeyStore.getInstance("JKS");
-    ks.load(null, null); // initialize
-    return ks;
-  }
-
-  private static void saveKeyStore(KeyStore ks, String filename, String password)
-      throws GeneralSecurityException, IOException {
-    FileOutputStream out = new FileOutputStream(filename);
-    ks.store(out, password.toCharArray());
-    out.close();
-  }
-
-  private static void createKeyStore(String filename, String password, String alias, Key privateKey, Certificate cert)
-      throws GeneralSecurityException, IOException {
-    KeyStore ks = createEmptyKeyStore();
-    ks.setKeyEntry(alias, privateKey, password.toCharArray(), new Certificate[]{cert});
-    saveKeyStore(ks, filename, password);
-  }
-
-  private static <T extends Certificate> void createTrustStore(String filename, String password, Map<String, T> certs)
-      throws GeneralSecurityException, IOException {
-    KeyStore ks = createEmptyKeyStore();
-    for (Map.Entry<String, T> cert : certs.entrySet()) {
-      ks.setCertificateEntry(cert.getKey(), cert.getValue());
-    }
-    saveKeyStore(ks, filename, password);
-  }
-
-  /**
-   * Performs complete setup of SSL configuration in preparation for testing an
-   * SSLFactory.  This includes keys, certs, keystore, truststore, the server
-   * SSL configuration file, the client SSL configuration file, and the master
-   * configuration file read by the SSLFactory.
-   *
-   * @param keystoreDir   String directory to save keystore
-   * @param sslConfDir    String directory to save SSL configuration files
-   * @param conf          Configuration master configuration to be used by an SSLFactory,
-   *                      which will be mutated by this method
-   * @param useClientCert boolean true to make the client present a cert in the SSL handshake
-   */
-  public static void setupSSLConfig(String keystoreDir, String sslConfDir, HasConfig conf, boolean useClientCert)
-      throws Exception {
-    setupSSLConfig(keystoreDir, sslConfDir, conf, useClientCert, true, "");
-  }
-
-  /**
-   * Performs complete setup of SSL configuration in preparation for testing an
-   * SSLFactory.  This includes keys, certs, keystore, truststore, the server
-   * SSL configuration file, the client SSL configuration file, and the master
-   * configuration file read by the SSLFactory.
-   *
-   * @param keystoreDir   String directory to save keystore
-   * @param sslConfDir    String directory to save SSL configuration files
-   * @param conf          Configuration master configuration to be used by an SSLFactory,
-   *                      which will be mutated by this method
-   * @param useClientCert boolean true to make the client present a cert in the SSL handshake
-   * @param trustStore    boolean true to create truststore, false not to create it
-   * @param excludeCiphers String comma separated ciphers to exclude
-   * @throws Exception e
-   */
-  private static void setupSSLConfig(String keystoreDir, String sslConfDir, HasConfig conf, boolean useClientCert,
-                                     boolean trustStore, String excludeCiphers) throws Exception {
-    String clientKS = keystoreDir + "/clientKS.jks";
-    String clientPassword = "clientP";
-    String serverKS = keystoreDir + "/serverKS.jks";
-    String serverPassword = "serverP";
-    String trustKS = null;
-    String trustPassword = "trustP";
-
-    File sslClientConfFile = new File(sslConfDir, getClientSSLConfigFileName());
-    File sslServerConfFile = new File(sslConfDir, getServerSSLConfigFileName());
-
-    Map<String, X509Certificate> certs = new HashMap<String, X509Certificate>();
-
-    if (useClientCert) {
-      KeyPair cKP = TestUtil.generateKeyPair("RSA");
-      X509Certificate cCert = TestUtil.generateCertificate("CN=localhost, O=client", cKP, 30, "SHA1withRSA");
-      TestUtil.createKeyStore(clientKS, clientPassword, "client", cKP.getPrivate(), cCert);
-      certs.put("client", cCert);
-    }
-
-    KeyPair sKP = TestUtil.generateKeyPair("RSA");
-    X509Certificate sCert = TestUtil.generateCertificate("CN=localhost, O=server", sKP, 30, "SHA1withRSA");
-    TestUtil.createKeyStore(serverKS, serverPassword, "server", sKP.getPrivate(), sCert);
-    certs.put("server", sCert);
-
-    if (trustStore) {
-      trustKS = keystoreDir + "/trustKS.jks";
-      TestUtil.createTrustStore(trustKS, trustPassword, certs);
-    }
-
-    HasConfig clientSSLConf = createClientSSLConfig(clientKS, clientPassword, clientPassword, trustKS, excludeCiphers);
-    HasConfig serverSSLConf = createServerSSLConfig(serverKS, serverPassword, serverPassword, trustKS, excludeCiphers);
-
-    saveConfig(sslClientConfFile, clientSSLConf);
-    saveConfig(sslServerConfFile, serverSSLConf);
-
-    conf.setString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
-    conf.setString(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfFile.getCanonicalPath());
-    conf.setString(SSLFactory.SSL_SERVER_CONF_KEY, sslServerConfFile.getCanonicalPath());
-    conf.setString(WebConfigKey.HAS_SERVER_HTTPS_KEYSTORE_RESOURCE_KEY, sslServerConfFile.getAbsolutePath());
-    conf.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, useClientCert);
-  }
-
-  /**
-   * Create SSL configuration for a client.
-   *
-   * @param clientKS       String client keystore file
-   * @param password       String store password, or null to avoid setting store password
-   * @param keyPassword    String key password, or null to avoid setting key password
-   * @param trustKS        String truststore file
-   * @param excludeCiphers String comma separated ciphers to exclude
-   * @return Configuration for client SSL
-   */
-  private static HasConfig createClientSSLConfig(String clientKS, String password, String keyPassword,
-                                                 String trustKS, String excludeCiphers) {
-    return createSSLConfig(SSLFactory.Mode.CLIENT, clientKS, password, keyPassword, trustKS, excludeCiphers);
-  }
-
-  /**
-   * Creates SSL configuration for a server.
-   *
-   * @param serverKS       String server keystore file
-   * @param password       String store password, or null to avoid setting store password
-   * @param keyPassword    String key password, or null to avoid setting key password
-   * @param trustKS        String truststore file
-   * @param excludeCiphers String comma separated ciphers to exclude
-   * @return HasConfig
-   * @throws IOException e
-   */
-  private static HasConfig createServerSSLConfig(String serverKS, String password, String keyPassword,
-                                                 String trustKS, String excludeCiphers) throws IOException {
-    return createSSLConfig(SSLFactory.Mode.SERVER, serverKS, password, keyPassword, trustKS, excludeCiphers);
-  }
-
-  /**
-   * Returns the client SSL configuration file name.  Under parallel test
-   * execution, this file name is parametrized by a unique ID to ensure that
-   * concurrent tests don't collide on an SSL configuration file.
-   *
-   * @return client SSL configuration file name
-   */
-  private static String getClientSSLConfigFileName() {
-    return getSSLConfigFileName("ssl-client");
-  }
-
-  /**
-   * Returns the server SSL configuration file name.  Under parallel test
-   * execution, this file name is parametrized by a unique ID to ensure that
-   * concurrent tests don't collide on an SSL configuration file.
-   *
-   * @return client SSL configuration file name
-   */
-  private static String getServerSSLConfigFileName() {
-    return getSSLConfigFileName("ssl-server");
-  }
-
-  /**
-   * Returns an SSL configuration file name.  Under parallel test
-   * execution, this file name is parametrized by a unique ID to ensure that
-   * concurrent tests don't collide on an SSL configuration file.
-   *
-   * @param base the base of the file name
-   * @return SSL configuration file name for base
-   */
-  private static String getSSLConfigFileName(String base) {
-    String testUniqueForkId = System.getProperty("test.unique.fork.id");
-    String fileSuffix = testUniqueForkId != null ? "-" + testUniqueForkId : "";
-    return base + fileSuffix + ".xml";
-  }
-
-  /**
-   * Creates SSL configuration.
-   *
-   * @param mode        SSLFactory.Mode mode to configure
-   * @param keystore    String keystore file
-   * @param password    String store password, or null to avoid setting store password
-   * @param keyPassword String key password, or null to avoid setting key password
-   * @param trustKS     String truststore file
-   * @return Configuration for SSL
-   */
-  private static HasConfig createSSLConfig(SSLFactory.Mode mode, String keystore, String password,
-                                           String keyPassword, String trustKS, String excludeCiphers) {
-    String trustPassword = "trustP";
-
-    HasConfig sslConf = new HasConfig();
-    if (keystore != null) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_KEYSTORE_LOCATION_TPL_KEY), keystore);
-    }
-    if (password != null) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_KEYSTORE_PASSWORD_TPL_KEY), password);
-    }
-    if (keyPassword != null) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_KEYSTORE_KEYPASSWORD_TPL_KEY),
-          keyPassword);
-    }
-    if (trustKS != null) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_TRUSTSTORE_LOCATION_TPL_KEY), trustKS);
-    }
-    if (trustPassword != null) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_TRUSTSTORE_PASSWORD_TPL_KEY),
-          trustPassword);
-    }
-    if (null != excludeCiphers && !excludeCiphers.isEmpty()) {
-      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-          FileBasedKeyStoresFactory.SSL_EXCLUDE_CIPHER_LIST),
-          excludeCiphers);
-    }
-    sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
-        FileBasedKeyStoresFactory.SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY), "1000");
-
-    return sslConf;
-  }
-
-  /**
-   * Saves configuration to a file.
-   *
-   * @param file File to save
-   * @param conf Configuration contents to write to file
-   * @throws IOException if there is an I/O error saving the file
-   */
-  private static void saveConfig(File file, HasConfig conf) throws IOException {
-    OutputStream output = new FileOutputStream(file);
-    Properties prop = new Properties();
-
-    // set the properties value
-    for (String name : conf.getNames()) {
-      prop.setProperty(name, conf.getString(name));
-    }
-
-    // save properties to project root folder
-    prop.store(output, null);
-  }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonConfApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonConfApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonConfApi.java
deleted file mode 100644
index 1f7b443..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonConfApi.java
+++ /dev/null
@@ -1,83 +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.hadoop.has.server.json;
-
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import java.io.File;
-import java.io.IOException;
-import javax.ws.rs.core.MultivaluedMap;
-
-import static org.junit.Assert.assertEquals;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestJsonConfApi extends TestRestApiBase {
-
-    @Test
-    public void testSetPlugin() {
-        WebResource webResource = getWebResource("conf/setplugin");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("plugin", "RAM");
-        String response = webResource.queryParams(params).put(String.class);
-        assertEquals("HAS plugin set successfully.\n", response);
-    }
-
-    @Test
-    public void testConfigKdcBackend() {
-        WebResource webResource = getWebResource("conf/configkdcbackend");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("backendType", "json");
-        String backend = null;
-        try {
-            backend = new File(testDir, "json-backend").getCanonicalPath();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        params.add("dir", backend);
-        String response = webResource.queryParams(params).put(String.class);
-        assertEquals("Json backend set successfully.\n", response);
-    }
-
-    @Test
-    public void testConfigXJsonKdc() {
-        WebResource webResource = getWebResource("conf/configkdc");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("realm", "HADOOP.COM");
-        params.add("host", "localhost");
-        params.add("port", "8866");
-        String response = webResource.queryParams(params).put(String.class);
-        assertEquals("HAS server KDC set successfully.\n", response);
-    }
-
-    @Test
-    public void testGetKrb5Conf() {
-        getKrb5Conf();
-    }
-
-    @Test
-    public void testGetHasConf() {
-        getHasConf();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHadminApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHadminApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHadminApi.java
deleted file mode 100644
index 412a8a1..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHadminApi.java
+++ /dev/null
@@ -1,80 +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.hadoop.has.server.json;
-
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import javax.ws.rs.core.MultivaluedMap;
-
-import static org.junit.Assert.assertEquals;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestJsonHadminApi extends TestRestApiBase {
-
-    @Test
-    public void testCreatePrincipals() {
-        createPrincipals();
-    }
-
-    @Test
-    public void testExportKeytabs() {
-        exportKeytabs();
-    }
-
-    @Test
-    public void testExportKeytab() {
-        exportKeytab();
-    }
-
-    @Test
-    public void testAddPrincipal() {
-        addPrincipal();
-    }
-
-    @Test
-    public void testGetPrincipals() {
-        getPrincipals();
-    }
-
-    @Test
-    public void testRenamePrincipal() {
-        renamePrincipal();
-    }
-
-    @Test
-    public void testXDeletePrincipal() {
-        deletePrincipal();
-    }
-
-    @Test
-    public void testSetConf() {
-        WebResource webResource = getWebResource("admin/setconf");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("isEnable", "true");
-        ClientResponse response = webResource.queryParams(params).put(ClientResponse.class);
-        assertEquals(200, response.getStatus());
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHasApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHasApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHasApi.java
deleted file mode 100644
index bd72448..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/json/TestJsonHasApi.java
+++ /dev/null
@@ -1,54 +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.hadoop.has.server.json;
-
-import com.sun.jersey.api.client.WebResource;
-import org.apache.hadoop.fs.FileUtil;
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import java.io.File;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestJsonHasApi extends TestRestApiBase {
-
-    @Test
-    public void hostRoles() {
-        WebResource webResource = getWebResource("hostroles");
-        String response = webResource.get(String.class);
-        System.out.println(response);
-    }
-
-    @Test
-    public void testKdcStart() {
-        kdcStart();
-        File backendDir = new File(testDir, "json-backend");
-        if (backendDir.exists()) {
-            FileUtil.fullyDelete(backendDir);
-        }
-    }
-
-    @Test
-    public void testKdcInit() {
-        kdcInit();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLConfApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLConfApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLConfApi.java
deleted file mode 100644
index 6dc240d..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLConfApi.java
+++ /dev/null
@@ -1,70 +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.hadoop.has.server.mysql;
-
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import javax.ws.rs.core.MultivaluedMap;
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestMySQLConfApi extends TestRestApiBase {
-
-    @Test
-    public void testConfigKdcBackend() throws IOException {
-        WebResource webResource = getWebResource("conf/configkdcbackend");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("backendType", "mysql");
-        params.add("driver", "org.h2.Driver");
-        params.add("url", "jdbc:h2:" + testDir.getCanonicalPath() + "/mysql-backend/mysqlbackend;MODE=MySQL");
-        params.add("user", "root");
-        params.add("password", "123456");
-        String response = webResource.queryParams(params).put(String.class);
-        assertEquals("MySQL backend set successfully.\n", response);
-    }
-
-    @Test
-    public void testConfigMySQLKdc() {
-        WebResource webResource = getWebResource("conf/configkdc");
-        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
-        params.add("realm", "HADOOP.COM");
-        params.add("host", "localhost");
-        params.add("port", "8899");
-        String response = webResource.queryParams(params).put(String.class);
-        assertEquals("HAS server KDC set successfully.\n", response);
-    }
-
-    @Test
-    public void testGetKrb5Conf() {
-        getKrb5Conf();
-    }
-
-    @Test
-    public void testGetHasConf() {
-        getHasConf();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHadminApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHadminApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHadminApi.java
deleted file mode 100644
index 8adb625..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHadminApi.java
+++ /dev/null
@@ -1,64 +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.hadoop.has.server.mysql;
-
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestMySQLHadminApi extends TestRestApiBase {
-
-    @Test
-    public void testCreatePrincipals() {
-        createPrincipals();
-    }
-
-    @Test
-    public void testExportKeytabs() {
-        exportKeytabs();
-    }
-
-    @Test
-    public void testExportKeytab() {
-        exportKeytab();
-    }
-
-    @Test
-    public void testAddPrincipal() {
-        addPrincipal();
-    }
-
-    @Test
-    public void testGetPrincipals() {
-        getPrincipals();
-    }
-
-    @Test
-    public void testRenamePrincipal() {
-        renamePrincipal();
-    }
-
-    @Test
-    public void testXDeletePrincipal() {
-        deletePrincipal();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHasApi.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHasApi.java b/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHasApi.java
deleted file mode 100644
index f2b6a4a..0000000
--- a/has/has-server/src/test/java/org/apache/hadoop/has/server/mysql/TestMySQLHasApi.java
+++ /dev/null
@@ -1,46 +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.hadoop.has.server.mysql;
-
-import org.apache.hadoop.fs.FileUtil;
-import org.apache.hadoop.has.server.TestRestApiBase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-import java.io.File;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class TestMySQLHasApi extends TestRestApiBase {
-
-    @Test
-    public void testKdcStart() {
-        kdcStart();
-        File backendDir = new File(testDir, "mysql-backend");
-        if (backendDir.exists()) {
-            FileUtil.fullyDelete(backendDir);
-        }
-    }
-
-    @Test
-    public void testKdcInit() {
-        kdcInit();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/kerby/has/server/TestHasWebServer.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/kerby/has/server/TestHasWebServer.java b/has/has-server/src/test/java/org/apache/kerby/has/server/TestHasWebServer.java
new file mode 100644
index 0000000..a26c1e2
--- /dev/null
+++ b/has/has-server/src/test/java/org/apache/kerby/has/server/TestHasWebServer.java
@@ -0,0 +1,128 @@
+/**
+ * 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.kerby.has.server;
+
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.util.URLConnectionFactory;
+import org.apache.kerby.has.server.web.WebConfigKey;
+import org.apache.kerby.has.server.web.WebServer;
+import org.apache.hadoop.http.HttpConfig.Policy;
+import org.apache.hadoop.net.NetUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(value = Parameterized.class)
+public class TestHasWebServer {
+  private static final String KEY_STORE_DIR = TestUtil.getTempPath("keystore");
+  private static File keyStoreDir = new File(KEY_STORE_DIR);
+  private static HasConfig httpsConf;
+  private static URLConnectionFactory connectionFactory;
+
+  @Parameterized.Parameters
+  public static Collection<Object[]> policy() {
+    Object[][] params = new Object[][]{{Policy.HTTP_ONLY},
+        {Policy.HTTPS_ONLY}, {Policy.HTTP_AND_HTTPS}};
+    return Arrays.asList(params);
+  }
+
+  private final Policy policy;
+
+  public TestHasWebServer(Policy policy) {
+    super();
+    this.policy = policy;
+  }
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    httpsConf = new HasConfig();
+    // Create test keystore dir.
+    if (!keyStoreDir.exists()) {
+      if (!keyStoreDir.mkdirs()) {
+        System.err.println("Failed to create keystore-dir.");
+        System.exit(3);
+      }
+    }
+    String sslConfDir = TestUtil.getClasspathDir(TestRestApiBase.class);
+    TestUtil.setupSSLConfig(KEY_STORE_DIR, sslConfDir, httpsConf, false);
+    connectionFactory = URLConnectionFactory.newDefaultURLConnectionFactory(httpsConf);
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    FileUtil.fullyDelete(keyStoreDir);
+  }
+
+  @Test
+  public void testHttpPolicy() throws Exception {
+    httpsConf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY, policy.name());
+    httpsConf.setString(WebConfigKey.HAS_HTTP_ADDRESS_KEY, "localhost:11236");
+    httpsConf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, "localhost:19278");
+    httpsConf.setString(WebConfigKey.HAS_AUTHENTICATION_FILTER_AUTH_TYPE, "simple");
+
+    WebServer server = null;
+    try {
+      server = new WebServer(httpsConf);
+      server.start();
+
+      Assert.assertTrue(implies(policy.isHttpEnabled(),
+          canAccess("http", server.getHttpAddress())));
+      Assert.assertTrue(implies(!policy.isHttpEnabled(),
+          server.getHttpAddress() == null));
+
+      Assert.assertTrue(implies(policy.isHttpsEnabled(),
+          canAccess("https", server.getHttpsAddress())));
+      Assert.assertTrue(implies(!policy.isHttpsEnabled(),
+          server.getHttpsAddress() == null));
+    } finally {
+      if (server != null) {
+        server.stop();
+      }
+    }
+  }
+
+  private static boolean canAccess(String scheme, InetSocketAddress address) {
+    if (address == null) {
+      return false;
+    }
+    try {
+      URL url = new URL(scheme + "://" + NetUtils.getHostPortString(address));
+      URLConnection conn = connectionFactory.openConnection(url);
+      conn.connect();
+      conn.getContent();
+    } catch (Exception e) {
+      return false;
+    }
+    return true;
+  }
+
+  private static boolean implies(boolean a, boolean b) {
+    return !a || b;
+  }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/kerby/has/server/TestRestApiBase.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/kerby/has/server/TestRestApiBase.java b/has/has-server/src/test/java/org/apache/kerby/has/server/TestRestApiBase.java
new file mode 100644
index 0000000..21353c9
--- /dev/null
+++ b/has/has-server/src/test/java/org/apache/kerby/has/server/TestRestApiBase.java
@@ -0,0 +1,336 @@
+/**
+ *  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.kerby.has.server;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.HasConfigKey;
+import org.apache.kerby.has.common.HasException;
+import org.apache.kerby.has.common.spnego.AuthenticationException;
+import org.apache.kerby.has.common.util.URLConnectionFactory;
+import org.apache.kerby.has.server.web.WebConfigKey;
+import org.apache.kerby.has.server.web.WebServer;
+import org.apache.hadoop.http.HttpConfig;
+import org.apache.hadoop.security.ssl.SSLFactory;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.glassfish.jersey.SslConfigurator;
+import org.junit.After;
+import org.junit.Before;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestRestApiBase {
+    private static String address;
+    protected static File testDir = new File(System.getProperty("test.dir", "target"));
+    private static File testClassDir = new File(testDir, "test-classes");
+    private static File confDir = new File(testClassDir, "conf");
+    private static File workDir = new File(testDir, "work-dir");
+    private static HasServer server = null;
+    private static final String KEY_STORE_DIR = TestUtil.getTempPath("keystore");
+    private static File keyStoreDir = new File(KEY_STORE_DIR);
+    private static HasConfig httpsConf;
+
+    @Before
+    public void startHasServer() throws Exception {
+        // Create test keystoreDir and workDir.
+        if (!keyStoreDir.exists()) {
+            if (!keyStoreDir.mkdirs()) {
+                System.err.println("Failed to create keystore-dir.");
+                System.exit(3);
+            }
+        }
+
+        if (!workDir.exists()) {
+            if (!workDir.mkdirs()) {
+                System.err.println("Failed to create work-dir.");
+                System.exit(3);
+            }
+        }
+
+        // Configure test HAS server.
+        httpsConf = new HasConfig();
+        String sslConfDir = TestUtil.getClasspathDir(TestRestApiBase.class);
+        TestUtil.setupSSLConfig(KEY_STORE_DIR, sslConfDir, httpsConf, false);
+        httpsConf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name());
+        httpsConf.setString(HasConfigKey.FILTER_AUTH_TYPE, "simple");
+
+        // Start test HAS server.
+        int httpsPort = 10000 + (int) (System.currentTimeMillis() % 10000); // Generate test port randomly
+        String host = "localhost";
+        address = host + ":" + httpsPort;
+        httpsConf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, address);
+
+        server = new HasServer(confDir);
+        server.setWebServer(new WebServer(httpsConf));
+        server.setWorkDir(workDir);
+        try {
+            server.startWebServer();
+        } catch (HasException e) {
+            System.err.println("Errors occurred when start HAS server: " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    @After
+    public void stopHasServer() {
+        server.stopWebServer();
+        if (keyStoreDir.exists()) {
+            FileUtil.fullyDelete(keyStoreDir);
+        }
+        if (workDir.exists()) {
+            FileUtil.fullyDelete(workDir);
+        }
+    }
+
+    private void startKdc() {
+        WebResource webResource = getWebResource("kdcstart");
+        String response = webResource.get(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            if (!result.getString("result").equals("success")) {
+                System.err.println("Errors occurred when start HAS KDC server.");
+                System.exit(6);
+            }
+        } catch (JSONException e) {
+            System.err.println("Errors occurred when start HAS KDC server. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected WebResource getWebResource(String restName) {
+        String apiUrl = "https://" + address + "/has/v1/" + restName;
+        HasConfig clientConf = new HasConfig();
+        try {
+            clientConf.addIniConfig(new File(httpsConf.getString(SSLFactory.SSL_CLIENT_CONF_KEY)));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        SslConfigurator sslConfigurator = SslConfigurator.newInstance()
+            .trustStoreFile(clientConf.getString("ssl.client.truststore.location"))
+            .trustStorePassword(clientConf.getString("ssl.client.truststore.password"));
+        sslConfigurator.securityProtocol("SSL");
+        SSLContext sslContext = sslConfigurator.createSSLContext();
+        ClientConfig clientConfig = new DefaultClientConfig();
+        clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+            new HTTPSProperties(new HostnameVerifier() {
+                @Override
+                public boolean verify(String s, SSLSession sslSession) {
+                    return false;
+                }
+            }, sslContext));
+        Client client = Client.create(clientConfig);
+        return client.resource(apiUrl);
+    }
+
+    protected void getKrb5Conf() {
+        WebResource webResource = getWebResource("getkrb5conf");
+        ClientResponse response = webResource.get(ClientResponse.class);
+        assertEquals(200, response.getStatus());
+    }
+
+    protected void getHasConf() {
+        WebResource webResource = getWebResource("gethasconf");
+        ClientResponse response = webResource.get(ClientResponse.class);
+        assertEquals(200, response.getStatus());
+        File hasConf = new File(confDir, "has-client.conf");
+        if (hasConf.exists()) {
+            if (!hasConf.delete()) {
+                System.err.println("Failed to delete has-client.conf.");
+            }
+        }
+    }
+
+    protected void kdcStart() {
+        WebResource webResource = getWebResource("kdcstart");
+        String response = webResource.get(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException e) {
+            System.err.println("Failed to start HAS KDC server. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected void kdcInit() {
+        startKdc();
+        WebResource webResource = getWebResource("kdcinit");
+        ClientResponse response = webResource.get(ClientResponse.class);
+        assertEquals(200, response.getStatus());
+    }
+
+    protected void createPrincipals() {
+        String webServerUrl = "https://" + address + "/has/v1/";
+        startKdc();
+
+        // Create test host roles json object.
+        JSONObject hostRoles = new JSONObject();
+        try {
+            JSONObject host1 = new JSONObject();
+            host1.put("name", "host1");
+            host1.put("hostRoles", "HDFS,YARN");
+            JSONObject host2 = new JSONObject();
+            host2.put("name", "host2");
+            host2.put("hostRoles", "ZOOKEEPER,HBASE");
+            JSONArray hosts = new JSONArray();
+            hosts.put(host1);
+            hosts.put(host2);
+            hostRoles.put("HOSTS", hosts);
+        } catch (JSONException e) {
+            System.err.println("Failed to create test host roles json object. " + e.toString());
+            System.exit(6);
+        }
+
+        try {
+            URL url = null;
+            try {
+                url = new URL(webServerUrl + "admin/createprincipals");
+            } catch (MalformedURLException e) {
+                e.printStackTrace();
+            }
+
+            URLConnectionFactory connectionFactory = URLConnectionFactory.newDefaultURLConnectionFactory(httpsConf);
+            HttpURLConnection httpConn = (HttpURLConnection) connectionFactory.openConnection(url, false, httpsConf);
+            httpConn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+            httpConn.setRequestMethod("PUT");
+            httpConn.setDoOutput(true);
+            httpConn.setDoInput(true);
+            httpConn.connect();
+
+            OutputStream out = httpConn.getOutputStream();
+            out.write(hostRoles.toString().getBytes());
+            out.flush();
+            out.close();
+
+            assertEquals(200, httpConn.getResponseCode());
+            BufferedReader reader = httpConn.getResponseCode()
+                == HttpURLConnection.HTTP_OK ? new BufferedReader(
+                new InputStreamReader(httpConn.getInputStream(),
+                    "UTF-8")) : new BufferedReader(
+                new InputStreamReader(httpConn.getErrorStream(),
+                    "UTF-8"));
+
+            String response = reader.readLine();
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException | IOException | AuthenticationException e) {
+            System.err.println("Failed to create principals by hostRoles. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected void exportKeytabs() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/exportkeytabs");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        params.add("host", "host1");
+        params.add("role", "HDFS");
+        ClientResponse response = webResource.queryParams(params).get(ClientResponse.class);
+        assertEquals(200, response.getStatus());
+    }
+
+    protected void exportKeytab() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/exportkeytab");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        params.add("principal", "admin@HADOOP.COM");
+        ClientResponse response = webResource.queryParams(params).get(ClientResponse.class);
+        assertEquals(200, response.getStatus());
+    }
+
+    protected void addPrincipal() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/addprincipal");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        params.add("principal", "admin");
+        params.add("password", "123");
+        String response = webResource.queryParams(params).post(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException e) {
+            System.err.println("Failed to add principal. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected void getPrincipals() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/getprincipals");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        String response = webResource.queryParams(params).get(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException e) {
+            System.err.println("Failed to get principals. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected void renamePrincipal() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/renameprincipal");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        params.add("oldprincipal", "admin");
+        params.add("newprincipal", "admin2");
+        String response = webResource.queryParams(params).post(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException e) {
+            System.err.println("Failed to rename principal. " + e.toString());
+            System.exit(6);
+        }
+    }
+
+    protected void deletePrincipal() {
+        startKdc();
+        WebResource webResource = getWebResource("admin/deleteprincipal");
+        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
+        params.add("principal", "admin2");
+        String response = webResource.queryParams(params).delete(String.class);
+        try {
+            JSONObject result = new JSONObject(response);
+            assertEquals("success", result.getString("result"));
+        } catch (JSONException e) {
+            System.err.println("Failed to delete principal. " + e.toString());
+            System.exit(6);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-server/src/test/java/org/apache/kerby/has/server/TestUtil.java
----------------------------------------------------------------------
diff --git a/has/has-server/src/test/java/org/apache/kerby/has/server/TestUtil.java b/has/has-server/src/test/java/org/apache/kerby/has/server/TestUtil.java
new file mode 100644
index 0000000..bcc0536
--- /dev/null
+++ b/has/has-server/src/test/java/org/apache/kerby/has/server/TestUtil.java
@@ -0,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
+ *
+ *     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.kerby.has.server;
+
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.server.web.WebConfigKey;
+import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory;
+import org.apache.hadoop.security.ssl.SSLFactory;
+import org.bouncycastle.x509.X509V1CertificateGenerator;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+class TestUtil {
+
+  /**
+   * system property for test data: {@value}
+   */
+  private static final String SYSPROP_TEST_DATA_DIR = "test.build.data";
+
+  /**
+   * The default path for using in Hadoop path references: {@value}
+   */
+  private static final String DEFAULT_TEST_DATA_PATH = "target/";
+
+  /**
+   * Get a temp path. This may or may not be relative; it depends on what the
+   * {@link #SYSPROP_TEST_DATA_DIR} is set to. If unset, it returns a path
+   * under the relative path {@link #DEFAULT_TEST_DATA_PATH}
+   *
+   * @param subPath sub path, with no leading "/" character
+   * @return a string to use in paths
+   */
+  public static String getTempPath(String subPath) {
+    String prop = System.getProperty(SYSPROP_TEST_DATA_DIR, DEFAULT_TEST_DATA_PATH);
+    if (prop.isEmpty()) {
+      // corner case: property is there but empty
+      prop = DEFAULT_TEST_DATA_PATH;
+    }
+    if (!prop.endsWith("/")) {
+      prop = prop + "/";
+    }
+    return prop + subPath;
+  }
+
+  public static String getClasspathDir(Class testClass) throws Exception {
+    String file = testClass.getName();
+    file = file.replace('.', '/') + ".class";
+    URL url = Thread.currentThread().getContextClassLoader().getResource(file);
+    String baseDir = url.toURI().getPath();
+    baseDir = baseDir.substring(0, baseDir.length() - file.length() - 1);
+    return baseDir;
+  }
+
+  @SuppressWarnings("deprecation")
+  /*
+   * Create a self-signed X.509 Certificate.
+   *
+   * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
+   * @param pair the KeyPair
+   * @param days how many days from now the Certificate is valid for
+   * @param algorithm the signing algorithm, eg "SHA1withRSA"
+   * @return the self-signed certificate
+   */
+  private static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
+      throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
+      NoSuchProviderException, NoSuchAlgorithmException, SignatureException {
+
+    Date from = new Date();
+    Date to = new Date(from.getTime() + days * 86400000L);
+    BigInteger sn = new BigInteger(64, new SecureRandom());
+    X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
+    X500Principal dnName = new X500Principal(dn);
+
+    certGen.setSerialNumber(sn);
+    certGen.setIssuerDN(dnName);
+    certGen.setNotBefore(from);
+    certGen.setNotAfter(to);
+    certGen.setSubjectDN(dnName);
+    certGen.setPublicKey(pair.getPublic());
+    certGen.setSignatureAlgorithm(algorithm);
+
+    return certGen.generate(pair.getPrivate());
+  }
+
+  private static KeyPair generateKeyPair(String algorithm) throws NoSuchAlgorithmException {
+    KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+    keyGen.initialize(1024);
+    return keyGen.genKeyPair();
+  }
+
+  private static KeyStore createEmptyKeyStore() throws GeneralSecurityException, IOException {
+    KeyStore ks = KeyStore.getInstance("JKS");
+    ks.load(null, null); // initialize
+    return ks;
+  }
+
+  private static void saveKeyStore(KeyStore ks, String filename, String password)
+      throws GeneralSecurityException, IOException {
+    FileOutputStream out = new FileOutputStream(filename);
+    ks.store(out, password.toCharArray());
+    out.close();
+  }
+
+  private static void createKeyStore(String filename, String password, String alias, Key privateKey, Certificate cert)
+      throws GeneralSecurityException, IOException {
+    KeyStore ks = createEmptyKeyStore();
+    ks.setKeyEntry(alias, privateKey, password.toCharArray(), new Certificate[]{cert});
+    saveKeyStore(ks, filename, password);
+  }
+
+  private static <T extends Certificate> void createTrustStore(String filename, String password, Map<String, T> certs)
+      throws GeneralSecurityException, IOException {
+    KeyStore ks = createEmptyKeyStore();
+    for (Map.Entry<String, T> cert : certs.entrySet()) {
+      ks.setCertificateEntry(cert.getKey(), cert.getValue());
+    }
+    saveKeyStore(ks, filename, password);
+  }
+
+  /**
+   * Performs complete setup of SSL configuration in preparation for testing an
+   * SSLFactory.  This includes keys, certs, keystore, truststore, the server
+   * SSL configuration file, the client SSL configuration file, and the master
+   * configuration file read by the SSLFactory.
+   *
+   * @param keystoreDir   String directory to save keystore
+   * @param sslConfDir    String directory to save SSL configuration files
+   * @param conf          Configuration master configuration to be used by an SSLFactory,
+   *                      which will be mutated by this method
+   * @param useClientCert boolean true to make the client present a cert in the SSL handshake
+   */
+  public static void setupSSLConfig(String keystoreDir, String sslConfDir, HasConfig conf, boolean useClientCert)
+      throws Exception {
+    setupSSLConfig(keystoreDir, sslConfDir, conf, useClientCert, true, "");
+  }
+
+  /**
+   * Performs complete setup of SSL configuration in preparation for testing an
+   * SSLFactory.  This includes keys, certs, keystore, truststore, the server
+   * SSL configuration file, the client SSL configuration file, and the master
+   * configuration file read by the SSLFactory.
+   *
+   * @param keystoreDir   String directory to save keystore
+   * @param sslConfDir    String directory to save SSL configuration files
+   * @param conf          Configuration master configuration to be used by an SSLFactory,
+   *                      which will be mutated by this method
+   * @param useClientCert boolean true to make the client present a cert in the SSL handshake
+   * @param trustStore    boolean true to create truststore, false not to create it
+   * @param excludeCiphers String comma separated ciphers to exclude
+   * @throws Exception e
+   */
+  private static void setupSSLConfig(String keystoreDir, String sslConfDir, HasConfig conf, boolean useClientCert,
+                                     boolean trustStore, String excludeCiphers) throws Exception {
+    String clientKS = keystoreDir + "/clientKS.jks";
+    String clientPassword = "clientP";
+    String serverKS = keystoreDir + "/serverKS.jks";
+    String serverPassword = "serverP";
+    String trustKS = null;
+    String trustPassword = "trustP";
+
+    File sslClientConfFile = new File(sslConfDir, getClientSSLConfigFileName());
+    File sslServerConfFile = new File(sslConfDir, getServerSSLConfigFileName());
+
+    Map<String, X509Certificate> certs = new HashMap<String, X509Certificate>();
+
+    if (useClientCert) {
+      KeyPair cKP = TestUtil.generateKeyPair("RSA");
+      X509Certificate cCert = TestUtil.generateCertificate("CN=localhost, O=client", cKP, 30, "SHA1withRSA");
+      TestUtil.createKeyStore(clientKS, clientPassword, "client", cKP.getPrivate(), cCert);
+      certs.put("client", cCert);
+    }
+
+    KeyPair sKP = TestUtil.generateKeyPair("RSA");
+    X509Certificate sCert = TestUtil.generateCertificate("CN=localhost, O=server", sKP, 30, "SHA1withRSA");
+    TestUtil.createKeyStore(serverKS, serverPassword, "server", sKP.getPrivate(), sCert);
+    certs.put("server", sCert);
+
+    if (trustStore) {
+      trustKS = keystoreDir + "/trustKS.jks";
+      TestUtil.createTrustStore(trustKS, trustPassword, certs);
+    }
+
+    HasConfig clientSSLConf = createClientSSLConfig(clientKS, clientPassword, clientPassword, trustKS, excludeCiphers);
+    HasConfig serverSSLConf = createServerSSLConfig(serverKS, serverPassword, serverPassword, trustKS, excludeCiphers);
+
+    saveConfig(sslClientConfFile, clientSSLConf);
+    saveConfig(sslServerConfFile, serverSSLConf);
+
+    conf.setString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
+    conf.setString(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfFile.getCanonicalPath());
+    conf.setString(SSLFactory.SSL_SERVER_CONF_KEY, sslServerConfFile.getCanonicalPath());
+    conf.setString(WebConfigKey.HAS_SERVER_HTTPS_KEYSTORE_RESOURCE_KEY, sslServerConfFile.getAbsolutePath());
+    conf.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, useClientCert);
+  }
+
+  /**
+   * Create SSL configuration for a client.
+   *
+   * @param clientKS       String client keystore file
+   * @param password       String store password, or null to avoid setting store password
+   * @param keyPassword    String key password, or null to avoid setting key password
+   * @param trustKS        String truststore file
+   * @param excludeCiphers String comma separated ciphers to exclude
+   * @return Configuration for client SSL
+   */
+  private static HasConfig createClientSSLConfig(String clientKS, String password, String keyPassword,
+                                                 String trustKS, String excludeCiphers) {
+    return createSSLConfig(SSLFactory.Mode.CLIENT, clientKS, password, keyPassword, trustKS, excludeCiphers);
+  }
+
+  /**
+   * Creates SSL configuration for a server.
+   *
+   * @param serverKS       String server keystore file
+   * @param password       String store password, or null to avoid setting store password
+   * @param keyPassword    String key password, or null to avoid setting key password
+   * @param trustKS        String truststore file
+   * @param excludeCiphers String comma separated ciphers to exclude
+   * @return HasConfig
+   * @throws IOException e
+   */
+  private static HasConfig createServerSSLConfig(String serverKS, String password, String keyPassword,
+                                                 String trustKS, String excludeCiphers) throws IOException {
+    return createSSLConfig(SSLFactory.Mode.SERVER, serverKS, password, keyPassword, trustKS, excludeCiphers);
+  }
+
+  /**
+   * Returns the client SSL configuration file name.  Under parallel test
+   * execution, this file name is parametrized by a unique ID to ensure that
+   * concurrent tests don't collide on an SSL configuration file.
+   *
+   * @return client SSL configuration file name
+   */
+  private static String getClientSSLConfigFileName() {
+    return getSSLConfigFileName("ssl-client");
+  }
+
+  /**
+   * Returns the server SSL configuration file name.  Under parallel test
+   * execution, this file name is parametrized by a unique ID to ensure that
+   * concurrent tests don't collide on an SSL configuration file.
+   *
+   * @return client SSL configuration file name
+   */
+  private static String getServerSSLConfigFileName() {
+    return getSSLConfigFileName("ssl-server");
+  }
+
+  /**
+   * Returns an SSL configuration file name.  Under parallel test
+   * execution, this file name is parametrized by a unique ID to ensure that
+   * concurrent tests don't collide on an SSL configuration file.
+   *
+   * @param base the base of the file name
+   * @return SSL configuration file name for base
+   */
+  private static String getSSLConfigFileName(String base) {
+    String testUniqueForkId = System.getProperty("test.unique.fork.id");
+    String fileSuffix = testUniqueForkId != null ? "-" + testUniqueForkId : "";
+    return base + fileSuffix + ".xml";
+  }
+
+  /**
+   * Creates SSL configuration.
+   *
+   * @param mode        SSLFactory.Mode mode to configure
+   * @param keystore    String keystore file
+   * @param password    String store password, or null to avoid setting store password
+   * @param keyPassword String key password, or null to avoid setting key password
+   * @param trustKS     String truststore file
+   * @return Configuration for SSL
+   */
+  private static HasConfig createSSLConfig(SSLFactory.Mode mode, String keystore, String password,
+                                           String keyPassword, String trustKS, String excludeCiphers) {
+    String trustPassword = "trustP";
+
+    HasConfig sslConf = new HasConfig();
+    if (keystore != null) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_KEYSTORE_LOCATION_TPL_KEY), keystore);
+    }
+    if (password != null) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_KEYSTORE_PASSWORD_TPL_KEY), password);
+    }
+    if (keyPassword != null) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_KEYSTORE_KEYPASSWORD_TPL_KEY),
+          keyPassword);
+    }
+    if (trustKS != null) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_TRUSTSTORE_LOCATION_TPL_KEY), trustKS);
+    }
+    if (trustPassword != null) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_TRUSTSTORE_PASSWORD_TPL_KEY),
+          trustPassword);
+    }
+    if (null != excludeCiphers && !excludeCiphers.isEmpty()) {
+      sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+          FileBasedKeyStoresFactory.SSL_EXCLUDE_CIPHER_LIST),
+          excludeCiphers);
+    }
+    sslConf.setString(FileBasedKeyStoresFactory.resolvePropertyName(mode,
+        FileBasedKeyStoresFactory.SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY), "1000");
+
+    return sslConf;
+  }
+
+  /**
+   * Saves configuration to a file.
+   *
+   * @param file File to save
+   * @param conf Configuration contents to write to file
+   * @throws IOException if there is an I/O error saving the file
+   */
+  private static void saveConfig(File file, HasConfig conf) throws IOException {
+    OutputStream output = new FileOutputStream(file);
+    Properties prop = new Properties();
+
+    // set the properties value
+    for (String name : conf.getNames()) {
+      prop.setProperty(name, conf.getString(name));
+    }
+
+    // save properties to project root folder
+    prop.store(output, null);
+  }
+}