public ClientSession createClientSession(IClientInfo client, String clientType) { // Both OE and BB share the session file. Don't stomp an existing file. if (client == null || !client.isConfigured()) { throw new IllegalStateException("Client not configured."); } clientType = clientType == null ? "" : clientType; ClientSession session = null; String tmpName = null; String targetName = null; try { File targetFile = getSessionFile(client.getLastActivationToken()); targetName = targetFile.getAbsolutePath(); if (targetFile.exists()) { session = new ClientSession(); session.read(targetFile); if (session.getLastActivationId() != client.getLastActivationId() || session.getUserId() != client.getUserId()) { // Existing session file found but it's clearly not ours. // A hash collision is improbable. If this occurs, its more likely to be a // bug. We can't safely rewrite the session file because another client // might later call getClientSession() and read our email. // This is a support concern. LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Found existing session, but the content is unexpected."); lmg.param(LoggingConsts.FILENAME, targetFile.getAbsolutePath()); m_logCategory.error(lmg.toString()); throw new ClientServiceException(""); } session.setActivationToken(client.getLastActivationToken()); } // targetFile already found. if (session == null) { UserAccount user = m_userService.getUserAccount(client.getCustomerId(), client.getUserId()); session = client.createSession(user); // What if the BB and OE create a session at the same time? // This ensures a unique filename. // The client who does the last renameTo() below wins the race // and that becomes the common session file. tmpName = targetFile.getAbsolutePath() + "_tmp_" + clientType; File tmpFile = new File(tmpName); session.write(tmpFile); // If 'targetFile' already exists it'll get clobbered. // Makes the session targetFile generation atomic. boolean ok = FileUtils.clobberingRename(tmpFile, targetFile); if (!ok) { throw new IOException("Rename failed"); } } // need to create session. } catch (Exception ex) { if (ex instanceof ClientServiceException) { // We already logged it. throw (ClientServiceException) ex; } LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Unable to generate session file."); lmg.param(LoggingConsts.USER_ID, client.getUserId()); lmg.param(LoggingConsts.TEMP_NAME, tmpName); lmg.param(LoggingConsts.FILENAME, targetName); m_logCategory.error(lmg.toString(), ex); throw new ClientServiceException(""); } return session; }
public void setKeyCreatingIfNeeded( List<? extends IClientInfo> clients, List<IClientInfo> clientsNeedingSignalUpdate, Connection c) throws SQLException { PreparedStatement select = null; // Create lazily. PreparedStatement update = null; try { select = c.prepareStatement("SELECT secure_hash_key FROM dat_user_account WHERE object_id=?"); for (IClientInfo client : clients) { int userId = client.getUserId(); // ensure dat_user_account.secure_hash_key is filled. select.setInt(1, userId); ResultSet rs = select.executeQuery(); if (!rs.next()) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("dat_user_account row not found"); lmg.param(LoggingConsts.USER_ID, userId); // possible that the user simply disappeared by the time we got here. m_logCategory.warn(lmg.toString()); continue; } boolean firstTimeCreate = false; byte[] key = rs.getBytes(1); if (key == null || key.length == 0) { if (update == null) { update = c.prepareStatement( "UPDATE dat_user_account SET secure_hash_key=? WHERE object_id=?"); } key = createNewRandomKey(); update.setBytes(1, key); update.setInt(2, userId); int ct = update.executeUpdate(); if (ct != 1) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Unable to update dat_user_account.secure_hash_key"); lmg.param(LoggingConsts.USER_ID, userId); m_logCategory.error(lmg.toString()); continue; } else { firstTimeCreate = true; } } // no existing key. client.getHashSupport().setHashKey(key); if (firstTimeCreate) { if (clientsNeedingSignalUpdate != null) { // EMSDEV-7854. Don't actually do // updateSignalFiles(client) right here; we want to avoid nfs usage in the middle of a // db // transaction. clientsNeedingSignalUpdate.add(client); } } } // each client. } finally { DbUtils.safeClose(select); DbUtils.safeClose(update); } }