Fix loading failures of JDBC drivers for SQL-based Identity stores

This commit is contained in:
Max Dor
2019-01-15 06:19:34 +01:00
committed by Max Dor
parent c689a3f161
commit d885932f45
10 changed files with 136 additions and 20 deletions

View File

@@ -129,7 +129,7 @@ dependencies {
compile 'org.xerial:sqlite-jdbc:3.20.0'
// PostgreSQL
compile 'org.postgresql:postgresql:42.1.4'
compile 'org.postgresql:postgresql:42.2.5'
// MariaDB/MySQL
compile 'org.mariadb.jdbc:mariadb-java-client:2.1.2'

View File

@@ -47,7 +47,7 @@ import io.kamax.mxisd.profile.ProfileManager;
import io.kamax.mxisd.profile.ProfileProviders;
import io.kamax.mxisd.session.SessionMananger;
import io.kamax.mxisd.storage.IStorage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqliteStorage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqlStorage;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
@@ -88,7 +88,7 @@ public class Mxisd {
srvFetcher = new RemoteIdentityServerFetcher(httpClient);
store = new OrmLiteSqliteStorage(cfg);
store = new OrmLiteSqlStorage(cfg);
keyMgr = CryptoFactory.getKeyManager(cfg.getKey());
signMgr = CryptoFactory.getSignatureManager(keyMgr, cfg.getServer());
ClientDnsOverwrite clientDns = new ClientDnsOverwrite(cfg.getDns().getOverwrite());

View File

@@ -0,0 +1,55 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2019 Kamax Sàrl
*
* https://www.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.sql;
import org.apache.commons.lang3.StringUtils;
public class BuiltInDriverLoader implements DriverLoader {
@Override
public void accept(String s) {
String className = null;
if (StringUtils.equals("sqlite", s)) {
className = "org.sqlite.JDBC";
}
if (StringUtils.equals("postgresql", s)) {
className = "org.postgresql.Driver";
}
if (StringUtils.equals("mariadb", s)) {
className = "org.mariadb.jdbc.Driver";
}
if (StringUtils.equals("mysql", s)) {
className = "org.mariadb.jdbc.Driver";
}
if (StringUtils.isNotEmpty(className)) {
try {
Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,26 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2019 Kamax Sàrl
*
* https://www.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.sql;
import java.util.function.Consumer;
public interface DriverLoader extends Consumer<String> {
}

View File

@@ -0,0 +1,38 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2019 Kamax Sàrl
*
* https://www.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.sql;
import java.util.Objects;
import java.util.ServiceLoader;
public class Drivers {
private static ServiceLoader<DriverLoader> svcLoader;
public static void load(String type) {
if (Objects.isNull(svcLoader)) {
svcLoader = ServiceLoader.load(DriverLoader.class);
}
svcLoader.iterator().forEachRemaining(drv -> drv.accept(type));
}
}

View File

@@ -37,11 +37,15 @@ public class SqlConnectionPool {
private ComboPooledDataSource ds;
public SqlConnectionPool(SqlConfig cfg) {
Drivers.load(cfg.getType());
ds = new ComboPooledDataSource();
ds.setJdbcUrl("jdbc:" + cfg.getType() + ":" + cfg.getConnection());
ds.setMinPoolSize(1);
ds.setMaxPoolSize(10);
ds.setAcquireIncrement(2);
ds.setAcquireRetryAttempts(10);
ds.setAcquireRetryDelay(1000);
}
public Connection get() throws SQLException {

View File

@@ -28,7 +28,7 @@ public class ConfigurationException extends RuntimeException {
private String detailedMsg;
public ConfigurationException(String key) {
super("Invalid or empty value for configuration item " + key);
super("Invalid or empty value for configuration item: " + key);
}
public ConfigurationException(Throwable t) {

View File

@@ -40,7 +40,6 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.time.Instant;
@@ -49,9 +48,9 @@ import java.util.Collection;
import java.util.List;
import java.util.Optional;
public class OrmLiteSqliteStorage implements IStorage {
public class OrmLiteSqlStorage implements IStorage {
private transient final Logger log = LoggerFactory.getLogger(OrmLiteSqliteStorage.class);
private transient final Logger log = LoggerFactory.getLogger(OrmLiteSqlStorage.class);
@FunctionalInterface
private interface Getter<T> {
@@ -71,11 +70,11 @@ public class OrmLiteSqliteStorage implements IStorage {
private Dao<ThreePidSessionDao, String> sessionDao;
private Dao<ASTransactionDao, String> asTxnDao;
public OrmLiteSqliteStorage(MxisdConfig cfg) {
public OrmLiteSqlStorage(MxisdConfig cfg) {
this(cfg.getStorage().getBackend(), cfg.getStorage().getProvider().getSqlite().getDatabase());
}
public OrmLiteSqliteStorage(String backend, String path) {
public OrmLiteSqlStorage(String backend, String path) {
if (StringUtils.isBlank(backend)) {
throw new ConfigurationException("storage.backend");
}
@@ -85,13 +84,6 @@ public class OrmLiteSqliteStorage implements IStorage {
}
withCatcher(() -> {
if (path.startsWith("/") && !path.startsWith("//")) {
File parent = new File(path).getParentFile();
if (!parent.mkdirs() && !parent.isDirectory()) {
throw new RuntimeException("Unable to create DB parent directory: " + parent);
}
}
ConnectionSource connPool = new JdbcConnectionSource("jdbc:" + backend + ":" + path);
invDao = createDaoAndTable(connPool, ThreePidInviteIO.class);
sessionDao = createDaoAndTable(connPool, ThreePidSessionDao.class);

View File

@@ -0,0 +1 @@
io.kamax.mxisd.backend.sql.BuiltInDriverLoader

View File

@@ -20,23 +20,23 @@
package io.kamax.mxisd.test.storage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqliteStorage;
import io.kamax.mxisd.storage.ormlite.OrmLiteSqlStorage;
import org.junit.Test;
import java.time.Instant;
public class OrmLiteSqliteStorageTest {
public class OrmLiteSqlStorageTest {
@Test
public void insertAsTxnDuplicate() {
OrmLiteSqliteStorage store = new OrmLiteSqliteStorage("sqlite", ":memory:");
OrmLiteSqlStorage store = new OrmLiteSqlStorage("sqlite", ":memory:");
store.insertTransactionResult("mxisd", "1", Instant.now(), "{}");
store.insertTransactionResult("mxisd", "2", Instant.now(), "{}");
}
@Test(expected = RuntimeException.class)
public void insertAsTxnSame() {
OrmLiteSqliteStorage store = new OrmLiteSqliteStorage("sqlite", ":memory:");
OrmLiteSqlStorage store = new OrmLiteSqlStorage("sqlite", ":memory:");
store.insertTransactionResult("mxisd", "1", Instant.now(), "{}");
store.insertTransactionResult("mxisd", "1", Instant.now(), "{}");
}