package com.owera.xaps.tr069.background; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import com.owera.common.log.Logger; import com.owera.common.scheduler.TaskDefaultImpl; import com.owera.xaps.dbi.DBI; import com.owera.xaps.dbi.Heartbeat; import com.owera.xaps.dbi.Syslog; import com.owera.xaps.dbi.SyslogConstants; import com.owera.xaps.dbi.SyslogEntry; import com.owera.xaps.dbi.SyslogFilter; import com.owera.xaps.dbi.util.SyslogClient; public class ActiveDeviceDetectionTask extends TaskDefaultImpl { private Logger logger = new Logger(); private DBI dbi; public static Map<String, Long> activeDevicesMap = new HashMap<String, Long>(); public ActiveDeviceDetectionTask(String taskName, DBI dbi) { super(taskName); this.dbi = dbi; } public static synchronized void addActiveDevice(String unitId, Long nextInformMs) { activeDevicesMap.put(unitId, System.currentTimeMillis() + nextInformMs); } public static int activeDevices() { return activeDevicesMap.size(); } @Override public void runImpl() throws Throwable { Long anHourAgo = System.currentTimeMillis() - 60 * 60000; logger.info("ActiveDeviceDetectionTask: Will check if some devices scheduled to return before " + new Date(anHourAgo) + " are too late"); Map<String, Long> inactiveUnits = cleanOld(anHourAgo); logger.info("ActiveDeviceDetectionTask: Have found " + inactiveUnits.size() + " inactive devices"); for (Entry<String, Long> entry : inactiveUnits.entrySet()) { String unitId = entry.getKey(); Syslog syslog = dbi.getXaps().getSyslog(); SyslogFilter sf = new SyslogFilter(); sf.setCollectorTmsStart(new Date(anHourAgo)); // look for syslog newer than 1 hour sf.setUnitId(unitId); boolean active = false; List<SyslogEntry> entries = syslog.read(sf, dbi.getXaps()); for (SyslogEntry sentry : entries) { if (sentry.getFacility() < SyslogConstants.FACILITY_SHELL && !sentry.getContent().contains(Heartbeat.MISSING_HEARTBEAT_ID)) { logger.notice("ActivceDeviceDetection: Found syslog activity for unit " + unitId + " at " + sentry.getCollectorTimestamp() + " : " + sentry.getContent()); active = true; break; } } if (active) { SyslogClient.notice(entry.getKey(), "ProvMsg: No provisioning at " + new Date(entry.getValue()) + " (as expected) or since, but device has been active since " + new Date(anHourAgo) + ". TR-069 client may have stopped", dbi.getXaps().getSyslog()); logger.notice("ActivceDeviceDetection: Unit " + entry.getKey() + ": No provisioning at " + new Date(entry.getValue()) + " (as expected) or since, but device has been active " + new Date(anHourAgo) + ". TR-069 client may have stopped"); } else { logger.info("ActivceDeviceDetection: Unit " + entry.getKey() + ": No provisioning at " + new Date(entry.getValue()) + " (as expected) or since, but device may be inactive since " + new Date(anHourAgo)); } } } private static synchronized Map<String, Long> cleanOld(long tms) { Iterator<String> iterator = activeDevicesMap.keySet().iterator(); Map<String, Long> removedUnitsMap = new HashMap<String, Long>(); while (iterator.hasNext()) { String unitId = iterator.next(); Long nextInformTms = activeDevicesMap.get(unitId); if (nextInformTms < tms) { iterator.remove(); removedUnitsMap.put(unitId, nextInformTms); } } return removedUnitsMap; } public static synchronized void remove(String unitId) { activeDevicesMap.remove(unitId); } @Override public Logger getLogger() { return logger; } }