diff --git a/src/com/serotonin/mango/MangoContextListener.java b/src/com/serotonin/mango/MangoContextListener.java index 52aed651fd..e265430887 100644 --- a/src/com/serotonin/mango/MangoContextListener.java +++ b/src/com/serotonin/mango/MangoContextListener.java @@ -176,13 +176,19 @@ private void initialized(ServletContextEvent evt) { } catch (Exception e) { log.error(e.getMessage(), e); } - + try { ApplicationBeans.getViewDaoBean().init(); + log.info("Cache views initialized"); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + try { ViewHierarchyCache.getInstance(); log.info("Cache views hierarchy initialized"); } catch (Exception e) { - log.error(e.getMessage(), e); + log.error(e); } initSchedule(); diff --git a/src/com/serotonin/mango/rt/RuntimeManager.java b/src/com/serotonin/mango/rt/RuntimeManager.java index 6f96ffd8ab..8eb4ef7945 100644 --- a/src/com/serotonin/mango/rt/RuntimeManager.java +++ b/src/com/serotonin/mango/rt/RuntimeManager.java @@ -23,14 +23,18 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; +import com.serotonin.db.IntValuePair; import com.serotonin.mango.db.dao.*; import com.serotonin.mango.rt.dataImage.*; import com.serotonin.mango.rt.event.*; import com.serotonin.mango.rt.event.schedule.ResetDailyLimitSendingEventRT; import com.serotonin.mango.rt.event.schedule.ScheduledExecuteInactiveEventRT; +import com.serotonin.mango.util.LoggingUtils; import com.serotonin.mango.view.event.NoneEventRenderer; import com.serotonin.mango.vo.User; +import com.serotonin.mango.vo.dataSource.PointLocatorVO; import com.serotonin.mango.vo.dataSource.http.ICheckReactivation; +import com.serotonin.mango.vo.dataSource.meta.MetaPointLocatorVO; import com.serotonin.mango.vo.mailingList.MailingList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -117,7 +121,7 @@ public class RuntimeManager { private final Map resetDailyLimitSentEmails = new ConcurrentHashMap<>(); - private boolean started = false; + private volatile boolean started = false; // // Lifecycle @@ -126,9 +130,6 @@ synchronized public void initialize(boolean safe) { throw new ShouldNeverHappenException( "RuntimeManager already started"); - // Set the started indicator to true. - started = true; - ScheduledExecuteInactiveEventService service = ScheduledExecuteInactiveEventService.getInstance(); MailingListService mailingListService = new MailingListService(); List mailingLists = mailingListService.getMailingLists(); @@ -152,13 +153,27 @@ synchronized public void initialize(boolean safe) { } // Initialize data sources that are enabled. - DataSourceService dataSourceService = new DataSourceService(); - List> configs = dataSourceService.getDataSources(); - List> pollingRound = new ArrayList<>(); - List> nonMetaDataSources = configs.stream().filter(dataSource -> dataSource.getType() != DataSourceVO.Type.META).collect(Collectors.toList()); - List> metaDataSources = configs.stream().filter(dataSource -> dataSource.getType() == DataSourceVO.Type.META).collect(Collectors.toList()); - initializeDataSources(safe, dataSourceService, nonMetaDataSources, pollingRound); - initializeDataSources(safe, dataSourceService, metaDataSources, pollingRound); + DataSourceDao dataSourceDao = new DataSourceDao(); + List> configs = dataSourceDao.getDataSources(); + List> pollingRound = new ArrayList>(); + for (DataSourceVO config : configs) { + + boolean isCheckToTrayEnableRun = (config instanceof ICheckReactivation); + boolean isToTrayEnable = false; + if (isCheckToTrayEnableRun) { + isToTrayEnable = ((ICheckReactivation) config).checkToTrayEnable(); + } + + if (config.isEnabled() || isToTrayEnable ) { + if (safe) { + config.setEnabled(false); + dataSourceDao.saveDataSource(config); + } else if (initializeDataSource(config)) + pollingRound.add(config); + } + } + + startPoints(); // Set up point links. PointLinkDao pointLinkDao = new PointLinkDao(); @@ -232,6 +247,9 @@ synchronized public void initialize(boolean safe) { startMaintenanceEvent(vo); } } + + // Set the started indicator to true. + started = true; } synchronized public void terminate() { @@ -356,7 +374,7 @@ private boolean initializeDataSource(DataSourceVO vo) { List dataSourcePoints = new DataPointDao() .getDataPoints(vo.getId(), null); for (DataPointVO dataPoint : dataSourcePoints) { - if (dataPoint.isEnabled()) + if (dataPoint.isEnabled() && started) startDataPointSafe(dataPoint); } @@ -467,6 +485,8 @@ private void startDataPoint(DataPointVO vo) { // Add/update it in the data source. ds.addDataPoint(dataPoint); + + LOG.info("Data point '" + vo.getExtendedName() + "' initialized"); } } } @@ -1046,22 +1066,78 @@ private void stopResetDailyLimitSentEmails(int mailingListId) { resetDailyLimitSentEmails.remove(mailingListId); } - private void initializeDataSources(boolean safe, DataSourceService dataSourceService, - List> configs, List> pollingRound) { - for (DataSourceVO config : configs) { + public boolean isStarted() { + return started; + } - boolean isCheckToTrayEnableRun = (config instanceof ICheckReactivation); - boolean isToTrayEnable = false; - if (isCheckToTrayEnableRun) { - isToTrayEnable = ((ICheckReactivation) config).checkToTrayEnable(); + private void startPoints() { + + DataPointService dataPointService = new DataPointService(); + List allPoints = dataPointService.getDataPoints(null, true); + List nonMetaDataPoints = allPoints.stream() + .filter(a -> !(a.getPointLocator() instanceof MetaPointLocatorVO)) + .collect(Collectors.toList()); + List metaDataPoints = allPoints.stream() + .filter(a -> a.getPointLocator() instanceof MetaPointLocatorVO) + .collect(Collectors.toList()); + + run(nonMetaDataPoints); + + List toRunning = new ArrayList<>(); + Set toCheck = new HashSet<>(); + int safe = 10; + for(DataPointVO dataPoint: metaDataPoints) { + collectMetaDataPointsFromContext(toCheck, toRunning, dataPoint, safe, allPoints); + } + + run(toRunning); + run(metaDataPoints); + } + + private void run(List dataPoints) { + for(DataPointVO dataPoint: dataPoints) { + if(dataPoint.isEnabled()) { + DataPointRT dataPointRT = getDataPoint(dataPoint.getId()); + if(dataPointRT == null) { + startDataPointSafe(dataPoint); + } } + } + } - if (config.isEnabled() || isToTrayEnable ) { - if (safe) { - config.setEnabled(false); - dataSourceService.saveDataSource(config); - } else if (initializeDataSource(config)) - pollingRound.add(config); + private void collectMetaDataPointsFromContext(Set toCheck, List toRunning, + DataPointVO dataPoint, int safe, + List allPoints) { + if(safe < 0) { + LOG.error("Recursion level exceeded: " + LoggingUtils.dataPointInfo(dataPoint)); + return; + } + if(dataPoint.isEnabled()) { + PointLocatorVO pointLocator = dataPoint.getPointLocator(); + if(pointLocator instanceof MetaPointLocatorVO) { + MetaPointLocatorVO metaPointLocator = (MetaPointLocatorVO) pointLocator; + if (metaPointLocator.getContext() != null && !metaPointLocator.getContext().isEmpty()) { + for (IntValuePair intValuePair : metaPointLocator.getContext()) { + if(intValuePair.getKey() > 0) { + DataPointRT dataPointRT = getDataPoint(intValuePair.getKey()); + if (dataPointRT == null) { + DataPointVO fromContextDataPoint = allPoints.stream() + .filter(a -> a.getId() == intValuePair.getKey()) + .findAny() + .orElse(null); + if (fromContextDataPoint != null) { + if (fromContextDataPoint.getPointLocator() instanceof MetaPointLocatorVO) { + collectMetaDataPointsFromContext(toCheck, toRunning, fromContextDataPoint, --safe, allPoints); + } + if (!toCheck.contains(fromContextDataPoint.getId())) { + toCheck.add(fromContextDataPoint.getId()); + toRunning.add(fromContextDataPoint); + } + } + } + } + } + } } } }