You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ze...@apache.org on 2018/06/06 03:10:17 UTC
directory-kerby git commit: Update MySQL backend for improving
concurrency performance.
Repository: directory-kerby
Updated Branches:
refs/heads/trunk 8b5b32464 -> 93d5aa6d3
Update MySQL backend for improving concurrency performance.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/93d5aa6d
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/93d5aa6d
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/93d5aa6d
Branch: refs/heads/trunk
Commit: 93d5aa6d38eec351d09d3d8268b69c1e6c898264
Parents: 8b5b324
Author: zenglinx <fr...@intel.com>
Authored: Wed Jun 6 11:09:47 2018 +0800
Committer: zenglinx <fr...@intel.com>
Committed: Wed Jun 6 11:09:47 2018 +0800
----------------------------------------------------------------------
.../server/mysql/MySQLHasServerPlugin.java | 6 +-
.../org/apache/kerby/has/server/HasServer.java | 13 +-
kerby-backend/mysql-backend/pom.xml | 5 +
.../identitybackend/MySQLIdentityBackend.java | 243 ++++++++++---------
4 files changed, 145 insertions(+), 122 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/93d5aa6d/has-project/has-plugins/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
----------------------------------------------------------------------
diff --git a/has-project/has-plugins/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java b/has-project/has-plugins/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
index 98f0675..bd9bd85 100644
--- a/has-project/has-plugins/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
+++ b/has-project/has-plugins/src/main/java/org/apache/kerby/has/plugins/server/mysql/MySQLHasServerPlugin.java
@@ -34,7 +34,7 @@ import java.util.Date;
public class MySQLHasServerPlugin extends AbstractHasServerPlugin {
private static final Logger LOG = LoggerFactory.getLogger(MySQLHasServerPlugin.class);
- /**
+ /**
* {@inheritDoc}
*/
@Override
@@ -75,7 +75,7 @@ public class MySQLHasServerPlugin extends AbstractHasServerPlugin {
preStm.setString(2, secret);
res = preStm.executeQuery();
if (res.next() && res.getInt(1) > 0) {
- LOG.debug("UserName: " + user);
+ LOG.debug("UserName: {}", user);
} else {
LOG.error("Authentication failed.");
throw new HasAuthenException("Authentication failed.");
@@ -103,7 +103,7 @@ public class MySQLHasServerPlugin extends AbstractHasServerPlugin {
* Start the MySQL connection.
*/
private Connection startConnection(String url, String user,
- String password) throws HasAuthenException {
+ String password) throws HasAuthenException {
Connection connection;
try {
Class.forName("org.drizzle.jdbc.DrizzleDriver");
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/93d5aa6d/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
----------------------------------------------------------------------
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
index 7e20fe7..94c26a1 100644
--- 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
@@ -241,7 +241,7 @@ public class HasServer {
* @param confName conf file name
* @param values customized values
* @throws IOException throw IOException
- * @throws KrbException e
+ * @throws HasException e
*/
public void updateConfFile(String confName, Map<String, String> values)
throws IOException, HasException {
@@ -277,7 +277,7 @@ public class HasServer {
* Get KDC Config from MySQL.
*
* @return Kdc config
- * @throws KrbException e
+ * @throws HasException e
*/
private Map<String, String> getKdcConf() throws HasException {
PreparedStatement preStm = null;
@@ -324,7 +324,7 @@ public class HasServer {
/**
* Update KDC conf file.
*
- * @throws KrbException e
+ * @throws HasException e
*/
private void updateKdcConf() throws HasException {
try {
@@ -347,7 +347,7 @@ public class HasServer {
* @param url url of connection
* @param user username of connection
* @param password password of connection
- * @throws KrbException e
+ * @throws HasException e
* @return MySQL JDBC connection
*/
private Connection startConnection(String driver, String url, String user,
@@ -422,7 +422,7 @@ public class HasServer {
/**
* Create kdc_config table in database.
* @param conn database connection
- * @throws KrbException e
+ * @throws HasException e
*/
private void createKdcTable(final Connection conn) throws HasException {
PreparedStatement preStm = null;
@@ -501,8 +501,7 @@ public class HasServer {
* Read in krb5-template.conf and substitute in the correct port.
*
* @return krb5 conf file
- * @throws IOException e
- * @throws KrbException e
+ * @throws HasException e
*/
public File generateKrb5Conf() throws HasException {
Map<String, String> kdcConf = getKdcConf();
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/93d5aa6d/kerby-backend/mysql-backend/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/pom.xml b/kerby-backend/mysql-backend/pom.xml
index af008be..a09124f 100644
--- a/kerby-backend/mysql-backend/pom.xml
+++ b/kerby-backend/mysql-backend/pom.xml
@@ -32,6 +32,11 @@
<version>1.6</version>
</dependency>
<dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>druid</artifactId>
+ <version>1.1.9</version>
+ </dependency>
+ <dependency>
<groupId>org.drizzle.jdbc</groupId>
<artifactId>drizzle-jdbc</artifactId>
<version>1.4</version>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/93d5aa6d/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
index 48c698e..4622c7a 100644
--- a/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
+++ b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
@@ -19,6 +19,7 @@
*/
package org.apache.kerby.kerberos.kdc.identitybackend;
+import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.dbutils.DbUtils;
import org.apache.kerby.config.Config;
import org.apache.kerby.kerberos.kerb.KrbException;
@@ -30,55 +31,67 @@ import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.Connection;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.sql.PreparedStatement;
import javax.sql.rowset.serial.SerialBlob;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
/**
* A MySQL based backend implementation.
*/
public class MySQLIdentityBackend extends AbstractIdentityBackend {
- private Connection connection;
- private String driver;
- private String url;
- private String user;
- private String password;
- private String identityTable;
private String keyInfoTable;
+ private String identityTable;
+ private static DruidDataSource dataSource = null;
private static final Logger LOG = LoggerFactory.getLogger(MySQLIdentityBackend.class);
/**
* Constructing an instance using specified config that contains anything
* to be used to initialize an MySQL Backend.
- * @param config . The config is used to config the backend.
+ *
+ * @param config used to config the backend
*/
public MySQLIdentityBackend(final Config config) {
setConfig(config);
}
- public MySQLIdentityBackend() { }
+ public MySQLIdentityBackend() {
+ }
/**
- * Start the MySQL connection.
+ * Create data base connection pool.
+ * @throws SQLException e
*/
- private void startConnection() throws KrbException {
- 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 KrbException("JDBC Driver Class not found. ", e);
- } catch (SQLException e) {
- throw new KrbException("Failed to connecting to MySQL. ", e);
- }
+ private void initializeDataSource(
+ String driver, String url, String user, String password) throws SQLException {
+ dataSource = new DruidDataSource();
+ dataSource.setDriverClassName(driver);
+ dataSource.setUrl(url);
+ dataSource.setUsername(user);
+ dataSource.setPassword(password);
+
+ dataSource.setInitialSize(10);
+ dataSource.setMinIdle(3);
+ dataSource.setMaxActive(80);
+ dataSource.setMaxWait(6000);
+ dataSource.setTestWhileIdle(true);
+ dataSource.setValidationQuery("SELECT 1");
+ dataSource.setTestOnBorrow(false);
+ dataSource.setTestOnReturn(false);
+ dataSource.setRemoveAbandoned(true);
+ dataSource.setRemoveAbandonedTimeout(180);
+ dataSource.setLogAbandoned(true);
+ dataSource.setMinEvictableIdleTimeMillis(300000);
+ dataSource.setTimeBetweenEvictionRunsMillis(90000);
+ dataSource.setPoolPreparedStatements(true);
+ dataSource.setMaxOpenPreparedStatements(20);
+ dataSource.setMaxPoolPreparedStatementPerConnectionSize(30);
+ dataSource.setAsyncInit(true);
+ dataSource.setFilters("stat");
}
/**
@@ -87,16 +100,27 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
@Override
protected void doInitialize() throws KrbException {
LOG.info("Initializing the MySQL identity backend.");
- driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true);
- user = getConfig().getString(MySQLConfKey.MYSQL_USER, true);
- password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD, true);
- String urlString = getConfig().getString(MySQLConfKey.MYSQL_URL, true);
- if (urlString == null || urlString.isEmpty()) {
- urlString = getBackendConfig().getString(MySQLConfKey.MYSQL_URL, true);
+ // Initialize data base connection pool
+ if (MySQLIdentityBackend.dataSource == null) {
+ String driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true);
+ String user = getConfig().getString(MySQLConfKey.MYSQL_USER, true);
+ String password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD, true);
+
+ String urlString = getConfig().getString(MySQLConfKey.MYSQL_URL, true);
+ if (urlString == null || urlString.isEmpty()) {
+ urlString = getBackendConfig().getString(MySQLConfKey.MYSQL_URL, true);
+ }
+
+ try {
+ initializeDataSource(driver, urlString, user, password);
+ } catch (SQLException e) {
+ LOG.error("Failed to initialize data source. " + e.toString());
+ throw new KrbException("Failed to initialize data source.", e);
+ }
}
- url = urlString;
+ Connection connection = null;
ResultSet resCheckTable = null;
PreparedStatement preInitialize = null;
PreparedStatement preKdcRealm = null;
@@ -104,7 +128,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
PreparedStatement preIdentity = null;
PreparedStatement preKey = null;
try {
- startConnection();
+ connection = dataSource.getConnection();
resCheckTable = connection.getMetaData().getTables(null, null, "kdc_config", null);
if (resCheckTable.next()) {
@@ -152,7 +176,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
preKey.executeUpdate();
} catch (SQLException e) {
- LOG.error("Error occurred while initialize MySQL backend." + e.toString());
+ LOG.error("Error occurred while initialize MySQL backend.", e);
throw new KrbException("Failed to create table in database. ", e);
} finally {
DbUtils.closeQuietly(resCheckTable);
@@ -161,7 +185,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
DbUtils.closeQuietly(resKdcRealm);
DbUtils.closeQuietly(preIdentity);
DbUtils.closeQuietly(preKey);
- doStop();
+ DbUtils.closeQuietly(connection);
}
}
@@ -170,24 +194,14 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
*/
@Override
protected void doStop() throws KrbException {
- try {
- closeConnection();
- if (connection.isClosed()) {
- LOG.info("Succeeded in closing connection with MySQL.");
- }
- } catch (SQLException e) {
- LOG.error("Failed to close connection with MySQL.");
- throw new KrbException("Failed to close connection with MySQL. ", e);
+ if (dataSource == null) {
+ return;
}
- }
-
- /**
- * Close the connection for stop().
- * @throws SQLException if SQLException handled
- */
- private void closeConnection() throws SQLException {
- if (!connection.isClosed()) {
- connection.close();
+ dataSource.close();
+ if (dataSource.isClosed()) {
+ LOG.info("Succeeded in closing connection with MySQL.");
+ } else {
+ throw new KrbException("Failed to close connection with MySQL.");
}
}
@@ -205,6 +219,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
long expireTime = identity.getExpireTime().getTime();
Map<EncryptionType, EncryptionKey> keys = identity.getKeys();
+ Connection connection = null;
PreparedStatement preIdentity = null;
PreparedStatement preKey = null;
@@ -215,13 +230,13 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
return duplicateIdentity;
} else {
try {
- startConnection();
+ connection = dataSource.getConnection();
connection.setAutoCommit(false);
// Insert identity to identity table
- String stmIdentity = "insert into " + identityTable
- + " (principal, key_version, kdc_flags, disabled, locked, created_time, expire_time)"
- + " values(?, ?, ?, ?, ?, ?, ?)";
+ String stmIdentity = "INSERT INTO " + identityTable
+ + " (principal, key_version, kdc_flags, disabled, locked,"
+ + " created_time, expire_time) VALUES(?, ?, ?, ?, ?, ?, ?)";
preIdentity = connection.prepareStatement(stmIdentity);
preIdentity.setString(1, principalName);
preIdentity.setInt(2, keyVersion);
@@ -234,8 +249,8 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
// Insert keys to key table
for (Map.Entry<EncryptionType, EncryptionKey> entry : keys.entrySet()) {
- String stmKey = "insert into " + keyInfoTable + " (key_type, kvno, key_value, principal)"
- + " values(?, ?, ?, ?)";
+ String stmKey = "INSERT INTO " + keyInfoTable
+ + " (key_type, kvno, key_value, principal) VALUES(?, ?, ?, ?)";
preKey = connection.prepareStatement(stmKey);
preKey.setString(1, entry.getKey().getName());
preKey.setInt(2, entry.getValue().getKvno());
@@ -249,7 +264,9 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
} catch (SQLException e) {
try {
LOG.info("Transaction is being rolled back.");
- connection.rollback();
+ if (connection != null) {
+ connection.rollback();
+ }
} catch (SQLException ex) {
throw new KrbException("Transaction roll back failed. ", ex);
}
@@ -258,7 +275,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
} finally {
DbUtils.closeQuietly(preIdentity);
DbUtils.closeQuietly(preKey);
- doStop();
+ DbUtils.closeQuietly(connection);
}
}
}
@@ -268,60 +285,56 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
*/
@Override
protected KrbIdentity doGetIdentity(final String principalName) throws KrbException {
- KrbIdentity krbIdentity = new KrbIdentity(principalName);
+ KrbIdentity krbIdentity = null;
+ Connection connection = null;
PreparedStatement preIdentity = null;
ResultSet resIdentity = null;
- PreparedStatement preKey = null;
- ResultSet resKey = null;
try {
- startConnection();
+ connection = dataSource.getConnection();
- // Get identity from identity table
- String stmIdentity = "SELECT * FROM " + identityTable + " where principal = ?";
+ // Get identity from identity and key table
+ String stmIdentity = String.format("SELECT * FROM %s a left join %s b on "
+ + "a.principal = b.principal where a.principal = ?", identityTable, keyInfoTable);
preIdentity = connection.prepareStatement(stmIdentity);
preIdentity.setString(1, principalName);
resIdentity = preIdentity.executeQuery();
+ List<EncryptionKey> keys = new ArrayList<>();
- if (!resIdentity.isBeforeFirst()) {
+ if (resIdentity.isBeforeFirst()) {
+ while (resIdentity.next()) {
+ if (krbIdentity == null) {
+ krbIdentity = new KrbIdentity(principalName);
+ krbIdentity.setKeyVersion(resIdentity.getInt("key_version"));
+ krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags"));
+ krbIdentity.setDisabled(resIdentity.getBoolean("disabled"));
+ krbIdentity.setLocked(resIdentity.getBoolean("locked"));
+ krbIdentity.setCreatedTime(new KerberosTime(resIdentity.getLong("created_time")));
+ krbIdentity.setExpireTime(new KerberosTime(resIdentity.getLong("expire_time")));
+ }
+
+ // Get key info
+ int kvno = resIdentity.getInt("kvno");
+ String keyType = resIdentity.getString("key_type");
+ EncryptionType eType = EncryptionType.fromName(keyType);
+ byte[] keyValue = resIdentity.getBytes("key_value");
+ EncryptionKey key = new EncryptionKey(eType, keyValue, kvno);
+ keys.add(key);
+ }
+ if (krbIdentity != null && keys.size() > 0) {
+ krbIdentity.addKeys(keys);
+ }
+ return krbIdentity;
+ } else {
return null;
}
-
- while (resIdentity.next()) {
- krbIdentity.setKeyVersion(resIdentity.getInt("key_version"));
- krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags"));
- krbIdentity.setDisabled(resIdentity.getBoolean("disabled"));
- krbIdentity.setLocked(resIdentity.getBoolean("locked"));
- krbIdentity.setCreatedTime(new KerberosTime(resIdentity.getLong("created_time")));
- krbIdentity.setExpireTime(new KerberosTime(resIdentity.getLong("expire_time")));
- }
-
- // Get keys from key table
- List<EncryptionKey> keys = new ArrayList<>();
- String stmKey = "SELECT * FROM " + keyInfoTable + " where principal = ?";
- preKey = connection.prepareStatement(stmKey);
- preKey.setString(1, principalName);
- resKey = preKey.executeQuery();
- while (resKey.next()) {
- int kvno = resKey.getInt("kvno");
- String keyType = resKey.getString("key_type");
- EncryptionType eType = EncryptionType.fromName(keyType);
- byte[] keyValue = resKey.getBytes("key_value");
- EncryptionKey key = new EncryptionKey(eType, keyValue, kvno);
- keys.add(key);
- }
-
- krbIdentity.addKeys(keys);
- return krbIdentity;
} catch (SQLException e) {
- LOG.error("Error occurred while getting identity.");
+ LOG.error("Error occurred while getting identity. " + e.toString());
throw new KrbException("Failed to get identity. ", e);
} finally {
DbUtils.closeQuietly(preIdentity);
DbUtils.closeQuietly(resIdentity);
- DbUtils.closeQuietly(preKey);
- DbUtils.closeQuietly(resKey);
- doStop();
+ DbUtils.closeQuietly(connection);
}
}
@@ -332,8 +345,10 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
protected KrbIdentity doUpdateIdentity(KrbIdentity identity) throws KrbException {
String principalName = identity.getPrincipalName();
try {
- doDeleteIdentity(principalName); // Delete former identity
- doAddIdentity(identity); // Insert new identity
+ // Delete old identity
+ doDeleteIdentity(principalName);
+ // Insert new identity
+ doAddIdentity(identity);
} catch (KrbException e) {
LOG.error("Error occurred while updating identity: " + principalName);
throw new KrbException("Failed to update identity. ", e);
@@ -347,20 +362,21 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
*/
@Override
protected void doDeleteIdentity(String principalName) throws KrbException {
+ Connection connection = null;
PreparedStatement preKey = null;
PreparedStatement preIdentity = null;
try {
- startConnection();
+ connection = dataSource.getConnection();
connection.setAutoCommit(false);
// Delete keys from key table
- String stmKey = "DELETE FROM " + keyInfoTable + " where principal = ?";
+ String stmKey = "DELETE FROM " + keyInfoTable + " WHERE principal = ?";
preKey = connection.prepareStatement(stmKey);
preKey.setString(1, principalName);
preKey.executeUpdate();
- // Dlete identity from identity table
- String stmIdentity = "DELETE FROM " + identityTable + " where principal = ? ";
+ // Delete identity from identity table
+ String stmIdentity = "DELETE FROM " + identityTable + " WHERE principal = ? ";
preIdentity = connection.prepareStatement(stmIdentity);
preIdentity.setString(1, principalName);
preIdentity.executeUpdate();
@@ -368,8 +384,10 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
connection.commit();
} catch (SQLException e) {
try {
- LOG.info("Transaction is being rolled back.");
- connection.rollback();
+ LOG.warn("Transaction is being rolled back.");
+ if (connection != null) {
+ connection.rollback();
+ }
} catch (SQLException ex) {
throw new KrbException("Transaction roll back failed. ", ex);
}
@@ -378,7 +396,7 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
} finally {
DbUtils.closeQuietly(preIdentity);
DbUtils.closeQuietly(preKey);
- doStop();
+ DbUtils.closeQuietly(connection);
}
}
@@ -388,10 +406,11 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
@Override
protected Iterable<String> doGetIdentities() throws KrbException {
List<String> identityNames = new ArrayList<>();
+ Connection connection = null;
PreparedStatement preSmt = null;
ResultSet result = null;
try {
- startConnection();
+ connection = dataSource.getConnection();
String statement = "SELECT * FROM " + identityTable;
preSmt = connection.prepareStatement(statement);
result = preSmt.executeQuery();
@@ -401,12 +420,12 @@ public class MySQLIdentityBackend extends AbstractIdentityBackend {
result.close();
preSmt.close();
} catch (SQLException e) {
- LOG.error("Error occurred while getting identities.");
+ LOG.error("Error occurred while getting identities.", e);
throw new KrbException("Failed to get identities. ", e);
} finally {
DbUtils.closeQuietly(preSmt);
DbUtils.closeQuietly(result);
- doStop();
+ DbUtils.closeQuietly(connection);
}
return identityNames;