You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by co...@apache.org on 2023/02/22 10:20:11 UTC

[directory-kerby] 01/01: DIRKRB-765 - Remove has project

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch coheigea/remove-has
in repository https://gitbox.apache.org/repos/asf/directory-kerby.git

commit 81bf39b948be5c4df353e30bae4fa215b5febda6
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed Feb 22 10:19:40 2023 +0000

    DIRKRB-765 - Remove has project
---
 README.md                                          |   4 -
 has-project/README.md                              |  87 ---
 has-project/docs/cross-realm.md                    |  73 --
 has-project/docs/deploy-https.md                   | 178 -----
 has-project/docs/deploy-spnego.md                  |  32 -
 has-project/docs/has-ha.md                         | 143 ----
 has-project/docs/has-overall.png                   | Bin 74116 -> 0 bytes
 has-project/docs/has-protocol-flow.png             | Bin 212202 -> 0 bytes
 has-project/docs/has-start.md                      | 250 -------
 has-project/docs/ldap-plugin.md                    |  74 --
 has-project/docs/mysql-backend.md                  |  42 --
 has-project/docs/mysql-plugin.md                   |  55 --
 has-project/docs/performance-report.md             | 117 ----
 has-project/has-client-plugin/pom.xml              |  44 --
 .../has/plugins/client/ldap/LDAPClientPlugin.java  |  96 ---
 .../plugins/client/mysql/MySQLHasClientPlugin.java |  67 --
 .../org.apache.kerby.has.client.HasClientPlugin    |  17 -
 .../src/main/resources/ldap-client.ini             |  21 -
 .../client/TestHasClientPluginRegistry.java        |  44 --
 has-project/has-client/pom.xml                     |  54 --
 .../kerby/has/client/AbstractHasClientPlugin.java  |  44 --
 .../kerby/has/client/HasAuthAdminClient.java       | 618 -----------------
 .../org/apache/kerby/has/client/HasClient.java     | 701 -------------------
 .../apache/kerby/has/client/HasClientPlugin.java   |  43 --
 .../kerby/has/client/HasClientPluginRegistry.java  |  62 --
 .../org/apache/kerby/has/client/HasClientUtil.java | 137 ----
 .../org/apache/kerby/has/client/HasInitClient.java | 276 --------
 .../apache/kerby/has/client/HasLoginException.java |  37 -
 .../apache/kerby/has/client/HasLoginModule.java    | 452 -------------
 .../src/main/resources/ssl-client.conf.template    |  20 -
 has-project/has-common/pom.xml                     |  69 --
 .../java/org/apache/kerby/has/common/Hadmin.java   |  38 --
 .../org/apache/kerby/has/common/HasConfig.java     | 113 ----
 .../org/apache/kerby/has/common/HasConfigKey.java  |  61 --
 .../org/apache/kerby/has/common/HasException.java  |  53 --
 .../apache/kerby/has/common/spnego/AuthToken.java  | 217 ------
 .../kerby/has/common/spnego/AuthenticatedURL.java  | 282 --------
 .../has/common/spnego/AuthenticationException.java |  54 --
 .../kerby/has/common/spnego/Authenticator.java     |  52 --
 .../has/common/spnego/KerberosAuthenticator.java   | 358 ----------
 .../common/spnego/KerberosHasAuthenticator.java    |  25 -
 .../kerby/has/common/spnego/KerberosUtil.java      | 262 --------
 .../kerby/has/common/ssl/KeyStoresFactory.java     | 252 -------
 .../has/common/ssl/ReloadingX509TrustManager.java  | 208 ------
 .../apache/kerby/has/common/ssl/SSLFactory.java    | 290 --------
 .../kerby/has/common/ssl/SSLHostnameVerifier.java  | 615 -----------------
 .../has/common/util/ConnectionConfigurator.java    |  39 --
 .../kerby/has/common/util/HasJaasLoginUtil.java    | 114 ----
 .../org/apache/kerby/has/common/util/HasUtil.java  |  96 ---
 .../apache/kerby/has/common/util/PlatformName.java |  78 ---
 .../apache/kerby/has/common/util/StringUtils.java  |  55 --
 .../has/common/util/URLConnectionFactory.java      | 203 ------
 has-project/has-server-plugin/pom.xml              |  64 --
 .../has/plugins/server/ldap/LDAPServerPlugin.java  |  68 --
 .../kerby/has/plugins/server/ldap/LDAPUtils.java   |  88 ---
 .../plugins/server/ldap/conf/LDAPServerConf.java   |  95 ---
 .../plugins/server/mysql/MySQLHasServerPlugin.java | 145 ----
 .../org.apache.kerby.has.server.HasServerPlugin    |  17 -
 .../server/TestHasServerPluginRegistry.java        |  43 --
 has-project/has-server/pom.xml                     | 117 ----
 .../kerby/has/server/AbstractHasServerPlugin.java  |  45 --
 .../kerby/has/server/HasAuthenException.java       |  37 -
 .../org/apache/kerby/has/server/HasServer.java     | 745 --------------------
 .../apache/kerby/has/server/HasServerPlugin.java   |  40 --
 .../kerby/has/server/HasServerPluginRegistry.java  |  63 --
 .../apache/kerby/has/server/admin/LocalHadmin.java | 163 -----
 .../apache/kerby/has/server/kdc/HasKdcHandler.java | 317 ---------
 .../apache/kerby/has/server/web/ConfFilter.java    |  72 --
 .../apache/kerby/has/server/web/HostRoleType.java  |  55 --
 .../apache/kerby/has/server/web/WebConfigKey.java  |  62 --
 .../org/apache/kerby/has/server/web/WebServer.java | 374 -----------
 .../kerby/has/server/web/rest/AsRequestApi.java    | 161 -----
 .../kerby/has/server/web/rest/ConfigApi.java       | 316 ---------
 .../kerby/has/server/web/rest/HadminApi.java       | 291 --------
 .../apache/kerby/has/server/web/rest/InitApi.java  |  88 ---
 .../kerby/has/server/web/rest/KadminApi.java       | 492 --------------
 .../has/server/web/rest/param/AuthTokenParam.java  |  45 --
 .../kerby/has/server/web/rest/param/HostParam.java |  45 --
 .../has/server/web/rest/param/HostRoleParam.java   |  45 --
 .../kerby/has/server/web/rest/param/Param.java     | 123 ----
 .../has/server/web/rest/param/PasswordParam.java   |  45 --
 .../has/server/web/rest/param/PrincipalParam.java  |  45 --
 .../has/server/web/rest/param/StringParam.java     |  66 --
 .../kerby/has/server/web/rest/param/TypeParam.java |  48 --
 .../src/main/resources/backend.conf.template       |  21 -
 .../src/main/resources/kdc.conf.template           |  23 -
 .../src/main/resources/krb5.conf.template          |  29 -
 .../org/apache/kerby/has/server/TestConfApi.java   |  81 ---
 .../org/apache/kerby/has/server/TestHadminApi.java |  60 --
 .../org/apache/kerby/has/server/TestInitApi.java   |  44 --
 .../org/apache/kerby/has/server/TestKadminApi.java |  62 --
 .../apache/kerby/has/server/TestRestApiBase.java   | 341 ----------
 .../java/org/apache/kerby/has/server/TestUtil.java | 373 -----------
 .../org/apache/kerby/has/server/TestWebServer.java | 126 ----
 .../src/test/resources/conf/backend.conf           |  20 -
 .../src/test/resources/conf/has-server.conf        |  25 -
 .../has-server/src/test/resources/conf/kdc.conf    |  23 -
 .../has-server/src/test/resources/conf/krb5.conf   |  29 -
 .../src/test/resources/webapps/WEB-INF/web.xml     |  17 -
 .../src/test/resources/webapps/has/index.html      |  24 -
 has-project/pom.xml                                |  36 -
 has-project/supports/hadoop/README.md              | 392 -----------
 has-project/supports/hadoop/hadoop-2.7.2.patch     | 162 -----
 has-project/supports/hbase/README.md               | 175 -----
 .../supports/hbase/hbase-hadoop-2.5.1.patch        | 136 ----
 has-project/supports/hive/README.md                |  74 --
 has-project/supports/oozie/README.md               | 124 ----
 has-project/supports/phoenix/README.md             |  49 --
 has-project/supports/presto/README.md              |  43 --
 has-project/supports/spark/README.md               |  64 --
 has-project/supports/spark/spark-v2.0.0.patch      |  59 --
 has-project/supports/thrift/README.md              |  89 ---
 has-project/supports/zookeeper/README.md           |  78 ---
 has-project/supports/zookeeper/conf/jaas.conf      |  31 -
 has-project/supports/zookeeper/conf/java.env       |  19 -
 has-project/supports/zookeeper/pom.xml             |  60 --
 kerby-dist/has-dist/LICENSE                        | 255 -------
 kerby-dist/has-dist/NOTICE                         | 151 -----
 kerby-dist/has-dist/README.txt                     |  37 -
 kerby-dist/has-dist/assembly.xml                   |  49 --
 kerby-dist/has-dist/bin/admin-local.sh             |  54 --
 kerby-dist/has-dist/bin/admin-remote.sh            |  56 --
 kerby-dist/has-dist/bin/has-init.sh                |  56 --
 kerby-dist/has-dist/bin/login-test.sh              |  35 -
 kerby-dist/has-dist/bin/start-has.cmd              | 101 ---
 kerby-dist/has-dist/bin/start-has.sh               | 117 ----
 kerby-dist/has-dist/bin/stop-has.cmd               |  35 -
 kerby-dist/has-dist/bin/stop-has.sh                |  75 ---
 kerby-dist/has-dist/conf/admin.conf                |  23 -
 kerby-dist/has-dist/conf/backend.conf              |  23 -
 kerby-dist/has-dist/conf/has-env.sh                |  29 -
 kerby-dist/has-dist/conf/has-server.conf           |  26 -
 kerby-dist/has-dist/conf/kdc.conf                  |  23 -
 kerby-dist/has-dist/conf/krb5.conf                 |  29 -
 .../has-dist/licenses/LICENSE-activation.txt       | 132 ----
 .../has-dist/licenses/LICENSE-animal-sniffer.txt   |  21 -
 kerby-dist/has-dist/licenses/LICENSE-base64.txt    |  26 -
 .../has-dist/licenses/LICENSE-bouncycastle.txt     |  14 -
 .../has-dist/licenses/LICENSE-drizzle.jdbc.txt     |  26 -
 .../licenses/LICENSE-javax.servlet.api.txt         | 746 ---------------------
 kerby-dist/has-dist/licenses/LICENSE-jaxb.txt      | 349 ----------
 kerby-dist/has-dist/licenses/LICENSE-jbzip2.txt    |  19 -
 kerby-dist/has-dist/licenses/LICENSE-jersey.txt    |  35 -
 kerby-dist/has-dist/licenses/LICENSE-jfastlz.txt   |  24 -
 kerby-dist/has-dist/licenses/LICENSE-jline.txt     |  35 -
 kerby-dist/has-dist/licenses/LICENSE-jquery.txt    |  20 -
 kerby-dist/has-dist/licenses/LICENSE-jsch.txt      |  30 -
 kerby-dist/has-dist/licenses/LICENSE-jsr166y.txt   |  26 -
 .../has-dist/licenses/LICENSE-jsr311.api.txt       | 118 ----
 .../has-dist/licenses/LICENSE-libdivsufsort.txt    |  22 -
 kerby-dist/has-dist/licenses/LICENSE-paranamer.txt |  28 -
 kerby-dist/has-dist/licenses/LICENSE-protobuf.txt  |  34 -
 kerby-dist/has-dist/licenses/LICENSE-re2j.txt      |  32 -
 kerby-dist/has-dist/licenses/LICENSE-slf4j.txt     |  21 -
 kerby-dist/has-dist/licenses/LICENSE-stax2.api.txt |  26 -
 kerby-dist/has-dist/licenses/LICENSE-webbit.txt    |  37 -
 kerby-dist/has-dist/log4j.properties               |  27 -
 kerby-dist/has-dist/pom.xml                        | 108 ---
 kerby-dist/has-dist/webapps/WEB-INF/web.xml        |  17 -
 kerby-dist/has-dist/webapps/has/index.html         |  24 -
 kerby-dist/pom.xml                                 |   1 -
 pom.xml                                            |   1 -
 162 files changed, 17804 deletions(-)

diff --git a/README.md b/README.md
index 94c87023..20ab18a5 100644
--- a/README.md
+++ b/README.md
@@ -175,10 +175,6 @@ The Apache Kerby is also available as a Maven dependency.
 - please replace the ${kerby-version} with the release version.
 - Apache Kerby 1.0.1 is the latest release and recommended version for all users.
 
-### Hadoop Authentication Service (HAS)
-HAS is a security solution to support the authentication of open source big data ecosystem in cloud computing platforms.
-Please look at [has-project](has-project/README.md) for details.
-
 ### License
 Apache License V2.0
 
diff --git a/has-project/README.md b/has-project/README.md
deleted file mode 100644
index 58451c1c..00000000
--- a/has-project/README.md
+++ /dev/null
@@ -1,87 +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.
--->
-
-# Hadoop Authentication Service (HAS)
-A dedicated Hadoop Authentication Server to support various authentication mechanisms other than just Kerberos.
-
-# High level considerations
-* Hadoop services are still strongly authenticated by Kerberos, as Kerberos is the only means so far to enable Hadoop security.
-* Hadoop users can remain to use their familiar login methods.
-* Security admins won't have to migrate and sync up their user accounts to Kerberos back and forth.
-* New authentication mechanism can be customized and plugined.
-
-# Architecture
-![](docs/has-overall.png)
-
-# Design
-Assuming existing users are stored in a SQL database (like MySQL), the detailed design and workflow may go like the following:
-![](docs/has-protocol-flow.png)
-
-# New mechanism plugin API
-
-## HAS client plugin HasClientPlugin:
-
-```Java
-// Get the login module type ID, used to distinguish this module from others. 
-// Should correspond to the server side module.
-String getLoginType()
-
-// Perform all the client side login logics, the results wrapped in an AuthToken, 
-// will be validated by HAS server.
-AuthToken login(Conf loginConf) throws HasLoginException
-```
-
-## HAS server plugin HasServerPlugin:
-
-```Java
-// Get the login module type ID, used to distinguish this module from others. 
-// Should correspond to the client side module.
-String getLoginType()
-
-// Perform all the server side authentication logics, the results wrapped in an AuthToken, 
-// will be used to exchange a Kerberos ticket.
-AuthToken authenticate(AuthToken userToken) throws HasAuthenException
-```
-## High Availability
-Please look at [High Availability](docs/has-ha.md) for details.
-
-## Cross Realm
-Please look at [How to setup cross-realm](docs/cross-realm.md) for details.
-
-## Performance test report
-Please look at [Performance test report](docs/performance-report.md) for details.
-
-## List of supported Hadoop ecosystem components
-
-|   Big Data Components   |           Supported         |   Rebuild Required   |
-|:-----------------------:|:---------------------------:|:--------------------:|
-| Hadoop                  | Yes                         | Yes                  |
-| Zookeeper               | Yes                         | Yes                  |
-| HBase                   | Yes                         | Yes                  |
-| Hive                    | Yes                         | No                   |
-| Phoenix                 | Yes                         | No                   |
-| Thrift                  | Yes                         | No                   |
-| Spark                   | Yes                         | No                   |
-| Oozie                   | Yes                         | No                   |
-| Presto                  | Yes (0.148 and later)       | No                   |
-| Pig                     | Yes                         | No                   |
-| Sqoop                   | Yes                         | No                   |
-
-## Getting Started
-Please look at [Getting Started](docs/has-start.md) for details.
diff --git a/has-project/docs/cross-realm.md b/has-project/docs/cross-realm.md
deleted file mode 100644
index 8c1fb36e..00000000
--- a/has-project/docs/cross-realm.md
+++ /dev/null
@@ -1,73 +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.
--->
-
-Establish cross realm trust
-============
-
-### Synchronize time of realms
-The time of realms should be synchronized.
-
-### Add the same special principals in realms, please select a very strong password
-```
-cd kerby-dist/kdc-dist
-sh bin/kadmin.sh [server-conf-dir] -k [keytab]
-// A.EXAMPLE.COM realm to access a service in the B.EXAMPLE.COM realm
-HadminLocalTool.local: addprinc -pw [same-password] krbtgt/B.EXAMPLE.COM@A.EXAMPLE.COM
-// Make sure that both principals have matching key version numbers and encryption types
-HadminLocalTool.local: getprinc krbtgt/B.EXAMPLE.COM@A.EXAMPLE.COM
-```
-
-### Configure krb5.conf of realms
-
-* config realms and domain_realms sections, make sure the realms are contained.
-
-* config capaths section, which contains the realm chain.
-
-An example of krb5.conf:
-```
-[realms]
-  A.EXAMPLE.COM = {
-    kdc = A.EXAMPLE.COM
-  }
-  B.EXAMPLE.COM = {
-    kdc = B.EXAMPLE.COM
-  }
-
-[domain_realm]
-  .A.EXAMPLE.COM = a.example.com
-  A.EXAMPLE.COM = a.example.com
-  .B.EXAMPLE.COM = b.example.com
-  B.EXAMPLE.COM = b.example.com
-
-[capaths]
-  A.EXAMPLE.COM = {
-    B.EXAMPLE.COM = .
-  }
-  B.EXAMPLE.COM = {
-    A.EXAMPLE.COM = .
-  }
-```
-
-> Make sure the FQDN match the realm name, e.g. if the FQDN is localhost.hadoop.com, the realm should be HADOOP.COM.
-
-### Validate
-```
-cd kerby-dist/tool-dist
-sh bin/kinit.sh -conf [client-conf-dir] -c [credential-cache-of-local-realm] -S [principal-name-of-remote-realm]
-```
diff --git a/has-project/docs/deploy-https.md b/has-project/docs/deploy-https.md
deleted file mode 100644
index 13dc0a1b..00000000
--- a/has-project/docs/deploy-https.md
+++ /dev/null
@@ -1,178 +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.
--->
-
-Deploy HTTPS
-===============
-
-## 1. Create a keystore file for each host
-
-> keystore: the keystore file that stores the certificate.
-> validity: the valid time of the certificate in days.
-```
-keytool -alias {hostname} -keystore {keystore} -validity {validity} -genkey
-```
-
-> The keytool will ask for more details such as the keystore password, keypassword and CN(hostname).
-
-## 2. Export the certificate public key to a certificate file for each host
-```
-keytool -export -alias {hostname} -keystore {keystore} -rfc -file {cert-file}
-```
-
-## 3. Create a common truststore file (trustAll)
-The truststore file contains the public key from all certificates. If you assume a 2-node cluster with node1 and node2,
-login to node1 and import the truststore file for node1.
-```
-keytool -import -alias {hostname} -keystore {trustAll} -file {cert-file}
-```
-
-## 4. Update the common truststore file
-* Move {trustAll} from node1 to node2 ({trustAll} already has the certificate entry of node1), and repeat Step 3.
-
-* Move the updated {trustAll} from node2 to node1. Repeat these steps for each node in the cluster.
-When you finish, the {trustAll} file will have the certificates from all nodes.
-
-> Note these work could be done on the same node, just notice the hostname.
-
-## 5. Copy {trustAll} from node1 to all of the other nodes
-
-## 6. Validate the common truststore file
-```
-keytool -list -v -keystore {trustAll}
-```
-
-## 7. Edit the Configuration files
-> Deploy {keystore} and {trustAll} files,
-and config `/<conf-dir>/ssl-server.conf` (e.g. `/etc/has/ssl-server.conf`) for HAS server.
-```
-ssl.server.keystore.location = {path to keystore}
-ssl.server.keystore.password = {keystore password set in step 1}
-ssl.server.keystore.keypassword = {keypassword set in step 1}
-ssl.server.truststore.reload.interval = 1000
-ssl.server.truststore.location = {path to trustAll}
-ssl.server.truststore.password = {trustAll password set in step 2}
-```
-
-If `ssl-server.conf` and `ssl-client.conf` do not specify the path of {keystore} and {trustAll},
-they should be put in `/etc/has`, which is the default location for HAS to get them.
-
-> Config `/etc/has/<https_host>/ssl-client.conf` for HAS client,
-the `<https_host>` is the HAS server address, the same as the value configured in has-client.conf.
-```
-ssl.client.truststore.location = {path to trustAll}
-ssl.client.truststore.password = {trustAll password}
-```
-
-Notice: `ssl-client.conf` is also required to appear in `/etc/has/` to avoid HTTPS validation problem.
-
-> Config $HADOOP_HOME/etc/hadoop/ssl-client.xml for Hadoop:
-```
-<configuration>
-
-<property>
-  <name>ssl.server.truststore.location</name>
-  <value>path to trustAll</value>
-</property>
-
-<property>
-  <name>ssl.server.truststore.password</name>
-  <value>trustAll password</value>
-</property>
-
-<property>
-  <name>ssl.server.truststore.type</name>
-  <value>jks</value>
-</property>
-
-<property>
-  <name>ssl.server.truststore.reload.interval</name>
-  <value>10000</value>
-</property>
-
-<property>
-  <name>ssl.server.keystore.location</name>
-  <value>path to keystore</value>
-</property>
-
-<property>
-  <name>ssl.server.keystore.password</name>
-  <value>keystore password</value>
-</property>
-
-<property>
-  <name>ssl.server.keystore.keypassword</name>
-  <value>keystore keypassword</value>
-</property>
-
-<property>
-  <name>ssl.server.keystore.type</name>
-  <value>jks</value>
-</property>
-
-</configuration>
-```
-
-> Config $HADOOP_HOME/etc/hadoop/ssl-client.xml for Hadoop
-```
-<configuration>
-
-<property>
-  <name>ssl.client.truststore.location</name>
-  <value>patch to trustAll</value>
-</property>
-
-<property>
-  <name>ssl.client.truststore.password</name>
-  <value>trustAll password</value>
-</property>
-
-<property>
-  <name>ssl.client.truststore.type</name>
-  <value>jks</value>
-</property>
-
-<property>
-  <name>ssl.client.truststore.reload.interval</name>
-  <value>10000</value>
-</property>
-
-<property>
-  <name>ssl.client.keystore.location</name>
-  <value>path to keystore</value>
-</property>
-
-<property>
-  <name>ssl.client.keystore.password</name>
-  <value>keystore password</value>
-</property>
-
-<property>
-  <name>ssl.client.keystore.keypassword</name>
-  <value>keystore keypassword</value>
-</property>
-
-<property>
-  <name>ssl.client.keystore.type</name>
-  <value>jks</value>
-</property>
-
-</configuration>
-```
-
-> To make the nodes in the cluster communicate bidirectionally, deploy above configuration files to each node.
diff --git a/has-project/docs/deploy-spnego.md b/has-project/docs/deploy-spnego.md
deleted file mode 100644
index 3f189078..00000000
--- a/has-project/docs/deploy-spnego.md
+++ /dev/null
@@ -1,32 +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.
--->
-
-Deploy SPNEGO
-================
-
-## 1. Server Side Configuration(in server side has-server.conf)
-
-To use Kerberos SPNEGO as the authentication mechanism, the authentication filter must be configured with the following init parameters:
-- filter_auth_type : the keyword kerberos. For example: filter_auth_type = kerberos
-
-## 2. Client Side Configuration(in client side admin.conf)
-
-- filter_auth_type the keyword kerberos.  For example: filter_auth_type = kerberos
-- admin_keytab: The path to the keytab file containing the credential for the admin principal(kadmin/<YOUR-REALM.COM>@<YOUR-REALM.COM>). For example: admin_keytab = /etc/has/admin.keytab
-- realm: The realm of KDC. For example: realm = YOUR-REALM.COM
diff --git a/has-project/docs/has-ha.md b/has-project/docs/has-ha.md
deleted file mode 100644
index e38eff23..00000000
--- a/has-project/docs/has-ha.md
+++ /dev/null
@@ -1,143 +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.
--->
-
-High Availability Using MySQL Backend
-========================================
-
-The HAS High Availability feature implemented by providing the option of running two redundant HAS servers. 
-
-## Deployment
-
-### 1. Configure has-server.conf
-
-The two redundant HAS servers must have same https ports. Below are examples:
-
-* has-server.conf of HAS server on emr-header-1:
-```
-[HAS]
-  https_host = emr-header-1
-  https_port = 8092
-  filter_auth_type = kerberos
-  enable_conf = true
-
-[PLUGIN]
-  auth_type = RAM
-```
-
-* has-server.conf of HAS server on emr-worker-1:
-```
-[HAS]
-  https_host = emr-worker-1
-  https_port = 8092
-  filter_auth_type = kerberos
-  enable_conf = true
-
-[PLUGIN]
-  auth_type = RAM
-```
-
-### 2. Start HAS servers
-
-### 3. Configure HAS backend
-
-The two redundant HAS servers must use **mysql** backend, and have same *mysql_url*, *mysql_user* and *mysql_password*.
-
-Please look at [How to use mysql backend](mysql-backend.md) for mysql backend configuration.
-
-### 4. Configure HAS KDC
-
-The two redundant HAS servers must have same ports and realms.
-
-### 5. Start and init HAS KDC servers
-
-> After doing init on either HAS server, the other one has been initialized too.
->
-> Please keep the shared admin.keytab safely.
-
-### 6. Reexport has-client.conf for HAS web server HA
-
-```
-cd kerby-dist/has-dist
-// Start KDC init tool
-sh bin/kdcinit.sh <conf_dir>
-// Get has-client.conf, and put it to /etc/has:
-HasInitTool: gethas -p /etc/has
-HasInitTool: exit
-```
-
-You will get has-client.conf like the following:
-```
-[HAS]
-  https_host = emr-header-1,emr-worker-1
-  https_port = 8092
-  filter_auth_type = kerberos
-  enable_conf = true
-
-[PLUGIN]
-  auth_type = RAM
-```
-
-Hadoop user can use HAS HA feature by updating **core-site.xml** without Reexport has-client.conf.
-add the following properties:
-```
-<property>
-   <name>hadoop.security.has</name>
-   <value>https://emr-header-1:8092/has/v1?auth_type=RAM;https://emr-worker-1:8092/has/v1?auth_type=RAM</value>
-</property>
-```
-
-### 7. Reexport krb5.conf for HAS KDC HA
-
-```
-cd kerby-dist/has-dist
-// Start KDC init tool:
-sh bin/has-init.sh <conf_dir>
-// Get krb5.conf, and put it to /etc:
-HasInitTool: getkrb5 -p /etc
-HasInitTool: exit
-```
-
-You will get krb5.conf like the following:
-```
-[libdefaults]
-    kdc_realm = HADOOP.COM
-    default_realm = HADOOP.COM
-    udp_preference_limit = 4096
-    kdc_tcp_port = 88
-    kdc_udp_port = 88
-
-[realms]
-    HADOOP.COM = {
-        kdc = localhost:88
-        kdc = localhost:88
-    }
-```
-
-## Verification
-
-You can use login-test tool to verify:
-
-### 1. Update hadmin.conf in <conf_dir>
-
-### 2. Run login-test tool
-```
-cd kerby-dist/has-dist
-// Use tgt to login
-sh bin/login-test.sh tgt <conf_dir> MySQL
-```
diff --git a/has-project/docs/has-overall.png b/has-project/docs/has-overall.png
deleted file mode 100644
index 2df5e48e..00000000
Binary files a/has-project/docs/has-overall.png and /dev/null differ
diff --git a/has-project/docs/has-protocol-flow.png b/has-project/docs/has-protocol-flow.png
deleted file mode 100644
index 8a978def..00000000
Binary files a/has-project/docs/has-protocol-flow.png and /dev/null differ
diff --git a/has-project/docs/has-start.md b/has-project/docs/has-start.md
deleted file mode 100644
index 5fa17336..00000000
--- a/has-project/docs/has-start.md
+++ /dev/null
@@ -1,250 +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.
--->
-
-Getting Started
-================
-
-## 1. Install
-
-### Download Kerby source code:
-```
-git clone https://github.com/apache/directory-kerby.git
-```
-
-### Install HAS:
-```
-cd directory-kerby
-mvn clean install -Pdist -DskipTests
-```
-
-## 2. Start and configure HAS server
-
-### Deploy https
-Please look at [How to deploy https](deploy-https.md) for details.
-
-### Configure has-server.conf in <conf_dir>:
-An example of has-server.conf:
-```
-[HAS]
-  https_host = localhost
-  https_port = 8092
-  filter_auth_type = kerberos
-
-[PLUGIN]
-  auth_type = MySQL
-```
-
-### Start HAS server:
-```
-cd HAS/has-dist
-sh bin/start-has.sh <conf_dir> <work_dir>
-```
-
-also:
-```
-export HAS_CONF_DIR=<conf_dir>
-export HAS_WORK_DIR=<work_dir>
-cd HAS/has-dist
-sh bin/start-has.sh
-```
-
-Root privileges required if https_port or KDC port numbers range from 0 to 1023.
-
-### Configure HAS plugin:
-```
-cd kerby-dist/has-dist
-// Proxy needed to be removed if it exists
-unset https_proxy
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-// Also: sh bin/has-init.sh, if HAS_CONF_DIR environment variable has been set.
-// Plugin_name example: MySQL
-HasInitTool: set_plugin <plugin_name>
-HasInitTool: exit
-```
-For MySQL plugin, please refer to [MySQL plugin](mysql-plugin.md) for details.
-
-For LDAP plugin, please refer to [LDAP plugin](ldap-plugin.md) for details.
-
-
-### Configure HAS backend:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-// An example of json backend:
-HasInitTool: config_kdcBackend json /tmp/has/jsonbackend
-// An example of mysql backend:
-HasInitTool: config_kdcBackend mysql jdbc:mysql://127.0.0.1:3306/mysqlbackend root passwd
-HasInitTool: exit
-```
-For mysql backend, please refer to [How to use mysql backend](mysql-backend.md) for details.
-
-### Configure HAS KDC:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-// An example of configure HAS KDC:
-HasInitTool: config_kdc localhost 88 HADOOP.COM
-HasInitTool: exit
-```
-Please make sure the following configuration files exist in the conf directory:
-```
-has-server.conf
-backend.conf
-kdc.conf
-```
-
-### Start HAS KDC server:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-HasInitTool: start
-HasInitTool: exit
-```
-
-### Init HAS server:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-HasInitTool: init
-HasInitTool: exit
-```
-
-### Deploy http spnego
-Please look at [How to deploy http spnego](deploy-spnego.md) for details.
-Please restart the HAS server
-
-```
-cd kerby-dist/has-dist
-sh bin/stop-has.sh
-
-cd kerby-dist/has-dist
-sh bin/start-has.sh <conf_dir> <work_dir>
-
-cd kerby-dist/has-dist
-sh bin/has-init.sh <conf_dir>
-HasInitTool: start
-HasInitTool: exit
-```
-
-### Get and deploy krb5.conf:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool:
-sh bin/has-init.sh <conf_dir>
-// Get krb5.conf, and put it to /etc:
-HasInitTool: getkrb5 -p /etc
-HasInitTool: exit
-```
-
-### Get and deploy has-client.conf:
-```
-cd kerby-dist/has-dist
-// Start HAS init tool
-sh bin/has-init.sh <conf_dir>
-// Get has-client.conf, and put it to /etc/has:
-HasInitTool: gethas -p /etc/has
-HasInitTool: exit
-```
-
-## 3. Prepare for Hadoop
-There are two ways to create and deploy corresponding keytabs of Hadoop.
-
-### a. Create and deploy keytabs manually
-#### Create service principals:
-```
-cd kerby-dist/has-dist
-echo { \
-    HOSTS: [ \
-       {"name":"<host>","hostRoles":"<role>,..., <role>"\}, \
-       ...
-       {"name":"<host>","hostRoles":"<role>,...,<role>"\} \
-    ] \
-\} > hosts.txt
-// Start local hadmin tool
-sh bin/admin-local.sh <conf_dir> -k <keytab>
-// Also: sh bin/admin-local.sh -k <keytab>, if HAS_CONF_DIR environment variable has been set.
-// Also you can use remote admin tool, admin.keytab file needed to be placed in /etc/has
-sh bin/admin-remote.sh <conf_dir>
-// Also: sh bin/admin-remote.sh, if HAS_CONF_DIR environment variable has been set.
-admin.local: creprincs hosts.txt
-admin.local: exit
-```
-The admin.keytab file is created by the has-init. In local and remote admin tool, you can type "?" for help.
-
-#### Export and deploy keytabs:
-```
-// Start local admin tool
-sh bin/admin-local.sh <conf_dir> -k <keytab>
-
-// keytab deploy [HostRoles-File] [Where-to-Deploy] [SSH-Port] [UserName] [Password]
-// Where-to-Deploy: The place to store the keytabs
-// UserName: The host user name
-// Password: The host password
-// All the hosts with the same user and password
-admin.local: keytab deploy hosts.txt 22 /etc/has/ username password
-admin.local: exit
-```
-
-### b. One step to create service principals, export keytabs and deploy keytabs:
-```
-cd kerby-dist/has-dist
-echo { \
-    HOSTS: [ \
-       {"name":"<host>","hostRoles":"<role>,..., <role>"\}, \
-       ...
-       {"name":"<host>","hostRoles":"<role>,...,<role>"\} \
-    ] \
-\} > hosts.txt
-
-// Start local admin tool
-sh bin/admin-local.sh <conf_dir> -k <keytab>
-
-// keytab create_deploy [HostRoles-File] [Where-to-Deploy] [SSH-Port] [UserName] [Password]
-// Where-to-Deploy: The place to store the keytabs
-// UserName: The host user name
-// Password: The host password
-// All the hosts with the same user and password
-admin.local: keytab create_deploy hosts.txt 22 /etc/has/ username password
-admin.local: exit
-```
-Note: The admin.keytab file is created by the `has-init`. In local admin tool, you can type "?" for help.
-
-### Enable Hadoop ecosystem components
-* [Enable Hadoop](../supports/hadoop/README.md)
-
-* [Enable Zookeeper](../supports/zookeeper/README.md)
-
-* [Enable HBase](../supports/hbase/README.md)
-
-* [Enable Hive](../supports/hive/README.md)
-
-* [Enable Phoenix](../supports/phoenix/README.md)
-
-* [Enable Thrift](../supports/thrift/README.md)
-
-* [Enable Spark](../supports/spark/README.md)
-
-* [Enable Oozie](../supports/oozie/README.md)
-
-* [Enable Presto](../supports/presto/README.md)
\ No newline at end of file
diff --git a/has-project/docs/ldap-plugin.md b/has-project/docs/ldap-plugin.md
deleted file mode 100644
index 8738f371..00000000
--- a/has-project/docs/ldap-plugin.md
+++ /dev/null
@@ -1,74 +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.
--->
-
-LDAP Plugin
-===============
-
-## Install and start [ApacheDS](https://directory.apache.org/apacheds/)
-
-Please refer to [install ApacheDS](https://directory.apache.org/apacheds/basic-ug/1.3-installing-and-starting.html).
-
-## Prepare user infomation in ApacheDS
-
-### Add user partition
-Please refer to [Add Partition](https://directory.apache.org/apacheds/basic-ug/1.4.3-adding-partition.html) .
-Example:
-```
-Partition Type: JDBM
-ID: has
-Suffix: ou=has,dc=kerby,dc=com
-```
-
-### Insert user into LDAP server
-
-Following is an example of the ldif file to be imported, username is "hdfs", password is "test":
-```
-dn: cn=hdfs,ou=has,dc=kerby,dc=com
-objectclass: inetOrgPerson
-objectclass: organizationalPerson
-objectclass: person
-objectclass: top
-cn: HDFS
-description: This is user hdfs.
-sn: hello
-mail: hello@apache.org
-userpassword: test
-```
-
-## Config /etc/has/ldap-server.ini in HAS server host
-Example:
-```
-  [ users ]
-      user_filter=objectclass=*
-      user_name_attr=cn
-
-  [ ldap ]
-       base_dn=ou=has,dc=kerby,dc=com
-       bind_dn=uid=admin,ou=system
-       bind_password=secret
-       host=127.0.0.1
-       port=10389
-```
-
-## Config client
-Example:
-```
-export LDAP_USER=hdfs
-export LDAP_PWD=test
-```
diff --git a/has-project/docs/mysql-backend.md b/has-project/docs/mysql-backend.md
deleted file mode 100644
index 29de3b13..00000000
--- a/has-project/docs/mysql-backend.md
+++ /dev/null
@@ -1,42 +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.
--->
-
-MySQL Backend
-===============
-
-## Install MySQL
-
-Please refer to [install mysql](https://dev.mysql.com/doc/refman/5.7/en/linux-installation.html).
-
-## Config backend
-```
-// Url: jdbc url of mysql database; mysqlbackend: name of has mysql backend database; username: mysql user name; password: mysql password
-cd kerby-dist/has-dist
-sh bin/has-init.sh conf
-HasInitTool: config_kdcBackend mysql jdbc:mysql://127.0.0.1:3306/mysqlbackend?createDB=true root passwd
-HasInitTool: exit
-```
-
-## Config kdc
-```
-cd kerby-dist/has-dist
-sh bin/has-init.sh conf
-HasInitTool: config_kdc localhost 88 HADOOP.COM
-HasInitTool: exit
-```
diff --git a/has-project/docs/mysql-plugin.md b/has-project/docs/mysql-plugin.md
deleted file mode 100644
index 1aea2465..00000000
--- a/has-project/docs/mysql-plugin.md
+++ /dev/null
@@ -1,55 +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.
--->
-
-MySQL Plugin
-===============
-
-## Install MySQL
-
-Please refer to [install mysql](https://dev.mysql.com/doc/refman/5.7/en/linux-installation.html).
-
-## Prepare user infomation in MySQL
-
-### Create database "has" and create table "has_user"
-```
-mysql> create database has;
-mysql> use has;
-mysql> CREATE TABLE has_user(user_name VARCHAR(100), pass_word VARCHAR(100));
-```
-
-### Insert user into table
-Example, username is "hdfs", password is "test":
-```
-mysql> INSERT INTO has_user VALUES ('hdfs', 'test');
-```
-
-## Config HAS server 
-Example:
-```
-export mysqlUrl=jdbc:mysql://127.0.0.1:3306/has
-export mysqlUser=root
-export mysqlPasswd=123456
-```
-
-## Config client
-Example:
-```
-export userName=hdfs
-export password=test
-```
diff --git a/has-project/docs/performance-report.md b/has-project/docs/performance-report.md
deleted file mode 100644
index 6ecf2c53..00000000
--- a/has-project/docs/performance-report.md
+++ /dev/null
@@ -1,117 +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.
--->
-
-# HAS Performance Test Report
-
-## 1. Overview
-
-HAS is a dedicated Hadoop authentication server to support various authentication mechanisms other than just Kerberos. With HAS users can remain their familiar login methods, and new authentication mechanism could be customized and plugined.  
-
-A Hadoop cluster could have thousands of nodes, there maybe so many authentication  requests are sent to HAS server at the same time. So the stability in high concurrency is so important for HAS.
-
-## 2. Test Environment
-
-The test use Alibaba Cloud Elastic Compute Service, detailed test environment like the following: 
-
-### 2.1 Hardware environment
-
-* HAS Server:
-
-> CPU:Intel(R) Xeon(R)CPU E5-2682 @ 2.50GHz    
-> MEM: 16GB    
-> Disk: 43GB 86GB    
-
-* HAS Client:
-
-> CPU:Intel(R) Xeon(R)CPU E5-2682 @ 2.50GHz    
-> MEM: 16GB    
-> Disk: 43GB 86GB * 3
-
-### 2.2 Software environment
-
-> OS: CentOS 7.2    
-> JAVA: 1.8    
-> HAS: 1.0.0    
-> MySQL: 5.5.52  
-
-## 3. Test Method
-
-By using [login-test](../../kerby-dist/has-dist/bin/login-test.sh) scripting tool, the test can be broadly divided into four steps:
-
-1. Add principals to HAS server
-2. Export keytab files to HAS Client  
-    
-    ```shell
-    cd HAS/has-dist         
-    sh bin/login-test add <conf_dir> <work_dir> <principal_num>
-    ```
-
-3. Use keytab files to login concurrently
-
-    ```shell                        
-    sh bin/login-test run <conf_dir> <work_dir> <concurrency_num>
-    ```
-
-4. Record login result and the cost time of login
-
-Testing process like the following:
-
-![testing process](https://user-images.githubusercontent.com/9171954/27905170-b7637602-6271-11e7-8fc9-27d494f9b1ee.jpg)
-
-## 4. Test Result
-
-The test result consists of total cost time and time per request of login using keytab file.
-
-### 4.1 Using Json Backend
-
-| Concurrency | 100 | 500 | 1000 | 5000 | 8000 | 10000 |
-| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-| Result | Success | Success  | Success  | Success | Success | Success |
-| Total time (ms) | 540 | 1115 | 1661  | 4571 | 6328 | 7208 |
-| Time per request (ms)| 5.400 | 2.230 | 1.661 | 0.914 | 0.791 | 0.721 |
-
-### 4.2 Using MySQL Backend
-
-MySQL Configuration:
-> max connection: 5000              
-> innodb buffer size: 8G
-
-| Concurrency | 100 | 500 | 1000 | 5000 | 8000 | 10000 |
-| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-| Result | Success | Success  | Success  | Success | Success | Success |
-| Total time (ms) | 765 | 2880  | 4821  | 12712 | 21419 | 22968 |
-| Time per request (ms)| 7.650 | 5.760  | 4.821  | 2.542 | 2.677 | 2.297 |
-
-## 5. Conclusion
-
-![performance in different backends](https://user-images.githubusercontent.com/9171954/27905152-a9bc2a44-6271-11e7-8ddc-16222ee7d3c4.png)
-
-Figure above demonstrates the time per request of HAS authentication in different backends and concurrency. As can be seen, HAS can complete authentication work in high concurrency, and has a good performance. So HAS is good enough for Hadoop.
-
-The CPU utilization and network IO of HAS server are demonstrated in the appendix, with the number of concurrency up to 10000. The appendix shows that HAS server is not under heavy workload in mysql backend. 
-
-## 6. Appendix
-
-* CPU Utilization
-
-![cpu utilization](https://user-images.githubusercontent.com/9171954/27905176-bf7ea410-6271-11e7-904e-abd1bf532725.jpg)
-
-* Network IO
-
-![network io](https://user-images.githubusercontent.com/9171954/27905186-c717b784-6271-11e7-96d3-2fd317defd96.jpg)
diff --git a/has-project/has-client-plugin/pom.xml b/has-project/has-client-plugin/pom.xml
deleted file mode 100644
index d1bd0007..00000000
--- a/has-project/has-client-plugin/pom.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed 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. See accompanying LICENSE file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>has-project</artifactId>
-        <groupId>org.apache.kerby</groupId>
-        <version>2.1.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>has-client-plugin</artifactId>
-    <name>HAS Client Plugin</name>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.kerby</groupId>
-            <artifactId>has-client</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ini4j</groupId>
-            <artifactId>ini4j</artifactId>
-            <version>${ini4j.version}</version>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/ldap/LDAPClientPlugin.java b/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/ldap/LDAPClientPlugin.java
deleted file mode 100755
index dffab6ee..00000000
--- a/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/ldap/LDAPClientPlugin.java
+++ /dev/null
@@ -1,96 +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.kerby.has.plugins.client.ldap;
-
-import org.apache.kerby.has.client.AbstractHasClientPlugin;
-import org.apache.kerby.has.client.HasLoginException;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.ini4j.Wini;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.util.Date;
-
-public class LDAPClientPlugin extends AbstractHasClientPlugin {
-    public static final Logger LOG = LoggerFactory.getLogger(LDAPClientPlugin.class);
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getLoginType() {
-        return "LDAP";
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void doLogin(AuthToken authToken) throws HasLoginException {
-        String user = System.getenv("LDAP_USER");
-        String pwd = System.getenv("LDAP_PWD");
-        if (user == null || pwd == null) {
-            String ldapConfigDir = System.getenv("HAS_CONF_DIR");
-            if (ldapConfigDir == null) {
-                LOG.error("Get LDAP User/Secret failed, "
-                        + "you can set them using export system environment(User/Secret),"
-                        + "or export HAS_CONF_DIR which has a credential.xml file");
-            } else {
-                try {
-                    String confFile = ldapConfigDir + "/ldap-client.ini";
-                    Wini ini = new Wini(new File(confFile));
-                    user = ini.get("user", "ldap_user");
-                    pwd = ini.get("user", "ldap_pwd");
-                } catch (Exception e) {
-                    LOG.error("parser ldap ini failed", e);
-                }
-
-                LOG.debug("Get LDAP User/Secret from " + ldapConfigDir
-                        + "/ldap-client.ini, user:" + user);
-            }
-        } else {
-            LOG.debug("Get LDAP User/Secret from sys environment, user:" + user);
-        }
-
-        if (user == null) {
-            user = System.getProperty("user.name");
-        }
-
-        if (user == null || pwd == null) {
-            String errMsg = "Get LDAP User/Secret failed, "
-                    + "you can set them using export system environment(User/Secret),"
-                    + "or export HAS_CONF_DIR which has a credential.xml file";
-            LOG.error(errMsg);
-            throw new HasLoginException(errMsg);
-        }
-
-        authToken.setIssuer("has");
-
-        final Date now = new Date(new Date().getTime() / 1000 * 1000);
-        authToken.setIssueTime(now);
-        // Set expiration in 60 minutes
-        Date exp = new Date(now.getTime() + 1000 * 60 * 60);
-        authToken.setExpirationTime(exp);
-
-        authToken.addAttribute("ldap_user", user);
-        authToken.addAttribute("ldap_pwd", pwd);
-        authToken.addAttribute("passPhrase", pwd);
-    }
-
-}
diff --git a/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/mysql/MySQLHasClientPlugin.java b/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/mysql/MySQLHasClientPlugin.java
deleted file mode 100644
index 3bbe6f81..00000000
--- a/has-project/has-client-plugin/src/main/java/org/apache/kerby/has/plugins/client/mysql/MySQLHasClientPlugin.java
+++ /dev/null
@@ -1,67 +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.kerby.has.plugins.client.mysql;
-
-import org.apache.kerby.has.client.AbstractHasClientPlugin;
-import org.apache.kerby.has.client.HasLoginException;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Date;
-
-public class MySQLHasClientPlugin extends AbstractHasClientPlugin {
-    private static final Logger LOG = LoggerFactory.getLogger(MySQLHasClientPlugin.class);
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getLoginType() {
-        return "MySQL";
-    }
-
-    @Override
-    protected void doLogin(AuthToken authToken) throws HasLoginException {
-
-        //Get the user info from env
-        String userName = System.getenv("userName");
-        if (userName == null || userName.isEmpty()) {
-            throw new HasLoginException("Please set the userName.");
-        }
-        String password = System.getenv("password");
-        if (password == null || password.isEmpty()) {
-            throw new HasLoginException("Please set the password.");
-        }
-        LOG.debug("Get the user info successfully.");
-
-        authToken.setIssuer("has");
-        authToken.setSubject(userName);
-
-        final Date now = new Date(System.currentTimeMillis() / 1000 * 1000);
-        authToken.setIssueTime(now);
-        // Set expiration in 60 minutes
-        Date exp = new Date(now.getTime() + 1000 * 60 * 60);
-        authToken.setExpirationTime(exp);
-
-        authToken.addAttribute("user", userName);
-        authToken.addAttribute("secret", password);
-
-        authToken.addAttribute("passPhrase", userName + password);
-    }
-}
diff --git a/has-project/has-client-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.client.HasClientPlugin b/has-project/has-client-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.client.HasClientPlugin
deleted file mode 100644
index 25382fce..00000000
--- a/has-project/has-client-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.client.HasClientPlugin
+++ /dev/null
@@ -1,17 +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.
-
-org.apache.kerby.has.plugins.client.mysql.MySQLHasClientPlugin
-org.apache.kerby.has.plugins.client.ldap.LDAPClientPlugin
diff --git a/has-project/has-client-plugin/src/main/resources/ldap-client.ini b/has-project/has-client-plugin/src/main/resources/ldap-client.ini
deleted file mode 100644
index fbe22d0c..00000000
--- a/has-project/has-client-plugin/src/main/resources/ldap-client.ini
+++ /dev/null
@@ -1,21 +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.
-#
-
-[ user ]
-    ldap_user=test
-    ldap_pwd=123456
diff --git a/has-project/has-client-plugin/src/test/java/org/apache/kerby/has/plugins/client/TestHasClientPluginRegistry.java b/has-project/has-client-plugin/src/test/java/org/apache/kerby/has/plugins/client/TestHasClientPluginRegistry.java
deleted file mode 100644
index bbef0a09..00000000
--- a/has-project/has-client-plugin/src/test/java/org/apache/kerby/has/plugins/client/TestHasClientPluginRegistry.java
+++ /dev/null
@@ -1,44 +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.kerby.has.plugins.client;
-
-import org.apache.kerby.has.client.HasClientPluginRegistry;
-import org.apache.kerby.has.common.HasException;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Set;
-
-public class TestHasClientPluginRegistry {
-
-  @Test
-  public void testInit() {
-    Set<String> pluginsNames = HasClientPluginRegistry.registeredPlugins();
-    Assert.assertTrue(pluginsNames.size() > 0);
-  }
-
-  @Test
-  public void testCreatePlugin() throws HasException {
-    Assert.assertTrue(HasClientPluginRegistry.createPlugin("MySQL") != null);
-    Set<String> pluginNames = HasClientPluginRegistry.registeredPlugins();
-    for (String name : pluginNames) {
-      HasClientPluginRegistry.createPlugin(name);
-    }
-  }
-}
-
diff --git a/has-project/has-client/pom.xml b/has-project/has-client/pom.xml
deleted file mode 100644
index cce9fb49..00000000
--- a/has-project/has-client/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed 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. See accompanying LICENSE file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>has-project</artifactId>
-        <groupId>org.apache.kerby</groupId>
-        <version>2.1.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>has-client</artifactId>
-    <name>HAS Client</name>
-
-    <dependencies>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <version>${slf4j.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>has-common</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-json</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-text</artifactId>
-      <version>${commons-text.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/AbstractHasClientPlugin.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/AbstractHasClientPlugin.java
deleted file mode 100644
index f60a6d07..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/AbstractHasClientPlugin.java
+++ /dev/null
@@ -1,44 +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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.kerberos.kerb.KrbRuntime;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractHasClientPlugin implements HasClientPlugin {
-    public static final Logger LOG = LoggerFactory.getLogger(AbstractHasClientPlugin.class);
-
-    protected abstract void doLogin(AuthToken token) throws HasLoginException;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public AuthToken login(HasConfig conf) throws HasLoginException {
-
-        AuthToken authToken = KrbRuntime.getTokenProvider("JWT").createTokenFactory().createToken();
-
-        doLogin(authToken);
-
-        return authToken;
-    }
-
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
deleted file mode 100644
index d6cd9a3f..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
+++ /dev/null
@@ -1,618 +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.kerby.has.client;
-
-import org.apache.kerby.KOptions;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.admin.kadmin.Kadmin;
-import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-public class HasAuthAdminClient implements Kadmin {
-    public static final Logger LOG = LoggerFactory.getLogger(HasAuthAdminClient.class);
-
-    private HasConfig hasConfig;
-
-    /**
-     * Create an instance of the HasAuthAdminClient.
-     *
-     * @param hasConfig the has config
-     */
-    public HasAuthAdminClient(HasConfig hasConfig) {
-        this.hasConfig = hasConfig;
-    }
-
-    private String getKadminBaseURL() throws KrbException {
-        return HasClientUtil.getBaseUrl(hasConfig, "kadmin");
-    }
-
-    private String getHadminBaseURL() throws KrbException {
-        return HasClientUtil.getBaseUrl(hasConfig, "hadmin");
-    }
-
-    @Override
-    public void addPrincipal(String principal) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "addprincipal?principal=" + principal);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "POST", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-    }
-
-    @Override
-    public void addPrincipal(String principal, String password) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "addprincipal?principal=" + principal
-                + "&password=" + password);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "POST", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-    }
-
-    @Override
-    public void addPrincipal(String principal, String password, KOptions kOptions) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void deletePrincipal(String principal) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "deleteprincipal?principal=" + principal);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "DELETE", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-            } else {
-                throw new KrbException("Connection deined.");
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-    }
-
-    @Override
-    public void modifyPrincipal(String principal, KOptions kOptions) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void renamePrincipal(String oldPrincipal, String newPrincipal) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "renameprincipal?oldprincipal=" + oldPrincipal
-                + "&newprincipal=" + newPrincipal);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "POST", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-    }
-
-    @Override
-    public List<String> getPrincipals() throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "listprincipals");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-        LOG.info("Remote Admin Url: " + url);
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-        String response;
-        try {
-            httpConn.setDoInput(true);
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                response = HasClientUtil.getResponse(httpConn);
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            LOG.error("IO error occurred." + e.getMessage());
-            throw new KrbException("IO error occurred.", e);
-        }
-        return convertJsonStringToList(response);
-    }
-
-    @Override
-    public List<String> getPrincipals(String exp) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "listprincipals?exp=" + exp);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object. ", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-        String response;
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                response = HasClientUtil.getResponse(httpConn);
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-        if (response == null) {
-            throw new KrbException("Please initial KDC first.");
-        }
-        return convertJsonStringToList(response);
-    }
-
-    /**
-     * Convert JSON string to a List.
-     *
-     * @param result principals JSON string which like
-     *               "["HTTP\/host1@HADOOP.COM","HTTP\/host2@HADOOP.COM"]"
-     * @return principal lists.
-     */
-    private List<String> convertJsonStringToList(String result) throws KrbException {
-        List<String> principalLists = new ArrayList<>();
-        try {
-            JSONArray jsonArray = new JSONArray(result);
-            for (int i = 0; i < jsonArray.length(); i++) {
-                principalLists.add("\t" + jsonArray.getString(i));
-            }
-        } catch (JSONException e) {
-            throw new KrbException("JSON Exception occurred. ", e);
-        }
-        return principalLists;
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile, String principal) throws KrbException {
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "exportkeytab?principal=" + principal);
-        } catch (MalformedURLException e) {
-            LOG.error("Failed to create a URL object." + e.getMessage());
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        HttpURLConnection httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-
-            try {
-                if (!keytabFile.exists() && !keytabFile.createNewFile()) {
-                    throw new KrbException("Failed to create keytab file "
-                            + keytabFile.getAbsolutePath());
-                }
-            } catch (IOException e) {
-                throw new KrbException("Failed to load or create keytab "
-                        + keytabFile.getAbsolutePath(), e);
-            }
-
-            try (FileOutputStream fos = new FileOutputStream(keytabFile);
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[3 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-        LOG.info("Receive keytab file \"" + keytabFile.getName() + "\" from server successfully.");
-    }
-
-    public void exportKeytabWithGlob(File keytabFile, String principal) throws KrbException {
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "exportkeytab?principal=" + principal + "&global=true");
-        } catch (MalformedURLException e) {
-            LOG.error("Failed to create a URL object.", e);
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        HttpURLConnection httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-
-            try {
-                if (!keytabFile.exists() && !keytabFile.createNewFile()) {
-                    throw new KrbException("Failed to create keytab file "
-                            + keytabFile.getAbsolutePath());
-                }
-            } catch (IOException e) {
-                throw new KrbException("Failed to load or create keytab "
-                        + keytabFile.getAbsolutePath(), e);
-            }
-
-            try (FileOutputStream fos = new FileOutputStream(keytabFile);
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[3 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            LOG.error("IO error occurred.", e);
-            throw new KrbException("IO error occurred.", e);
-        }
-        LOG.info("Receive keytab file " + keytabFile.getName() + " from server successfully.");
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile, List<String> principals) throws KrbException {
-        HttpURLConnection httpConn;
-        for (String principal : principals) {
-            String request = getKadminBaseURL() + "exportkeytab?principal=" + principal;
-            URL url;
-            try {
-                url = new URL(request);
-            } catch (MalformedURLException e) {
-                throw new KrbException("Failed to create a URL object.");
-            }
-            httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-            try {
-                httpConn.connect();
-                if (httpConn.getResponseCode() != 200) {
-                    throw new KrbException(HasClientUtil.getResponse(httpConn));
-                }
-                try (FileOutputStream fos = new FileOutputStream(keytabFile);
-                     InputStream in = httpConn.getInputStream()) {
-                    byte[] buffer = new byte[4 * 1024];
-                    int read;
-                    while ((read = in.read(buffer)) > 0) {
-                        fos.write(buffer, 0, read);
-                    }
-                }
-            } catch (IOException e) {
-                throw new KrbException("IO error occurred.", e);
-            }
-        }
-        LOG.info("Accept keytab file \"" + keytabFile.getName() + "\" from server.");
-    }
-
-    @Override
-    public void addPrincipal(String principal, KOptions kOptions) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public String getKadminPrincipal() {
-        return KrbUtil.makeKadminPrincipal(hasConfig.getRealm()).getName();
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile, String principal) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile, String principal, int kvno) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void removeOldKeytabEntriesOf(File keytabFile, String principal) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void changePassword(String principal,
-                               String newPassword) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "changepassword?principal=" + principal
-                    + "&password=" + newPassword);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "POST", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred.", e);
-        }
-    }
-
-    @Override
-    public void updateKeys(String principal) throws KrbException {
-        throw new KrbException("Unsupported feature");
-    }
-
-    @Override
-    public void release() throws KrbException {
-
-    }
-
-    public List<String> addPrincipalsByRole(String hostRoles) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getHadminBaseURL() + "addprincipalsbyrole");
-        } catch (MalformedURLException e) {
-            throw new KrbException(e.getMessage());
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", true);
-
-        String response;
-        try {
-            httpConn.connect();
-            OutputStream out = httpConn.getOutputStream();
-            out.write(hostRoles.toString().getBytes());
-            out.flush();
-            out.close();
-            if (httpConn.getResponseCode() == 200) {
-                response = HasClientUtil.getResponse(httpConn);
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (Exception e) {
-            throw new KrbException(e.getMessage());
-        }
-        return convertJsonStringToList(response);
-    }
-
-    public void setEnableOfConf(String isEnable) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getHadminBaseURL() + "setconf?isEnable=" + isEnable);
-        } catch (MalformedURLException e) {
-            throw new KrbException(e.getMessage());
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", true);
-
-        try {
-            httpConn.connect();
-            InputStream inputStream = httpConn.getResponseCode() == 200
-                    ? httpConn.getInputStream() : httpConn.getErrorStream();
-            BufferedReader reader = new BufferedReader(
-                    new InputStreamReader(inputStream));
-            String s;
-            StringBuilder result = new StringBuilder();
-            while ((s = reader.readLine()) != null) {
-                result.append(s);
-            }
-            if (httpConn.getResponseCode() == 200) {
-                System.out.println(result);
-            } else {
-                System.err.println(result);
-            }
-        } catch (Exception e) {
-            LOG.error("Fail to connect to server. " + e);
-            throw new KrbException(e.getMessage());
-        }
-    }
-
-    public File getKeytabByHostAndRole(String host, String role) throws KrbException {
-        String keytabName = host + ".zip";
-        HttpURLConnection httpConn;
-        String request = getHadminBaseURL() + "exportKeytabsbyrole?host=" + host;
-        if (!role.equals("")) {
-            request = request + "&role=" + role;
-            keytabName = role + "-" + host + ".keytab";
-        }
-
-        URL url;
-        try {
-            url = new URL(request);
-        } catch (MalformedURLException e) {
-            throw new KrbException(e.getMessage());
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-            try (FileOutputStream fos = new FileOutputStream(new File(keytabName));
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[4 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            throw new KrbException(e.getMessage());
-        }
-        System.out.println("Accept keytab file \"" + keytabName + "\" from server.");
-
-        return new File(keytabName);
-    }
-
-    public String getHostRoles() throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getHadminBaseURL() + "hostroles");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", true);
-
-        String response;
-        try {
-            httpConn.setDoInput(true);
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                response = HasClientUtil.getResponse(httpConn);
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            LOG.error("IO error occurred." + e.getMessage());
-            throw new KrbException("IO error occurred.", e);
-        }
-        return response;
-    }
-
-    public String getPrincipal(String principalName) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getKadminBaseURL() + "getprincipal?principal=" + principalName);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "POST", true);
-
-        String response;
-        try {
-            httpConn.setDoInput(true);
-            httpConn.connect();
-
-            OutputStream out = httpConn.getOutputStream();
-            out.write(principalName.getBytes());
-            out.flush();
-            out.close();
-
-            if (httpConn.getResponseCode() == 200) {
-                response = HasClientUtil.getResponse(httpConn);
-                LOG.info(response);
-            } else {
-                LOG.info(HasClientUtil.getResponse(httpConn));
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            LOG.error("IO error occurred.", e);
-            throw new KrbException("IO error occurred.", e);
-        }
-
-        return response;
-    }
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
deleted file mode 100755
index da8ba4d4..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
+++ /dev/null
@@ -1,701 +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
- * <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.kerby.has.client;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.text.CharacterPredicates;
-import org.apache.commons.text.RandomStringGenerator;
-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.ssl.SSLFactory;
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.has.common.util.URLConnectionFactory;
-import org.apache.kerby.kerberos.kerb.KrbCodec;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.KrbRuntime;
-import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
-import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
-import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptedData;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
-import org.apache.kerby.kerberos.kerb.type.base.KrbError;
-import org.apache.kerby.kerberos.kerb.type.base.KrbMessage;
-import org.apache.kerby.kerberos.kerb.type.base.KrbMessageType;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.apache.kerby.kerberos.kerb.type.kdc.EncAsRepPart;
-import org.apache.kerby.kerberos.kerb.type.kdc.EncKdcRepPart;
-import org.apache.kerby.kerberos.kerb.type.kdc.KdcRep;
-import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
-import org.apache.kerby.util.IOUtil;
-import org.apache.kerby.util.SysUtil;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.ProtocolException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-/**
- * HAS client
- */
-public class HasClient {
-
-    public static final Logger LOG = LoggerFactory.getLogger(HasClient.class);
-
-    public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf";
-    public static final String HAS_HTTP_PORT_DEFAULT = "9870";
-    public static final String HAS_CONFIG_DEFAULT = "/etc/has/has-client.conf";
-    public static final String CA_ROOT_DEFAULT = "/etc/has/ca-root.pem";
-
-    private String hadoopSecurityHas = null;
-    private String type;
-    private File clientConfigFolder;
-
-
-    public HasClient() { }
-
-    /**
-     * Create an instance of the HasClient.
-     *
-     * @param hadoopSecurityHas the has config
-     */
-    public HasClient(String hadoopSecurityHas) {
-        this.hadoopSecurityHas = hadoopSecurityHas;
-    }
-
-
-    public TgtTicket requestTgt() throws HasException {
-        HasConfig config;
-        if (hadoopSecurityHas == null) {
-            String hasClientConf = System.getenv("HAS_CLIENT_CONF");
-            if (hasClientConf == null) {
-                hasClientConf = HAS_CONFIG_DEFAULT;
-            }
-            LOG.debug("has-client conf path: " + hasClientConf);
-            File confFile = new File(hasClientConf);
-            if (!confFile.exists()) {
-                LOG.warn("The HAS client config file: " + hasClientConf + " does not exist.");
-                throw new HasException("The HAS client config file: " + hasClientConf
-                    + " does not exist.");
-            }
-            try {
-                config = HasUtil.getHasConfig(confFile);
-            } catch (HasException e) {
-                LOG.error("Failed to get has client config: " + e.getMessage());
-                throw new HasException("Failed to get has client config: " + e.getMessage());
-            }
-        } else {
-            config = new HasConfig();
-            String[] urls = hadoopSecurityHas.split(";");
-            StringBuilder host = new StringBuilder();
-            int port = 0;
-            try {
-                for (String url : urls) {
-                    URI uri = new URI(url.trim());
-
-                    // parse host
-                    host.append(uri.getHost()).append(",");
-
-                    // parse port
-                    if (port == 0) {
-                        port = uri.getPort();
-                    } else {
-                        if (port != uri.getPort()) {
-                            throw new HasException("Invalid port: not even.");
-                        }
-                    }
-
-                    // We will get the auth type from env first
-                    type = System.getenv("auth_type");
-                    // parse host
-                    if (type == null) {
-                        String[] strs = uri.getQuery().split("=");
-                        if (strs[0].equals("auth_type")) {
-                            type = strs[1];
-                        } else {
-                            LOG.warn("No auth type in conf.");
-                        }
-                    }
-                }
-                if (host.length() == 0 || port == 0) {
-                    throw new HasException("host is null.");
-                } else {
-                    config.setString(HasConfigKey.HTTPS_HOST,  host.subSequence(0, host.length() - 1).toString());
-                    config.setInt(HasConfigKey.HTTPS_PORT, port);
-                    config.setString(HasConfigKey.AUTH_TYPE, type);
-                }
-            } catch (URISyntaxException e) {
-                LOG.error("Errors occurred when getting web url. " + e.getMessage());
-                throw new HasException(
-                    "Errors occurred when getting web url. " + e.getMessage());
-            }
-        }
-        if (config == null) {
-            throw new HasException("Failed to get HAS client config.");
-        }
-        clientConfigFolder = new File("/etc/has/" + config.getHttpsHost());
-        if (!clientConfigFolder.exists()) {
-            clientConfigFolder.mkdirs();
-        }
-
-        // get and set ssl-client/trustStore first
-        String sslClientConfPath = clientConfigFolder + "/ssl-client.conf";
-        loadSslClientConf(config, sslClientConfPath);
-        config.setString(HasConfigKey.SSL_CLIENT_CONF, sslClientConfPath);
-
-        HasClientPlugin plugin;
-        try {
-            plugin = getClientTokenPlugin(config);
-        } catch (HasException e) {
-            LOG.error("Failed to get client token plugin from config: " + e.getMessage());
-            throw new HasException(
-                "Failed to get client token plugin from config: " + e.getMessage());
-        }
-        AuthToken authToken;
-        try {
-            authToken = plugin.login(config);
-        } catch (HasLoginException e) {
-            LOG.error(e.getMessage());
-            throw new HasException(e.getMessage());
-        }
-        type = plugin.getLoginType();
-
-        return requestTgt(authToken, type, config);
-    }
-
-    private HasClientPlugin getClientTokenPlugin(HasConfig config) throws HasException {
-        String pluginName = config.getPluginName();
-        HasClientPlugin clientPlugin;
-        if (pluginName != null) {
-            clientPlugin = HasClientPluginRegistry.createPlugin(pluginName);
-        } else {
-            LOG.debug("Please set the plugin name in has client conf");
-            throw new HasException("Please set the plugin name in has client conf");
-        }
-
-        return clientPlugin;
-    }
-
-    /**
-     * Request a TGT with user token, plugin type and has config.
-     * @param authToken auth token
-     * @param type login type
-     * @param config HAS config
-     * @return TGT ticket grant ticket
-     * @throws HasException e
-     */
-    public TgtTicket requestTgt(AuthToken authToken, String type, HasConfig config)
-        throws HasException {
-        TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider("JWT").createTokenEncoder();
-
-        String tokenString;
-        try {
-            tokenString = tokenEncoder.encodeAsString(authToken);
-        } catch (KrbException e) {
-            LOG.debug("Failed to decode the auth token. " + e.getMessage());
-            throw new HasException("Failed to decode the auth token. " + e.getMessage());
-        }
-
-        JSONObject json = null;
-        int responseStatus = 0;
-        boolean success = false;
-        if (config.getHttpsPort() != null && config.getHttpsHost() != null) {
-            String sslClientConfPath = clientConfigFolder + "/ssl-client.conf";
-            config.setString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
-            config.setString(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfPath);
-            config.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, false);
-
-            URLConnectionFactory connectionFactory = URLConnectionFactory
-                .newDefaultURLConnectionFactory(config);
-
-            URL url;
-            String[] hosts = config.getHttpsHost().split(",");
-            for (String host : hosts) {
-                try {
-                    url = new URL("https://" + host.trim() + ":" + config.getHttpsPort()
-                        + "/has/v1?type=" + type + "&authToken=" + tokenString);
-                } catch (MalformedURLException e) {
-                    LOG.warn("Failed to get url. " + e.toString());
-                    continue;
-                }
-                HttpURLConnection conn;
-                try {
-                    conn = (HttpURLConnection) connectionFactory.openConnection(url);
-                } catch (IOException e) {
-                    LOG.warn("Failed to open connection. " + e.toString());
-                    continue;
-                }
-
-                conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
-                try {
-                    conn.setRequestMethod("PUT");
-                } catch (ProtocolException e) {
-                    LOG.warn("Failed to set request method. " + e.toString());
-                    continue;
-                }
-                conn.setDoOutput(true);
-                conn.setDoInput(true);
-                try {
-                    conn.connect();
-
-                    responseStatus = conn.getResponseCode();
-                    switch (responseStatus) {
-                        case 200:
-                        case 201:
-                            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-                            StringBuilder sb = new StringBuilder();
-                            String line;
-                            while ((line = br.readLine()) != null) {
-                                sb.append(line + "\n");
-                            }
-                            br.close();
-
-                            json = new JSONObject(sb.toString());
-                    }
-
-                } catch (IOException | JSONException e) {
-                    LOG.warn("ERROR! " + e.toString());
-                    continue;
-                }
-
-                if (responseStatus == 200 || responseStatus == 201) {
-                    success = true;
-                    break;
-                }
-            }
-            if (!success) {
-                throw new HasException("Failed: HTTP error code : "
-                    + responseStatus);
-            }
-        } else {
-            throw new HasException("Please set https host and port.");
-        }
-
-        try {
-            return handleResponse(json, (String) authToken.getAttributes().get("passPhrase"));
-        } catch (HasException e) {
-            LOG.debug("Failed to handle response when requesting tgt ticket in client."
-                + e.getMessage());
-            throw new HasException(e.getMessage());
-        }
-    }
-
-    private File loadSslClientConf(HasConfig config, String sslClientConfPath) throws HasException {
-        File sslClientConf = new File(sslClientConfPath);
-        if (!sslClientConf.exists()) {
-            String httpHost = config.getHttpHost();
-            String httpPort = config.getHttpPort();
-            if (httpHost == null) {
-                // Can't find the http host in config, the https host will be used.
-                httpHost = config.getHttpsHost();
-            }
-            if (httpPort == null) {
-                // Can't find the http port in config, the default http port will be used.
-                httpPort = HAS_HTTP_PORT_DEFAULT;
-            }
-            X509Certificate certificate = getCertificate(httpHost, httpPort);
-            if (verifyCertificate(certificate)) {
-                String password = createTrustStore(config.getHttpsHost(), certificate);
-                createClientSSLConfig(password);
-            } else {
-                throw new HasException("The certificate from HAS server is invalid.");
-            }
-        }
-        return sslClientConf;
-    }
-
-    public KrbMessage getKrbMessage(JSONObject json) throws HasException {
-
-        try {
-            boolean success = json.getBoolean("success");
-            if (!success) {
-                String message = json.getString("krbMessage");
-                LOG.debug(message);
-                throw new HasException(message);
-            }
-        } catch (JSONException e) {
-            LOG.debug("Failed to get message. " + e.getMessage());
-            throw new HasException("Failed to get message." + e.getMessage());
-        }
-
-        String typeString;
-        try {
-            typeString = json.getString("type");
-        } catch (JSONException e) {
-            LOG.debug("Failed to get message." + e.getMessage());
-            throw new HasException("Failed to get message." + e.getMessage());
-        }
-
-        if (typeString != null && typeString.equals(type)) {
-            String krbMessageString;
-            try {
-                krbMessageString = json.getString("krbMessage");
-            } catch (JSONException e) {
-                LOG.debug("Failed to get the krbMessage. " + e.getMessage());
-                throw new HasException("Failed to get the krbMessage. " + e.getMessage());
-            }
-            Base64 base64 = new Base64(0);
-            byte[] krbMessage = base64.decode(krbMessageString);
-            ByteBuffer byteBuffer = ByteBuffer.wrap(krbMessage);
-            KrbMessage kdcRep;
-            try {
-                kdcRep = KrbCodec.decodeMessage(byteBuffer);
-            } catch (IOException e) {
-                LOG.debug("Krb decoding message failed. " + e.getMessage());
-                throw new HasException("Krb decoding message failed. " + e.getMessage());
-            }
-            return kdcRep;
-        } else {
-            throw new HasException("Can't get the right message from server.");
-        }
-    }
-
-    public TgtTicket handleResponse(JSONObject json, String passPhrase)
-        throws HasException {
-        KrbMessage kdcRep = getKrbMessage(json);
-
-        KrbMessageType messageType = kdcRep.getMsgType();
-        if (messageType == KrbMessageType.AS_REP) {
-            return processResponse((KdcRep) kdcRep, passPhrase);
-        } else if (messageType == KrbMessageType.KRB_ERROR) {
-            KrbError error = (KrbError) kdcRep;
-            LOG.error("HAS server response with message: "
-                + error.getErrorCode().getMessage());
-
-            throw new HasException(error.getEtext());
-        }
-        return null;
-    }
-
-    public TgtTicket processResponse(KdcRep kdcRep, String passPhrase)
-        throws HasException {
-
-        PrincipalName clientPrincipal = kdcRep.getCname();
-        String clientRealm = kdcRep.getCrealm();
-        clientPrincipal.setRealm(clientRealm);
-
-        // Get the client to decrypt the EncryptedData
-        EncryptionKey clientKey = null;
-        try {
-            clientKey = HasUtil.getClientKey(clientPrincipal.getName(),
-                passPhrase,
-                kdcRep.getEncryptedEncPart().getEType());
-        } catch (KrbException e) {
-            throw new HasException("Could not generate key. " + e.getMessage());
-        }
-
-        byte[] decryptedData = decryptWithClientKey(kdcRep.getEncryptedEncPart(),
-            KeyUsage.AS_REP_ENCPART, clientKey);
-        if ((decryptedData[0] & 0x1f) == 26) {
-            decryptedData[0] = (byte) (decryptedData[0] - 1);
-        }
-        EncKdcRepPart encKdcRepPart = new EncAsRepPart();
-        try {
-            encKdcRepPart.decode(decryptedData);
-        } catch (IOException e) {
-            throw new HasException("Failed to decode EncAsRepPart. " + e.getMessage());
-        }
-        kdcRep.setEncPart(encKdcRepPart);
-
-        TgtTicket tgtTicket = getTicket(kdcRep);
-        LOG.debug("Ticket expire time: " + tgtTicket.getEncKdcRepPart().getEndTime());
-
-        storeTgtTicket(tgtTicket);
-
-        return tgtTicket;
-
-    }
-
-    private void storeTgtTicket(TgtTicket tgtTicket) throws HasException {
-        String ccacheName = getCcacheName();
-        File ccacheFile = new File(ccacheName);
-        LOG.debug("Storing the tgt to the credential cache file.");
-        if (!ccacheFile.exists()) {
-            createCacheFile(ccacheFile);
-        }
-        if (ccacheFile.exists() && ccacheFile.canWrite()) {
-            CredentialCache cCache = new CredentialCache(tgtTicket);
-            try {
-                cCache.store(ccacheFile);
-            } catch (IOException e) {
-                throw new HasException("Failed to store tgt. " + e.getMessage());
-            }
-        } else {
-            throw new IllegalArgumentException("Invalid ccache file, "
-                    + "not exist or writable: " + ccacheFile.getAbsolutePath());
-        }
-    }
-
-    /**
-     * Create the specified credential cache file.
-     */
-    private void createCacheFile(File ccacheFile) throws HasException {
-        try {
-            if (!ccacheFile.createNewFile()) {
-                throw new HasException("Failed to create ccache file "
-                        + ccacheFile.getAbsolutePath());
-            }
-            // sets read-write permissions to owner only
-            ccacheFile.setReadable(true, true);
-            if (!ccacheFile.setWritable(true, true)) {
-                throw new HasException("Cache file is not readable.");
-            }
-        } catch (IOException e) {
-            throw new HasException("Failed to create ccache file "
-                    + ccacheFile.getAbsolutePath() + ". " + e.getMessage());
-        }
-    }
-
-    /**
-     * Get credential cache file name.
-     */
-    private String getCcacheName() {
-        final String ccacheNameEnv = System.getenv("KRB5CCNAME");
-        String ccacheName;
-        if (ccacheNameEnv != null) {
-            ccacheName = ccacheNameEnv;
-        } else {
-            StringBuilder uid = new StringBuilder();
-            try {
-                //Get UID through "id -u" command
-                String command = "id -u";
-                Process child = Runtime.getRuntime().exec(command);
-                InputStream in = child.getInputStream();
-                int c;
-                while ((c = in.read()) != -1) {
-                    uid.append((char) c);
-                }
-                in.close();
-            } catch (IOException e) {
-                System.err.println("Failed to get UID.");
-                System.exit(1);
-            }
-            ccacheName = "krb5cc_" + uid.toString().trim();
-            ccacheName = SysUtil.getTempDir().toString() + "/" + ccacheName;
-        }
-
-        return ccacheName;
-    }
-
-    protected byte[] decryptWithClientKey(EncryptedData data,
-                                          KeyUsage usage,
-                                          EncryptionKey clientKey) throws HasException {
-        if (clientKey == null) {
-            throw new HasException("Client key isn't available");
-        }
-        try {
-            return EncryptionHandler.decrypt(data, clientKey, usage);
-        } catch (KrbException e) {
-            throw new HasException("Errors occurred when decrypting the data." + e.getMessage());
-        }
-    }
-
-    /**
-     * Get the tgt ticket from KdcRep
-     *
-     * @param kdcRep the KdcRep
-     * @return TgtTicket the ticket grant ticket
-     */
-    public TgtTicket getTicket(KdcRep kdcRep) {
-        TgtTicket tgtTicket = new TgtTicket(kdcRep.getTicket(),
-            (EncAsRepPart) kdcRep.getEncPart(), kdcRep.getCname());
-        return tgtTicket;
-    }
-
-    /**
-     * Get certificate from HAS server.
-     *
-     * @param host the HAS server http host name
-     * @param port the HAS server http port
-     * @return X509Certificate the x509 certificate from HAS server
-     */
-    private X509Certificate getCertificate(String host, String port) throws HasException {
-        X509Certificate certificate;
-
-        HttpURLConnection httpConn = null;
-
-        URL url;
-        try {
-            url = new URL("http://" + host + ":" + port + "/has/v1/conf/getcert");
-        } catch (MalformedURLException e) {
-            throw new HasException("Failed to create a URL object." + e.getMessage());
-        }
-        try {
-            httpConn = (HttpURLConnection) url.openConnection();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        httpConn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
-        try {
-            httpConn.setRequestMethod("GET");
-        } catch (ProtocolException e) {
-            LOG.error("Failed to add principal. " + e);
-            throw new HasException("Failed to set the method for URL request. " + e.getMessage());
-        }
-
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new HasException(HasClientUtil.getResponse(httpConn));
-            }
-            try {
-                CertificateFactory factory = CertificateFactory.getInstance("X.509");
-                InputStream in = HasClientUtil.getInputStream(httpConn);
-                certificate = (X509Certificate) factory.generateCertificate(in);
-            } catch (CertificateException e) {
-                throw new HasException("Failed to get certificate from HAS server. "
-                    + e.getMessage());
-            }
-
-        } catch (IOException e) {
-            throw new HasException("IO error occurred. " + e.getMessage());
-        }
-
-        return certificate;
-    }
-
-    /**
-     * Verify certificate.
-     *
-     * @param certificate the x509 certificate
-     * @return boolean true if verify successfully
-     * @throws HasException HAS exception when verifying certificate
-     */
-    private boolean verifyCertificate(X509Certificate certificate) throws HasException {
-        // Check if certificate is expired
-        try {
-            Date date = new Date();
-            certificate.checkValidity(date);
-        } catch (GeneralSecurityException e) {
-            return false;
-        }
-
-        // Get certificate from ca root
-        X509Certificate caRoot;
-        try {
-            //Get the ca root path from env, client should export it.
-            String caRootPath = System.getenv("CA_ROOT");
-            if (caRootPath == null) {
-                caRootPath = CA_ROOT_DEFAULT;
-            }
-            File caRootFile;
-            if (caRootPath != null) {
-                caRootFile = new File(caRootPath);
-                if (!caRootFile.exists()) {
-                    LOG.debug("CA_ROOT: " + caRootPath + " not exist.");
-                    throw new HasException("CA_ROOT: " + caRootPath + " not exist.");
-                }
-            } else {
-                throw new HasException("Please set the CA_ROOT.");
-            }
-
-            CertificateFactory factory = CertificateFactory.getInstance("X.509");
-            try (FileInputStream in = new FileInputStream(caRootFile)) {
-                caRoot = (X509Certificate) factory.generateCertificate(in);
-            }
-        } catch (CertificateException | IOException e) {
-            throw new HasException("Failed to get certificate from ca root file. "
-                + e.getMessage());
-        }
-
-        // Verify certificate with root certificate
-        try {
-            PublicKey publicKey = caRoot.getPublicKey();
-            if (publicKey != null) {
-                certificate.verify(publicKey);
-            } else {
-                throw new HasException("Failed to get public key in ca root.");
-            }
-        } catch (GeneralSecurityException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Create and save truststore file based on certificate.
-     *
-     */
-    private String createTrustStore(String host, X509Certificate certificate) throws HasException {
-        KeyStore trustStore;
-
-        // Create password
-        RandomStringGenerator generator = new RandomStringGenerator.Builder()
-            .withinRange('a', 'z')
-            .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
-            .build();
-        String password = generator.generate(15);
-
-        File trustStoreFile = new File(clientConfigFolder + "/truststore.jks");
-        try {
-            trustStore = KeyStore.getInstance("jks");
-            trustStore.load(null, null);
-            trustStore.setCertificateEntry(host, certificate);
-            try (FileOutputStream out = new FileOutputStream(trustStoreFile)) {
-                trustStore.store(out, password.toCharArray());
-            }
-        } catch (IOException | GeneralSecurityException e) {
-            throw new HasException("Failed to create and save truststore file. "
-                + e.getMessage());
-        }
-        return password;
-    }
-
-    /**
-     * Create ssl configuration file for client.
-     *
-     */
-    private void createClientSSLConfig(String password) throws HasException {
-        String resourcePath = "/ssl-client.conf.template";
-        try (InputStream templateResource = getClass().getResourceAsStream(resourcePath)) {
-            String content = IOUtil.readInput(templateResource);
-            content = content.replaceAll("_location_", clientConfigFolder.getAbsolutePath()
-                + "/truststore.jks");
-            content = content.replaceAll("_password_", password);
-
-            IOUtil.writeFile(content, new File(clientConfigFolder + "/ssl-client.conf"));
-        } catch (IOException e) {
-            throw new HasException("Failed to create client ssl configuration file. "
-                + e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPlugin.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPlugin.java
deleted file mode 100644
index dd28a68f..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPlugin.java
+++ /dev/null
@@ -1,43 +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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-
-public interface HasClientPlugin {
-
-    /**
-     * Get the login module type ID, used to distinguish this module from others.
-     * Should correspond to the server side module.
-     *
-     * @return login type
-     */
-    String getLoginType();
-
-    /**
-     * Perform all the client side login logics, the results wrapped in an AuthToken,
-     * will be validated by HAS server.
-     *
-     * @param conf token plugin config
-     * @return user auth token
-     * @throws HasLoginException HAS login exception
-     */
-    AuthToken login(HasConfig conf) throws HasLoginException;
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPluginRegistry.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPluginRegistry.java
deleted file mode 100644
index 2add2501..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientPluginRegistry.java
+++ /dev/null
@@ -1,62 +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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class HasClientPluginRegistry {
-    static final Logger LOG = LoggerFactory.getLogger(HasClientPluginRegistry.class);
-
-    private static Map<String, Class> allPlugins = new ConcurrentHashMap<>();
-
-    static {
-        ServiceLoader<HasClientPlugin> plugins = ServiceLoader.load(HasClientPlugin.class);
-
-        for (HasClientPlugin plugin : plugins) {
-            allPlugins.put(plugin.getLoginType(), plugin.getClass());
-        }
-    }
-
-    public static Set<String> registeredPlugins() {
-        return Collections.unmodifiableSet(allPlugins.keySet());
-    }
-
-    public static boolean registeredPlugin(String name) {
-        return allPlugins.containsKey(name);
-    }
-
-    public static HasClientPlugin createPlugin(String name) throws HasException {
-        if (!registeredPlugin(name)) {
-            throw new HasException("Unregistered plugin " + name);
-        }
-        try {
-            return (HasClientPlugin) allPlugins.get(name).newInstance();
-        } catch (Exception e) {
-            LOG.error("Create {} plugin failed", name, e);
-            throw new HasException(e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientUtil.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientUtil.java
deleted file mode 100644
index 1b5c97df..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClientUtil.java
+++ /dev/null
@@ -1,137 +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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.ssl.SSLFactory;
-import org.apache.kerby.has.common.util.URLConnectionFactory;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.ProtocolException;
-import java.net.URL;
-
-public class HasClientUtil {
-
-    public static HttpURLConnection getHttpsConnection(HasConfig hasConfig, URL url, boolean isSpnego)
-            throws Exception {
-        HasConfig conf = new HasConfig();
-
-        conf.setString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
-        String sslClientConf = hasConfig.getSslClientConf();
-        File sslClientConfFile = new File(sslClientConf);
-        if (!sslClientConfFile.exists()) {
-            throw new HasException("The ssl client config file "
-                + sslClientConf + " does not exist.");
-        }
-        conf.setString(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConf);
-        conf.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, false);
-
-        URLConnectionFactory connectionFactory = URLConnectionFactory
-                .newDefaultURLConnectionFactory(conf);
-        return (HttpURLConnection) connectionFactory.openConnection(url, isSpnego, hasConfig);
-    }
-
-    /**
-     * Create an authenticated connection to the Has server.
-     * <p>
-     * It uses Hadoop-auth client authentication which by default supports
-     * Kerberos HTTP SPNEGO, Pseudo/Simple and anonymous.
-     *
-     * @param hasConfig the HAS client config.
-     * @param url    the URL to open a HTTP connection to.
-     * @param method the HTTP method for the HTTP connection.
-     * @param  isSpnego  true or false.
-     * @return an authenticated connection to the has server.
-     * @throws KrbException if an IO error occurred.
-     */
-    public static HttpURLConnection createConnection(HasConfig hasConfig, URL url, String method, boolean isSpnego)
-            throws KrbException {
-        HttpURLConnection conn = null;
-        if (hasConfig.getHttpsPort() != null && hasConfig.getHttpsHost() != null) {
-            try {
-                conn = getHttpsConnection(hasConfig, url, isSpnego);
-            } catch (Exception e) {
-                throw new KrbException("Error occurred when creating https connection. "
-                        + e.getMessage());
-            }
-        }
-        if (conn == null) {
-            throw new KrbException("Error occurred when creating https connection.");
-        }
-        try {
-            conn.setRequestMethod(method);
-        } catch (ProtocolException e) {
-            throw new KrbException("Failed to set the method for URL request.", e);
-        }
-        if (method.equals("POST") || method.equals("PUT")) {
-            conn.setDoOutput(true);
-        }
-        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
-        return conn;
-    }
-
-    public static String getBaseUrl(HasConfig hasConfig, String input) throws KrbException {
-        String url = null;
-        if (hasConfig.getHttpsPort() != null && hasConfig.getHttpsHost() != null) {
-            url = "https://" + hasConfig.getHttpsHost() + ":" + hasConfig.getHttpsPort()
-                    + "/has/v1/" + input + "/";
-        }
-        if (url == null) {
-            throw new KrbException("Please set the https address and port.");
-        }
-        return url;
-    }
-
-    public static String getResponse(HttpURLConnection httpConn) throws IOException {
-        StringBuilder data = new StringBuilder();
-
-        InputStream inputStream = getInputStream(httpConn);
-        if (inputStream == null) {
-            throw new IOException("Failed to get the InputStream");
-        }
-
-        try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
-            String s;
-            while ((s = br.readLine()) != null) {
-                data.append(s);
-                data.append(System.getProperty("line.separator"));
-            }
-            return data.toString();
-        }
-    }
-
-    public static InputStream getInputStream(HttpURLConnection httpConn) throws IOException {
-        InputStream inputStream;
-        if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
-            inputStream = httpConn.getInputStream();
-        } else {
-            /* Error from server */
-            inputStream = httpConn.getErrorStream();
-        }
-        return inputStream;
-    }
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasInitClient.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasInitClient.java
deleted file mode 100644
index 0daf57f0..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasInitClient.java
+++ /dev/null
@@ -1,276 +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
- * <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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * HAS client API for applications to interact with HAS server
- */
-public class HasInitClient {
-
-    public static final Logger LOG = LoggerFactory.getLogger(HasInitClient.class);
-
-    private HasConfig hasConfig;
-    private File confDir;
-
-    public HasInitClient(HasConfig hasConfig, File confDir) {
-        this.hasConfig = hasConfig;
-        this.confDir = confDir;
-    }
-
-    public File getConfDir() {
-        return confDir;
-    }
-
-    private String getInitBaseURL() throws KrbException {
-        return HasClientUtil.getBaseUrl(hasConfig, "init");
-    }
-
-    private String getConfigBaseURL() throws KrbException {
-        return HasClientUtil.getBaseUrl(hasConfig, "conf");
-    }
-
-    public String startKdc() throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getInitBaseURL() + "kdcstart");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", false);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                String response = HasClientUtil.getResponse(httpConn);
-                LOG.info(response);
-                return response;
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public void initKdc(File keytab) throws KrbException {
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getInitBaseURL() + "kdcinit");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", false);
-
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-            try (FileOutputStream fos = new FileOutputStream(keytab);
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[3 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public void getKrb5conf(File file) throws KrbException {
-
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getConfigBaseURL() + "getkrb5conf");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", false);
-
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-            try (FileOutputStream fos = new FileOutputStream(file);
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[3 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public void getHasClientConf(File file) throws KrbException {
-
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getConfigBaseURL() + "gethasclientconf");
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "GET", false);
-
-        try {
-            httpConn.connect();
-            if (httpConn.getResponseCode() != 200) {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-            try (FileOutputStream fos = new FileOutputStream(file);
-                 InputStream in = httpConn.getInputStream()) {
-                byte[] buffer = new byte[3 * 1024];
-                int read;
-                while ((read = in.read(buffer)) > 0) {
-                    fos.write(buffer, 0, read);
-                }
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public String setPlugin(String plugin) throws KrbException {
-
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getConfigBaseURL() + "setplugin?plugin=" + plugin);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", false);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                String response = HasClientUtil.getResponse(httpConn);
-                LOG.info(response);
-                return response;
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public String configKdc(String port, String realm, String host) throws KrbException {
-
-        HttpURLConnection httpConn;
-
-        URL url;
-        try {
-            url = new URL(getConfigBaseURL() + "configkdc?port=" + port + "&realm="
-                    + realm + "&host=" + host);
-        } catch (MalformedURLException e) {
-            throw new KrbException("Failed to create a URL object.", e);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", false);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                String response = HasClientUtil.getResponse(httpConn);
-                LOG.info(response);
-                return response;
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-
-    public String configBackend(String backendType, String dir, String mysqlUrl, String user,
-                              String password) throws KrbException {
-
-        HttpURLConnection httpConn;
-
-        URL url;
-        if (backendType.equals("json")) {
-            try {
-                url = new URL(getConfigBaseURL() + "configbackend?backendType=" + backendType
-                        + "&dir=" + dir);
-            } catch (MalformedURLException e) {
-                throw new KrbException("Failed to create a URL object.", e);
-            }
-        } else if (backendType.equals("mysql")) {
-            try {
-                url = new URL(getConfigBaseURL() + "configbackend?backendType=" + backendType
-                        + "&url=" + mysqlUrl + "&user=" + user + "&password=" + password);
-            } catch (MalformedURLException e) {
-                throw new KrbException("Failed to create a URL object.", e);
-            }
-        } else {
-            throw new KrbException("Unsupported backend: " + backendType);
-        }
-
-        httpConn = HasClientUtil.createConnection(hasConfig, url, "PUT", false);
-
-        try {
-            httpConn.connect();
-
-            if (httpConn.getResponseCode() == 200) {
-                String response = HasClientUtil.getResponse(httpConn);
-                LOG.info(response);
-                return response;
-            } else {
-                throw new KrbException(HasClientUtil.getResponse(httpConn));
-            }
-        } catch (IOException e) {
-            throw new KrbException("IO error occurred. " + e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginException.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginException.java
deleted file mode 100644
index 21575379..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginException.java
+++ /dev/null
@@ -1,37 +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
- * <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.kerby.has.client;
-
-import org.apache.kerby.has.common.HasException;
-
-public class HasLoginException extends HasException {
-    private static final long serialVersionUID = 4140429098192628252L;
-
-    public HasLoginException(Throwable cause) {
-        super(cause);
-    }
-
-    public HasLoginException(String message) {
-        super(message);
-    }
-
-    public HasLoginException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginModule.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginModule.java
deleted file mode 100644
index b045eb59..00000000
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasLoginModule.java
+++ /dev/null
@@ -1,452 +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
- * <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.kerby.has.client;
-
-import com.sun.security.auth.module.Krb5LoginModule;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.kerberos.kerb.ccache.Credential;
-import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sun.security.krb5.KrbException;
-import sun.security.krb5.PrincipalName;
-import sun.security.krb5.RealmException;
-
-import javax.security.auth.DestroyFailedException;
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This <code>LoginModule</code> authenticates users using tgt ticket
- * The client's TGT will be retrieved from the API of HasClient
- */
-public class HasLoginModule implements LoginModule {
-
-    public static final Logger LOG = LoggerFactory.getLogger(HasLoginModule.class);
-
-    Krb5LoginModule krb5LoginModule;
-
-    // initial state
-    private Subject subject;
-
-    // configurable option
-    private boolean debug = false;
-    private boolean doNotPrompt = false;
-    private boolean useTgtTicket = false;
-    private String hadoopSecurityHas = null;
-    private String princName = null;
-
-    private boolean refreshKrb5Config = false;
-
-    // specify if initiator.
-    // perform authentication exchange if initiator
-    private boolean isInitiator = true;
-
-    // the authentication status
-    private boolean succeeded = false;
-    private boolean commitSucceeded = false;
-
-    private Credential credential = null;
-
-    private PrincipalName principal = null;
-    private KerberosPrincipal kerbClientPrinc = null;
-    private KerberosTicket kerbTicket = null;
-    private StringBuilder krb5PrincName = null;
-    private boolean unboundServer = false;
-
-    /**
-     * Initialize this <code>LoginModule</code>.
-     *
-     * @param subject         the <code>Subject</code> to be authenticated. <p>
-     * @param callbackHandler a <code>CallbackHandler</code> for
-     *                        communication with the end user (prompting for
-     *                        usernames and passwords, for example). <p>
-     * @param sharedState     shared <code>LoginModule</code> state. <p>
-     * @param options         options specified in the login
-     *                        <code>Configuration</code> for this particular
-     *                        <code>LoginModule</code>.
-     */
-    public void initialize(Subject subject,
-                           CallbackHandler callbackHandler,
-                           Map<String, ?> sharedState,
-                           Map<String, ?> options) {
-
-        this.subject = subject;
-
-        // initialize any configured options
-        useTgtTicket = "true".equalsIgnoreCase((String) options.get("useTgtTicket"));
-
-        if (useTgtTicket) {
-            debug = "true".equalsIgnoreCase((String) options.get("debug"));
-            doNotPrompt = "true".equalsIgnoreCase((String) options.get("doNotPrompt"));
-            useTgtTicket = "true".equalsIgnoreCase((String) options.get("useTgtTicket"));
-            hadoopSecurityHas = (String) options.get("hadoopSecurityHas");
-            princName = (String) options.get("principal");
-            refreshKrb5Config =
-                "true".equalsIgnoreCase((String) options.get("refreshKrb5Config"));
-
-            // check isInitiator value
-            String isInitiatorValue = (String) options.get("isInitiator");
-            if (isInitiatorValue != null) {
-                // use default, if value not set
-                isInitiator = "true".equalsIgnoreCase(isInitiatorValue);
-            }
-
-            if (debug) {
-                System.out.print("Debug is  " + debug
-                    + " doNotPrompt " + doNotPrompt
-                    + " isInitiator " + isInitiator
-                    + " refreshKrb5Config is " + refreshKrb5Config
-                    + " principal is " + princName + "\n");
-            }
-        } else {
-            krb5LoginModule = new Krb5LoginModule();
-            krb5LoginModule.initialize(subject, callbackHandler, sharedState, options);
-        }
-    }
-
-    /**
-     * Authenticate the user
-     *
-     * @return true in all cases since this <code>LoginModule</code>
-     * should not be ignored.
-     * @throws LoginException       if this <code>LoginModule</code>
-     *                              is unable to perform the authentication.
-     */
-    public boolean login() throws LoginException {
-
-        if (useTgtTicket) {
-            if (refreshKrb5Config) {
-                try {
-                    if (debug) {
-                        System.out.println("Refreshing Kerberos configuration");
-                    }
-                    sun.security.krb5.Config.refresh();
-                } catch (KrbException ke) {
-                    LoginException le = new LoginException(ke.getMessage());
-                    le.initCause(ke);
-                    throw le;
-                }
-            }
-            String principalProperty = System.getProperty("sun.security.krb5.principal");
-            if (principalProperty != null) {
-                krb5PrincName = new StringBuilder(principalProperty);
-            } else {
-                if (princName != null) {
-                    krb5PrincName = new StringBuilder(princName);
-                }
-            }
-
-            validateConfiguration();
-
-            if (krb5PrincName != null && krb5PrincName.toString().equals("*")) {
-                unboundServer = true;
-            }
-
-            // attempt the authentication by getting the username and pwd
-            // by prompting or configuration i.e. not from shared state
-
-            try {
-                attemptAuthentication();
-                succeeded = true;
-                cleanState();
-                return true;
-            } catch (LoginException e) {
-                // authentication failed -- clean out state
-                if (debug) {
-                    System.out.println("\t\t[HasLoginModule] "
-                        + "authentication failed \n"
-                        + e.getMessage());
-                }
-                succeeded = false;
-                cleanState();
-                throw e;
-            }
-        } else {
-            succeeded = krb5LoginModule.login();
-            return succeeded;
-        }
-    }
-
-    /**
-     * Process the configuration options
-     * Get the TGT from Has Client
-     */
-    private void attemptAuthentication()
-        throws LoginException {
-
-        /*
-         * Check the creds cache to see whether
-         * we have TGT for this client principal
-         */
-        if (krb5PrincName != null) {
-            try {
-                principal = new PrincipalName(krb5PrincName.toString(),
-                        PrincipalName.KRB_NT_PRINCIPAL);
-            } catch (KrbException e) {
-                LoginException le = new LoginException(e.getMessage());
-                le.initCause(e);
-                throw le;
-            }
-        }
-
-        try {
-            if (useTgtTicket) {
-                if (debug) {
-                    System.out.println("use tgt ticket to login, acquire TGT TICKET...");
-                }
-                HasClient hasClient = new HasClient(hadoopSecurityHas);
-                TgtTicket tgtTicket;
-                try {
-                    tgtTicket = hasClient.requestTgt();
-                } catch (HasException e) {
-                    LoginException le = new LoginException(e.getMessage());
-                    le.initCause(e);
-                    throw le;
-                }
-                credential = new Credential(tgtTicket);
-                // get the principal name from the ticket cache
-                if (principal == null) {
-                    principal = new PrincipalName(credential.getClientName().getName(), 1);
-                }
-                if (debug) {
-                    System.out.println("Principal is " + principal);
-                }
-            }
-        } catch (RealmException ee) {
-            LoginException ie = new LoginException(ee.getMessage());
-            ie.initCause(ee);
-            throw ie;
-        }
-    }
-
-    private void validateConfiguration() throws LoginException {
-        if (doNotPrompt && !useTgtTicket) {
-            throw new LoginException("Configuration Error"
-                + " - either doNotPrompt should be "
-                + " false or"
-                + " useTgtTicket"
-                + " should be true");
-        }
-
-        if (krb5PrincName != null && krb5PrincName.toString().equals("*") && isInitiator) {
-            throw new LoginException("Configuration Error"
-                + " - principal cannot be * when isInitiator is true");
-        }
-    }
-
-    /**
-     * <p> This method is called if the LoginContext's
-     * overall authentication succeeded
-     *
-     * @return true if this LoginModule's own login and commit
-     * attempts succeeded, or false otherwise.
-     * @throws LoginException if the commit fails.
-     */
-
-    public boolean commit() throws LoginException {
-        if (debug) {
-            System.out.println("Login success? " + succeeded);
-        }
-
-        if (useTgtTicket) {
-            if (!succeeded) {
-                cleanKerberosCred();
-                return false;
-            } else {
-                if (isInitiator &&  credential == null) {
-                    succeeded = false;
-                    throw new LoginException("Null Client Credential");
-                }
-
-                if (subject.isReadOnly()) {
-                    cleanKerberosCred();
-                    throw new LoginException("Subject is Readonly");
-                }
-
-                Set<Object> privCredSet = subject.getPrivateCredentials();
-                Set<Principal> princSet = subject.getPrincipals();
-                kerbClientPrinc = new KerberosPrincipal(principal.getName());
-
-                // create Kerberos Ticket
-                if (isInitiator) {
-                    boolean[] flags = new boolean[7];
-                    int flag = credential.getTicketFlags().getFlags();
-                    for (int i = 6; i >= 0; i--) {
-                        flags[i] = (flag & (1 << i)) != 0;
-                    }
-                    Date startTime = null;
-                    if (credential.getStartTime() != null) {
-                        startTime = credential.getStartTime().getValue();
-                    }
-                    try {
-                        kerbTicket = new KerberosTicket(
-                                credential.getTicket().encode(),
-                                new KerberosPrincipal(credential.getClientName().getName(), 1),
-                                new KerberosPrincipal(credential.getServerName().getName(), 2),
-                                credential.getKey().getKeyData(),
-                                credential.getKey().getKeyType().getValue(),
-                                flags,
-                                credential.getAuthTime().getValue(),
-                                startTime,
-                                credential.getEndTime().getValue(),
-                                credential.getRenewTill().getValue(),
-                                null);
-                    } catch (IOException e) {
-                        LoginException ie = new LoginException(e.getMessage());
-                        ie.initCause(e);
-                        throw ie;
-                    }
-                }
-
-                // Let us add the kerbClientPrinc,kerbTicket
-
-                // We won't add "*" as a KerberosPrincipal
-                if (!unboundServer
-                    && !princSet.contains(kerbClientPrinc)) {
-                    princSet.add(kerbClientPrinc);
-                }
-
-                // add the TGT
-                if (kerbTicket != null && !privCredSet.contains(kerbTicket)) {
-                    privCredSet.add(kerbTicket);
-                }
-            }
-            commitSucceeded = true;
-            if (debug) {
-                System.out.println("Commit Succeeded \n");
-            }
-            return true;
-        } else {
-            return krb5LoginModule.commit();
-        }
-    }
-
-    /**
-     * <p> This method is called if the LoginContext's
-     * overall authentication failed.
-     *
-     * @return false if this LoginModule's own login and/or commit attempts
-     * failed, and true otherwise.
-     * @throws LoginException if the abort fails.
-     */
-
-    public boolean abort() throws LoginException {
-        if (useTgtTicket) {
-            if (!succeeded) {
-                return false;
-            } else if (succeeded && commitSucceeded) {
-                // we succeeded, but another required module failed
-                logout();
-            } else {
-                // our commit failed
-                succeeded = false;
-            }
-            return true;
-        } else {
-            return krb5LoginModule.abort();
-        }
-    }
-
-    /**
-     * Logout the user.
-     *
-     * @return true in all cases since this <code>LoginModule</code>
-     * should not be ignored.
-     * @throws LoginException if the logout fails.
-     */
-    public boolean logout() throws LoginException {
-
-        if (useTgtTicket) {
-            if (debug) {
-                System.out.println("\t\t[Krb5LoginModule]: "
-                    + "Entering logout");
-            }
-
-            if (subject.isReadOnly()) {
-                cleanKerberosCred();
-                throw new LoginException("Subject is Readonly");
-            }
-
-            subject.getPrincipals().remove(kerbClientPrinc);
-            // Let us remove all Kerberos credentials stored in the Subject
-            Iterator<Object> it = subject.getPrivateCredentials().iterator();
-            while (it.hasNext()) {
-                Object o = it.next();
-                if (o instanceof KerberosTicket) {
-                    it.remove();
-                }
-            }
-            // clean the kerberos ticket and keys
-            cleanKerberosCred();
-
-            succeeded = false;
-            commitSucceeded = false;
-            if (debug) {
-                System.out.println("\t\t[HasLoginModule]: "
-                    + "logged out Subject");
-            }
-            return true;
-        } else {
-            return krb5LoginModule.logout();
-        }
-    }
-
-    /**
-     * Clean Kerberos credentials
-     */
-    private void cleanKerberosCred() throws LoginException {
-        // Clean the ticket and server key
-        try {
-            if (kerbTicket != null) {
-                kerbTicket.destroy();
-            }
-        } catch (DestroyFailedException e) {
-            throw new LoginException("Destroy Failed on Kerberos Private Credentials");
-        }
-        kerbTicket = null;
-        kerbClientPrinc = null;
-    }
-
-    /**
-     * Clean out the state
-     */
-    private void cleanState() {
-
-        if (!succeeded) {
-            // remove temp results for the next try
-            principal = null;
-        }
-        if (krb5PrincName != null && krb5PrincName.length() != 0) {
-            krb5PrincName.delete(0, krb5PrincName.length());
-        }
-        krb5PrincName = null;
-    }
-}
diff --git a/has-project/has-client/src/main/resources/ssl-client.conf.template b/has-project/has-client/src/main/resources/ssl-client.conf.template
deleted file mode 100644
index c5ca70a9..00000000
--- a/has-project/has-client/src/main/resources/ssl-client.conf.template
+++ /dev/null
@@ -1,20 +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.
-#
-
-ssl.client.truststore.location = _location_
-ssl.client.truststore.password = _password_
diff --git a/has-project/has-common/pom.xml b/has-project/has-common/pom.xml
deleted file mode 100644
index 46124aa3..00000000
--- a/has-project/has-common/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed 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. See accompanying LICENSE file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <parent>
-      <artifactId>has-project</artifactId>
-      <groupId>org.apache.kerby</groupId>
-      <version>2.1.0-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>has-common</artifactId>
-  <name>HAS Common</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>token-provider</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerby-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-client</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-annotations</artifactId>
-      <version>${hadoop.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-      <version>${commons-codec.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>${commons-logging.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <version>${slf4j.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-admin</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
deleted file mode 100644
index 15c3feaa..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
+++ /dev/null
@@ -1,38 +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.kerby.has.common;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Server side admin facilities from remote, similar to MIT kadmin remote mode.
- */
-public interface Hadmin {
-
-
-    List<String> addPrincByRole(String host, String role) throws HasException;
-
-    File getKeytabByHostAndRole(String host, String role) throws HasException;
-
-    void getHostRoles();
-
-    void setEnableOfConf(String isEnable) throws HasException;
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfig.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfig.java
deleted file mode 100644
index bbc8e534..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfig.java
+++ /dev/null
@@ -1,113 +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.kerby.has.common;
-
-import org.apache.kerby.kerberos.kerb.common.Krb5Conf;
-
-import java.io.File;
-
-/**
- * AK configuration API.
- */
-public class HasConfig extends Krb5Conf {
-    private File confDir;
-
-    public void setConfDir(File dir) {
-        this.confDir = dir;
-    }
-
-    public File getConfDir() {
-        return confDir;
-    }
-
-    public String getHttpsHost() {
-        return getString(HasConfigKey.HTTPS_HOST, false, "HAS");
-    }
-
-    public String getHttpsPort() {
-        return getString(HasConfigKey.HTTPS_PORT, false, "HAS");
-    }
-
-    public String getHttpHost() {
-        return getString(HasConfigKey.HTTP_HOST, false, "HAS");
-    }
-
-    public String getHttpPort() {
-        return getString(HasConfigKey.HTTP_PORT, false, "HAS");
-    }
-
-    public String getPluginName() {
-        return getString(HasConfigKey.AUTH_TYPE, true, "PLUGIN");
-    }
-
-    public String getRealm() {
-        return getString(HasConfigKey.REALM, false, "HAS");
-    }
-
-    public String getSslServerConf() {
-        String value = getString(HasConfigKey.SSL_SERVER_CONF, false, "HAS");
-        if (value != null) {
-            return value;
-        }
-        if (getConfDir() != null) {
-            File sslSrvConf = new File(getConfDir(), "ssl-server.conf");
-            if (sslSrvConf.exists() && sslSrvConf.isFile()) {
-                return sslSrvConf.getAbsolutePath();
-            }
-        }
-        return getString(HasConfigKey.SSL_SERVER_CONF, true, "HAS");
-    }
-
-    public String getSslClientConf() {
-        return getString(HasConfigKey.SSL_CLIENT_CONF, true, "HAS");
-    }
-
-    public String getFilterAuthType() {
-        return getString(HasConfigKey.FILTER_AUTH_TYPE, true, "HAS");
-    }
-
-    public String getKerberosPrincipal() {
-        return getString(HasConfigKey.KERBEROS_PRINCIPAL, false, "HAS");
-    }
-
-    public String getKerberosKeytab() {
-        return getString(HasConfigKey.KERBEROS_KEYTAB, false, "HAS");
-    }
-
-    public String getKerberosNameRules() {
-        return getString(HasConfigKey.KERBEROS_NAME_RULES, false, "HAS");
-    }
-
-    public String getAdminKeytab() {
-        return getString(HasConfigKey.ADMIN_KEYTAB, false, "HAS");
-    }
-
-    public String getAdminKeytabPrincipal() {
-        return getString(HasConfigKey.ADMIN_KEYTAB_PRINCIPAL, false, "HAS");
-    }
-
-    public String getEnableConf() {
-        return getString(HasConfigKey.ENABLE_CONF, false, "HAS");
-    }
-
-    public String getSslClientCert() {
-        return getString(HasConfigKey.SSL_CLIENT_CERT, true, "HAS");
-    }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
deleted file mode 100644
index d4cc4747..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
+++ /dev/null
@@ -1,61 +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.kerby.has.common;
-
-import org.apache.kerby.config.ConfigKey;
-
-public enum HasConfigKey implements ConfigKey {
-    HTTP_HOST,
-    HTTP_PORT,
-    HTTPS_HOST,
-    HTTPS_PORT,
-    AUTH_TYPE("MySQL"),
-    REALM,
-    ENABLE_CONF,
-    SSL_SERVER_CONF("/etc/has/ssl-server.conf"),
-    SSL_CLIENT_CONF("/etc/has/ssl-client.conf"),
-    SSL_CLIENT_CERT("/etc/has/cert-signed"),
-    FILTER_AUTH_TYPE("kerberos"),
-    KERBEROS_PRINCIPAL,
-    KERBEROS_KEYTAB,
-    KERBEROS_NAME_RULES,
-    ADMIN_KEYTAB,
-    ADMIN_KEYTAB_PRINCIPAL;
-
-    private Object defaultValue;
-
-    HasConfigKey() {
-        this.defaultValue = null;
-    }
-
-    HasConfigKey(Object defaultValue) {
-        this.defaultValue = defaultValue;
-    }
-
-    @Override
-    public String getPropertyKey() {
-        return name().toLowerCase();
-    }
-
-    @Override
-    public Object getDefaultValue() {
-        return this.defaultValue;
-    }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasException.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasException.java
deleted file mode 100644
index 9e5db446..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasException.java
+++ /dev/null
@@ -1,53 +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
- * <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.kerby.has.common;
-
-public class HasException extends Exception {
-
-    private static final long serialVersionUID = -1916788959202646914L;
-
-    /**
-     * Creates an {@link HasException}.
-     *
-     * @param cause original exception.
-     */
-    public HasException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Creates an {@link HasException}.
-     *
-     * @param message exception message.
-     */
-    public HasException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates an {@link HasException}.
-     *
-     * @param message exception message.
-     * @param cause   original exception.
-     */
-    public HasException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthToken.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthToken.java
deleted file mode 100644
index 9c31fe9b..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthToken.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.spnego;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-/**
- * Borrow the class from Apache hadoop
- */
-@SuppressWarnings("PMD")
-public class AuthToken implements Principal {
-
-  /**
-   * Constant that identifies an anonymous request.
-   */
-
-  private static final String ATTR_SEPARATOR = "&";
-  private static final String USER_NAME = "u";
-  private static final String PRINCIPAL = "p";
-  private static final String EXPIRES = "e";
-  private static final String TYPE = "t";
-
-  private static final Set<String> ATTRIBUTES =
-    new HashSet<>(Arrays.asList(USER_NAME, PRINCIPAL, EXPIRES, TYPE));
-
-  private String userName;
-  private String principal;
-  private String type;
-  private long expires;
-  private String tokenStr;
-
-  protected AuthToken() {
-    userName = null;
-    principal = null;
-    type = null;
-    expires = -1;
-    tokenStr = "ANONYMOUS";
-    generateToken();
-  }
-
-  private static final String ILLEGAL_ARG_MSG = " is NULL, empty or contains a '" + ATTR_SEPARATOR + "'";
-
-  /**
-   * Creates an authentication token.
-   *
-   * @param userName user name.
-   * @param principal principal (commonly matches the user name, with Kerberos is the full/long principal
-   * name while the userName is the short name).
-   * @param type the authentication mechanism name.
-   * (<code>System.currentTimeMillis() + validityPeriod</code>).
-   */
-  public AuthToken(String userName, String principal, String type) {
-    checkForIllegalArgument(userName, "userName");
-    checkForIllegalArgument(principal, "principal");
-    checkForIllegalArgument(type, "type");
-    this.userName = userName;
-    this.principal = principal;
-    this.type = type;
-    this.expires = -1;
-  }
-  
-  /**
-   * Check if the provided value is invalid. Throw an error if it is invalid, NOP otherwise.
-   * 
-   * @param value the value to check.
-   * @param name the parameter name to use in an error message if the value is invalid.
-   */
-  protected static void checkForIllegalArgument(String value, String name) {
-    if (value == null || value.length() == 0 || value.contains(ATTR_SEPARATOR)) {
-      throw new IllegalArgumentException(name + ILLEGAL_ARG_MSG);
-    }
-  }
-
-  /**
-   * Sets the expiration of the token.
-   *
-   * @param expires expiration time of the token in milliseconds since the epoch.
-   */
-  public void setExpires(long expires) {
-    this.expires = expires;
-      generateToken();
-  }
-
-  /**
-   * Returns true if the token has expired.
-   *
-   * @return true if the token has expired.
-   */
-  public boolean isExpired() {
-    return getExpires() != -1 && System.currentTimeMillis() > getExpires();
-  }
-
-  /**
-   * Generates the token.
-   */
-  private void generateToken() {
-    StringBuilder sb = new StringBuilder();
-    sb.append(USER_NAME).append("=").append(getUserName()).append(ATTR_SEPARATOR);
-    sb.append(PRINCIPAL).append("=").append(getName()).append(ATTR_SEPARATOR);
-    sb.append(TYPE).append("=").append(getType()).append(ATTR_SEPARATOR);
-    sb.append(EXPIRES).append("=").append(getExpires());
-    tokenStr = sb.toString();
-  }
-
-  /**
-   * Returns the user name.
-   *
-   * @return the user name.
-   */
-  public String getUserName() {
-    return userName;
-  }
-
-  /**
-   * Returns the principal name (this method name comes from the JDK {@link Principal} interface).
-   *
-   * @return the principal name.
-   */
-  @Override
-  public String getName() {
-    return principal;
-  }
-
-  /**
-   * Returns the authentication mechanism of the token.
-   *
-   * @return the authentication mechanism of the token.
-   */
-  public String getType() {
-    return type;
-  }
-
-  /**
-   * Returns the expiration time of the token.
-   *
-   * @return the expiration time of the token, in milliseconds since Epoc.
-   */
-  public long getExpires() {
-    return expires;
-  }
-
-  /**
-   * Returns the string representation of the token.
-   * <p>
-   * This string representation is parseable by the {@link #parse} method.
-   *
-   * @return the string representation of the token.
-   */
-  @Override
-  public String toString() {
-    return tokenStr;
-  }
-
-  public static AuthToken parse(String tokenStr) throws AuthenticationException {
-    if (tokenStr.length() >= 2) {
-      // strip the \" at the two ends of the tokenStr
-      if (tokenStr.charAt(0) == '\"' && tokenStr.charAt(tokenStr.length() - 1) == '\"') {
-        tokenStr = tokenStr.substring(1, tokenStr.length() - 1);
-      }
-    }
-    Map<String, String> map = split(tokenStr);
-    // remove the signature part, since client doesn't care about it
-    map.remove("s");
-
-    if (!map.keySet().equals(ATTRIBUTES)) {
-      throw new AuthenticationException("Invalid token string, missing attributes");
-    }
-    long expires = Long.parseLong(map.get(EXPIRES));
-    AuthToken token = new AuthToken(map.get(USER_NAME), map.get(PRINCIPAL), map.get(TYPE));
-    token.setExpires(expires);
-    return token;
-  }
-
-  /**
-   * Splits the string representation of a token into attributes pairs.
-   *
-   * @param tokenStr string representation of a token.
-   *
-   * @return a map with the attribute pairs of the token.
-   *
-   * @throws AuthenticationException thrown if the string representation of the token could not be broken into
-   * attribute pairs.
-   */
-  private static Map<String, String> split(String tokenStr) throws AuthenticationException {
-    Map<String, String> map = new HashMap<>();
-    StringTokenizer st = new StringTokenizer(tokenStr, ATTR_SEPARATOR);
-    while (st.hasMoreTokens()) {
-      String part = st.nextToken();
-      int separator = part.indexOf('=');
-      if (separator == -1) {
-        throw new AuthenticationException("Invalid authentication token");
-      }
-      String key = part.substring(0, separator);
-      String value = part.substring(separator + 1);
-      map.put(key, value);
-    }
-    return map;
-  }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticatedURL.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticatedURL.java
deleted file mode 100644
index 372c5cd8..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticatedURL.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.spnego;
-
-import org.apache.kerby.has.common.util.ConnectionConfigurator;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * <p>
- * The authentication mechanisms supported by default are Hadoop Simple  authentication
- * (also known as pseudo authentication) and Kerberos SPNEGO authentication.
- * <p>
- * Additional authentication mechanisms can be supported via {@link Authenticator} implementations.
- * <p>
- * The default {@link Authenticator} is the {@link KerberosAuthenticator} class which supports
- * automatic fallback from Kerberos SPNEGO to Hadoop Simple authentication.
- * <p>
- * <code>AuthenticatedURL</code> instances are not thread-safe.
- * <p>
- * The usage pattern of the {@link AuthenticatedURL} is:
- * <pre>
- *
- * // establishing an initial connection
- *
- * URL url = new URL("http://foo:8080/bar");
- * AuthenticatedURL.Token token = new AuthenticatedURL.Token();
- * AuthenticatedURL aUrl = new AuthenticatedURL();
- * HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection();
- * ....
- * // use the 'conn' instance
- * ....
- *
- * // establishing a follow up connection using a token from the previous connection
- *
- * HttpURLConnection conn = new AuthenticatedURL(url, token).openConnection();
- * ....
- * // use the 'conn' instance
- * ....
- *
- * </pre>
- */
-public class AuthenticatedURL {
-
-  /**
-   * Name of the HTTP cookie used for the authentication token between the client and the server.
-   */
-  public static final String AUTH_COOKIE = "hadoop.auth";
-
-  private static final String AUTH_COOKIE_EQ = AUTH_COOKIE + "=";
-
-  /**
-   * Client side authentication token.
-   */
-  public static class Token {
-
-    private String token;
-
-    /**
-     * Creates a token.
-     */
-    public Token() {
-    }
-
-    /**
-     * Creates a token using an existing string representation of the token.
-     *
-     * @param tokenStr string representation of the tokenStr.
-     */
-    public Token(String tokenStr) {
-      if (tokenStr == null) {
-        throw new IllegalArgumentException("tokenStr cannot be null");
-      }
-      set(tokenStr);
-    }
-
-    /**
-     * Returns if a token from the server has been set.
-     *
-     * @return if a token from the server has been set.
-     */
-    public boolean isSet() {
-      return token != null;
-    }
-
-    /**
-     * Sets a token.
-     *
-     * @param tokenStr string representation of the tokenStr.
-     */
-    void set(String tokenStr) {
-      token = tokenStr;
-    }
-
-    /**
-     * Returns the string representation of the token.
-     *
-     * @return the string representation of the token.
-     */
-    @Override
-    public String toString() {
-      return token;
-    }
-
-  }
-
-  private static Class<? extends Authenticator> defaultAuthenticator
-      = KerberosAuthenticator.class;
-
-  /**
-   * Sets the default {@link Authenticator} class to use when an {@link AuthenticatedURL} instance
-   * is created without specifying an authenticator.
-   *
-   * @param authenticator the authenticator class to use as default.
-   */
-  public static void setDefaultAuthenticator(Class<? extends Authenticator> authenticator) {
-    defaultAuthenticator = authenticator;
-  }
-
-  /**
-   * Returns the default {@link Authenticator} class to use when an {@link AuthenticatedURL} instance
-   * is created without specifying an authenticator.
-   *
-   * @return the authenticator class to use as default.
-   */
-  public static Class<? extends Authenticator> getDefaultAuthenticator() {
-    return defaultAuthenticator;
-  }
-
-  private Authenticator authenticator;
-  private ConnectionConfigurator connConfigurator;
-
-  /**
-   * Creates an {@link AuthenticatedURL}.
-   */
-  public AuthenticatedURL() {
-    this(null);
-  }
-
-  /**
-   * Creates an <code>AuthenticatedURL</code>.
-   *
-   * @param authenticator the {@link Authenticator} instance to use, if <code>null</code> a {@link
-   * KerberosAuthenticator} is used.
-   */
-  public AuthenticatedURL(Authenticator authenticator) {
-    this(authenticator, null);
-  }
-
-  /**
-   * Creates an <code>AuthenticatedURL</code>.
-   *
-   * @param authenticator the {@link Authenticator} instance to use, if <code>null</code> a {@link
-   * KerberosAuthenticator} is used.
-   * @param connConfigurator a connection configurator.
-   */
-  public AuthenticatedURL(Authenticator authenticator,
-                          ConnectionConfigurator connConfigurator) {
-    try {
-      this.authenticator = (authenticator != null) ? authenticator : defaultAuthenticator.newInstance();
-    } catch (Exception ex) {
-      throw new RuntimeException(ex);
-    }
-    this.connConfigurator = connConfigurator;
-    this.authenticator.setConnectionConfigurator(connConfigurator);
-  }
-
-  /**
-   * Returns the {@link Authenticator} instance used by the
-   * <code>AuthenticatedURL</code>.
-   *
-   * @return the {@link Authenticator} instance
-   */
-  protected Authenticator getAuthenticator() {
-    return authenticator;
-  }
-
-  /**
-   * Returns an authenticated {@link HttpURLConnection}.
-   *
-   * @param url the URL to connect to. Only HTTP/S URLs are supported.
-   * @param token the authentication token being used for the user.
-   *
-   * @return an authenticated {@link HttpURLConnection}.
-   *
-   * @throws IOException if an IO error occurred.
-   * @throws AuthenticationException if an authentication exception occurred.
-   */
-  public HttpURLConnection openConnection(URL url, Token token) throws IOException, AuthenticationException {
-    if (url == null) {
-      throw new IllegalArgumentException("url cannot be NULL");
-    }
-    if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) {
-      throw new IllegalArgumentException("url must be for a HTTP or HTTPS resource");
-    }
-    if (token == null) {
-      throw new IllegalArgumentException("token cannot be NULL");
-    }
-    authenticator.authenticate(url, token);
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    if (connConfigurator != null) {
-      conn = connConfigurator.configure(conn);
-    }
-    injectToken(conn, token);
-    return conn;
-  }
-
-  /**
-   * Helper method that injects an authentication token to send with a connection.
-   *
-   * @param conn connection to inject the authentication token into.
-   * @param token authentication token to inject.
-   */
-  public static void injectToken(HttpURLConnection conn, Token token) {
-    String t = token.token;
-    if (t != null) {
-      if (!t.startsWith("\"")) {
-        t = "\"" + t + "\"";
-      }
-      conn.addRequestProperty("Cookie", AUTH_COOKIE_EQ + t);
-    }
-  }
-
-  /**
-   * Helper method that extracts an authentication token received from a connection.
-   * <p>
-   * This method is used by {@link Authenticator} implementations.
-   *
-   * @param conn connection to extract the authentication token from.
-   * @param token the authentication token.
-   *
-   * @throws IOException if an IO error occurred.
-   * @throws AuthenticationException if an authentication exception occurred.
-   */
-  public static void extractToken(HttpURLConnection conn, Token token) throws IOException, AuthenticationException {
-    int respCode = conn.getResponseCode();
-    if (respCode == HttpURLConnection.HTTP_OK
-        || respCode == HttpURLConnection.HTTP_CREATED
-        || respCode == HttpURLConnection.HTTP_ACCEPTED) {
-      Map<String, List<String>> headers = conn.getHeaderFields();
-      List<String> cookies = headers.get("Set-Cookie");
-      if (cookies != null) {
-        for (String cookie : cookies) {
-          if (cookie.startsWith(AUTH_COOKIE_EQ)) {
-            String value = cookie.substring(AUTH_COOKIE_EQ.length());
-            int separator = value.indexOf(";");
-            if (separator > -1) {
-              value = value.substring(0, separator);
-            }
-            if (value.length() > 0) {
-              token.set(value);
-            }
-          }
-        }
-      }
-    } else {
-      token.set(null);
-      throw new AuthenticationException("Authentication failed, status: " + conn.getResponseCode()
-          + ", message: " + conn.getResponseMessage());
-    }
-  }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticationException.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticationException.java
deleted file mode 100644
index 38e5f6a7..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/AuthenticationException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.spnego;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Exception thrown when an authentication error occurrs.
- */
-public class AuthenticationException extends Exception {
-  
-  static final long serialVersionUID = 0;
-
-  /**
-   * Creates an {@link AuthenticationException}.
-   *
-   * @param cause original exception.
-   */
-  public AuthenticationException(Throwable cause) {
-    super(cause);
-  }
-
-  /**
-   * Creates an {@link AuthenticationException}.
-   *
-   * @param msg exception message.
-   */
-  public AuthenticationException(String msg) {
-    super(msg);
-  }
-
-  /**
-   * Creates an {@link AuthenticationException}.
-   *
-   * @param msg exception message.
-   * @param cause original exception.
-   */
-  public AuthenticationException(String msg, Throwable cause) {
-    super(msg, cause);
-  }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/Authenticator.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/Authenticator.java
deleted file mode 100644
index a643218c..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/Authenticator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.spnego;
-
-import org.apache.kerby.has.common.util.ConnectionConfigurator;
-
-import java.io.IOException;
-import java.net.URL;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Interface for client authentication mechanisms.
- * <p>
- * Implementations are use-once instances, they don't need to be thread safe.
- */
-public interface Authenticator {
-
-  /**
-   * Sets a {@link ConnectionConfigurator} instance to use for
-   * configuring connections.
-   *
-   * @param configurator the {@link ConnectionConfigurator} instance.
-   */
-  void setConnectionConfigurator(ConnectionConfigurator configurator);
-
-  /**
-   * Authenticates against a URL and returns a {@link AuthenticatedURL.Token} to be
-   * used by subsequent requests.
-   *
-   * @param url the URl to authenticate against.
-   * @param token the authentication token being used for the user.
-   *
-   * @throws IOException if an IO error occurred.
-   * @throws AuthenticationException if an authentication error occurred.
-   */
-  void authenticate(URL url, AuthenticatedURL.Token token) throws IOException, AuthenticationException;
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosAuthenticator.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosAuthenticator.java
deleted file mode 100644
index b9d23a16..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosAuthenticator.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.spnego;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.kerby.has.common.util.ConnectionConfigurator;
-import org.ietf.jgss.GSSContext;
-import org.ietf.jgss.GSSManager;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.Oid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosKey;
-import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.kerby.has.common.util.PlatformName.IBM_JAVA;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * The {@link KerberosAuthenticator} implements the Kerberos SPNEGO authentication sequence.
- * It uses the default principal for the Kerberos cache (normally set via kinit).
- */
-@SuppressWarnings("PMD")
-public class KerberosAuthenticator implements Authenticator {
-  
-  private static final Logger LOG = LoggerFactory.getLogger(KerberosAuthenticator.class);
-
-  /**
-   * HTTP header used by the SPNEGO server endpoint during an authentication sequence.
-   */
-  public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
-
-  /**
-   * HTTP header used by the SPNEGO client endpoint during an authentication sequence.
-   */
-  public static final String AUTHORIZATION = "Authorization";
-
-  /**
-   * HTTP header prefix used by the SPNEGO client/server endpoints during an authentication sequence.
-   */
-  public static final String NEGOTIATE = "Negotiate";
-
-  private static final String AUTH_HTTP_METHOD = "OPTIONS";
-
-  private static String keytabPrincipal = null;
-  private static String keytabFile = null;
-
-  /*
-  * Defines the Kerberos configuration that will be used to obtain the Kerberos principal from the
-  * Kerberos cache.
-  */
-  private static class KerberosConfiguration extends Configuration {
-
-    private static final String OS_LOGIN_MODULE_NAME;
-    private static final boolean WINDOWS = System.getProperty("os.name").startsWith("Windows");
-    private static final boolean IS_64_BIT = System.getProperty("os.arch").contains("64");
-    private static final boolean AIX = System.getProperty("os.name").equals("AIX");
-
-    /* Return the OS login module class name */
-    private static String getOSLoginModuleName() {
-      if (IBM_JAVA) {
-        if (WINDOWS) {
-          return IS_64_BIT ? "com.ibm.security.auth.module.Win64LoginModule"
-              : "com.ibm.security.auth.module.NTLoginModule";
-        } else if (AIX) {
-          return IS_64_BIT ? "com.ibm.security.auth.module.AIX64LoginModule"
-              : "com.ibm.security.auth.module.AIXLoginModule";
-        } else {
-          return "com.ibm.security.auth.module.LinuxLoginModule";
-        }
-      } else {
-        return WINDOWS ? "com.sun.security.auth.module.NTLoginModule"
-            : "com.sun.security.auth.module.UnixLoginModule";
-      }
-    }
-
-    static {
-      OS_LOGIN_MODULE_NAME = getOSLoginModuleName();
-    }
-
-    private static final AppConfigurationEntry OS_SPECIFIC_LOGIN =
-      new AppConfigurationEntry(OS_LOGIN_MODULE_NAME,
-                                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
-                                new HashMap<String, String>());
-
-    private static final Map<String, String> KEYTAB_KERBEROS_OPTIONS
-        = new HashMap<>();
-    static {
-      if (IBM_JAVA) {
-        KEYTAB_KERBEROS_OPTIONS.put("credsType", "both");
-        KEYTAB_KERBEROS_OPTIONS.put("useKeytab",
-            prependFileAuthority(keytabFile));
-      } else {
-        KEYTAB_KERBEROS_OPTIONS.put("doNotPrompt", "true");
-        KEYTAB_KERBEROS_OPTIONS.put("useKeyTab", "true");
-        KEYTAB_KERBEROS_OPTIONS.put("storeKey", "true");
-        KEYTAB_KERBEROS_OPTIONS.put("keyTab", keytabFile);
-      }
-      KEYTAB_KERBEROS_OPTIONS.put("principal", keytabPrincipal);
-      KEYTAB_KERBEROS_OPTIONS.put("refreshKrb5Config", "true");
-      KEYTAB_KERBEROS_OPTIONS.put("debug", "false");
-    }
-
-    private static final AppConfigurationEntry USER_KERBEROS_LOGIN =
-      new AppConfigurationEntry(KerberosUtil.getKrb5LoginModuleName(),
-                                AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL,
-                                KEYTAB_KERBEROS_OPTIONS);
-
-    private static final AppConfigurationEntry[] USER_KERBEROS_CONF =
-      new AppConfigurationEntry[]{OS_SPECIFIC_LOGIN, USER_KERBEROS_LOGIN};
-
-    @Override
-    public AppConfigurationEntry[] getAppConfigurationEntry(String appName) {
-      return USER_KERBEROS_CONF;
-    }
-
-    private static String prependFileAuthority(String keytabPath) {
-      return keytabPath.startsWith("file://") ? keytabPath
-          : "file://" + keytabPath;
-    }
-  }
-  
-  private URL url;
-  private HttpURLConnection conn;
-  private Base64 base64;
-  private ConnectionConfigurator connConfigurator;
-
-  /**
-   * Sets a {@link ConnectionConfigurator} instance to use for
-   * configuring connections.
-   *
-   * @param configurator the {@link ConnectionConfigurator} instance.
-   */
-  @Override
-  public void setConnectionConfigurator(ConnectionConfigurator configurator) {
-    connConfigurator = configurator;
-  }
-
-  /**
-   * Performs SPNEGO authentication against the specified URL.
-   * <p>
-   * If a token is given it does a NOP and returns the given token.
-   * <p>
-   * If no token is given, it will perform the SPNEGO authentication sequence using an
-   * HTTP <code>OPTIONS</code> request.
-   *
-   * @param url the URl to authenticate against.
-   * @param token the authentication token being used for the user.
-   *
-   * @throws IOException if an IO error occurred.
-   * @throws AuthenticationException if an authentication error occurred.
-   */
-  @Override
-  public void authenticate(URL url, AuthenticatedURL.Token token)
-    throws IOException, AuthenticationException {
-
-    if (!token.isSet()) {
-      this.url = url;
-      base64 = new Base64(0);
-      conn = (HttpURLConnection) url.openConnection();
-      if (connConfigurator != null) {
-        conn = connConfigurator.configure(conn);
-      }
-      conn.setRequestMethod(AUTH_HTTP_METHOD);
-      conn.connect();
-      
-      boolean needFallback = false;
-      if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
-        LOG.debug("JDK performed authentication on our behalf.");
-        // If the JDK already did the SPNEGO back-and-forth for
-        // us, just pull out the token.
-        AuthenticatedURL.extractToken(conn, token);
-        if (isTokenKerberos(token)) {
-          return;
-        }
-        needFallback = true;
-      }
-      if (!needFallback && isNegotiate()) {
-        LOG.debug("Performing our own SPNEGO sequence.");
-        doSpnegoSequence(token);
-      } else {
-        throw new IOException("Should perform our own SPNEGO sequence");
-      }
-    }
-  }
-
-  public void setKeyTab(String keytabFile, String keytabPrincipal) {
-    this.keytabFile = keytabFile;
-    this.keytabPrincipal = keytabPrincipal;
-  }
-
-  /*
-   * Check if the passed token is of type "kerberos" or "kerberos-dt"
-   */
-  private boolean isTokenKerberos(AuthenticatedURL.Token token)
-      throws AuthenticationException {
-    if (token.isSet()) {
-      AuthToken aToken = AuthToken.parse(token.toString());
-      if (aToken.getType().equals("kerberos")
-          || aToken.getType().equals("kerberos-dt")) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /*
-  * Indicates if the response is starting a SPNEGO negotiation.
-  */
-  private boolean isNegotiate() throws IOException {
-    boolean negotiate = false;
-    if (conn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
-      String authHeader = conn.getHeaderField(WWW_AUTHENTICATE);
-      negotiate = authHeader != null && authHeader.trim().startsWith(NEGOTIATE);
-    }
-    return negotiate;
-  }
-
-  /**
-   * Implements the SPNEGO authentication sequence interaction using the current default principal
-   * in the Kerberos cache (normally set via kinit).
-   *
-   * @param token the authentication token being used for the user.
-   *
-   * @throws IOException if an IO error occurred.
-   * @throws AuthenticationException if an authentication error occurred.
-   */
-  private void doSpnegoSequence(AuthenticatedURL.Token token) throws IOException, AuthenticationException {
-    try {
-      AccessControlContext context = AccessController.getContext();
-      Subject subject = Subject.getSubject(context);
-      if (subject == null
-          || (subject.getPrivateCredentials(KerberosKey.class).isEmpty()
-              && subject.getPrivateCredentials(KerberosTicket.class).isEmpty())) {
-        LOG.debug("No subject in context, logging in");
-        subject = new Subject();
-        LoginContext login = new LoginContext("", subject,
-            null, new KerberosConfiguration());
-        login.login();
-      }
-
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Using subject: " + subject);
-      }
-      Subject.doAs(subject, new PrivilegedExceptionAction<Void>() {
-
-        @Override
-        public Void run() throws Exception {
-          GSSContext gssContext = null;
-          try {
-            GSSManager gssManager = GSSManager.getInstance();
-            String servicePrincipal = KerberosUtil.getServicePrincipal("HTTP",
-                KerberosAuthenticator.this.url.getHost());
-            LOG.info("service principal is:" + servicePrincipal);
-            Oid oid = KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL");
-            GSSName serviceName = gssManager.createName(servicePrincipal,
-                                                        oid);
-            oid = KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID");
-            gssContext = gssManager.createContext(serviceName, oid, null,
-                                                  GSSContext.DEFAULT_LIFETIME);
-            gssContext.requestCredDeleg(true);
-            gssContext.requestMutualAuth(true);
-
-            byte[] inToken = new byte[0];
-            byte[] outToken;
-            boolean established = false;
-
-            // Loop while the context is still not established
-            while (!established) {
-              outToken = gssContext.initSecContext(inToken, 0, inToken.length);
-              if (outToken != null) {
-                sendToken(outToken);
-              }
-
-              if (!gssContext.isEstablished()) {
-                inToken = readToken();
-              } else {
-                established = true;
-              }
-            }
-          } finally {
-            if (gssContext != null) {
-              gssContext.dispose();
-              gssContext = null;
-            }
-          }
-          return null;
-        }
-      });
-    } catch (PrivilegedActionException ex) {
-      throw new AuthenticationException(ex.getException());
-    } catch (LoginException ex) {
-      throw new AuthenticationException(ex);
-    }
-    AuthenticatedURL.extractToken(conn, token);
-  }
-
-  /*
-  * Sends the Kerberos token to the server.
-  */
-  private void sendToken(byte[] outToken) throws IOException {
-    String token = base64.encodeToString(outToken);
-    conn = (HttpURLConnection) url.openConnection();
-    if (connConfigurator != null) {
-      conn = connConfigurator.configure(conn);
-    }
-    conn.setRequestMethod(AUTH_HTTP_METHOD);
-    conn.setRequestProperty(AUTHORIZATION, NEGOTIATE + " " + token);
-    conn.connect();
-  }
-
-  /*
-  * Retrieves the Kerberos token returned by the server.
-  */
-  private byte[] readToken() throws IOException, AuthenticationException {
-    int status = conn.getResponseCode();
-    if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_UNAUTHORIZED) {
-      String authHeader = conn.getHeaderField(WWW_AUTHENTICATE);
-      if (authHeader == null || !authHeader.trim().startsWith(NEGOTIATE)) {
-        throw new AuthenticationException("Invalid SPNEGO sequence, '" + WWW_AUTHENTICATE
-            + "' header incorrect: " + authHeader);
-      }
-      String negotiation = authHeader.trim().substring((NEGOTIATE + " ").length()).trim();
-      return base64.decode(negotiation);
-    }
-    throw new AuthenticationException("Invalid SPNEGO sequence, status code: " + status);
-  }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosHasAuthenticator.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosHasAuthenticator.java
deleted file mode 100644
index da598a30..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosHasAuthenticator.java
+++ /dev/null
@@ -1,25 +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
- * <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.kerby.has.common.spnego;
-
-public class KerberosHasAuthenticator extends KerberosAuthenticator {
-
-    public KerberosHasAuthenticator(String keytabFile, String keytabPrincipal) {
-        setKeyTab(keytabFile, keytabPrincipal);
-    }
-}
\ No newline at end of file
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosUtil.java
deleted file mode 100644
index f2cafd6e..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/spnego/KerberosUtil.java
+++ /dev/null
@@ -1,262 +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.kerby.has.common.spnego;
-
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.ietf.jgss.GSSException;
-import org.ietf.jgss.Oid;
-
-import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosTicket;
-import javax.security.auth.kerberos.KeyTab;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import static org.apache.kerby.has.common.util.PlatformName.IBM_JAVA;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-@SuppressWarnings("PMD")
-public class KerberosUtil {
-
-  /* Return the Kerberos login module name */
-  public static String getKrb5LoginModuleName() {
-    return (IBM_JAVA)
-      ? "com.ibm.security.auth.module.Krb5LoginModule"
-      : "com.sun.security.auth.module.Krb5LoginModule";
-  }
-
-  public static Oid getOidInstance(String oidName)
-      throws ClassNotFoundException, GSSException, NoSuchFieldException,
-      IllegalAccessException {
-    Class<?> oidClass;
-    if (IBM_JAVA) {
-      if ("NT_GSS_KRB5_PRINCIPAL".equals(oidName)) {
-        // IBM JDK GSSUtil class does not have field for krb5 principal oid
-        return new Oid("1.2.840.113554.1.2.2.1");
-      }
-      oidClass = Class.forName("com.ibm.security.jgss.GSSUtil");
-    } else {
-      oidClass = Class.forName("sun.security.jgss.GSSUtil");
-    }
-    Field oidField = oidClass.getDeclaredField(oidName);
-    return (Oid) oidField.get(oidClass);
-  }
-
-  public static String getDefaultRealm()
-      throws ClassNotFoundException, NoSuchMethodException,
-      IllegalArgumentException, IllegalAccessException,
-      InvocationTargetException {
-    Object kerbConf;
-    Class<?> classRef;
-    Method getInstanceMethod;
-    Method getDefaultRealmMethod;
-    if (IBM_JAVA) {
-      classRef = Class.forName("com.ibm.security.krb5.internal.Config");
-    } else {
-      classRef = Class.forName("sun.security.krb5.Config");
-    }
-    getInstanceMethod = classRef.getMethod("getInstance", new Class[0]);
-    kerbConf = getInstanceMethod.invoke(classRef, new Object[0]);
-    getDefaultRealmMethod = classRef.getDeclaredMethod("getDefaultRealm",
-        new Class[0]);
-    return (String) getDefaultRealmMethod.invoke(kerbConf, new Object[0]);
-  }
-
-  public static String getDefaultRealmProtected() {
-    String realmString = null;
-    try {
-      realmString = getDefaultRealm();
-    } catch (RuntimeException rte) {
-      //silently catch everything
-    } catch (Exception e) {
-      //silently return null
-    }
-    return realmString;
-  }
-
-  /*
-   * For a Service Host Principal specification, map the host's domain
-   * to kerberos realm, as specified by krb5.conf [domain_realm] mappings.
-   * Unfortunately the mapping routines are private to the security.krb5
-   * package, so have to construct a PrincipalName instance to derive the realm.
-   *
-   * Many things can go wrong with Kerberos configuration, and this is not
-   * the place to be throwing exceptions to help debug them.  Nor do we choose
-   * to make potentially voluminous logs on every call to a communications API.
-   * So we simply swallow all exceptions from the underlying libraries and
-   * return null if we can't get a good value for the realmString.
-   *
-   * @param shortprinc A service principal name with host fqdn as instance, e.g.
-   *     "HTTP/myhost.mydomain"
-   * @return String value of Kerberos realm, mapped from host fqdn
-   *     May be default realm, or may be null.
-   */
-  public static String getDomainRealm(String shortprinc) {
-    Class<?> classRef;
-    Object principalName; //of type sun.security.krb5.PrincipalName or IBM equiv
-    String realmString = null;
-    try {
-      if (IBM_JAVA) {
-        classRef = Class.forName("com.ibm.security.krb5.PrincipalName");
-      } else {
-        classRef = Class.forName("sun.security.krb5.PrincipalName");
-      }
-      int tKrbNtSrvHst = classRef.getField("KRB_NT_SRV_HST").getInt(null);
-      principalName = classRef.getConstructor(String.class, int.class).
-          newInstance(shortprinc, tKrbNtSrvHst);
-      realmString = (String) classRef.getMethod("getRealmString", new Class[0]).
-          invoke(principalName, new Object[0]);
-    } catch (RuntimeException rte) {
-      //silently catch everything
-    } catch (Exception e) {
-      //silently return default realm (which may itself be null)
-    }
-    if (null == realmString || realmString.equals("")) {
-      return getDefaultRealmProtected();
-    } else {
-      return realmString;
-    }
-  }
-
-  /* Return fqdn of the current host */
-  static String getLocalHostName() throws UnknownHostException {
-    return InetAddress.getLocalHost().getCanonicalHostName();
-  }
-  
-  /**
-   * Create Kerberos principal for a given service and hostname,
-   * inferring realm from the fqdn of the hostname. It converts
-   * hostname to lower case. If hostname is null or "0.0.0.0", it uses
-   * dynamically looked-up fqdn of the current host instead.
-   * If domain_realm mappings are inadequately specified, it will
-   * use default_realm, per usual Kerberos behavior.
-   * If default_realm also gives a null value, then a principal
-   * without realm will be returned, which by Kerberos definitions is
-   * just another way to specify default realm.
-   *
-   * @param service
-   *          Service for which you want to generate the principal.
-   * @param hostname
-   *          Fully-qualified domain name.
-   * @return Converted Kerberos principal name.
-   * @throws UnknownHostException
-   *           If no IP address for the local host could be found.
-   */
-  public static final String getServicePrincipal(String service,
-                                                 String hostname)
-      throws UnknownHostException {
-    String fqdn = hostname;
-    String shortprinc = null;
-    String realmString = null;
-    if (null == fqdn || fqdn.equals("") || fqdn.equals("0.0.0.0")) {
-      fqdn = getLocalHostName();
-    }
-    // convert hostname to lowercase as kerberos does not work with hostnames
-    // with uppercase characters.
-    fqdn = fqdn.toLowerCase(Locale.US);
-    shortprinc = service + "/" + fqdn;
-    // Obtain the realm name inferred from the domain of the host
-    realmString = getDomainRealm(shortprinc);
-    if (null == realmString || realmString.equals("")) {
-      return shortprinc;
-    } else {
-      return shortprinc + "@" + realmString;
-    }
-  }
-
-  /**
-   * Get all the unique principals present in the keytabfile.
-   * 
-   * @param keytabFileName 
-   *          Name of the keytab file to be read.
-   * @return list of unique principals in the keytab.
-   * @throws IOException
-   *          If keytab entries cannot be read from the file.
-   */
-  static final String[] getPrincipalNames(String keytabFileName) throws IOException {
-    Keytab keytab = Keytab.loadKeytab(new File(keytabFileName));
-    Set<String> principals = new HashSet<>();
-    List<PrincipalName> entries = keytab.getPrincipals();
-    for (PrincipalName entry : entries) {
-      principals.add(entry.getName().replace("\\", "/"));
-    }
-    return principals.toArray(new String[0]);
-  }
-
-  /**
-   * Get all the unique principals from keytabfile which matches a pattern.
-   * 
-   * @param keytab Name of the keytab file to be read.
-   * @param pattern pattern to be matched.
-   * @return list of unique principals which matches the pattern.
-   * @throws IOException if cannot get the principal name
-   */
-  public static final String[] getPrincipalNames(String keytab,
-                                                 Pattern pattern) throws IOException {
-    String[] principals = getPrincipalNames(keytab);
-    if (principals.length != 0) {
-      List<String> matchingPrincipals = new ArrayList<>();
-      for (String principal : principals) {
-        if (pattern.matcher(principal).matches()) {
-          matchingPrincipals.add(principal);
-        }
-      }
-      principals = matchingPrincipals.toArray(new String[0]);
-    }
-    return principals;
-  }
-
-  /**
-   * Check if the subject contains Kerberos keytab related objects.
-   * The Kerberos keytab object attached in subject has been changed
-   * from KerberosKey (JDK 7) to KeyTab (JDK 8)
-   *
-   *
-   * @param subject subject to be checked
-   * @return true if the subject contains Kerberos keytab
-   */
-  public static boolean hasKerberosKeyTab(Subject subject) {
-    return !subject.getPrivateCredentials(KeyTab.class).isEmpty();
-  }
-
-  /**
-   * Check if the subject contains Kerberos ticket.
-   *
-   *
-   * @param subject subject to be checked
-   * @return true if the subject contains Kerberos ticket
-   */
-  public static boolean hasKerberosTicket(Subject subject) {
-    return !subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
-  }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/KeyStoresFactory.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/KeyStoresFactory.java
deleted file mode 100644
index f8aaecb4..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/KeyStoresFactory.java
+++ /dev/null
@@ -1,252 +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.kerby.has.common.ssl;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.util.StringUtils;
-import org.apache.kerby.kerberos.kerb.client.KrbConfig;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.text.MessageFormat;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Interface that gives access to {@link KeyManager} and {@link TrustManager}
- * implementations.
- */
-@InterfaceAudience.Private
-@InterfaceStability.Evolving
-public class KeyStoresFactory extends KrbConfig {
-
-  private static final Log LOG =
-    LogFactory.getLog(KeyStoresFactory.class);
-
-  public static final String SSL_KEYSTORE_LOCATION_TPL_KEY =
-    "ssl.{0}.keystore.location";
-  public static final String SSL_KEYSTORE_PASSWORD_TPL_KEY =
-    "ssl.{0}.keystore.password";
-  public static final String SSL_KEYSTORE_KEYPASSWORD_TPL_KEY =
-    "ssl.{0}.keystore.keypassword";
-  public static final String SSL_KEYSTORE_TYPE_TPL_KEY =
-    "ssl.{0}.keystore.type";
-
-  public static final String SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY =
-    "ssl.{0}.truststore.reload.interval";
-  public static final String SSL_TRUSTSTORE_LOCATION_TPL_KEY =
-    "ssl.{0}.truststore.location";
-  public static final String SSL_TRUSTSTORE_PASSWORD_TPL_KEY =
-    "ssl.{0}.truststore.password";
-  public static final String SSL_TRUSTSTORE_TYPE_TPL_KEY =
-    "ssl.{0}.truststore.type";
-
-  /**
-   * Default format of the keystore files.
-   */
-  public static final String DEFAULT_KEYSTORE_TYPE = "jks";
-
-  /**
-   * Reload interval in milliseconds.
-   */
-  public static final long DEFAULT_SSL_TRUSTSTORE_RELOAD_INTERVAL = 10000;
-
-  private HasConfig conf;
-  private KeyManager[] keyManagers;
-  private TrustManager[] trustManagers;
-  private ReloadingX509TrustManager trustManager;
-
-  /**
-   * Sets the configuration for the factory.
-   *
-   * @param conf the configuration for the factory.
-   */
-  public void setConf(HasConfig conf) {
-    this.conf = conf;
-  }
-
-  /**
-   * Returns the configuration of the factory.
-   *
-   * @return the configuration of the factory.
-   */
-  public HasConfig getConf() {
-    return conf;
-  }
-
-
-  /**
-   * Initializes the keystores of the factory.
-   *
-   * @param mode if the keystores are to be used in client or server mode.
-   * @throws IOException thrown if the keystores could not be initialized due
-   * to an IO error.
-   * @throws GeneralSecurityException thrown if the keystores could not be
-   * initialized due to an security error.
-   */
-  public void init(SSLFactory.Mode mode) throws IOException, GeneralSecurityException {
-     boolean requireClientCert =
-      conf.getBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY,
-          SSLFactory.DEFAULT_SSL_REQUIRE_CLIENT_CERT);
-
-    // certificate store
-    String keystoreType =
-      conf.getString(resolvePropertyName(mode, SSL_KEYSTORE_TYPE_TPL_KEY),
-               DEFAULT_KEYSTORE_TYPE);
-    KeyStore keystore = KeyStore.getInstance(keystoreType);
-    String keystoreKeyPassword = null;
-    if (requireClientCert || mode == SSLFactory.Mode.SERVER) {
-      String locationProperty =
-        resolvePropertyName(mode, SSL_KEYSTORE_LOCATION_TPL_KEY);
-      String keystoreLocation = conf.getString(locationProperty, "");
-      if (keystoreLocation.isEmpty()) {
-        throw new GeneralSecurityException("The property '" + locationProperty
-            + "' has not been set in the ssl configuration file.");
-      }
-      String passwordProperty =
-        resolvePropertyName(mode, SSL_KEYSTORE_PASSWORD_TPL_KEY);
-      String keystorePassword = getPassword(conf, passwordProperty, "");
-      if (keystorePassword.isEmpty()) {
-        throw new GeneralSecurityException("The property '" + passwordProperty
-            + "' has not been set in the ssl configuration file.");
-      }
-      String keyPasswordProperty =
-        resolvePropertyName(mode, SSL_KEYSTORE_KEYPASSWORD_TPL_KEY);
-      // Key password defaults to the same value as store password for
-      // compatibility with legacy configurations that did not use a separate
-      // configuration property for key password.
-      keystoreKeyPassword = getPassword(
-          conf, keyPasswordProperty, keystorePassword);
-      LOG.debug(mode.toString() + " KeyStore: " + keystoreLocation);
-
-      InputStream is = new FileInputStream(keystoreLocation);
-      try {
-        keystore.load(is, keystorePassword.toCharArray());
-      } finally {
-        is.close();
-      }
-      LOG.debug(mode.toString() + " Loaded KeyStore: " + keystoreLocation);
-    } else {
-      keystore.load(null, null);
-    }
-    KeyManagerFactory keyMgrFactory = KeyManagerFactory
-        .getInstance(SSLFactory.SSLCERTIFICATE);
-
-    keyMgrFactory.init(keystore, (keystoreKeyPassword != null)
-        ? keystoreKeyPassword.toCharArray() : null);
-    keyManagers = keyMgrFactory.getKeyManagers();
-
-    //trust store
-    String truststoreType =
-      conf.getString(resolvePropertyName(mode, SSL_TRUSTSTORE_TYPE_TPL_KEY),
-               DEFAULT_KEYSTORE_TYPE);
-
-    String locationProperty =
-      resolvePropertyName(mode, SSL_TRUSTSTORE_LOCATION_TPL_KEY);
-    String truststoreLocation = conf.getString(locationProperty, "");
-    if (!truststoreLocation.isEmpty()) {
-      String passwordProperty = resolvePropertyName(mode,
-          SSL_TRUSTSTORE_PASSWORD_TPL_KEY);
-      String truststorePassword = getPassword(conf, passwordProperty, "");
-      if (truststorePassword.isEmpty()) {
-        throw new GeneralSecurityException("The property '" + passwordProperty
-            + "' has not been set in the ssl configuration file.");
-      }
-      long truststoreReloadInterval =
-          conf.getLong(resolvePropertyName(mode, SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY),
-              DEFAULT_SSL_TRUSTSTORE_RELOAD_INTERVAL);
-
-      LOG.debug(mode.toString() + " TrustStore: " + truststoreLocation);
-
-      trustManager = new ReloadingX509TrustManager(truststoreType,
-          truststoreLocation,
-          truststorePassword,
-          truststoreReloadInterval);
-      trustManager.init();
-      LOG.debug(mode.toString() + " Loaded TrustStore: " + truststoreLocation);
-      trustManagers = new TrustManager[]{trustManager};
-    } else {
-      LOG.debug("The property '" + locationProperty + "' has not been set, "
-          + "no TrustStore will be loaded");
-      trustManagers = null;
-    }
-  }
-
-  String getPassword(HasConfig conf, String alias, String defaultPass) {
-    String password = defaultPass;
-    password = conf.getString(alias);
-    return password;
-  }
-
-  /**
-   * Releases any resources being used.
-   */
-  public void destroy() {
-    if (trustManager != null) {
-      trustManager.destroy();
-      trustManager = null;
-      keyManagers = null;
-      trustManagers = null;
-    }
-  }
-
-  /**
-   * Returns the keymanagers for owned certificates.
-   *
-   * @return the keymanagers for owned certificates.
-   */
-  public KeyManager[] getKeyManagers() {
-    return keyManagers;
-  }
-
-  /**
-   * Returns the trustmanagers for trusted certificates.
-   *
-   * @return the trustmanagers for trusted certificates.
-   */
-  public TrustManager[] getTrustManagers() {
-    return trustManagers;
-  }
-
-  /**
-   * Resolves a property name to its client/server version if applicable.
-   *
-   * NOTE: This method is public for testing purposes.
-   *
-   * @param mode client/server mode.
-   * @param template property name template.
-   * @return the resolved property name.
-   */
-  public static String resolvePropertyName(SSLFactory.Mode mode,
-                                           String template) {
-    return MessageFormat.format(
-        template, StringUtils.toLowerCase(mode.toString()));
-  }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/ReloadingX509TrustManager.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/ReloadingX509TrustManager.java
deleted file mode 100644
index 1dc4c50c..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/ReloadingX509TrustManager.java
+++ /dev/null
@@ -1,208 +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.kerby.has.common.ssl;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * A {@link TrustManager} implementation that reloads its configuration when
- * the truststore file on disk changes.
- */
-@InterfaceAudience.Private
-@InterfaceStability.Evolving
-public final class ReloadingX509TrustManager
-  implements X509TrustManager, Runnable {
-
-  private static final Log LOG =
-    LogFactory.getLog(ReloadingX509TrustManager.class);
-
-  private String type;
-  private File file;
-  private String password;
-  private long lastLoaded;
-  private long reloadInterval;
-  private AtomicReference<X509TrustManager> trustManagerRef;
-
-  private volatile boolean running;
-  private Thread reloader;
-
-  /**
-   * Creates a reloadable trustmanager. The trustmanager reloads itself
-   * if the underlying trustore file has changed.
-   *
-   * @param type type of truststore file, typically 'jks'.
-   * @param location local path to the truststore file.
-   * @param password password of the truststore file.
-   * @param reloadInterval interval to check if the truststore file has
-   * changed, in milliseconds.
-   * @throws IOException thrown if the truststore could not be initialized due
-   * to an IO error.
-   * @throws GeneralSecurityException thrown if the truststore could not be
-   * initialized due to a security error.
-   */
-  public ReloadingX509TrustManager(String type, String location,
-                                   String password, long reloadInterval)
-    throws IOException, GeneralSecurityException {
-    this.type = type;
-    file = new File(location);
-    this.password = password;
-    trustManagerRef = new AtomicReference<>();
-    trustManagerRef.set(loadTrustManager());
-    this.reloadInterval = reloadInterval;
-  }
-
-  /**
-   * Starts the reloader thread.
-   */
-  public void init() {
-    reloader = new Thread(this, "Truststore reloader thread");
-    reloader.setDaemon(true);
-    running =  true;
-    reloader.start();
-  }
-
-  /**
-   * Stops the reloader thread.
-   */
-  public void destroy() {
-    running = false;
-    reloader.interrupt();
-  }
-
-  /**
-   * Returns the reload check interval.
-   *
-   * @return the reload check interval, in milliseconds.
-   */
-  public long getReloadInterval() {
-    return reloadInterval;
-  }
-
-  @Override
-  public void checkClientTrusted(X509Certificate[] chain, String authType)
-    throws CertificateException {
-    X509TrustManager tm = trustManagerRef.get();
-    if (tm != null) {
-      tm.checkClientTrusted(chain, authType);
-    } else {
-      throw new CertificateException("Unknown client chain certificate: "
-          + chain[0].toString());
-    }
-  }
-
-  @Override
-  public void checkServerTrusted(X509Certificate[] chain, String authType)
-    throws CertificateException {
-    X509TrustManager tm = trustManagerRef.get();
-    if (tm != null) {
-      tm.checkServerTrusted(chain, authType);
-    } else {
-      throw new CertificateException("Unknown server chain certificate: "
-          + chain[0].toString());
-    }
-  }
-
-  private static final X509Certificate[] EMPTY = new X509Certificate[0];
-  @Override
-  public X509Certificate[] getAcceptedIssuers() {
-    X509Certificate[] issuers = EMPTY;
-    X509TrustManager tm = trustManagerRef.get();
-    if (tm != null) {
-      issuers = tm.getAcceptedIssuers();
-    }
-    return issuers;
-  }
-
-  boolean needsReload() {
-    boolean reload = true;
-    if (file.exists()) {
-      if (file.lastModified() == lastLoaded) {
-        reload = false;
-      }
-    } else {
-      lastLoaded = 0;
-    }
-    return reload;
-  }
-
-  X509TrustManager loadTrustManager()
-  throws IOException, GeneralSecurityException {
-    X509TrustManager trustManager = null;
-    KeyStore ks = KeyStore.getInstance(type);
-    lastLoaded = file.lastModified();
-    FileInputStream in = new FileInputStream(file);
-    try {
-      ks.load(in, password.toCharArray());
-      LOG.debug("Loaded truststore '" + file + "'");
-    } finally {
-      in.close();
-    }
-
-    TrustManagerFactory trustManagerFactory = 
-      TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-    trustManagerFactory.init(ks);
-    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
-    for (TrustManager trustManager1 : trustManagers) {
-      if (trustManager1 instanceof X509TrustManager) {
-        trustManager = (X509TrustManager) trustManager1;
-        break;
-      }
-    }
-    return trustManager;
-  }
-
-  @Override
-  public void run() {
-    while (running) {
-      try {
-        Thread.sleep(reloadInterval);
-      } catch (InterruptedException e) {
-        //NOP
-      }
-      if (running && needsReload()) {
-        try {
-          trustManagerRef.set(loadTrustManager());
-        } catch (Exception ex) {
-          LOG.warn("Could not load truststore (keep using existing one) : "
-              + ex.toString(), ex);
-        }
-      }
-    }
-  }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLFactory.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLFactory.java
deleted file mode 100644
index 2067e668..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLFactory.java
+++ /dev/null
@@ -1,290 +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.kerby.has.common.ssl;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.util.ConnectionConfigurator;
-import org.apache.kerby.has.common.util.StringUtils;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.security.GeneralSecurityException;
-
-import static org.apache.kerby.has.common.util.PlatformName.IBM_JAVA;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Factory that creates SSLEngine and SSLSocketFactory instances using
- * Hadoop configuration information.
- *
- * which reloads public keys if the truststore file changes.
- *
- * This factory is used to configure HTTPS in Hadoop HTTP based endpoints, both
- * client and server.
- */
-@InterfaceAudience.Private
-@InterfaceStability.Evolving
-public class SSLFactory implements ConnectionConfigurator {
-
-  @InterfaceAudience.Private
-  public enum Mode {
-    CLIENT, SERVER
-  }
-
-  public static final String SSL_REQUIRE_CLIENT_CERT_KEY =
-    "hadoop.ssl.require.client.CERT";
-  public static final String SSL_HOSTNAME_VERIFIER_KEY =
-    "hadoop.ssl.hostname.verifier";
-  public static final String SSL_CLIENT_CONF_KEY =
-    "hadoop.ssl.client.conf";
-  public static final String SSL_SERVER_CONF_KEY =
-      "hadoop.ssl.server.conf";
-  public static final String SSLCERTIFICATE = IBM_JAVA ? "ibmX509" : "SunX509";
-
-  public static final boolean DEFAULT_SSL_REQUIRE_CLIENT_CERT = false;
-
-  public static final String KEYSTORES_FACTORY_CLASS_KEY =
-    "hadoop.ssl.keystores.factory.class";
-
-  public static final String SSL_ENABLED_PROTOCOLS =
-      "hadoop.ssl.enabled.protocols";
-
-  private HasConfig conf;
-  private Mode mode;
-  private boolean requireClientCert;
-  private SSLContext context;
-  private HostnameVerifier hostnameVerifier;
-  private KeyStoresFactory keystoresFactory;
-
-  private String[] enabledProtocols = null;
-
-  /**
-   * Creates an SSLFactory.
-   *
-   * @param mode SSLFactory mode, client or server.
-   * @param conf Hadoop configuration from where the SSLFactory configuration
-   * will be read.
-   * @throws HasException thrown if an HAS error happened.
-   */
-  public SSLFactory(Mode mode, HasConfig conf) throws HasException {
-    this.conf = conf;
-    if (mode == null) {
-      throw new IllegalArgumentException("mode cannot be NULL");
-    }
-    this.mode = mode;
-    requireClientCert = conf.getBoolean(SSL_REQUIRE_CLIENT_CERT_KEY,
-                                        DEFAULT_SSL_REQUIRE_CLIENT_CERT);
-    HasConfig sslConf = readSSLConfiguration(mode);
-
-    keystoresFactory = new KeyStoresFactory();
-    keystoresFactory.setConf(sslConf);
-
-    enabledProtocols = new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"};
-  }
-
-  private HasConfig readSSLConfiguration(Mode mode) throws HasException {
-    HasConfig sslConf = new HasConfig();
-    sslConf.setBoolean(SSL_REQUIRE_CLIENT_CERT_KEY, requireClientCert);
-    String sslConfResource;
-    if (mode == Mode.CLIENT) {
-      sslConfResource = conf.getString(SSLFactory.SSL_CLIENT_CONF_KEY);
-    } else {
-      sslConfResource = conf.getString(SSLFactory.SSL_SERVER_CONF_KEY);
-    }
-    try {
-      sslConf.addIniConfig(new File(sslConfResource));
-    } catch (IOException e) {
-      throw new HasException(e);
-    }
-    return sslConf;
-  }
-
-  /**
-   * Initializes the factory.
-   *
-   * @throws GeneralSecurityException thrown if an SSL initialization error
-   * happened.
-   * @throws IOException thrown if an IO error happened while reading the SSL
-   * configuration.
-   */
-  public void init() throws GeneralSecurityException, IOException {
-    keystoresFactory.init(mode);
-    context = SSLContext.getInstance("TLS");
-    context.init(keystoresFactory.getKeyManagers(),
-                 keystoresFactory.getTrustManagers(), null);
-    context.getDefaultSSLParameters().setProtocols(enabledProtocols);
-    hostnameVerifier = getHostnameVerifier(conf);
-  }
-
-  private HostnameVerifier getHostnameVerifier(HasConfig conf)
-      throws GeneralSecurityException, IOException {
-    return getHostnameVerifier(StringUtils.toUpperCase(
-        conf.getString(SSL_HOSTNAME_VERIFIER_KEY, "DEFAULT").trim()));
-  }
-
-  public static HostnameVerifier getHostnameVerifier(String verifier)
-    throws GeneralSecurityException, IOException {
-    HostnameVerifier hostnameVerifier;
-    if (verifier.equals("DEFAULT")) {
-      hostnameVerifier = SSLHostnameVerifier.DEFAULT;
-    } else if (verifier.equals("DEFAULT_AND_LOCALHOST")) {
-      hostnameVerifier = SSLHostnameVerifier.DEFAULT_AND_LOCALHOST;
-    } else if (verifier.equals("STRICT")) {
-      hostnameVerifier = SSLHostnameVerifier.STRICT;
-    } else if (verifier.equals("STRICT_IE6")) {
-      hostnameVerifier = SSLHostnameVerifier.STRICT_IE6;
-    } else if (verifier.equals("ALLOW_ALL")) {
-      hostnameVerifier = SSLHostnameVerifier.ALLOW_ALL;
-    } else {
-      throw new GeneralSecurityException("Invalid hostname verifier: "
-          + verifier);
-    }
-    return hostnameVerifier;
-  }
-
-  /**
-   * Releases any resources being used.
-   */
-  public void destroy() {
-    keystoresFactory.destroy();
-  }
-  /**
-   * Returns the SSLFactory KeyStoresFactory instance.
-   *
-   * @return the SSLFactory KeyStoresFactory instance.
-   */
-  public KeyStoresFactory getKeystoresFactory() {
-    return keystoresFactory;
-  }
-
-  /**
-   * Returns a configured SSLEngine.
-   *
-   * @return the configured SSLEngine.
-   * @throws GeneralSecurityException thrown if the SSL engine could not
-   * be initialized.
-   * @throws IOException thrown if and IO error occurred while loading
-   * the server keystore.
-   */
-  public SSLEngine createSSLEngine()
-    throws GeneralSecurityException, IOException {
-    SSLEngine sslEngine = context.createSSLEngine();
-    if (mode == Mode.CLIENT) {
-      sslEngine.setUseClientMode(true);
-    } else {
-      sslEngine.setUseClientMode(false);
-      sslEngine.setNeedClientAuth(requireClientCert);
-    }
-    sslEngine.setEnabledProtocols(enabledProtocols);
-    return sslEngine;
-  }
-
-  /**
-   * Returns a configured SSLServerSocketFactory.
-   *
-   * @return the configured SSLSocketFactory.
-   * @throws GeneralSecurityException thrown if the SSLSocketFactory could not
-   * be initialized.
-   * @throws IOException thrown if and IO error occurred while loading
-   * the server keystore.
-   */
-  public SSLServerSocketFactory createSSLServerSocketFactory()
-    throws GeneralSecurityException, IOException {
-    if (mode != Mode.SERVER) {
-      throw new IllegalStateException("Factory is in CLIENT mode");
-    }
-    return context.getServerSocketFactory();
-  }
-
-  /**
-   * Returns a configured SSLSocketFactory.
-   *
-   * @return the configured SSLSocketFactory.
-   * @throws GeneralSecurityException thrown if the SSLSocketFactory could not
-   * be initialized.
-   * @throws IOException thrown if and IO error occurred while loading
-   * the server keystore.
-   */
-  public SSLSocketFactory createSSLSocketFactory()
-    throws GeneralSecurityException, IOException {
-    if (mode != Mode.CLIENT) {
-      throw new IllegalStateException("Factory is in CLIENT mode");
-    }
-    return context.getSocketFactory();
-  }
-
-  /**
-   * Returns the hostname verifier it should be used in HttpsURLConnections.
-   *
-   * @return the hostname verifier.
-   */
-  public HostnameVerifier getHostnameVerifier() {
-    if (mode != Mode.CLIENT) {
-      throw new IllegalStateException("Factory is in CLIENT mode");
-    }
-    return hostnameVerifier;
-  }
-
-  /**
-   * Returns if client certificates are required or not.
-   *
-   * @return if client certificates are required or not.
-   */
-  public boolean isClientCertRequired() {
-    return requireClientCert;
-  }
-
-  /**
-   * If the given {@link HttpURLConnection} is an {@link HttpsURLConnection}
-   * configures the connection with the {@link SSLSocketFactory} and
-   * {@link HostnameVerifier} of this SSLFactory, otherwise does nothing.
-   *
-   * @param conn the {@link HttpURLConnection} instance to configure.
-   * @return the configured {@link HttpURLConnection} instance.
-   *
-   * @throws IOException if an IO error occurred.
-   */
-  @Override
-  public HttpURLConnection configure(HttpURLConnection conn)
-    throws IOException {
-    if (conn instanceof HttpsURLConnection) {
-      HttpsURLConnection sslConn = (HttpsURLConnection) conn;
-      try {
-        sslConn.setSSLSocketFactory(createSSLSocketFactory());
-      } catch (GeneralSecurityException ex) {
-        throw new IOException(ex);
-      }
-      sslConn.setHostnameVerifier(getHostnameVerifier());
-      conn = sslConn;
-    }
-    return conn;
-  }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLHostnameVerifier.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLHostnameVerifier.java
deleted file mode 100644
index 46b4be75..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/ssl/SSLHostnameVerifier.java
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * $HeadURL$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- * 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.kerby.has.common.ssl;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.kerby.has.common.util.StringUtils;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeSet;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- ************************************************************************
- * Copied from the not-yet-commons-ssl project at
- * http://juliusdavies.ca/commons-ssl/
- * This project is not yet in Apache, but it is Apache 2.0 licensed.
- ************************************************************************
- * Interface for checking if a hostname matches the names stored inside the
- * server's X.509 certificate.  Correctly implements
- * javax.net.ssl.HostnameVerifier, but that interface is not recommended.
- * Instead we added several check() methods that take SSLSocket,
- * or X509Certificate, or ultimately (they all end up calling this one),
- * String.  (It's easier to supply JUnit with Strings instead of mock
- * SSLSession objects!)
- * Our check() methods throw exceptions if the name is
- * invalid, whereas javax.net.ssl.HostnameVerifier just returns true/false.
- *
- * We provide the HostnameVerifier.DEFAULT, HostnameVerifier.STRICT, and
- * HostnameVerifier.ALLOW_ALL implementations.  We also provide the more
- * specialized HostnameVerifier.DEFAULT_AND_LOCALHOST, as well as
- * HostnameVerifier.STRICT_IE6.  But feel free to define your own
- * implementations!
- *
- * Inspired by Sebastian Hauer's original StrictSSLProtocolSocketFactory in the
- * HttpClient "contrib" repository.
- */
-@InterfaceAudience.Private
-@InterfaceStability.Evolving
-@SuppressWarnings("PMD")
-public interface SSLHostnameVerifier extends javax.net.ssl.HostnameVerifier {
-
-    @Override
-    boolean verify(String host, SSLSession session);
-
-    void check(String host, SSLSocket ssl) throws IOException;
-
-    void check(String host, X509Certificate cert) throws SSLException;
-
-    void check(String host, String[] cns, String[] subjectAlts)
-        throws SSLException;
-
-    void check(String[] hosts, SSLSocket ssl) throws IOException;
-
-    void check(String[] hosts, X509Certificate cert) throws SSLException;
-
-
-    /**
-     * Checks to see if the supplied hostname matches any of the supplied CNs
-     * or "DNS" Subject-Alts.  Most implementations only look at the first CN,
-     * and ignore any additional CNs.  Most implementations do look at all of
-     * the "DNS" Subject-Alts. The CNs or Subject-Alts may contain wildcards
-     * according to RFC 2818.
-     *
-     * @param cns         CN fields, in order, as extracted from the X.509
-     *                    certificate.
-     * @param subjectAlts Subject-Alt fields of type 2 ("DNS"), as extracted
-     *                    from the X.509 certificate.
-     * @param hosts       The array of hostnames to verify.
-     * @throws SSLException If verification failed.
-     */
-    void check(String[] hosts, String[] cns, String[] subjectAlts)
-        throws SSLException;
-
-
-    /**
-     * The DEFAULT HostnameVerifier works the same way as Curl and Firefox.
-     *
-     * The hostname must match either the first CN, or any of the subject-alts.
-     * A wildcard can occur in the CN, and in any of the subject-alts.
-     *
-     * The only difference between DEFAULT and STRICT is that a wildcard (such
-     * as "*.foo.com") with DEFAULT matches all subdomains, including
-     * "a.b.foo.com".
-     */
-    SSLHostnameVerifier DEFAULT =
-        new AbstractVerifier() {
-            @Override
-            public void check(final String[] hosts, final String[] cns,
-                                    final String[] subjectAlts)
-                throws SSLException {
-                check(hosts, cns, subjectAlts, false, false);
-            }
-
-            @Override
-            public String toString() {
-                return "DEFAULT";
-            }
-        };
-
-
-    /**
-     * The DEFAULT_AND_LOCALHOST HostnameVerifier works like the DEFAULT
-     * one with one additional relaxation:  a host of "localhost",
-     * "localhost.localdomain", "127.0.0.1", "::1" will always pass, no matter
-     * what is in the server's certificate.
-     */
-    SSLHostnameVerifier DEFAULT_AND_LOCALHOST =
-        new AbstractVerifier() {
-            @Override
-            public void check(final String[] hosts, final String[] cns,
-                                    final String[] subjectAlts)
-                throws SSLException {
-                if (isLocalhost(hosts[0])) {
-                    return;
-                }
-                check(hosts, cns, subjectAlts, false, false);
-            }
-
-            @Override
-            public String toString() {
-                return "DEFAULT_AND_LOCALHOST";
-            }
-        };
-
-    /**
-     * The STRICT HostnameVerifier works the same way as java.net.URL in Sun
-     * Java 1.4, Sun Java 5, Sun Java 6.  It's also pretty close to IE6.
-     * This implementation appears to be compliant with RFC 2818 for dealing
-     * with wildcards.
-     *
-     * The hostname must match either the first CN, or any of the subject-alts.
-     * A wildcard can occur in the CN, and in any of the subject-alts.  The
-     * one divergence from IE6 is how we only check the first CN.  IE6 allows
-     * a match against any of the CNs present.  We decided to follow in
-     * Sun Java 1.4's footsteps and only check the first CN.
-     *
-     * A wildcard such as "*.foo.com" matches only subdomains in the same
-     * level, for example "a.foo.com".  It does not match deeper subdomains
-     * such as "a.b.foo.com".
-     */
-    SSLHostnameVerifier STRICT =
-        new AbstractVerifier() {
-            @Override
-            public void check(final String[] host, final String[] cns,
-                                    final String[] subjectAlts)
-                throws SSLException {
-                check(host, cns, subjectAlts, false, true);
-            }
-
-            @Override
-            public String toString() {
-                return "STRICT";
-            }
-        };
-
-    /**
-     * The STRICT_IE6 HostnameVerifier works just like the STRICT one with one
-     * minor variation:  the hostname can match against any of the CN's in the
-     * server's certificate, not just the first one.  This behaviour is
-     * identical to IE6's behaviour.
-     */
-    SSLHostnameVerifier STRICT_IE6 =
-        new AbstractVerifier() {
-            @Override
-            public void check(final String[] host, final String[] cns,
-                                    final String[] subjectAlts)
-                throws SSLException {
-                check(host, cns, subjectAlts, true, true);
-            }
-
-            @Override
-            public String toString() {
-                return "STRICT_IE6";
-            }
-        };
-
-    /**
-     * The ALLOW_ALL HostnameVerifier essentially turns hostname verification
-     * off.  This implementation is a no-op, and never throws the SSLException.
-     */
-    SSLHostnameVerifier ALLOW_ALL =
-        new AbstractVerifier() {
-            @Override
-            public void check(final String[] host, final String[] cns,
-                                    final String[] subjectAlts) {
-                // Allow everything - so never blowup.
-            }
-
-            @Override
-            public String toString() {
-                return "ALLOW_ALL";
-            }
-        };
-
-    abstract class AbstractVerifier implements SSLHostnameVerifier {
-
-        /**
-         * This contains a list of 2nd-level domains that aren't allowed to
-         * have wildcards when combined with country-codes.
-         * For example: [*.co.uk].
-         * <p/>
-         * The [*.co.uk] problem is an interesting one.  Should we just hope
-         * that CA's would never foolishly allow such a certificate to happen?
-         * Looks like we're the only implementation guarding against this.
-         * Firefox, Curl, Sun Java 1.4, 5, 6 don't bother with this check.
-         */
-        private static final String[] BAD_COUNTRY_2LDS =
-            {"ac", "co", "com", "ed", "edu", "go", "gouv", "gov", "info",
-                "lg", "ne", "net", "or", "org"};
-
-        private static final String[] LOCALHOSTS = {"::1", "127.0.0.1",
-            "localhost",
-            "localhost.localdomain"};
-
-
-        static {
-            // Just in case developer forgot to manually sort the array.  :-)
-            Arrays.sort(BAD_COUNTRY_2LDS);
-            Arrays.sort(LOCALHOSTS);
-        }
-
-        protected AbstractVerifier() {
-        }
-
-        /**
-         * The javax.net.ssl.HostnameVerifier contract.
-         *
-         * @param host    'hostname' we used to create our socket
-         * @param session SSLSession with the remote server
-         * @return true if the host matched the one in the certificate.
-         */
-        @Override
-        public boolean verify(String host, SSLSession session) {
-            try {
-                Certificate[] certs = session.getPeerCertificates();
-                X509Certificate x509 = (X509Certificate) certs[0];
-                check(new String[]{host}, x509);
-                return true;
-            } catch (SSLException e) {
-                return false;
-            }
-        }
-
-        @Override
-        public void check(String host, SSLSocket ssl) throws IOException {
-            check(new String[]{host}, ssl);
-        }
-
-        @Override
-        public void check(String host, X509Certificate cert)
-            throws SSLException {
-            check(new String[]{host}, cert);
-        }
-
-        @Override
-        public void check(String host, String[] cns, String[] subjectAlts)
-            throws SSLException {
-            check(new String[]{host}, cns, subjectAlts);
-        }
-
-        @Override
-        public void check(String[] host, SSLSocket ssl)
-            throws IOException {
-            if (host == null) {
-                throw new NullPointerException("host to verify is null");
-            }
-
-            SSLSession session = ssl.getSession();
-            if (session == null) {
-                // In our experience this only happens under IBM 1.4.x when
-                // spurious (unrelated) certificates show up in the server'
-                // chain.  Hopefully this will unearth the real problem:
-                InputStream in = ssl.getInputStream();
-                in.available();
-                /*
-                  If you're looking at the 2 lines of code above because
-                  you're running into a problem, you probably have two
-                  options:
-
-                    #1.  Clean up the certificate chain that your server
-                         is presenting (e.g. edit "/etc/apache2/server.crt"
-                         or wherever it is your server's certificate chain
-                         is defined).
-
-                                               OR
-
-                    #2.   Upgrade to an IBM 1.5.x or greater JVM, or switch
-                          to a non-IBM JVM.
-                */
-
-                // If ssl.getInputStream().available() didn't cause an
-                // exception, maybe at least now the session is available?
-                session = ssl.getSession();
-                if (session == null) {
-                    // If it's still null, probably a startHandshake() will
-                    // unearth the real problem.
-                    ssl.startHandshake();
-
-                    // Okay, if we still haven't managed to cause an exception,
-                    // might as well go for the NPE.  Or maybe we're okay now?
-                    session = ssl.getSession();
-                }
-            }
-            Certificate[] certs;
-            try {
-                certs = session.getPeerCertificates();
-            } catch (SSLPeerUnverifiedException spue) {
-                InputStream in = ssl.getInputStream();
-                in.available();
-                // Didn't trigger anything interesting?  Okay, just throw
-                // original.
-                throw spue;
-            }
-            X509Certificate x509 = (X509Certificate) certs[0];
-            check(host, x509);
-        }
-
-        @Override
-        public void check(String[] host, X509Certificate cert)
-            throws SSLException {
-            String[] cns = Certificates.getCNs(cert);
-            String[] subjectAlts = Certificates.getDNSSubjectAlts(cert);
-            check(host, cns, subjectAlts);
-        }
-
-        public void check(final String[] hosts, final String[] cns,
-                          final String[] subjectAlts, final boolean ie6,
-                          final boolean strictWithSubDomains)
-            throws SSLException {
-            // Build up lists of allowed hosts For logging/debugging purposes.
-            StringBuilder buf = new StringBuilder(32);
-            buf.append('<');
-            for (int i = 0; i < hosts.length; i++) {
-                String h = hosts[i];
-                h = h != null ? StringUtils.toLowerCase(h.trim()) : "";
-                hosts[i] = h;
-                if (i > 0) {
-                    buf.append('/');
-                }
-                buf.append(h);
-            }
-            buf.append('>');
-            String hostnames = buf.toString();
-            // Build the list of names we're going to check.  Our DEFAULT and
-            // STRICT implementations of the HostnameVerifier only use the
-            // first CN provided.  All other CNs are ignored.
-            // (Firefox, wget, curl, Sun Java 1.4, 5, 6 all work this way).
-            final Set<String> names = new TreeSet<>();
-            if (cns != null && cns.length > 0 && cns[0] != null) {
-                names.add(cns[0]);
-                if (ie6) {
-                    for (int i = 1; i < cns.length; i++) {
-                        names.add(cns[i]);
-                    }
-                }
-            }
-            if (subjectAlts != null) {
-                for (int i = 0; i < subjectAlts.length; i++) {
-                    if (subjectAlts[i] != null) {
-                        names.add(subjectAlts[i]);
-                    }
-                }
-            }
-            if (names.isEmpty()) {
-                String msg = "Certificate for " + hosts[0] + " doesn't contain CN or DNS subjectAlt";
-                throw new SSLException(msg);
-            }
-
-            // StringBuilder for building the error message.
-            buf = new StringBuilder();
-
-            boolean match = false;
-            out:
-            for (Iterator<String> it = names.iterator(); it.hasNext();) {
-                // Don't trim the CN, though!
-                final String cn = StringUtils.toLowerCase(it.next());
-                // Store CN in StringBuffer in case we need to report an error.
-                buf.append(" <");
-                buf.append(cn);
-                buf.append('>');
-                if (it.hasNext()) {
-                    buf.append(" OR");
-                }
-
-                // The CN better have at least two dots if it wants wildcard
-                // action.  It also can't be [*.co.uk] or [*.co.jp] or
-                // [*.org.uk], etc...
-                boolean doWildcard = cn.startsWith("*.")
-                    && cn.lastIndexOf('.') >= 0
-                    && !isIP4Address(cn)
-                    && acceptableCountryWildcard(cn);
-
-                for (int i = 0; i < hosts.length; i++) {
-                    final String hostName =
-                        StringUtils.toLowerCase(hosts[i].trim());
-                    if (doWildcard) {
-                        match = hostName.endsWith(cn.substring(1));
-                        if (match && strictWithSubDomains) {
-                            // If we're in strict mode, then [*.foo.com] is not
-                            // allowed to match [a.b.foo.com]
-                            match = countDots(hostName) == countDots(cn);
-                        }
-                    } else {
-                        match = hostName.equals(cn);
-                    }
-                    if (match) {
-                        break out;
-                    }
-                }
-            }
-            if (!match) {
-                throw new SSLException("hostname in certificate didn't match: " + hostnames + " !=" + buf);
-            }
-        }
-
-        public static boolean isIP4Address(final String cn) {
-            boolean isIP4 = true;
-            String tld = cn;
-            int x = cn.lastIndexOf('.');
-            // We only bother analyzing the characters after the final dot
-            // in the name.
-            if (x >= 0 && x + 1 < cn.length()) {
-                tld = cn.substring(x + 1);
-            }
-            for (int i = 0; i < tld.length(); i++) {
-                if (!Character.isDigit(tld.charAt(0))) {
-                    isIP4 = false;
-                    break;
-                }
-            }
-            return isIP4;
-        }
-
-        public static boolean acceptableCountryWildcard(final String cn) {
-            int cnLen = cn.length();
-            if (cnLen >= 7 && cnLen <= 9) {
-                // Look for the '.' in the 3rd-last position:
-                if (cn.charAt(cnLen - 3) == '.') {
-                    // Trim off the [*.] and the [.XX].
-                    String s = cn.substring(2, cnLen - 3);
-                    // And test against the sorted array of bad 2lds:
-                    int x = Arrays.binarySearch(BAD_COUNTRY_2LDS, s);
-                    return x < 0;
-                }
-            }
-            return true;
-        }
-
-        public static boolean isLocalhost(String host) {
-            host = host != null ? StringUtils.toLowerCase(host.trim()) : "";
-            if (host.startsWith("::1")) {
-                int x = host.lastIndexOf('%');
-                if (x >= 0) {
-                    host = host.substring(0, x);
-                }
-            }
-            int x = Arrays.binarySearch(LOCALHOSTS, host);
-            return x >= 0;
-        }
-
-        /**
-         * Counts the number of dots "." in a string.
-         *
-         * @param s string to count dots from
-         * @return number of dots
-         */
-        public static int countDots(final String s) {
-            int count = 0;
-            for (int i = 0; i < s.length(); i++) {
-                if (s.charAt(i) == '.') {
-                    count++;
-                }
-            }
-            return count;
-        }
-    }
-
-    class Certificates {
-      public static String[] getCNs(X509Certificate cert) {
-        final List<String> cnList = new LinkedList<>();
-        /*
-          Sebastian Hauer's original StrictSSLProtocolSocketFactory used
-          getName() and had the following comment:
-
-             Parses a X.500 distinguished name for the value of the
-             "Common Name" field.  This is done a bit sloppy right
-             now and should probably be done a bit more according to
-             <code>RFC 2253</code>.
-
-           I've noticed that toString() seems to do a better job than
-           getName() on these X500Principal objects, so I'm hoping that
-           addresses Sebastian's concern.
-
-           For example, getName() gives me this:
-           1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d
-
-           whereas toString() gives me this:
-           EMAILADDRESS=juliusdavies@cucbc.com
-
-           Looks like toString() even works with non-ascii domain names!
-           I tested it with "&#x82b1;&#x5b50;.co.jp" and it worked fine.
-          */
-        String subjectPrincipal = cert.getSubjectX500Principal().toString();
-        StringTokenizer st = new StringTokenizer(subjectPrincipal, ",");
-        while (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            int x = tok.indexOf("CN=");
-            if (x >= 0) {
-                cnList.add(tok.substring(x + 3));
-            }
-        }
-        if (!cnList.isEmpty()) {
-            String[] cns = new String[cnList.size()];
-            cnList.toArray(cns);
-            return cns;
-        } else {
-            return null;
-        }
-      }
-
-
-      /**
-       * Extracts the array of SubjectAlt DNS names from an X509Certificate.
-       * Returns null if there aren't any.
-       *
-       * Note:  Java doesn't appear able to extract international characters
-       * from the SubjectAlts.  It can only extract international characters
-       * from the CN field.
-       *
-       * (Or maybe the version of OpenSSL I'm using to test isn't storing the
-       * international characters correctly in the SubjectAlts?).
-       *
-       * @param cert X509Certificate
-       * @return Array of SubjectALT DNS names stored in the certificate.
-       */
-      public static String[] getDNSSubjectAlts(X509Certificate cert) {
-          final List<String> subjectAltList = new LinkedList<>();
-          Collection<List<?>> c = null;
-          try {
-              c = cert.getSubjectAlternativeNames();
-          } catch (CertificateParsingException cpe) {
-              // Should probably log.debug() this?
-              cpe.printStackTrace();
-          }
-          if (c != null) {
-              Iterator<List<?>> it = c.iterator();
-              while (it.hasNext()) {
-                  List<?> list = it.next();
-                  int type = ((Integer) list.get(0)).intValue();
-                  // If type is 2, then we've got a dNSName
-                  if (type == 2) {
-                      String s = (String) list.get(1);
-                      subjectAltList.add(s);
-                  }
-              }
-          }
-          if (!subjectAltList.isEmpty()) {
-              String[] subjectAlts = new String[subjectAltList.size()];
-              subjectAltList.toArray(subjectAlts);
-              return subjectAlts;
-          } else {
-              return null;
-          }
-      }
-    }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/ConnectionConfigurator.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/ConnectionConfigurator.java
deleted file mode 100644
index c913e59f..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/ConnectionConfigurator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Licensed 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. See accompanying LICENSE file.
- */
-package org.apache.kerby.has.common.util;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Interface to configure  {@link HttpURLConnection} created by
- * {@link org.apache.kerby.has.common.spnego.AuthenticatedURL} instances.
- */
-public interface ConnectionConfigurator {
-
-  /**
-   * Configures the given {@link HttpURLConnection} instance.
-   *
-   * @param conn the {@link HttpURLConnection} instance to configure.
-   * @return the configured {@link HttpURLConnection} instance.
-   * 
-   * @throws IOException if an IO error occurred.
-   */
-  HttpURLConnection configure(HttpURLConnection conn) throws IOException;
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java
deleted file mode 100644
index 3a0342cb..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java
+++ /dev/null
@@ -1,114 +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.kerby.has.common.util;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.kerby.has.common.util.PlatformName.IBM_JAVA;
-
-/**
- * JAAS utilities for Has login.
- */
-public class HasJaasLoginUtil {
-    public static final Logger LOG = LoggerFactory.getLogger(HasJaasLoginUtil.class);
-
-    public static final boolean ENABLE_DEBUG = true;
-
-    private static String getKrb5LoginModuleName() {
-        return IBM_JAVA
-            ? "com.ibm.security.auth.module.Krb5LoginModule"
-            : "org.apache.kerby.has.client.HasLoginModule";
-    }
-
-    /**
-     * Log a user in from a tgt ticket.
-     *
-     * @param hadoopSecurityHas the params for authentication
-     * @return Subject the subject
-     * @throws IOException if an IO error occurred.
-     */
-    public static synchronized Subject loginUserFromTgtTicket(String hadoopSecurityHas) throws IOException {
-
-        TICKET_KERBEROS_OPTIONS.put("hadoopSecurityHas", hadoopSecurityHas);
-        Subject subject = new Subject();
-        Configuration conf = new HasJaasConf();
-        String confName = "ticket-kerberos";
-        LoginContext loginContext = null;
-        try {
-            loginContext = new LoginContext(confName, subject, null, conf);
-        } catch (LoginException e) {
-            throw new IOException("Fail to create LoginContext for " + e);
-        }
-        try {
-            loginContext.login();
-            LOG.info("Login successful for user "
-                + subject.getPrincipals().iterator().next().getName());
-        } catch (LoginException e) {
-            throw new IOException("Login failure for " + e);
-        }
-        return loginContext.getSubject();
-    }
-
-    /**
-     * Has Jaas config.
-     */
-    static class HasJaasConf extends Configuration {
-        @Override
-        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-
-            return new AppConfigurationEntry[]{
-                TICKET_KERBEROS_LOGIN};
-        }
-    }
-
-    private static final Map<String, String> BASIC_JAAS_OPTIONS =
-        new HashMap<>();
-
-    static {
-        String jaasEnvVar = System.getenv("HADOOP_JAAS_DEBUG");
-        if (jaasEnvVar != null && "true".equalsIgnoreCase(jaasEnvVar)) {
-            BASIC_JAAS_OPTIONS.put("debug", String.valueOf(ENABLE_DEBUG));
-        }
-    }
-
-    private static final Map<String, String> TICKET_KERBEROS_OPTIONS =
-        new HashMap<>();
-
-    static {
-        TICKET_KERBEROS_OPTIONS.put("doNotPrompt", "true");
-        TICKET_KERBEROS_OPTIONS.put("useTgtTicket", "true");
-        TICKET_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS);
-    }
-
-    private static final AppConfigurationEntry TICKET_KERBEROS_LOGIN =
-        new AppConfigurationEntry(getKrb5LoginModuleName(),
-            AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL,
-            TICKET_KERBEROS_OPTIONS);
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
deleted file mode 100644
index 8b88c5dd..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
+++ /dev/null
@@ -1,96 +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.kerby.has.common.util;
-
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-
-public class HasUtil {
-
-    /**
-     * Get has configuration
-     * @param hasConfFile configuration directory
-     * @return has configuration
-     * @throws HasException the HAS exception
-     */
-    public static HasConfig getHasConfig(File hasConfFile) throws HasException {
-
-        if (hasConfFile.exists()) {
-            HasConfig hasConfig = new HasConfig();
-            try {
-                hasConfig.addIniConfig(hasConfFile);
-            } catch (IOException e) {
-                throw new HasException("Can not load the has configuration file "
-                    + hasConfFile.getAbsolutePath());
-            }
-            return hasConfig;
-        } else {
-            throw new HasException(hasConfFile.getName() + " not found in "
-                + hasConfFile.getParent() + ". ");
-        }
-    }
-
-    public static void setEnableConf(File hasConfFile, String value)
-            throws HasException, IOException {
-        String oldValue = getHasConfig(hasConfFile).getEnableConf();
-        if (oldValue == null) {
-            throw new HasException("Please set enable_conf in has-server.conf.");
-        }
-        if (oldValue.equals(value)) {
-            return;
-        }
-        try {
-            StringBuilder sb = new StringBuilder();
-            try (BufferedReader bf = new BufferedReader(new FileReader(hasConfFile))) {
-                String tempString;
-                while ((tempString = bf.readLine()) != null) {
-                    if (tempString.trim().startsWith("enable_conf")) {
-                        tempString = tempString.replace(oldValue, value);
-                    }
-                    sb.append(tempString + "\n");
-                }
-            }
-            try (PrintStream ps = new PrintStream(new FileOutputStream(hasConfFile))) {
-                ps.print(sb.toString());
-            }
-        } catch (FileNotFoundException e) {
-            throw new HasException("Can not load the has configuration file "
-                    + hasConfFile.getAbsolutePath());
-        }
-    }
-
-    public static EncryptionKey getClientKey(String userName, String passPhrase,
-                                             EncryptionType type) throws KrbException {
-        EncryptionKey clientKey = EncryptionHandler.string2Key(userName,
-            passPhrase, type);
-        return clientKey;
-    }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/PlatformName.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/PlatformName.java
deleted file mode 100644
index f4b8bc99..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/PlatformName.java
+++ /dev/null
@@ -1,78 +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.kerby.has.common.util;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * A helper class for getting build-info of the java-vm.
- *
- */
-@InterfaceAudience.LimitedPrivate({"HBase"})
-@InterfaceStability.Unstable
-public class PlatformName {
-  /**
-   * The complete platform 'name' to identify the platform as
-   * per the java-vm.
-   */
-  public static final String PLATFORM_NAME =
-      (System.getProperty("os.name").startsWith("Windows")
-      ? System.getenv("os") : System.getProperty("os.name"))
-      + "-" + System.getProperty("os.arch")
-      + "-" + System.getProperty("sun.arch.data.model");
-
-  /**
-   * The java vendor name used in this platform.
-   */
-  public static final String JAVA_VENDOR_NAME = System.getProperty("java.vendor");
-
-  /**
-   * A public static variable to indicate the current java vendor is
-   * IBM and the type is Java Technology Edition which provides its
-   * own implementations of many security packages and Cipher suites.
-   * Note that these are not provided in Semeru runtimes:
-   * See https://developer.ibm.com/languages/java/semeru-runtimes/
-   * The class used is present in any supported IBM JTE Runtimes.
-   */
-  public static final boolean IBM_JAVA = shouldUseIbmSecurity();
-
-  private static boolean shouldUseIbmSecurity() {
-    if (!JAVA_VENDOR_NAME.contains("IBM")) {
-      return false;
-    }
-
-    try {
-      Class.forName("com.ibm.security.auth.module.JAASLoginModule",
-        false,
-        PlatformName.class.getClassLoader());
-      return true;
-    } catch (Exception ignored) { }
-
-    return false;
-  }
-
-  public static void main(String[] args) {
-    System.out.println(PLATFORM_NAME);
-  }
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/StringUtils.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/StringUtils.java
deleted file mode 100644
index b9c323d5..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/StringUtils.java
+++ /dev/null
@@ -1,55 +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.kerby.has.common.util;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-
-import java.util.Locale;
-
-/**
- * General string utils
- */
-@InterfaceAudience.Private
-@InterfaceStability.Unstable
-public class StringUtils {
-
-  /**
-   * Converts all of the characters in this String to lower case with
-   * Locale.ENGLISH.
-   *
-   * @param str  string to be converted
-   * @return     the str, converted to lowercase.
-   */
-  public static String toLowerCase(String str) {
-    return str.toLowerCase(Locale.ENGLISH);
-  }
-
-  /**
-   * Converts all of the characters in this String to upper case with
-   * Locale.ENGLISH.
-   *
-   * @param str  string to be converted
-   * @return     the str, converted to uppercase.
-   */
-  public static String toUpperCase(String str) {
-    return str.toUpperCase(Locale.ENGLISH);
-  }
-
-}
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/URLConnectionFactory.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/URLConnectionFactory.java
deleted file mode 100644
index 61a3b2ad..00000000
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/URLConnectionFactory.java
+++ /dev/null
@@ -1,203 +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.kerby.has.common.util;
-
-import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.spnego.AuthenticatedURL;
-import org.apache.kerby.has.common.spnego.AuthenticationException;
-import org.apache.kerby.has.common.spnego.KerberosHasAuthenticator;
-import org.apache.kerby.has.common.ssl.SSLFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.GeneralSecurityException;
-
-/**
- * Borrow the class from Apache Hadoop
- */
-
-/**
- * Utilities for handling URLs
- */
-@InterfaceStability.Unstable
-public class URLConnectionFactory {
-  private static final Logger LOG = LoggerFactory
-      .getLogger(URLConnectionFactory.class);
-
-  /**
-   * Timeout for socket connects and reads
-   */
-   // 1 minute
-  public static final int DEFAULT_SOCKET_TIMEOUT = 60 * 1000;
-  private final ConnectionConfigurator connConfigurator;
-
-  private static final ConnectionConfigurator DEFAULT_TIMEOUT_CONN_CONFIGURATOR
-      = new ConnectionConfigurator() {
-        @Override
-        public HttpURLConnection configure(HttpURLConnection conn)
-            throws IOException {
-          URLConnectionFactory.setTimeouts(conn,
-                                           DEFAULT_SOCKET_TIMEOUT,
-                                           DEFAULT_SOCKET_TIMEOUT);
-          return conn;
-        }
-      };
-
-  /**
-   * The URLConnectionFactory that sets the default timeout and it only trusts
-   * Java's SSL certificates.
-   */
-  public static final URLConnectionFactory DEFAULT_SYSTEM_CONNECTION_FACTORY =
-      new URLConnectionFactory(DEFAULT_TIMEOUT_CONN_CONFIGURATOR);
-
-  /**
-   * Construct a new URLConnectionFactory based on the configuration. It will
-   * try to load SSL certificates when it is specified.
-   * @param conf The has config
-   * @return URLConnectionFactory The URL connection factory.
-   */
-  public static URLConnectionFactory newDefaultURLConnectionFactory(HasConfig conf) {
-    ConnectionConfigurator conn;
-    try {
-      conn = newSslConnConfigurator(DEFAULT_SOCKET_TIMEOUT, conf);
-    } catch (Exception e) {
-      LOG.debug(
-          "Cannot load customized ssl related configuration. Fallback to system-generic settings.",
-          e);
-      conn = DEFAULT_TIMEOUT_CONN_CONFIGURATOR;
-    }
-    return new URLConnectionFactory(conn);
-  }
-
-  URLConnectionFactory(ConnectionConfigurator connConfigurator) {
-    this.connConfigurator = connConfigurator;
-  }
-
-  /**
-   * Create a new ConnectionConfigurator for SSL connections
-   */
-  private static ConnectionConfigurator newSslConnConfigurator(
-      final int defaultTimeout, HasConfig conf)
-      throws IOException, GeneralSecurityException, HasException {
-    final SSLFactory factory;
-    final SSLSocketFactory sf;
-    final HostnameVerifier hv;
-    final int connectTimeout;
-    final int readTimeout;
-
-    factory = new SSLFactory(SSLFactory.Mode.CLIENT, conf);
-    factory.init();
-    sf = factory.createSSLSocketFactory();
-    hv = factory.getHostnameVerifier();
-
-    connectTimeout = defaultTimeout;
-
-    readTimeout = defaultTimeout;
-
-    return new ConnectionConfigurator() {
-      @Override
-      public HttpURLConnection configure(HttpURLConnection conn)
-          throws IOException {
-        if (conn instanceof HttpsURLConnection) {
-          HttpsURLConnection c = (HttpsURLConnection) conn;
-          c.setSSLSocketFactory(sf);
-          c.setHostnameVerifier(hv);
-        }
-        URLConnectionFactory.setTimeouts(conn, connectTimeout, readTimeout);
-        return conn;
-      }
-    };
-  }
-
-  /**
-   * Opens a url with read and connect timeouts
-   *
-   * @param url
-   *          to open
-   * @return URLConnection
-   * @throws IOException thrown if an IO error happened while opening connection
-   */
-  public URLConnection openConnection(URL url) throws IOException {
-    try {
-      return openConnection(url, false, null);
-    } catch (AuthenticationException e) {
-      // Unreachable
-      LOG.error("Open connection {} failed", url, e);
-      return null;
-    }
-  }
-
-  /**
-   * Opens a url with read and connect timeouts
-   *
-   * @param url
-   *          URL to open
-   * @param isSpnego
-   *          whether the url should be authenticated via SPNEGO
-   * @param  hasConfig
-   *          has config to open
-   * @return URLConnection the url connection
-   * @throws IOException thrown if an IO error happened while opening connection
-   * @throws AuthenticationException thrown if an authentication error happened
-   * while opening connection
-   */
-  public URLConnection openConnection(URL url, boolean isSpnego, HasConfig hasConfig)
-      throws IOException, AuthenticationException {
-    if (isSpnego && hasConfig != null) {
-      LOG.debug("open AuthenticatedURL connection {}", url);
-      final AuthenticatedURL.Token authToken = new AuthenticatedURL.Token();
-      return new AuthenticatedURL(new KerberosHasAuthenticator(hasConfig.getAdminKeytab(),
-          hasConfig.getAdminKeytabPrincipal()),
-          connConfigurator).openConnection(url, authToken);
-    } else {
-      LOG.debug("open URL connection");
-      URLConnection connection = url.openConnection();
-      if (connection instanceof HttpURLConnection) {
-        connConfigurator.configure((HttpURLConnection) connection);
-      }
-      return connection;
-    }
-  }
-
-  /**
-   * Sets timeout parameters on the given URLConnection.
-   *
-   * @param connection
-   *          URLConnection to set
-   * @param connectTimeout
-   *          the connection timeout of the connection.
-   * @param  readTimeout
-   *          the read timeout of the connection
-   */
-  private static void setTimeouts(URLConnection connection,
-                                  int connectTimeout,
-                                  int readTimeout) {
-    connection.setConnectTimeout(connectTimeout);
-    connection.setReadTimeout(readTimeout);
-  }
-}
diff --git a/has-project/has-server-plugin/pom.xml b/has-project/has-server-plugin/pom.xml
deleted file mode 100644
index b399c229..00000000
--- a/has-project/has-server-plugin/pom.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed 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. See accompanying LICENSE file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>has-project</artifactId>
-        <groupId>org.apache.kerby</groupId>
-        <version>2.1.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>has-server-plugin</artifactId>
-    <name>HAS Server Plugin</name>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.kerby</groupId>
-            <artifactId>has-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.kerby</groupId>
-            <artifactId>has-server</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-dbutils</groupId>
-            <artifactId>commons-dbutils</artifactId>
-            <version>${commons-dbutils.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ini4j</groupId>
-            <artifactId>ini4j</artifactId>
-            <version>${ini4j.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.directory.api</groupId>
-            <artifactId>api-ldap-client-api</artifactId>
-            <version>${ldap.api.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.directory.api</groupId>
-            <artifactId>api-ldap-codec-standalone</artifactId>
-            <version>${ldap.api.version}</version>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPServerPlugin.java b/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPServerPlugin.java
deleted file mode 100755
index 513e21d8..00000000
--- a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPServerPlugin.java
+++ /dev/null
@@ -1,68 +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.kerby.has.plugins.server.ldap;
-
-import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.server.AbstractHasServerPlugin;
-import org.apache.kerby.has.server.HasAuthenException;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-
-public class LDAPServerPlugin extends AbstractHasServerPlugin {
-    public static final Logger LOG = LoggerFactory.getLogger(LDAPServerPlugin.class);
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getLoginType() {
-        return "LDAP";
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void doAuthenticate(AuthToken userToken, AuthToken authToken) throws HasAuthenException {
-
-        String user = (String) userToken.getAttributes().get("ldap_user");
-        String pwd = (String) userToken.getAttributes().get("ldap_pwd");
-        if (user == null || pwd == null) {
-            LOG.error("LDAP: user or pwd is null");
-            throw new HasAuthenException("LDAP: user or pwd is null");
-        }
-
-        try {
-            if (LDAPUtils.doUserAuth(user, pwd)) {
-                authToken.setIssuer(userToken.getIssuer());
-                authToken.setSubject(user);
-                authToken.setExpirationTime(userToken.getExpiredTime());
-                authToken.addAttribute("passPhrase", pwd);
-            } else {
-                throw new HasAuthenException("LDAP user auth failed");
-            }
-        } catch (HasException | IOException | LdapInvalidAttributeValueException e) {
-            throw new HasAuthenException("LDAP user auth failed. " + e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPUtils.java b/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPUtils.java
deleted file mode 100644
index d0bdcd48..00000000
--- a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/LDAPUtils.java
+++ /dev/null
@@ -1,88 +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.kerby.has.plugins.server.ldap;
-
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
-import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.api.ldap.model.name.Rdn;
-import org.apache.directory.api.ldap.model.password.PasswordUtil;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.plugins.server.ldap.conf.LDAPServerConf;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-
-public class LDAPUtils {
-    public static final Logger LOG = LoggerFactory.getLogger(LDAPUtils.class);
-
-    private static String ldapServerConfDir = "/etc/has/";
-    private static LDAPServerConf ldapServerConf = null;
-    static {
-        try {
-            ldapServerConf = new LDAPServerConf(ldapServerConfDir);
-        } catch (Exception e) {
-            LOG.error("load conf failed,", e);
-        }
-    }
-
-    public static boolean doUserAuth(String user, String pwd)
-        throws HasException, IOException, LdapInvalidAttributeValueException {
-        LdapNetworkConnection connection = new LdapNetworkConnection(
-            ldapServerConf.getHost(), Integer.parseInt(ldapServerConf.getPort()));
-        try {
-            connection.bind(ldapServerConf.getBindDN(), ldapServerConf.getBindPwd());
-        } catch (LdapException e) {
-            connection.close();
-            throw new HasException("Failed to bind. " + e.getMessage());
-        }
-        Dn dn;
-        try {
-            dn = new Dn(new Rdn(ldapServerConf.getUserNameAttr(), user),
-                new Dn(ldapServerConf.getBaseDN()));
-        } catch (LdapInvalidDnException e) {
-            connection.close();
-            throw new HasException(e.getMessage());
-        }
-        Entry entry;
-        try {
-            entry = connection.lookup(dn);
-        } catch (LdapException e) {
-            throw new HasException(e.getMessage());
-        } finally {
-            connection.close();
-        }
-
-        if (entry == null) {
-            throw new HasException("Please check your user name: " + user);
-        }
-        try {
-            if (PasswordUtil.compareCredentials(pwd.getBytes(), entry.get("userpassword").getBytes())) {
-                return true;
-            } else {
-                throw new HasException("Wrong user password.");
-            }
-        } catch (LdapInvalidAttributeValueException e) {
-            throw new HasException(e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/conf/LDAPServerConf.java b/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/conf/LDAPServerConf.java
deleted file mode 100644
index fbea0360..00000000
--- a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/ldap/conf/LDAPServerConf.java
+++ /dev/null
@@ -1,95 +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.kerby.has.plugins.server.ldap.conf;
-
-import org.ini4j.Wini;
-
-import java.io.File;
-
-public class LDAPServerConf {
-
-    private String userNameAttr = "sn";
-    private String baseDN = null;
-    private String bindDN = null;
-    private String bindPwd = null;
-    private String host;
-    private String port;
-
-    public LDAPServerConf(String confDir) throws Exception {
-        if (confDir == null) {
-            throw new RuntimeException("ldap server conf dir is null");
-        }
-
-        String confFile = confDir + "/ldap-server.ini";
-        Wini ini = new Wini(new File(confFile));
-        host = ini.get("ldap", "host");
-        port = ini.get("ldap", "port");
-        userNameAttr = ini.get("users", "user_name_attr");
-        baseDN = ini.get("ldap", "base_dn");
-        bindDN = ini.get("ldap", "bind_dn");
-        bindPwd = ini.get("ldap", "bind_password");
-    }
-
-    public String getHost() {
-        return host;
-    }
-
-    public void setHost(String host) {
-        this.host = host;
-    }
-
-    public String getPort() {
-        return port;
-    }
-
-    public void setPort(String port) {
-        this.port = port;
-    }
-
-    public String getUserNameAttr() {
-        return userNameAttr;
-    }
-
-    public void setUserNameAttr(String userNameAttr) {
-        this.userNameAttr = userNameAttr;
-    }
-
-    public String getBaseDN() {
-        return baseDN;
-    }
-
-    public void setBaseDN(String baseDN) {
-        this.baseDN = baseDN;
-    }
-
-    public String getBindDN() {
-        return bindDN;
-    }
-
-    public void setBindDN(String bindDN) {
-        this.bindDN = bindDN;
-    }
-
-    public String getBindPwd() {
-        return bindPwd;
-    }
-
-    public void setBindPwd(String bindPwd) {
-        this.bindPwd = bindPwd;
-    }
-}
diff --git a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java b/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
deleted file mode 100644
index e262c9f4..00000000
--- a/has-project/has-server-plugin/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
+++ /dev/null
@@ -1,145 +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.kerby.has.plugins.server.mysql;
-
-import org.apache.commons.dbutils.DbUtils;
-import org.apache.kerby.has.server.AbstractHasServerPlugin;
-import org.apache.kerby.has.server.HasAuthenException;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.sql.ResultSet;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.util.Date;
-
-public class MySQLHasServerPlugin extends AbstractHasServerPlugin {
-    private static final Logger LOG = LoggerFactory.getLogger(MySQLHasServerPlugin.class);
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getLoginType() {
-        return "MySQL";
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void doAuthenticate(AuthToken userToken, AuthToken authToken)
-        throws HasAuthenException {
-
-        // Check if the token is expired
-        Date expiredTime = userToken.getExpiredTime();
-        Date now = new Date();
-        if (now.after(expiredTime)) {
-            LOG.error("Authentication failed: token is expired.");
-            throw new HasAuthenException("Authentication failed: token is expired.");
-        }
-
-        String user = (String) userToken.getAttributes().get("user");
-        String secret = (String) userToken.getAttributes().get("secret");
-
-        String mysqlUrl = System.getenv("mysqlUrl");
-        if (mysqlUrl == null || mysqlUrl.isEmpty()) {
-            throw new HasAuthenException("Please set the mysqlUrl.");
-        }
-        mysqlUrl = mysqlUrl.replace("jdbc:mysql:", "jdbc:mysql:thin:");
-        String mysqlUser = System.getenv("mysqlUser");
-        if (mysqlUser == null || mysqlUser.isEmpty()) {
-            throw new HasAuthenException("Please set the mysqlUser.");
-        }
-        String mysqlPasswd = System.getenv("mysqlPasswd");
-        if (mysqlPasswd == null || mysqlPasswd.isEmpty()) {
-            throw new HasAuthenException("Please set the mysqlPasswd.");
-        }
-        Connection connection = startConnection(mysqlUrl, mysqlUser, mysqlPasswd);
-
-        ResultSet res = null;
-        PreparedStatement preStm = null;
-        try {
-            String stm = "SELECT COUNT(*) FROM `has_user` WHERE user_name = ? AND pass_word = ?";
-            preStm = connection.prepareStatement(stm);
-            preStm.setString(1, user);
-            preStm.setString(2, secret);
-            res = preStm.executeQuery();
-
-            if (res.next() && res.getInt(1) > 0) {
-                LOG.debug("UserName: {}", user);
-            } else {
-                String sql = "SELECT COUNT(*) FROM `has_user` WHERE user_name = ?";
-                preStm = connection.prepareStatement(sql);
-                preStm.setString(1, user);
-                res = preStm.executeQuery();
-                if (res.next() && res.getInt(1) > 0) {
-                    throw new HasAuthenException("Authentication failed. "
-                            + "Incorrect password.");
-                } else if (!res.next()) {
-                    throw new HasAuthenException("Authentication failed. "
-                            + "Incorrect userName: " + user);
-                } else {
-                    throw new HasAuthenException("Authentication failed. "
-                            + "Please check your userName and password.");
-                }
-            }
-        } catch (SQLException e) {
-            LOG.error("Failed.");
-            LOG.error("Error code: " + e.getErrorCode());
-            LOG.error("Error message: " + e.getMessage());
-            throw new HasAuthenException("Authentication failed." + e.getMessage());
-        } finally {
-            DbUtils.closeQuietly(preStm);
-            DbUtils.closeQuietly(res);
-            DbUtils.closeQuietly(connection);
-        }
-
-        authToken.setIssuer(userToken.getIssuer());
-        authToken.setSubject(user);
-        authToken.setExpirationTime(userToken.getExpiredTime());
-
-        authToken.addAttribute("userName", user);
-        authToken.addAttribute("passPhrase", user + secret);
-    }
-
-    /**
-     * Start the MySQL connection.
-     */
-    private Connection startConnection(String url, String user,
-        String password) throws HasAuthenException {
-        Connection connection;
-        try {
-            Class.forName("org.drizzle.jdbc.DrizzleDriver");
-            connection = DriverManager.getConnection(url, user, password);
-            if (!connection.isClosed()) {
-                LOG.info("Succeeded in connecting to MySQL.");
-            }
-        } catch (ClassNotFoundException e) {
-            throw new HasAuthenException("JDBC Driver Class not found. ", e);
-        } catch (SQLException e) {
-            throw new HasAuthenException("Failed to connect to MySQL. "
-                    + "Please check MySQL URL, username and password. ", e);
-        }
-
-        return connection;
-    }
-}
diff --git a/has-project/has-server-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.server.HasServerPlugin b/has-project/has-server-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.server.HasServerPlugin
deleted file mode 100644
index a7757bad..00000000
--- a/has-project/has-server-plugin/src/main/resources/META-INF/services/org.apache.kerby.has.server.HasServerPlugin
+++ /dev/null
@@ -1,17 +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.
-
-org.apache.kerby.has.plugins.server.mysql.MySQLHasServerPlugin
-org.apache.kerby.has.plugins.server.ldap.LDAPServerPlugin
diff --git a/has-project/has-server-plugin/src/test/java/org/apache/kerby/has/plugins/server/TestHasServerPluginRegistry.java b/has-project/has-server-plugin/src/test/java/org/apache/kerby/has/plugins/server/TestHasServerPluginRegistry.java
deleted file mode 100644
index 3d2d7fe8..00000000
--- a/has-project/has-server-plugin/src/test/java/org/apache/kerby/has/plugins/server/TestHasServerPluginRegistry.java
+++ /dev/null
@@ -1,43 +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.kerby.has.plugins.server;
-
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.server.HasServerPluginRegistry;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Set;
-
-public class TestHasServerPluginRegistry {
-
-  @Test
-  public void testInit() {
-    Set<String> pluginsNames = HasServerPluginRegistry.registeredPlugins();
-    Assert.assertTrue(pluginsNames.size() > 0);
-  }
-
-  @Test
-  public void testCreatePlugin() throws HasException {
-    Assert.assertTrue(HasServerPluginRegistry.createPlugin("MySQL") != null);
-    Set<String> pluginNames = HasServerPluginRegistry.registeredPlugins();
-    for (String name : pluginNames) {
-      HasServerPluginRegistry.createPlugin(name);
-    }
-  }
-}
diff --git a/has-project/has-server/pom.xml b/has-project/has-server/pom.xml
deleted file mode 100644
index e3e596b3..00000000
--- a/has-project/has-server/pom.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed 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. See accompanying LICENSE file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <parent>
-    <artifactId>has-project</artifactId>
-    <groupId>org.apache.kerby</groupId>
-    <version>2.1.0-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>has-server</artifactId>
-  <name>HAS Server</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerby-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-identity</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-server-api-all</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>kerby-kdc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>json-backend</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>mysql-backend</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.h2database</groupId>
-      <artifactId>h2</artifactId>
-      <version>${h2.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>token-provider</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <version>${hadoop.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kerby</groupId>
-      <artifactId>has-common</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcprov-jdk15on</artifactId>
-      <version>${bouncycastle.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-dbutils</groupId>
-      <artifactId>commons-dbutils</artifactId>
-      <version>${commons-dbutils.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.drizzle.jdbc</groupId>
-      <artifactId>drizzle-jdbc</artifactId>
-      <version>${drizzle-jdbc.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-client</artifactId>
-      <version>${jersey.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.glassfish.jersey.core</groupId>
-      <artifactId>jersey-common</artifactId>
-      <version>2.39</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/AbstractHasServerPlugin.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/AbstractHasServerPlugin.java
deleted file mode 100644
index f9d0b33d..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/AbstractHasServerPlugin.java
+++ /dev/null
@@ -1,45 +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.kerby.has.server;
-
-import org.apache.kerby.kerberos.kerb.KrbRuntime;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractHasServerPlugin implements HasServerPlugin {
-
-    public static final Logger LOG = LoggerFactory.getLogger(AbstractHasServerPlugin.class);
-
-    protected abstract void doAuthenticate(AuthToken userToken, AuthToken authToken)
-        throws HasAuthenException;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public AuthToken authenticate(AuthToken userToken) throws HasAuthenException {
-
-        AuthToken authToken = KrbRuntime.getTokenProvider("JWT").createTokenFactory().createToken();
-
-        doAuthenticate(userToken, authToken);
-
-        return authToken;
-    }
-
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasAuthenException.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasAuthenException.java
deleted file mode 100644
index 57342b14..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasAuthenException.java
+++ /dev/null
@@ -1,37 +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
- * <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.kerby.has.server;
-
-import org.apache.kerby.has.common.HasException;
-
-public class HasAuthenException extends HasException {
-    private static final long serialVersionUID = 171016915395892939L;
-
-    public HasAuthenException(Throwable cause) {
-        super(cause);
-    }
-
-    public HasAuthenException(String message) {
-        super(message);
-    }
-
-    public HasAuthenException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
deleted file mode 100644
index bc4eaf7d..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
+++ /dev/null
@@ -1,745 +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.kerby.has.server;
-
-import org.apache.commons.dbutils.DbUtils;
-import org.apache.hadoop.http.HttpConfig;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.has.server.web.WebConfigKey;
-import org.apache.kerby.has.server.web.WebServer;
-import org.apache.kerby.kerberos.kdc.impl.NettyKdcServerImpl;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadmin;
-import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadminImpl;
-import org.apache.kerby.kerberos.kerb.client.ClientUtil;
-import org.apache.kerby.kerberos.kerb.client.KrbConfig;
-import org.apache.kerby.kerberos.kerb.client.KrbSetting;
-import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.server.KdcServer;
-import org.apache.kerby.kerberos.kerb.server.KdcUtil;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.apache.kerby.util.IOUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * The HAS KDC server implementation.
- */
-public class HasServer {
-    public static final Logger LOG = LoggerFactory.getLogger(HasServer.class);
-
-    private static HasServer server = null;
-
-    private KrbSetting krbSetting;
-    private KdcServer kdcServer;
-    private WebServer webServer;
-    private File confDir;
-    private File workDir;
-    private String kdcHost;
-    private HasConfig hasConfig;
-
-    public HasServer(File confDir) throws KrbException {
-        this.confDir = confDir;
-    }
-
-    private void setConfDir(File confDir) {
-        this.confDir = confDir;
-    }
-
-    public File getConfDir() {
-        return confDir;
-    }
-
-    public File getWorkDir() {
-        return workDir;
-    }
-
-    public void setWorkDir(File workDir) {
-        this.workDir = workDir;
-    }
-
-    public void setKdcHost(String host) {
-        this.kdcHost = host;
-    }
-
-    public String getKdcHost() {
-        return kdcHost;
-    }
-
-    public KrbSetting getKrbSetting() {
-        return krbSetting;
-    }
-
-    public KdcServer getKdcServer() {
-        return kdcServer;
-    }
-
-    public WebServer getWebServer() {
-        return webServer;
-    }
-
-    public void setWebServer(WebServer webServer) {
-        this.webServer = webServer;
-    }
-
-    public void startKdcServer() throws HasException {
-        BackendConfig backendConfig;
-        try {
-            backendConfig = KdcUtil.getBackendConfig(getConfDir());
-        } catch (KrbException e) {
-            throw new HasException("Failed to get backend config. " + e);
-        }
-        String backendJar = backendConfig.getString("kdc_identity_backend");
-        if (backendJar.equals("org.apache.kerby.kerberos.kdc.identitybackend.MySQLIdentityBackend")) {
-            updateKdcConf();
-        }
-        try {
-            kdcServer = new KdcServer(confDir);
-        } catch (KrbException e) {
-            throw new HasException("Failed to create KdcServer. " + e.getMessage());
-        }
-        kdcServer.setWorkDir(workDir);
-        kdcServer.setInnerKdcImpl(new NettyKdcServerImpl(kdcServer.getKdcSetting()));
-        try {
-            kdcServer.init();
-        } catch (KrbException e) {
-            LOG.error("Errors occurred when init has kdc server:  " + e.getMessage());
-            throw new HasException("Errors occurred when init has kdc server:  " + e.getMessage());
-        }
-
-        KrbConfig krbConfig;
-        try {
-            krbConfig = ClientUtil.getConfig(confDir);
-        } catch (KrbException e) {
-            throw new HasException("Errors occurred when getting the config from conf dir. "
-                + e.getMessage());
-        }
-        if (krbConfig == null) {
-            krbConfig = new KrbConfig();
-        }
-        this.krbSetting = new KrbSetting(krbConfig);
-        try {
-            kdcServer.start();
-        } catch (KrbException e) {
-            throw new HasException("Failed to start kdc server. " + e.getMessage());
-        }
-        try {
-            HasUtil.setEnableConf(new File(confDir, "has-server.conf"), "false");
-        } catch (Exception e) {
-            throw new HasException("Failed to enable conf. " + e.getMessage());
-        }
-        setHttpFilter();
-    }
-
-    public File initKdcServer() throws KrbException {
-        File adminKeytabFile = new File(workDir, "admin.keytab");
-        if (kdcServer == null) {
-            throw new KrbException("Please start KDC server first.");
-        }
-        LocalKadmin kadmin = new LocalKadminImpl(kdcServer.getKdcSetting(),
-            kdcServer.getIdentityService());
-        String kadminPrincipalName = kadmin.getKadminPrincipal();
-        if (adminKeytabFile.exists()) {
-            try {
-                Keytab keytab = Keytab.loadKeytab(adminKeytabFile);
-                boolean deleteFlag = false;
-                if (!keytab.getPrincipals().isEmpty()) {
-                    for (PrincipalName principal: keytab.getPrincipals()) {
-                        if (!principal.getName().equals(kadminPrincipalName)) {
-                            deleteFlag = true;
-                            break;
-                        }
-                    }
-                } else {
-                    deleteFlag = true;
-                }
-                if (deleteFlag) {
-                    if (!adminKeytabFile.delete()) {
-                        throw new KrbException("Failed to delete wrong admin keytab file.");
-                    } else {
-                        System.out.println("The old admin.keytab is wrong and will be regenerated.");
-                    }
-                } else {
-                    return adminKeytabFile;
-                }
-            } catch (IOException e) {
-                throw new KrbException("Failed to load existing admin keytab file.");
-            }
-        }
-        if (kadmin.getPrincipal(kadminPrincipalName) == null) {
-            kadmin.createBuiltinPrincipals();
-        }
-        kadmin.exportKeytab(adminKeytabFile, kadmin.getKadminPrincipal());
-        System.out.println("The keytab for kadmin principal "
-            + "has been exported to the specified file "
-            + adminKeytabFile.getAbsolutePath() + ", please keep it safe, "
-            + "in order to use kadmin tool later");
-
-        return adminKeytabFile;
-    }
-
-    private void setHttpFilter() throws HasException {
-        File httpKeytabFile = new File(workDir, "http.keytab");
-        LocalKadmin kadmin = new LocalKadminImpl(kdcServer.getKdcSetting(),
-            kdcServer.getIdentityService());
-        createHttpPrincipal(kadmin);
-        try {
-            kadmin.exportKeytab(httpKeytabFile, getHttpPrincipal());
-        } catch (KrbException e) {
-            throw new HasException("Failed to export keytab: " + e.getMessage());
-        }
-        webServer.getConf().setString(WebConfigKey.HAS_AUTHENTICATION_FILTER_AUTH_TYPE,
-            hasConfig.getFilterAuthType());
-        webServer.getConf().setString(WebConfigKey.HAS_AUTHENTICATION_KERBEROS_PRINCIPAL_KEY,
-            getHttpPrincipal());
-        webServer.getConf().setString(WebConfigKey.HAS_AUTHENTICATION_KERBEROS_KEYTAB_KEY,
-            httpKeytabFile.getPath());
-        webServer.defineFilter();
-    }
-
-    public void createHttpPrincipal(LocalKadmin kadmin) throws HasException {
-        String httpPrincipal = getHttpPrincipal();
-        IdentityBackend backend = kdcServer.getIdentityService();
-        try {
-            if (backend.getIdentity(httpPrincipal) == null) {
-                kadmin.addPrincipal(httpPrincipal);
-            } else {
-                LOG.info("The http principal already exists in backend.");
-            }
-        } catch (KrbException e) {
-            throw new HasException("Failed to add principal, " + e.getMessage());
-        }
-    }
-
-    public String getHttpPrincipal() throws HasException {
-        String realm = kdcServer.getKdcSetting().getKdcRealm();
-        String nameString;
-        try {
-            InetAddress addr = InetAddress.getLocalHost();
-            String fqName = addr.getCanonicalHostName();
-            nameString = "HTTP/" + fqName + "@" + realm;
-        } catch (UnknownHostException e) {
-            throw new HasException(e);
-        }
-        LOG.info("The http principal name is: " + nameString);
-        return nameString;
-    }
-
-     /**
-     * Update conf file.
-     *
-     * @param confName  conf file name
-     * @param values    customized values
-     * @throws IOException throw IOException
-     * @throws HasException e
-     */
-    public void updateConfFile(String confName, Map<String, String> values)
-        throws IOException, HasException {
-        File confFile = new File(getConfDir().getAbsolutePath(), confName);
-        if (confFile.exists()) {
-            // Update conf file content
-            InputStream templateResource;
-            if (confName.equals("has-server.conf")) {
-                templateResource = new FileInputStream(confFile);
-            } else {
-                String resourcePath = "/" + confName + ".template";
-                templateResource = getClass().getResourceAsStream(resourcePath);
-            }
-            String content;
-            try {
-                content = IOUtil.readInput(templateResource);
-            } finally {
-                templateResource.close();
-            }
-            for (Map.Entry<String, String> entry : values.entrySet()) {
-                content = content.replaceAll(Pattern.quote(entry.getKey()), entry.getValue());
-            }
-
-            // Delete the original conf file
-            boolean delete = confFile.delete();
-            if (!delete) {
-                throw new HasException("Failed to delete conf file: " + confName);
-            }
-
-            // Save the updated conf file
-            IOUtil.writeFile(content, confFile);
-        } else {
-            throw new HasException("Conf file: " + confName + " not found.");
-        }
-    }
-
-    /**
-     * Get KDC Config from MySQL.
-     *
-     * @return Kdc config
-     * @throws HasException e
-     */
-    private Map<String, String> getKdcConf() throws HasException {
-        PreparedStatement preStm = null;
-        ResultSet result = null;
-        Map<String, String> kdcConf = new HashMap<>();
-        BackendConfig backendConfig;
-        try {
-            backendConfig = KdcUtil.getBackendConfig(getConfDir());
-        } catch (KrbException e) {
-            throw new HasException("Getting backend config failed." + e.getMessage());
-        }
-        String driver = backendConfig.getString("mysql_driver");
-        String url = backendConfig.getString("mysql_url");
-        String user = backendConfig.getString("mysql_user");
-        String password = backendConfig.getString("mysql_password");
-        Connection connection = startConnection(driver, url, user, password);
-        try {
-
-            // Get Kdc configuration from kdc_config table
-            String stmKdc = "SELECT * FROM `kdc_config` WHERE id = 1";
-            preStm = connection.prepareStatement(stmKdc);
-            result = preStm.executeQuery();
-            while (result.next()) {
-                String realm = result.getString("realm");
-                String servers = result.getString("servers");
-                String port = String.valueOf(result.getInt("port"));
-                kdcConf.put("servers", servers);
-                kdcConf.put("_PORT_", port);
-                kdcConf.put("_REALM_", realm);
-            }
-
-        } catch (SQLException e) {
-            LOG.error("Error occurred while getting kdc config.");
-            throw new HasException("Failed to get kdc config. ", e);
-        } finally {
-            DbUtils.closeQuietly(preStm);
-            DbUtils.closeQuietly(result);
-            DbUtils.closeQuietly(connection);
-        }
-
-        return kdcConf;
-    }
-
-    /**
-     * Update KDC conf file.
-     *
-     * @throws HasException e
-     */
-    private void updateKdcConf() throws HasException {
-        try {
-            Map<String, String> values = getKdcConf();
-            String host = getKdcHost();
-            if (host == null) {
-                InetSocketAddress bind = getWebServer().getBindAddress();
-                if (bind != null) {
-                    host = bind.getHostName();
-                }
-            }
-            values.remove("servers");
-            values.put("_HOST_", host);
-            updateConfFile("kdc.conf", values);
-        } catch (IOException e) {
-            throw new HasException("Failed to update kdc config. ", e);
-        }
-    }
-
-      /**
-     * Start the MySQL connection.
-     *
-     * @param url url of connection
-     * @param user username of connection
-     * @param password password of connection
-     * @throws HasException e
-     * @return MySQL JDBC connection
-     */
-    private Connection startConnection(String driver, String url, String user,
-                                       String password) throws HasException {
-        Connection connection;
-        try {
-            Class.forName(driver);
-            connection = DriverManager.getConnection(url, user, password);
-            if (!connection.isClosed()) {
-                LOG.info("Succeeded in connecting to MySQL.");
-            }
-        } catch (ClassNotFoundException e) {
-            throw new HasException("JDBC Driver Class not found. ", e);
-        } catch (SQLException e) {
-            throw new HasException("Failed to connecting to MySQL. ", e);
-        }
-
-        return connection;
-    }
-
-    /**
-     * Config HAS server KDC which have MySQL backend.
-     * @param backendConfig MySQL backend config
-     * @param realm KDC realm to set
-     * @param port has server port
-     * @param host KDC host to set
-     * @param hasServer has server to get param
-     * @throws HasException e
-     */
-    public void configMySQLKdc(BackendConfig backendConfig, String realm, int port,
-                               String host, HasServer hasServer) throws HasException {
-
-        // Start mysql connection
-        String driver = backendConfig.getString("mysql_driver");
-        String url = backendConfig.getString("mysql_url");
-        String user = backendConfig.getString("mysql_user");
-        String password = backendConfig.getString("mysql_password");
-        Connection connection = startConnection(driver, url, user, password);
-
-        ResultSet resConfig = null;
-        PreparedStatement preStm = null;
-        try {
-            createKdcTable(connection); // Create kdc_config table if not exists
-            String stm = "SELECT * FROM `kdc_config` WHERE id = 1";
-            preStm = connection.prepareStatement(stm);
-            resConfig = preStm.executeQuery();
-            if (!resConfig.next()) {
-                addKdcConfig(connection, realm, port, host);
-            } else {
-                String oldHost = hasServer.getKdcHost();
-                String servers = resConfig.getString("servers");
-                String[] serverArray = servers.split(",");
-                List<String> serverList = new ArrayList<>();
-                Collections.addAll(serverList, serverArray);
-                if (serverList.contains(oldHost)) {
-                    servers = servers.replaceAll(oldHost, host);
-                } else {
-                    servers = servers + "," + host;
-                }
-                boolean initialized = resConfig.getBoolean("initialized");
-                updateKdcConfig(connection, initialized, port, realm, servers);
-            }
-            hasServer.setKdcHost(host);
-        } catch (SQLException e) {
-            throw new HasException("Failed to config HAS KDC. ", e);
-        } finally {
-            DbUtils.closeQuietly(preStm);
-            DbUtils.closeQuietly(resConfig);
-            DbUtils.closeQuietly(connection);
-        }
-    }
-
-    /**
-     * Create kdc_config table in database.
-     * @param conn database connection
-     * @throws HasException e
-     */
-    private void createKdcTable(final Connection conn) throws HasException {
-        PreparedStatement preStm = null;
-        try {
-            String stm = "CREATE TABLE IF NOT EXISTS `kdc_config` ("
-                + "port INTEGER DEFAULT 88, servers VARCHAR(255) NOT NULL, "
-                + "initialized bool DEFAULT FALSE, realm VARCHAR(255) "
-                + "DEFAULT NULL, id INTEGER DEFAULT 1, CHECK (id=1), PRIMARY KEY (id)) "
-                + "ENGINE=INNODB;";
-            preStm = conn.prepareStatement(stm);
-            preStm.executeUpdate();
-        } catch (SQLException e) {
-            throw new HasException("Failed to create kdc_config table. ", e);
-        } finally {
-            DbUtils.closeQuietly(preStm);
-        }
-    }
-
-    /**
-     * Add KDC Config information in database.
-     * @param conn database connection
-     * @param realm realm to add
-     * @param port port to add
-     * @param host host to add
-     */
-    private void addKdcConfig(Connection conn, String realm, int port, String host)
-        throws HasException {
-        PreparedStatement preStm = null;
-        try {
-            String stm = "INSERT INTO `kdc_config` (port, servers, realm)" + " VALUES(?, ?, ?)";
-            preStm = conn.prepareStatement(stm);
-            preStm.setInt(1, port);
-            preStm.setString(2, host);
-            preStm.setString(3, realm);
-            preStm.executeUpdate();
-        } catch (SQLException e) {
-            throw new HasException("Failed to insert into kdc_config table. ", e);
-        } finally {
-            DbUtils.closeQuietly(preStm);
-        }
-    }
-
-    /**
-     * Update KDC Config record in database.
-     * @param conn database connection
-     * @param realm realm to update
-     * @param port port to update
-     * @param servers servers to update
-     * @param initialized initial state of KDC Config
-     */
-    private void updateKdcConfig(Connection conn, boolean initialized, int port,
-                                 String realm, String servers) throws HasException {
-        PreparedStatement preStm = null;
-        try {
-            if (initialized) {
-                String stmUpdate = "UPDATE `kdc_config` SET servers = ? WHERE id = 1";
-                preStm = conn.prepareStatement(stmUpdate);
-                preStm.setString(1, servers);
-                preStm.executeUpdate();
-            } else {
-                String stmUpdate = "UPDATE `kdc_config` SET port = ?, realm = ?, servers = ? WHERE id = 1";
-                preStm = conn.prepareStatement(stmUpdate);
-                preStm.setInt(1, port);
-                preStm.setString(2, realm);
-                preStm.setString(3, servers);
-                preStm.executeUpdate();
-            }
-        } catch (SQLException e) {
-            throw new HasException("Failed to update KDC Config. ", e);
-        } finally {
-            DbUtils.closeQuietly(preStm);
-        }
-    }
-
-    /**
-     * Read in krb5-template.conf and substitute in the correct port.
-     *
-     * @return krb5 conf file
-     * @throws HasException e
-     */
-    public File generateKrb5Conf() throws HasException {
-        Map<String, String> kdcConf = getKdcConf();
-        String[] servers = kdcConf.get("servers").split(",");
-        int kdcPort = Integer.parseInt(kdcConf.get("_PORT_"));
-        String kdcRealm = kdcConf.get("_REALM_");
-        StringBuilder kdcBuilder = new StringBuilder();
-        for (String server : servers) {
-            String append = "\t\tkdc = " + server.trim() + ":" + kdcPort + "\n";
-            kdcBuilder.append(append);
-        }
-        String kdc = kdcBuilder.toString();
-        kdc = kdc.substring(0, kdc.length() - 1);
-        String resourcePath = "/krb5.conf.template";
-        String content;
-        try (InputStream templateResource = getClass().getResourceAsStream(resourcePath)) {
-            content = IOUtil.readInput(templateResource);
-        } catch (IOException e) {
-            throw new HasException("Read template resource failed. " + e.getMessage());
-        }
-        content = content.replaceAll("_REALM_", kdcRealm);
-        content = content.replaceAll("_PORT_", String.valueOf(kdcPort));
-        content = content.replaceAll("_UDP_LIMIT_", "4096");
-        content = content.replaceAll("_KDCS_", kdc);
-        File confFile = new File(confDir, "krb5.conf");
-        if (confFile.exists()) {
-            boolean delete = confFile.delete();
-            if (!delete) {
-                throw new HasException("File delete error!");
-            }
-        }
-        try {
-            IOUtil.writeFile(content, confFile);
-        } catch (IOException e) {
-            throw new HasException("Write content to conf file failed. " + e.getMessage());
-        }
-
-        return confFile;
-    }
-
-    /**
-     * Read in has-server.conf and create has-client.conf.
-     *
-     * @return has conf file
-     * @throws IOException e
-     * @throws HasException e
-     */
-    public File generateHasConf() throws HasException, IOException {
-        Map<String, String> kdcConf = getKdcConf();
-        String servers = kdcConf.get("servers");
-        File confFile = new File(getConfDir().getAbsolutePath(), "has-server.conf");
-        HasConfig hasConfig = HasUtil.getHasConfig(confFile);
-        if (hasConfig != null) {
-            String defaultValue = hasConfig.getHttpsHost();
-            String content;
-            try (InputStream templateResource = new FileInputStream(confFile)) {
-                content = IOUtil.readInput(templateResource);
-            }
-            content = content.replaceFirst(Pattern.quote(defaultValue), servers);
-            File hasFile = new File(confDir, "has-client.conf");
-            IOUtil.writeFile(content, hasFile);
-            return hasFile;
-        } else {
-            throw new HasException("has-server.conf not found. ");
-        }
-    }
-
-    public void stopKdcServer() {
-        try {
-            kdcServer.stop();
-        } catch (KrbException e) {
-            LOG.error("Fail to stop has kdc server");
-        }
-    }
-
-    public void startWebServer() throws HasException {
-        if (webServer == null) {
-            HasConfig conf = new HasConfig();
-
-            // Parse has-server.conf to get http_host and http_port
-            File confFile = new File(confDir, "has-server.conf");
-            hasConfig = HasUtil.getHasConfig(confFile);
-            hasConfig.setConfDir(getConfDir().getAbsoluteFile());
-            try {
-                String httpHost;
-                String httpPort;
-                String httpsHost;
-                String httpsPort;
-                if (hasConfig.getHttpHost() != null) {
-                    httpHost = hasConfig.getHttpHost();
-                } else {
-                    LOG.info("Cannot get the http_host from has-server.conf, using the default http host.");
-                    httpHost = WebConfigKey.HAS_HTTP_HOST_DEFAULT;
-                }
-                if (hasConfig.getHttpPort() != null) {
-                    httpPort = hasConfig.getHttpPort();
-                } else {
-                    LOG.info("Cannot get the http_port from has-server.conf, using the default http port.");
-                    httpPort = String.valueOf(WebConfigKey.HAS_HTTP_PORT_DEFAULT);
-                }
-                if (hasConfig.getHttpsHost() != null) {
-                    httpsHost = hasConfig.getHttpsHost();
-                } else {
-                    LOG.info("Cannot get the https_host from has-server.conf, using the default https host.");
-                    httpsHost = WebConfigKey.HAS_HTTPS_HOST_DEFAULT;
-                }
-                if (hasConfig.getHttpsPort() != null) {
-                    httpsPort = hasConfig.getHttpsPort();
-                } else {
-                    LOG.info("Cannot get the https_port from has-server.conf , using the default https port.");
-                    httpsPort = String.valueOf(WebConfigKey.HAS_HTTPS_PORT_DEFAULT);
-                }
-                String hasHttpAddress = httpHost + ":" + httpPort;
-                String hasHttpsAddress = httpsHost + ":" + httpsPort;
-                LOG.info("The web server http address: " + hasHttpAddress);
-                LOG.info("The web server https address: " + hasHttpsAddress);
-
-                conf.setString(WebConfigKey.HAS_HTTP_ADDRESS_KEY, hasHttpAddress);
-                conf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, hasHttpsAddress);
-                conf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY,
-                    HttpConfig.Policy.HTTP_AND_HTTPS.name());
-                conf.setString(WebConfigKey.HAS_SERVER_HTTPS_KEYSTORE_RESOURCE_KEY,
-                    hasConfig.getSslServerConf());
-                webServer = new WebServer(conf);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("https_port should be a number. "
-                    + e.getMessage());
-            }
-        } else {
-            hasConfig = webServer.getConf();
-        }
-        webServer.start();
-        webServer.defineConfFilter();
-        try {
-            HasUtil.setEnableConf(new File(confDir, "has-server.conf"), "true");
-        } catch (IOException e) {
-            throw new HasException("Errors occurred when enable conf. " + e.getMessage());
-        }
-        webServer.setWebServerAttribute(this);
-    }
-
-    public void stopWebServer() {
-        if (webServer != null) {
-            try {
-                webServer.stop();
-            } catch (Exception e) {
-                LOG.error("Failed to stop http server. " + e.getMessage());
-            }
-        }
-    }
-
-    public static void main(String[] args) {
-        if (args[0].equals("-start")) {
-            String confDirPath = args[1];
-            String workDirPath = args[2];
-            File confDir = new File(confDirPath);
-            if (!confDir.exists()) {
-                System.err.println("The conf-dir is invalid or does not exist");
-                System.exit(3);
-            }
-            File workDir = new File(workDirPath);
-            if (!workDir.exists()) {
-                System.err.println("The work-dir is invalid or does not exist");
-                System.exit(3);
-            }
-
-            try {
-                server = new HasServer(confDir);
-            } catch (KrbException e) {
-                LOG.error("Errors occurred when create kdc server:  " + e.getMessage());
-                System.exit(4);
-            }
-            server.setConfDir(confDir);
-            server.setWorkDir(workDir);
-            //Only start the webserver, the kdcserver could be started after setting the realm
-            try {
-                server.startWebServer();
-            } catch (HasException e) {
-                LOG.error("Errors occurred when start has http server:  " + e.getMessage());
-                System.exit(6);
-            }
-
-            if (server.getWebServer().getHttpAddress() != null) {
-                LOG.info("HAS http server started.");
-                LOG.info("host: " + server.getWebServer().getHttpAddress().getHostName());
-                LOG.info("port: " + server.getWebServer().getHttpAddress().getPort());
-            }
-            if (server.getWebServer().getHttpsAddress() != null) {
-                LOG.info("HAS https server started.");
-                LOG.info("host: " + server.getWebServer().getHttpsAddress().getHostName());
-                LOG.info("port: " + server.getWebServer().getHttpsAddress().getPort());
-            }
-        } else if (args[0].equals("-stop")) {
-            if (server != null) {
-                server.stopWebServer();
-                server.stopKdcServer();
-            }
-        } else {
-            System.exit(2);
-        }
-    }
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPlugin.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPlugin.java
deleted file mode 100644
index f076b0e6..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPlugin.java
+++ /dev/null
@@ -1,40 +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.kerby.has.server;
-
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-
-public interface HasServerPlugin {
-        /**
-         * Get the login module type ID, used to distinguish this module from others.
-         * Should correspond to the client side module.
-         *
-         * @return login type
-         */
-        String getLoginType();
-
-        /**
-         * Perform all the server side authentication logics, the results wrapped in an AuthToken,
-         * will be used to exchange a Kerberos ticket.
-         *
-         * @param userToken user token
-         * @return auth token
-         * @throws HasAuthenException HAS authentication error
-         */
-        AuthToken authenticate(AuthToken userToken) throws HasAuthenException;
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPluginRegistry.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPluginRegistry.java
deleted file mode 100644
index d75b7149..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServerPluginRegistry.java
+++ /dev/null
@@ -1,63 +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.kerby.has.server;
-
-import org.apache.kerby.has.common.HasException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class HasServerPluginRegistry {
-    static final Logger LOG = LoggerFactory.getLogger(HasServerPluginRegistry.class);
-
-    private static Map<String, Class> allPlugins = new ConcurrentHashMap<>();
-
-    static {
-        ServiceLoader<HasServerPlugin> plugins = ServiceLoader.load(HasServerPlugin.class);
-
-        for (HasServerPlugin plugin : plugins) {
-            allPlugins.put(plugin.getLoginType(), plugin.getClass());
-        }
-    }
-
-    public static Set<String> registeredPlugins() {
-        return Collections.unmodifiableSet(allPlugins.keySet());
-    }
-
-    public static boolean registeredPlugin(String name) {
-        return allPlugins.containsKey(name);
-    }
-
-    public static HasServerPlugin createPlugin(String name) throws HasException {
-        if (!registeredPlugin(name)) {
-            throw new HasException("Unregistered plugin " + name);
-        }
-        try {
-            HasServerPlugin serverPlugin = (HasServerPlugin) allPlugins.get(name).newInstance();
-            return serverPlugin;
-        } catch (Exception e) {
-            LOG.error("Create {} plugin failed", name, e);
-            throw new HasException(e.getMessage());
-        }
-    }
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
deleted file mode 100644
index acf78554..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
+++ /dev/null
@@ -1,163 +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.kerby.has.server.admin;
-
-import org.apache.kerby.has.common.Hadmin;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.has.server.HasServer;
-import org.apache.kerby.has.server.web.HostRoleType;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadmin;
-import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadminImpl;
-import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
-import org.apache.kerby.kerberos.kerb.server.KdcConfig;
-import org.apache.kerby.kerberos.kerb.server.KdcSetting;
-import org.apache.kerby.kerberos.kerb.server.KdcUtil;
-import org.apache.kerby.kerberos.kerb.server.ServerSetting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class LocalHadmin implements Hadmin {
-    public static final Logger LOG = LoggerFactory.getLogger(LocalHadmin.class);
-
-    private final ServerSetting serverSetting;
-    private LocalKadmin kadmin;
-    private File confDir;
-
-    public LocalHadmin(HasServer hasServer) throws KrbException {
-        if (hasServer.getKdcServer() == null) {
-            throw new RuntimeException("Could not get HAS KDC server, please start KDC first.");
-        }
-        this.serverSetting = hasServer.getKdcServer().getKdcSetting();
-
-        kadmin = new LocalKadminImpl(serverSetting);
-    }
-
-    /**
-     * Construct with prepared conf dir.
-     *
-     * @param confDir The path of conf dir
-     * @throws KrbException e
-     */
-    public LocalHadmin(File confDir) throws KrbException {
-        this.confDir = confDir;
-        KdcConfig tmpKdcConfig = KdcUtil.getKdcConfig(confDir);
-        if (tmpKdcConfig == null) {
-            tmpKdcConfig = new KdcConfig();
-        }
-
-        BackendConfig tmpBackendConfig = KdcUtil.getBackendConfig(confDir);
-        if (tmpBackendConfig == null) {
-            tmpBackendConfig = new BackendConfig();
-        }
-
-        this.serverSetting = new KdcSetting(tmpKdcConfig, tmpBackendConfig);
-        kadmin = new LocalKadminImpl(serverSetting);
-    }
-
-    @Override
-    public List<String> addPrincByRole(String host, String role) throws HasException {
-        List<String> result = new ArrayList<>();
-        String realm = "/" + host + "@" + kadmin.getKdcConfig().getKdcRealm();
-        String[] princs = HostRoleType.valueOf(role).getPrincs();
-        if (princs == null) {
-            LOG.error("Cannot find the role of : " + role);
-            result.add("Cannot find the role of : " + role);
-            return result;
-        }
-        for (String princ : princs) {
-            try {
-                kadmin.addPrincipal(princ + realm);
-                LOG.info("Success to add princ: " + princ + realm);
-                result.add("Success to add princ: " + princ + realm);
-            } catch (KrbException e) {
-                String message = e.getMessage();
-                LOG.info(message);
-                result.add(message);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public File getKeytabByHostAndRole(String host, String role) throws HasException {
-        String realm = "/" + host + "@" + kadmin.getKdcConfig().getKdcRealm();
-        File path = new File("/tmp/" + System.currentTimeMillis());
-        path.mkdirs();
-        File keytab = new File(path, role + "-" + host + ".keytab");
-        if (keytab.exists()) {
-            keytab.delete();
-        }
-        String[] princs = HostRoleType.valueOf(role).getPrincs();
-        for (String princ : princs) {
-            try {
-                if (kadmin.getPrincipal(princ + realm) == null) {
-                    continue;
-                }
-            } catch (KrbException e) {
-                throw new HasException(e);
-            }
-            try {
-                kadmin.exportKeytab(keytab, princ + realm);
-            } catch (KrbException e) {
-                throw new HasException(e);
-            }
-        }
-        return keytab;
-    }
-
-    @Override
-    public void getHostRoles() {
-        for (HostRoleType role : HostRoleType.values()) {
-            System.out.print("\tHostRole: " + role.getName()
-                + ", PrincipalNames: ");
-            String[] princs = role.getPrincs();
-            for (int j = 0; j < princs.length; j++) {
-                System.out.print(princs[j]);
-                if (j == princs.length - 1) {
-                    System.out.println();
-                } else {
-                    System.out.print(", ");
-                }
-            }
-        }
-    }
-
-    @Override
-    public void setEnableOfConf(String isEnable) throws HasException {
-        File hasConf = new File(confDir, "has-server.conf");
-        if (!hasConf.exists()) {
-            System.err.println("has-server.conf is not exists.");
-            return;
-        }
-        try {
-            HasUtil.setEnableConf(hasConf, isEnable);
-        } catch (IOException e) {
-            System.err.println(e.getMessage());
-            return;
-        }
-    }
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/kdc/HasKdcHandler.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/kdc/HasKdcHandler.java
deleted file mode 100644
index a8af29c7..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/kdc/HasKdcHandler.java
+++ /dev/null
@@ -1,317 +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.kerby.has.server.kdc;
-
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.has.server.HasServer;
-import org.apache.kerby.kerberos.kerb.KrbCodec;
-import org.apache.kerby.kerberos.kerb.KrbErrorCode;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.client.KrbContext;
-import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
-import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
-import org.apache.kerby.kerberos.kerb.server.KdcContext;
-import org.apache.kerby.kerberos.kerb.server.KdcRecoverableException;
-import org.apache.kerby.kerberos.kerb.server.KdcServer;
-import org.apache.kerby.kerberos.kerb.server.preauth.PreauthHandler;
-import org.apache.kerby.kerberos.kerb.server.request.AsRequest;
-import org.apache.kerby.kerberos.kerb.server.request.KdcRequest;
-import org.apache.kerby.kerberos.kerb.type.KerberosTime;
-import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
-import org.apache.kerby.kerberos.kerb.type.base.HostAddress;
-import org.apache.kerby.kerberos.kerb.type.base.HostAddresses;
-import org.apache.kerby.kerberos.kerb.type.base.KrbError;
-import org.apache.kerby.kerberos.kerb.type.base.KrbMessage;
-import org.apache.kerby.kerberos.kerb.type.base.KrbToken;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.apache.kerby.kerberos.kerb.type.base.TokenFormat;
-import org.apache.kerby.kerberos.kerb.type.kdc.AsReq;
-import org.apache.kerby.kerberos.kerb.type.kdc.KdcOption;
-import org.apache.kerby.kerberos.kerb.type.kdc.KdcOptions;
-import org.apache.kerby.kerberos.kerb.type.kdc.KdcReqBody;
-import org.apache.kerby.kerberos.kerb.type.pa.PaData;
-import org.apache.kerby.kerberos.kerb.type.pa.PaDataEntry;
-import org.apache.kerby.kerberos.kerb.type.pa.PaDataType;
-import org.apache.kerby.kerberos.kerb.type.pa.token.PaTokenRequest;
-import org.apache.kerby.kerberos.kerb.type.pa.token.TokenInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class HasKdcHandler {
-    private static final Logger LOG = LoggerFactory.getLogger(HasKdcHandler.class);
-
-    private KdcContext kdcContext;
-    private KrbContext krbContext;
-    private KdcServer kdcServer;
-
-    /**
-     * Constructor with has server.
-     *
-     * @param hasServer has server
-     */
-    public HasKdcHandler(HasServer hasServer) {
-        this.krbContext = new KrbContext();
-        this.krbContext.init(hasServer.getKrbSetting());
-        this.kdcServer = hasServer.getKdcServer();
-        prepareHandler(kdcServer);
-    }
-
-    public KrbContext getKrbContext() {
-        return krbContext;
-    }
-
-    public KdcContext getKdcContext() {
-        return kdcContext;
-    }
-
-    private KdcServer getKdcServer() {
-        return kdcServer;
-    }
-
-    private void prepareHandler(KdcServer kdcServer) {
-        this.kdcContext = new KdcContext(kdcServer.getKdcSetting());
-        this.kdcContext.setIdentityService(kdcServer.getIdentityService());
-        PreauthHandler preauthHandler = new PreauthHandler();
-        preauthHandler.init();
-        this.kdcContext.setPreauthHandler(preauthHandler);
-    }
-
-    private String getAudience(String name) {
-        return name + "/" + getKdcContext().getKdcRealm() + "@" + getKdcContext().getKdcRealm();
-    }
-
-    public KrbMessage getResponse(AuthToken authToken, String passPhrase) {
-        KrbMessage krbMessage = null;
-        try {
-            krbMessage = handleMessage(authToken, passPhrase);
-        } catch (KrbException e) {
-            LOG.error("Failed to handle message. " + e.getMessage());
-        }
-        return krbMessage;
-    }
-
-    /**
-     * Process the client request message.
-     *
-     * @param authToken the auth token
-     * @param passPhrase the password phrase
-     * @return KrbMessage KRB message
-     * @throws KrbException KRB exception when handling message
-     */
-    public KrbMessage handleMessage(AuthToken authToken, String passPhrase) throws KrbException {
-
-        // set the audiences
-        List<String> auds = new ArrayList<>();
-        String audience = getAudience("krbtgt");
-        auds.add(audience);
-        authToken.setAudiences(auds);
-
-        AsReq asReq = createAsReq(authToken);
-        KdcRequest kdcRequest = new AsRequest(asReq, kdcContext);
-        kdcRequest.setHttps(true);
-        List<EncryptionType> requestedTypes = getEncryptionTypes();
-        EncryptionType bestType = EncryptionUtil.getBestEncryptionType(requestedTypes,
-                kdcContext.getConfig().getEncryptionTypes());
-
-        if (bestType == null) {
-            LOG.error("Can't get the best encryption type.");
-            throw new KrbException(KrbErrorCode.KDC_ERR_ETYPE_NOSUPP);
-        }
-
-        PrincipalName clientPrincipal = new PrincipalName(authToken.getSubject());
-        String clientRealm = asReq.getReqBody().getRealm();
-        if (clientRealm == null || clientRealm.isEmpty()) {
-            clientRealm = getKdcContext().getKdcRealm();
-        }
-        clientPrincipal.setRealm(clientRealm);
-
-        // Set the client key
-        EncryptionKey clientKey = HasUtil.getClientKey(clientPrincipal.getName(),
-            passPhrase, bestType);
-        kdcRequest.setClientKey(clientKey);
-
-        // Set the token issuers
-        getKdcServer().getKdcConfig().setString(KdcConfigKey.TOKEN_ISSUERS, "has");
-
-        KrbMessage krbResponse;
-
-        try {
-            kdcRequest.process();
-            krbResponse = kdcRequest.getReply();
-        } catch (KrbException e) {
-            LOG.error("Error occurred when request tgt. " + e.getMessage());
-            if (e instanceof KdcRecoverableException) {
-                krbResponse = handleRecoverableException(
-                        (KdcRecoverableException) e, kdcRequest);
-            } else {
-                KrbError krbError = new KrbError();
-                krbError.setStime(KerberosTime.now());
-                krbError.setSusec(100);
-                if (e.getKrbErrorCode() != null) {
-                    krbError.setErrorCode(e.getKrbErrorCode());
-                } else {
-                    krbError.setErrorCode(KrbErrorCode.UNKNOWN_ERR);
-                }
-                krbError.setCrealm(kdcContext.getKdcRealm());
-                if (kdcRequest.getClientPrincipal() != null) {
-                    krbError.setCname(kdcRequest.getClientPrincipal());
-                }
-                krbError.setRealm(kdcContext.getKdcRealm());
-                if (kdcRequest.getServerPrincipal() != null) {
-                    krbError.setSname(kdcRequest.getServerPrincipal());
-                } else {
-                    PrincipalName serverPrincipal = kdcRequest.getKdcReq().getReqBody().getSname();
-                    serverPrincipal.setRealm(kdcRequest.getKdcReq().getReqBody().getRealm());
-                    krbError.setSname(serverPrincipal);
-                }
-                if (KrbErrorCode.KRB_AP_ERR_BAD_INTEGRITY.equals(e.getKrbErrorCode())) {
-                    krbError.setEtext("PREAUTH_FAILED");
-                } else {
-                    krbError.setEtext(e.getMessage());
-                }
-                krbResponse = krbError;
-            }
-        }
-        return krbResponse;
-    }
-
-    /**
-     * Process the recoverable exception.
-     *
-     * @param e The exception return by kdc
-     * @param kdcRequest kdc request
-     * @return The KrbError
-     */
-    private KrbMessage handleRecoverableException(KdcRecoverableException e,
-                                                  KdcRequest kdcRequest) {
-        LOG.info("KRB error occurred while processing request:"
-                + e.getMessage());
-
-        KrbError error = e.getKrbError();
-        error.setStime(KerberosTime.now());
-        error.setSusec(100);
-        error.setErrorCode(e.getKrbError().getErrorCode());
-        error.setRealm(kdcContext.getKdcRealm());
-        if (kdcRequest != null) {
-            error.setSname(kdcRequest.getKdcReq().getReqBody().getCname());
-        } else {
-            error.setSname(new PrincipalName("NONE"));
-        }
-        error.setEtext(e.getMessage());
-        return error;
-    }
-
-    public AsReq createAsReq(AuthToken authToken) throws KrbException {
-        AsReq asReq = new AsReq();
-        KdcReqBody body = makeReqBody();
-        asReq.setReqBody(body);
-
-        PaTokenRequest tokenPa = new PaTokenRequest();
-        KrbToken krbToken = new KrbToken(authToken, TokenFormat.JWT);
-        tokenPa.setToken(krbToken);
-        TokenInfo info = new TokenInfo();
-        info.setTokenVendor(authToken.getIssuer());
-        tokenPa.setTokenInfo(info);
-
-        PaDataEntry paDataEntry = new PaDataEntry();
-        paDataEntry.setPaDataType(PaDataType.TOKEN_REQUEST);
-        paDataEntry.setPaDataValue(KrbCodec.encode(tokenPa));
-
-        PaData paData = new PaData();
-        paData.addElement(paDataEntry);
-        asReq.setPaData(paData);
-        return asReq;
-    }
-
-    /**
-     * Create the KdcReqBody
-     *
-     * @return KdcReqBody the KDC req body
-     */
-     protected KdcReqBody makeReqBody() {
-        KdcReqBody body = new KdcReqBody();
-
-        long startTime = System.currentTimeMillis();
-        body.setFrom(new KerberosTime(startTime));
-
-         // set the client principal as null
-        PrincipalName cName = null;
-        body.setCname(cName);
-
-        body.setRealm(getKrbContext().getKrbSetting().getKdcRealm());
-
-        PrincipalName sName = getServerPrincipal();
-        body.setSname(sName);
-
-        body.setTill(new KerberosTime(startTime + krbContext.getTicketValidTime()));
-
-        int nonce = krbContext.generateNonce();
-        body.setNonce(nonce);
-//        setChosenNonce(nonce);
-
-        body.setKdcOptions(getKdcOptions());
-
-        HostAddresses addresses = getHostAddresses();
-        if (addresses != null) {
-            body.setAddresses(addresses);
-        }
-
-        body.setEtypes(getEncryptionTypes());
-
-        return body;
-    }
-
-    private PrincipalName getServerPrincipal() {
-        return KrbUtil.makeTgsPrincipal(getKrbContext().getKrbSetting().getKdcRealm());
-    }
-
-    private KdcOptions getKdcOptions() {
-        KdcOptions kdcOptions = new KdcOptions();
-        // By default enforce these flags
-        kdcOptions.setFlag(KdcOption.FORWARDABLE);
-        kdcOptions.setFlag(KdcOption.PROXIABLE);
-        kdcOptions.setFlag(KdcOption.RENEWABLE_OK);
-        return kdcOptions;
-    }
-
-    public HostAddresses getHostAddresses() {
-        List<HostAddress> hostAddresses = new ArrayList<>();
-        HostAddresses addresses = null;
-        //empty
-        if (!hostAddresses.isEmpty()) {
-            addresses = new HostAddresses();
-            for (HostAddress ha : hostAddresses) {
-                addresses.addElement(ha);
-            }
-        }
-        return addresses;
-    }
-
-    public List<EncryptionType> getEncryptionTypes() {
-        List<EncryptionType> encryptionTypes = krbContext.getConfig().getEncryptionTypes();
-        return EncryptionUtil.orderEtypesByStrength(encryptionTypes);
-    }
-}
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/ConfFilter.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/ConfFilter.java
deleted file mode 100644
index 548a3081..00000000
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/ConfFilter.java
+++ /dev/null
@@ -1,72 +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.kerby.has.server.web;
-
-
-import org.apache.hadoop.classification.InterfaceAudience.Private;
-import org.apache.hadoop.classification.InterfaceStability.Unstable;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.has.server.HasServer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import java.io.File;
-import java.io.IOException;
-
-@Private
-@Unstable
-public class ConfFilter implements Filter {
-    public static final Logger LOG = LoggerFactory.getLogger(ConfFilter.class);
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-
-    }
-
-    @Override
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
-                         FilterChain filterChain) throws IOException, ServletException {
... 8968 lines suppressed ...