diff options
| author | Stephan Schwaer | 2015-09-30 17:17:46 +0200 |
|---|---|---|
| committer | Stephan Schwaer | 2015-09-30 17:17:46 +0200 |
| commit | 2ba39e9891998638829f8308c9b981076875c27f (patch) | |
| tree | 18b6ce535df09c601956a8855f6bfd5e1b902f70 /dozentenmodulserver/src/main/java | |
| parent | [client] Changed keylisteners in loginWindow to keyBindings. Added some Keybi... (diff) | |
| parent | Merge branch 'v1.1' of git.openslx.org:openslx-ng/tutor-module into v1.1 (diff) | |
| download | tutor-module-2ba39e9891998638829f8308c9b981076875c27f.tar.gz tutor-module-2ba39e9891998638829f8308c9b981076875c27f.tar.xz tutor-module-2ba39e9891998638829f8308c9b981076875c27f.zip | |
Merge branch 'v1.1' of git.openslx.org:openslx-ng/tutor-module into v1.1
Diffstat (limited to 'dozentenmodulserver/src/main/java')
6 files changed, 122 insertions, 72 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java index 97029e55..931b2f23 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java @@ -3,10 +3,7 @@ package org.openslx.bwlp.sat; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.sql.SQLException; -import java.util.Date; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.net.ssl.SSLContext; @@ -16,8 +13,7 @@ import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.thrift.transport.TTransportException; -import org.openslx.bwlp.sat.database.Database; -import org.openslx.bwlp.sat.database.mappers.DbImage; +import org.openslx.bwlp.sat.database.mappers.DbUser; import org.openslx.bwlp.sat.fileserv.FileServer; import org.openslx.bwlp.sat.maintenance.DeleteOldImages; import org.openslx.bwlp.sat.maintenance.DeleteOldLectures; @@ -30,15 +26,9 @@ import org.openslx.bwlp.sat.thrift.cache.VirtualizerList; import org.openslx.bwlp.sat.util.Configuration; import org.openslx.bwlp.sat.util.Identity; import org.openslx.bwlp.sat.web.WebServer; -import org.openslx.bwlp.thrift.iface.ImageSummaryRead; -import org.openslx.bwlp.thrift.iface.NetDirection; -import org.openslx.bwlp.thrift.iface.NetRule; -import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.thrifthelper.ThriftManager; import org.openslx.thrifthelper.ThriftManager.ErrorCallback; -import org.openslx.util.Json; import org.openslx.util.QuickTimer; -import org.openslx.util.QuickTimer.Task; public class App { @@ -118,6 +108,8 @@ public class App { // Start watch dog to ensure nobody else is messing with the vmstore QuickTimer.scheduleAtFixedDelay(new StorageUseCheck(), 10000, 60000); + // Set a flag that we need to convert userids if applicable + DbUser.checkIfLegacyUsersExist(); // Set up maintenance tasks DeleteOldImages.init(); @@ -138,29 +130,6 @@ public class App { t = new Thread(new WebServer(9080)); t.setDaemon(true); t.start(); - // DEBUG - if (DEBUG) { - Database.printCharsetInformation(); - List<ImageSummaryRead> allVisible; - try { - allVisible = DbImage.getAllVisible(new UserInfo("bla", "blu", null, null, null), null, 0); - LOGGER.info("Got " + allVisible.size()); - } catch (SQLException e) { - LOGGER.warn("could not test query getallvisible"); - } - QuickTimer.scheduleAtFixedDelay(new Task() { - @Override - public void fire() { - Database.printDebug(); - } - }, 100, 5000); - NetRule nr = new NetRule(2, NetDirection.OUT, "dsafg", 1336); - String data = Json.serialize(nr); - LOGGER.info(data); - Json.registerThriftClass(NetRule.class); - NetRule nn = Json.deserializeThrift(data, NetRule.class); - LOGGER.info(nn); - } Runtime.getRuntime().addShutdownHook(new Thread() { @Override diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java index af350a9b..1436aa36 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java @@ -439,6 +439,9 @@ public class DbLecture { } public static VmMetaData getClientLaunchData(String lectureId) throws SQLException, TNotFoundException { + byte[] config; + String lectureName; + String osKeyword; try (MysqlConnection connection = Database.getConnection()) { // Get required data about lecture and used image MysqlStatement stmt = connection.prepareStatement("SELECT" @@ -455,18 +458,9 @@ public class DbLecture { || rs.getLong("endtime") < now) { throw new TNotFoundException(); } - byte[] config = rs.getBytes("virtualizerconfig"); - if (config == null) { - return null; - } - VmwareMetaData meta = new VmwareMetaData(OperatingSystemList.get(), config, config.length); - meta.addDisplayName(rs.getString("lecturename")); - if (meta.getOs() == null) { - meta.setOs(rs.getString("virtoskeyword")); - } - meta.addHddTemplate("%VM_DISK_PATH%", "%VM_DISK_MODE%", "%VM_DISK_REDOLOGDIR%"); - meta.addEthernet(EthernetType.NAT); // TODO: Use config - meta.disableSuspend(); + config = rs.getBytes("virtualizerconfig"); + lectureName = rs.getString("lecturename"); + osKeyword = rs.getString("virtoskeyword"); // Everything worked so far, update statistics counters MysqlStatement upStmt = connection.prepareStatement("UPDATE" + " lecture SET lastused = UNIX_TIMESTAMP(), usecount = usecount + 1" @@ -474,11 +468,22 @@ public class DbLecture { upStmt.setString("lectureid", lectureId); upStmt.executeUpdate(); connection.commit(); - return meta; } catch (SQLException e) { LOGGER.error("Query failed in DbLecture.getClientLaunchData()", e); throw e; } + if (config == null) { + return null; + } + VmwareMetaData meta = new VmwareMetaData(OperatingSystemList.get(), config, config.length); + meta.addDisplayName(lectureName); + if (osKeyword != null) { + meta.setOs(osKeyword); + } + meta.addHddTemplate("%VM_DISK_PATH%", "%VM_DISK_MODE%", "%VM_DISK_REDOLOGDIR%"); + meta.addEthernet(EthernetType.NAT); // TODO: Use config + meta.disableSuspend(); + return meta; } public static void deleteOld(int minAgeDays) throws SQLException { diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java index 85774dde..bc63894c 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java @@ -16,10 +16,14 @@ import org.openslx.bwlp.sat.database.models.LocalUser; import org.openslx.bwlp.thrift.iface.SatelliteUserConfig; import org.openslx.bwlp.thrift.iface.TNotFoundException; import org.openslx.bwlp.thrift.iface.UserInfo; +import org.openslx.util.QuickTimer; +import org.openslx.util.QuickTimer.Task; import org.openslx.util.TimeoutHashMap; public class DbUser { + private static boolean legacyUsersExist = false; + public static class User { public final UserInfo ui; public final LocalUser local; @@ -119,24 +123,84 @@ public class DbUser { if (ui.eMail.length() > 50) { ui.eMail = ui.eMail.substring(0, 50); } + boolean recheckLegacy = true; try (MysqlConnection connection = Database.getConnection()) { - MysqlStatement stmt = connection.prepareStatement("INSERT INTO user" - + " (userid, firstname, lastname, email, organizationid, lastlogin, canlogin, issuperuser)" - + " VALUES" - + " (:userid, :firstname, :lastname, :email, :organizationid, UNIX_TIMESTAMP(), 1, 0)" - + " ON DUPLICATE KEY UPDATE lastlogin = UNIX_TIMESTAMP(), email = VALUES(email)," - + " firstname = VALUES(firstname), lastname = VALUES(lastname), organizationid = VALUES(organizationid)"); - stmt.setString("userid", ui.userId); - stmt.setString("firstname", ui.firstName); - stmt.setString("lastname", ui.lastName); - stmt.setString("email", ui.eMail); - stmt.setString("organizationid", ui.organizationId); - stmt.executeUpdate(); + if (!legacyUsersExist || !tryLegacyUserUpdate(connection, ui)) { + // No legacy messed up account found - use normal way + MysqlStatement insUpStmt = connection.prepareStatement("INSERT INTO user" + + " (userid, firstname, lastname, email, organizationid, lastlogin, canlogin, issuperuser)" + + " VALUES" + + " (:userid, :firstname, :lastname, :email, :organizationid, UNIX_TIMESTAMP(), 1, 0)" + + " ON DUPLICATE KEY UPDATE lastlogin = UNIX_TIMESTAMP(), email = VALUES(email)," + + " firstname = VALUES(firstname), lastname = VALUES(lastname), organizationid = VALUES(organizationid)"); + insUpStmt.setString("userid", ui.userId); + insUpStmt.setString("firstname", ui.firstName); + insUpStmt.setString("lastname", ui.lastName); + insUpStmt.setString("email", ui.eMail); + insUpStmt.setString("organizationid", ui.organizationId); + insUpStmt.executeUpdate(); + recheckLegacy = false; + } connection.commit(); } catch (SQLException e) { LOGGER.error("Query failed in DbUser.writeUserOnLogin()", e); throw e; } + if (recheckLegacy) { + // Run check again + checkIfLegacyUsersExist(); + } + } + + /** + * Try to update a legacy imported user and fix the entry + */ + private static boolean tryLegacyUserUpdate(MysqlConnection connection, UserInfo ui) throws SQLException { + // Well... don't look at the code below. The old server had a bug where it wrote + // wrong user ids to the data base. If we imported old data, the user info table + // might contain a messed up entry for the given user. So instead of a nice + // INSERT ... ON DUPLICATE KEY we have to do this funny stuff. + MysqlStatement findStmt = connection.prepareStatement("SELECT userid FROM user" + + " WHERE firstname = :firstname AND lastname = :lastname AND email = :email"); + findStmt.setString("firstname", ui.firstName); + findStmt.setString("lastname", ui.lastName); + findStmt.setString("email", "@" + ui.eMail + "@"); + ResultSet rs = findStmt.executeQuery(); + if (!rs.next()) + return false; + // We actually found an old imported entry - just update + String oldId = rs.getString("userid"); + MysqlStatement insUpStmt = connection.prepareStatement("UPDATE IGNORE user" + + " SET lastlogin = UNIX_TIMESTAMP(), email = :email, userid = :newuserid, organizationid = :organizationid" + + " WHERE userid = :olduserid"); + insUpStmt.setString("newuserid", ui.userId); + insUpStmt.setString("email", ui.eMail); + insUpStmt.setString("organizationid", ui.organizationId); + insUpStmt.setString("olduserid", oldId); + insUpStmt.executeUpdate(); + // Be extra safe: in case the update failed (dup key?) we patch the old entry so it doesn't look like an old one anymore + MysqlStatement fixStmt = connection.prepareStatement("UPDATE user SET" + + " email = 'void', emailnotifications = 0 WHERE userid = :olduserid"); + fixStmt.setString("olduserid", oldId); + fixStmt.executeUpdate(); + return true; + } + + public static void checkIfLegacyUsersExist() { + QuickTimer.scheduleOnce(new Task() { + @Override + public void fire() { + try (MysqlConnection connection = Database.getConnection()) { + MysqlStatement stmt = connection.prepareStatement("SELECT userid FROM user" + + " WHERE email = '@%@' LIMIT 1"); + ResultSet rs = stmt.executeQuery(); + legacyUsersExist = rs.next(); + } catch (SQLException e) { + LOGGER.error("Query failed in DbUser.checkIfLegacyUsersExist()", e); + } + LOGGER.info("Imported legacy users exist: " + Boolean.toString(legacyUsersExist)); + } + }); } public static User getCached(String userId) throws SQLException, TNotFoundException { diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java index b712c065..6c252ace 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java @@ -65,16 +65,12 @@ public class User { return null; // User locally known, use user-specific permission return AuthorizationError.ACCOUNT_SUSPENDED; } - // User not locally known - refresh organization cache first - LocalOrganization local = LocalData.getLocalOrganization(user.organizationId); - if (local == null && OrganizationList.find(user.organizationId) != null) { - Util.sleep(1000); // Since writing to DB is async.. (yeah I know) - local = LocalData.getLocalOrganization(user.organizationId); - } // User unknown, check per-organization login permission - if (local == null) + LocalOrganization local = LocalData.getLocalOrganization(user.organizationId); + if (local == null && OrganizationList.find(user.organizationId) == null) return AuthorizationError.INVALID_ORGANIZATION; - if (local.canLogin) + // Organization known an allowed to login + if (local != null && local.canLogin) return null; // Special case: If user is not allowed to login, check if there are no allowed // organizations yet. If so, automatically allow the organization of this user. diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java index ddaa729a..02412f08 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java @@ -156,9 +156,10 @@ public class SessionManager { throw new TInvocationException(); } LOGGER.info("Got user " + ui.userId + " for token " + token); - // TODO XXX HACK: Remove this once master server supplies role - if (ui.role == null) - ui.role = Role.TUTOR; + if (ui.role == null) { + // Fail-safe: No role supplied, assume student + ui.role = Role.STUDENT; + } // Valid reply, check if user is allowed to communicate with this satellite server AuthorizationError authError = User.canLogin(ui); if (authError != null) { diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java index e45273db..8bb356e1 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Constants.java @@ -14,6 +14,7 @@ public class Constants { public static final String INCOMPLETE_UPLOAD_SUFFIX = ".upload.partial"; public static final int MAX_UPLOADS; public static final int MAX_DOWNLOADS; + public static final int MAX_CONNECTIONS_PER_TRANSFER; public static final int MAX_MASTER_UPLOADS = 2; public static final int MAX_MASTER_DOWNLOADS = 3; public static final int TRANSFER_TIMEOUT = 15 * 1000; // 15s @@ -48,14 +49,28 @@ public class Constants { // Now maxMem is the amount of memory in MiB LOGGER.debug("Maximum JVM memory: " + maxMem + "MiB"); - MAX_UPLOADS = (int) Math.max(1, (maxMem - 64) / (FileChunk.CHUNK_SIZE_MIB * 2)); - MAX_DOWNLOADS = MAX_UPLOADS * 2; + int cpuCount = Runtime.getRuntime().availableProcessors(); int hashQueueLen = (int) (maxMem / 100); if (hashQueueLen < 1) { hashQueueLen = 1; } else if (hashQueueLen > 6) { hashQueueLen = 6; } + int maxPerTransfer = (int) Math.max(1, (maxMem - 400) / (FileChunk.CHUNK_SIZE_MIB * 8)); + if (maxPerTransfer > 4) { + maxPerTransfer = 4; + } + if (maxPerTransfer > cpuCount) { + maxPerTransfer = cpuCount; + } + int maxUploads = (int) Math.max(1, (maxMem - 64) / (FileChunk.CHUNK_SIZE_MIB * (hashQueueLen + 1))); + if (maxUploads > cpuCount * 4) { + maxUploads = cpuCount * 4; + } + + MAX_CONNECTIONS_PER_TRANSFER = maxPerTransfer; + MAX_UPLOADS = maxUploads; + MAX_DOWNLOADS = MAX_UPLOADS * 2; HASHCHECK_QUEUE_LEN = hashQueueLen; } } |
