package codeine.db.mysql.connectors; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.inject.Inject; import org.apache.log4j.Logger; import codeine.db.IStatusDatabaseConnector; import codeine.db.mysql.DbUtils; import codeine.jsons.global.ExperimentalConfJsonStore; import codeine.jsons.peer_status.PeerStatusJsonV2; import codeine.jsons.peer_status.PeerStatusString; import codeine.jsons.peer_status.PeerType; import codeine.utils.ExceptionUtils; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.Gson; public class StatusMysqlConnector implements IStatusDatabaseConnector{ private static final Logger log = Logger.getLogger(StatusMysqlConnector.class); @Inject private DbUtils dbUtils; @Inject private Gson gson; @Inject private ExperimentalConfJsonStore webConfJsonStore; private static final String TABLE_NAME = "ProjectStatusList"; public StatusMysqlConnector() { super(); } public StatusMysqlConnector(DbUtils dbUtils, Gson gson, ExperimentalConfJsonStore webConfJsonStore) { super(); this.dbUtils = dbUtils; this.gson = gson; this.webConfJsonStore = webConfJsonStore; } public void createTables() { if (webConfJsonStore.get().readonly_web_server()) { log.info("read only mode"); return; } String colsDefinition = "peer_key VARCHAR(150) NOT NULL PRIMARY KEY, data text, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, status VARCHAR(50) DEFAULT 'On' NOT NULL"; dbUtils.executeUpdate("create table if not exists " + TABLE_NAME + " (" + colsDefinition + ")"); } @Override public void putReplaceStatus(PeerStatusJsonV2 p) { String json = gson.toJson(p); log.info("will update status to " + dbUtils.server() + "\n" + json); dbUtils.executeUpdate("DELETE FROM "+TABLE_NAME+" WHERE peer_key = '" + p.peer_old_key() + "'"); dbUtils.executeUpdate("REPLACE INTO "+TABLE_NAME+" (peer_key, data, update_time ) VALUES (?, ?, CURRENT_TIMESTAMP())", p.peer_key(), json); } @Override public Map<String, PeerStatusJsonV2> getPeersStatus() { log.info("getPeersStatus " + dbUtils.server()); final Map<String, PeerStatusJsonV2> $ = Maps.newHashMap(); Function<ResultSet, Void> function = new Function<ResultSet, Void>() { @Override public Void apply(ResultSet rs){ try { String key = rs.getString(1); String value = rs.getString(2); PeerStatusJsonV2 peerStatus = gson.fromJson(value, PeerStatusJsonV2.class); peerStatus.status(PeerStatusString.valueOf(rs.getString("status"))); updateNodesWithPeer(peerStatus); $.put(key, peerStatus); return null; } catch (SQLException e) { throw ExceptionUtils.asUnchecked(e); } } }; dbUtils.executeQueryCompressed("select * from " + TABLE_NAME, function); return $; } private void updateNodesWithPeer(PeerStatusJsonV2 peerStatus) { peerStatus.updateNodesWithPeer(); } @Override public void updatePeersStatus(final long timeToRemove, final long timeToDisc) { final List<String> idToRemove = Lists.newArrayList(); final List<String> idToDisc = Lists.newArrayList(); Function<ResultSet, Void> function = new Function<ResultSet, Void>() { @Override public Void apply(ResultSet rs){ try { String key = rs.getString("peer_key"); // PeerStatusString status = PeerStatusString.valueOf(rs.getString("status")); String value = rs.getString("data"); String status = rs.getString("status"); PeerStatusJsonV2 peerStatus = gson.fromJson(value, PeerStatusJsonV2.class); PeerType peerType = peerStatus.peer_type(); long timeToRemovePeer = peerType == PeerType.Reporter ? timeToRemove + TimeUnit.DAYS.toMinutes(7) : timeToRemove; long timeToDiscPeer = peerType == PeerType.Reporter ? timeToDisc + TimeUnit.DAYS.toMinutes(7) : timeToDisc; long timeDiff = rs.getLong("TIME_DIFF"); log.debug("time diff is " + timeDiff); if (timeDiff > timeToRemovePeer){ log.info("time diff is " + timeDiff); log.info("deleting " + peerStatus); // rs.deleteRow(); idToRemove.add(key); } else if (timeDiff > timeToDiscPeer && !status.equals(PeerStatusString.Disc.toString())){ log.info("time diff is " + timeDiff); log.info("update to disc " + peerStatus); idToDisc.add(key); // rs.updateString("status", "Disc"); // rs.updateRow(); } return null; } catch (SQLException e) { throw ExceptionUtils.asUnchecked(e); } } }; dbUtils.executeUpdateableQuery("select *,TIMESTAMPDIFF(MINUTE,update_time,CURRENT_TIMESTAMP()) as TIME_DIFF from " + TABLE_NAME, function); if (webConfJsonStore.get().readonly_web_server()) { log.info("read only mode"); return; } for (String key : idToRemove) { log.info("deleting " + key); dbUtils.executeUpdate("DELETE from " + TABLE_NAME + " WHERE peer_key = ?", key); } for (String key : idToDisc) { log.info("discing " + key); dbUtils.executeUpdate("UPDATE " + TABLE_NAME + " SET status = '" + PeerStatusString.Disc.toString() + "' WHERE peer_key = ?", key); } } @Override public String server() { return dbUtils.toString(); } @Override public String toString() { return "StatusMysqlConnector [dbUtils=" + dbUtils + "]"; } }