/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2010-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.features.poller.remote.gwt.server;
import static org.opennms.core.utils.InetAddressUtils.str;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import org.hibernate.criterion.Restrictions;
import org.opennms.core.utils.BeanUtils;
import org.opennms.core.utils.LogUtils;
import org.opennms.features.poller.remote.gwt.client.AppStatusDetailsComputer;
import org.opennms.features.poller.remote.gwt.client.ApplicationDetails;
import org.opennms.features.poller.remote.gwt.client.ApplicationInfo;
import org.opennms.features.poller.remote.gwt.client.ApplicationState;
import org.opennms.features.poller.remote.gwt.client.GWTLatLng;
import org.opennms.features.poller.remote.gwt.client.GWTLocationMonitor;
import org.opennms.features.poller.remote.gwt.client.GWTLocationSpecificStatus;
import org.opennms.features.poller.remote.gwt.client.GWTMarkerState;
import org.opennms.features.poller.remote.gwt.client.GWTMonitoredService;
import org.opennms.features.poller.remote.gwt.client.GWTPollResult;
import org.opennms.features.poller.remote.gwt.client.LocationMonitorState;
import org.opennms.features.poller.remote.gwt.client.Status;
import org.opennms.features.poller.remote.gwt.client.StatusDetails;
import org.opennms.features.poller.remote.gwt.client.location.LocationDetails;
import org.opennms.features.poller.remote.gwt.client.location.LocationInfo;
import org.opennms.features.poller.remote.gwt.server.geocoding.Geocoder;
import org.opennms.features.poller.remote.gwt.server.geocoding.GeocoderException;
import org.opennms.netmgt.dao.ApplicationDao;
import org.opennms.netmgt.dao.LocationMonitorDao;
import org.opennms.netmgt.dao.MonitoredServiceDao;
import org.opennms.netmgt.model.OnmsApplication;
import org.opennms.netmgt.model.OnmsCriteria;
import org.opennms.netmgt.model.OnmsIpInterface;
import org.opennms.netmgt.model.OnmsLocationMonitor;
import org.opennms.netmgt.model.OnmsLocationSpecificStatus;
import org.opennms.netmgt.model.OnmsMonitoredService;
import org.opennms.netmgt.model.OnmsMonitoringLocationDefinition;
import org.opennms.netmgt.model.OnmsSnmpInterface;
import org.opennms.netmgt.model.PollStatus;
import org.opennms.netmgt.model.OnmsLocationMonitor.MonitorStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>DefaultLocationDataService class.</p>
*/
public class DefaultLocationDataService implements LocationDataService, InitializingBean {
/**
* MonitorTracker
*
* @author brozow
*/
public class MonitorTracker {
Map<String, List<OnmsLocationMonitor>> m_monitors = new HashMap<String, List<OnmsLocationMonitor>>();
public void onMonitor(OnmsLocationMonitor locationMon) {
List<OnmsLocationMonitor> monitors = getMonitorList(locationMon.getDefinitionName());
monitors.add(locationMon);
}
private List<OnmsLocationMonitor> getMonitorList(String definitionName) {
List<OnmsLocationMonitor> monitors = m_monitors.get(definitionName);
if (monitors == null) {
monitors = new ArrayList<OnmsLocationMonitor>();
m_monitors.put(definitionName, monitors);
}
return monitors;
}
public Collection<GWTLocationMonitor> drain(String defName) {
final Collection<GWTLocationMonitor> gwtMonitors = new ArrayList<GWTLocationMonitor>();
if (!m_monitors.containsKey(defName)) return gwtMonitors;
List<OnmsLocationMonitor> monitors = m_monitors.get(defName);
for (OnmsLocationMonitor monitor : monitors) {
gwtMonitors.add(transformLocationMonitor(monitor));
}
return gwtMonitors;
}
}
private static final int AVAILABILITY_MS = 1000 * 60 * 60 * 24; // 1 day
@Autowired
private LocationMonitorDao m_locationDao;
@Autowired
private ApplicationDao m_applicationDao;
@Autowired
private MonitoredServiceDao m_monitoredServiceDao;
@Autowired
private Geocoder m_geocoder;
/**
* <p>setLocationMonitorDao</p>
*
* @param dao a {@link org.opennms.netmgt.dao.LocationMonitorDao} object.
*/
public void setLocationMonitorDao(final LocationMonitorDao dao) {
m_locationDao = dao;
}
/**
* <p>setApplicationDao</p>
*
* @param dao a {@link org.opennms.netmgt.dao.ApplicationDao} object.
*/
public void setApplicationDao(final ApplicationDao dao) {
m_applicationDao = dao;
}
/**
* <p>setMonitoredServiceDao</p>
*
* @param dao a {@link org.opennms.netmgt.dao.MonitoredServiceDao} object.
*/
public void setMonitoredServiceDao(final MonitoredServiceDao dao) {
m_monitoredServiceDao = dao;
}
/**
* <p>setGeocoder</p>
*
* @param geocoder a {@link org.opennms.features.poller.remote.gwt.server.geocoding.Geocoder} object.
*/
public void setGeocoder(final Geocoder geocoder) {
m_geocoder = geocoder;
}
private CountDownLatch m_initializationLatch = new CountDownLatch(1);
private volatile Map<String, MonitorStatus> m_monitorStatuses = new HashMap<String, MonitorStatus>();
// whether to save monitoring-locations.xml changes
public boolean m_save = true;
/**
* <p>Constructor for DefaultLocationDataService.</p>
*/
public DefaultLocationDataService() {
}
/**
* <p>setSave</p>
*
* @param save a boolean.
*/
public void setSave(final boolean save) {
m_save = save;
}
/**
* <p>afterPropertiesSet</p>
*/
@Override
public void afterPropertiesSet() throws Exception {
BeanUtils.assertAutowiring(this);
initialize();
}
/**
* <p>initialize</p>
*/
public void initialize() {
new InitializationThread().start();
}
private class InitializationThread extends Thread {
public InitializationThread() {
}
public void run() {
updateGeolocations();
}
}
/** {@inheritDoc} */
@Transactional
public LocationInfo getLocationInfo(final String locationName) {
waitForGeocoding("getLocationInfo");
final OnmsMonitoringLocationDefinition def = m_locationDao.findMonitoringLocationDefinition(locationName);
if (def == null) {
LogUtils.warnf(this, "no monitoring location found for name %s", locationName);
return null;
}
return getLocationInfo(def);
}
/**
* <p>getLocationInfo</p>
*
* @param def a {@link org.opennms.netmgt.model.OnmsMonitoringLocationDefinition} object.
* @return a {@link org.opennms.features.poller.remote.gwt.client.location.LocationInfo} object.
*/
@Transactional
public LocationInfo getLocationInfo(final OnmsMonitoringLocationDefinition def) {
waitForGeocoding("getLocationInfo");
if (def == null) {
LogUtils.warnf(this, "no location definition specified");
return null;
}
final StatusDetails monitorStatus = getStatusDetailsForLocation(def);
return getLocationInfo(def, monitorStatus);
}
private LocationInfo getLocationInfo(final OnmsMonitoringLocationDefinition def, final StatusDetails monitorStatus) {
GWTLatLng latLng = getLatLng(def, false);
if (latLng == null) {
LogUtils.debugf(this, "no geolocation or coordinates found, using OpenNMS World HQ");
latLng = new GWTLatLng(35.715751, -79.16262);
}
final GWTMarkerState state = new GWTMarkerState(def.getName(), latLng, Status.UNKNOWN);
final LocationInfo locationInfo = new LocationInfo(
def.getName(),
def.getArea(),
def.getGeolocation(),
latLng.getCoordinates(),
def.getPriority(),
state,
null,
def.getTags()
);
state.setStatus(monitorStatus.getStatus());
locationInfo.setStatusDetails(monitorStatus);
//LogUtils.debugf(this, "getLocationInfo(%s) returning %s", def.getName(), locationInfo.toString());
return locationInfo;
}
/** {@inheritDoc} */
@Transactional
public StatusDetails getStatusDetailsForLocation(final OnmsMonitoringLocationDefinition def) {
waitForGeocoding("getStatusDetails");
final DefaultLocationDataService.MonitorStatusTracker mst = new DefaultLocationDataService.MonitorStatusTracker(def.getName());
final List<GWTLocationMonitor> monitors = new ArrayList<GWTLocationMonitor>();
for (OnmsLocationMonitor mon : m_locationDao.findByLocationDefinition(def)) {
monitors.add(transformLocationMonitor(mon));
}
for (OnmsLocationSpecificStatus status : m_locationDao.getMostRecentStatusChangesForLocation(def.getName())) {
mst.onStatus(status);
}
LocationMonitorState monitorState = new LocationMonitorState(monitors, mst.drain());
StatusDetails statusDetails = monitorState.getStatusDetails();
LogUtils.debugf(this, "getStatusDetails(%s) returning %s", def.getName(), statusDetails);
return statusDetails;
}
/** {@inheritDoc} */
@Transactional
public LocationInfo getLocationInfoForMonitor(Integer monitorId) {
waitForGeocoding("getLocationInfoForMonitor");
final OnmsCriteria criteria = new OnmsCriteria(OnmsLocationMonitor.class).add(Restrictions.eq("id", monitorId));
final List<OnmsLocationMonitor> monitors = m_locationDao.findMatching(criteria);
if (monitors == null) {
LogUtils.warnf(this, "unable to get location monitor list for monitor ID '%d'", monitorId);
return null;
}
final String definitionName = monitors.get(0).getDefinitionName();
final OnmsMonitoringLocationDefinition def = m_locationDao.findMonitoringLocationDefinition(definitionName);
if (def == null) {
LogUtils.warnf(this, "unable to find monitoring location definition for '%s'", definitionName);
return null;
}
return getLocationInfo(def);
}
/** {@inheritDoc} */
@Transactional
public ApplicationInfo getApplicationInfo(final String applicationName) {
waitForGeocoding("getApplicationInfo");
final OnmsApplication app = m_applicationDao.findByName(applicationName);
if (app == null) {
LogUtils.warnf(this, "no application found with name '%s'", applicationName);
}
return getApplicationInfo(app);
}
/**
* <p>getApplicationInfo</p>
*
* @param app a {@link org.opennms.netmgt.model.OnmsApplication} object.
* @return a {@link org.opennms.features.poller.remote.gwt.client.ApplicationInfo} object.
*/
@Transactional
public ApplicationInfo getApplicationInfo(final OnmsApplication app) {
waitForGeocoding("getApplicationInfo");
ApplicationInfo info = null;
if (app == null) {
LogUtils.warnf(this, "no application specified");
} else {
info = getApplicationInfo(app, getStatusDetailsForApplication(app));
}
return info;
}
/** {@inheritDoc} */
@Transactional
public StatusDetails getStatusDetailsForApplication(final OnmsApplication app) {
waitForGeocoding("getStatusDetailsForApplication");
List<GWTLocationSpecificStatus> statuses = new ArrayList<GWTLocationSpecificStatus>();
final Date to = new Date();
final Date from = new Date(to.getTime() - AVAILABILITY_MS);
final Collection<OnmsMonitoredService> services = m_monitoredServiceDao.findByApplication(app);
final Set<GWTLocationMonitor> monitors = new LinkedHashSet<GWTLocationMonitor>();
final Set<GWTMonitoredService> gwtServices = new LinkedHashSet<GWTMonitoredService>(services.size());
for (final OnmsMonitoredService service : services) {
gwtServices.add(transformMonitoredService(service));
}
for (OnmsLocationSpecificStatus status : m_locationDao.getStatusChangesForApplicationBetween(to, from, app.getName())) {
monitors.add(transformLocationMonitor(status.getLocationMonitor()));
statuses.add(transformLocationSpecificStatus(status));
}
StatusDetails statusDetails = new AppStatusDetailsComputer(from, to, monitors, gwtServices, statuses).compute();
LogUtils.warnf(this, "getStatusDetailsForApplication(%s) returning %s", app.getName(), statusDetails);
return statusDetails;
}
/**
* <p>getStatusDetailsForApplicationOld</p>
*
* @param app a {@link org.opennms.netmgt.model.OnmsApplication} object.
* @return a {@link org.opennms.features.poller.remote.gwt.client.StatusDetails} object.
*/
@Transactional
public StatusDetails getStatusDetailsForApplicationOld(final OnmsApplication app) {
waitForGeocoding("getStatusDetailsForApplication");
List<GWTLocationSpecificStatus> statuses = new ArrayList<GWTLocationSpecificStatus>();
final Date to = new Date();
final Date from = new Date(to.getTime() - AVAILABILITY_MS);
final Collection<OnmsMonitoredService> services = m_monitoredServiceDao.findByApplication(app);
final List <GWTLocationMonitor> monitors = new ArrayList<GWTLocationMonitor>();
final Set<GWTMonitoredService> gwtServices = new LinkedHashSet<GWTMonitoredService>(services.size());
for (final OnmsMonitoredService service : services) {
gwtServices.add(transformMonitoredService(service));
}
for (final OnmsLocationMonitor monitor : m_locationDao.findByApplication(app)) {
monitors.add(transformLocationMonitor(monitor));
for (final OnmsLocationSpecificStatus locationSpecificStatus : m_locationDao.getStatusChangesForLocationBetween(from, to, monitor.getDefinitionName())) {
if (services.contains(locationSpecificStatus.getMonitoredService())) {
statuses.add(transformLocationSpecificStatus(locationSpecificStatus));
}
}
}
StatusDetails statusDetails = new AppStatusDetailsComputer(from, to, monitors, gwtServices, statuses).compute();
LogUtils.warnf(this, "getStatusDetailsForApplication(%s) returning %s", app.getName(), statusDetails);
return statusDetails;
}
/** {@inheritDoc} */
@Transactional
public ApplicationInfo getApplicationInfo(final OnmsApplication app, final StatusDetails status) {
waitForGeocoding("getApplicationInfo");
if (app == null) {
LogUtils.warnf(this, "no application specified");
return null;
}
final Set<GWTMonitoredService> services = new TreeSet<GWTMonitoredService>();
final Set<String> locationNames = new TreeSet<String>();
for (final OnmsMonitoredService service : m_monitoredServiceDao.findByApplication(app)) {
services.add(transformMonitoredService(service));
}
for (final OnmsLocationMonitor mon : m_locationDao.findByApplication(app)) {
locationNames.add(mon.getDefinitionName());
}
final ApplicationInfo applicationInfo = new ApplicationInfo(app.getId(), app.getName(), services, locationNames, status);
LogUtils.debugf(this, "getApplicationInfo(%s) returning %s", app.getName(), applicationInfo.toString());
return applicationInfo;
}
/** {@inheritDoc} */
@Transactional
public LocationDetails getLocationDetails(final String locationName) {
waitForGeocoding("getLocationDetails");
final OnmsMonitoringLocationDefinition def = m_locationDao.findMonitoringLocationDefinition(locationName);
if (def == null) {
LogUtils.warnf(this, "no monitoring location found for name %s", locationName);
return null;
}
return getLocationDetails(def);
}
/**
* <p>getLocationDetails</p>
*
* @param def a {@link org.opennms.netmgt.model.OnmsMonitoringLocationDefinition} object.
* @return a {@link org.opennms.features.poller.remote.gwt.client.location.LocationDetails} object.
*/
@Transactional
public LocationDetails getLocationDetails(final OnmsMonitoringLocationDefinition def) {
waitForGeocoding("getLocationDetails");
final LocationDetails ld = new LocationDetails();
final DefaultLocationDataService.MonitorStatusTracker mst = new DefaultLocationDataService.MonitorStatusTracker(def.getName());
final DefaultLocationDataService.ApplicationStatusTracker ast = new DefaultLocationDataService.ApplicationStatusTracker(def.getName());
final List<GWTLocationMonitor> monitors = new ArrayList<GWTLocationMonitor>();
for (OnmsLocationMonitor mon : m_locationDao.findByLocationDefinition(def)) {
monitors.add(transformLocationMonitor(mon));
}
final Set<ApplicationInfo> applications = new HashSet<ApplicationInfo>();
// final Map<String, Set<OnmsMonitoredService>> services = new HashMap<String, Set<OnmsMonitoredService>>();
for (final OnmsApplication application : m_applicationDao.findAll()) {
applications.add(transformApplication(m_monitoredServiceDao.findByApplication(application), application));
}
// for (final OnmsMonitoredService service : m_monitoredServiceDao.findAll()) {
// for (final OnmsApplication app : service.getApplications()) {
// final String appName = app.getName();
// Set<OnmsMonitoredService> serv = services.get(appName);
// if (serv == null) {
// serv = new HashSet<OnmsMonitoredService>();
// services.put(appName, serv);
// }
// serv.add(service);
// }
// }
final Date to = new Date();
final Date from = new Date(to.getTime() - AVAILABILITY_MS);
for (OnmsLocationSpecificStatus status : m_locationDao.getMostRecentStatusChangesForLocation(def.getName())) {
mst.onStatus(status);
ast.onStatus(status);
}
ld.setLocationMonitorState(new LocationMonitorState(monitors, mst.drain()));
ld.setApplicationState(new ApplicationState(from, to, applications, monitors, ast.drainStatuses()));
LogUtils.debugf(this, "getLocationDetails(%s) returning %s", def.getName(), ld);
return ld;
}
/** {@inheritDoc} */
@Transactional
public ApplicationDetails getApplicationDetails(final String applicationName) {
waitForGeocoding("getApplicationDetails");
final OnmsApplication app = m_applicationDao.findByName(applicationName);
return getApplicationDetails(app);
}
/**
* <p>getApplicationDetails</p>
*
* @param app a {@link org.opennms.netmgt.model.OnmsApplication} object.
* @return a {@link org.opennms.features.poller.remote.gwt.client.ApplicationDetails} object.
*/
@Transactional
public ApplicationDetails getApplicationDetails(final OnmsApplication app) {
waitForGeocoding("getApplicationDetails");
final ApplicationInfo applicationInfo = getApplicationInfo(app, StatusDetails.unknown());
List<GWTLocationSpecificStatus> statuses = new ArrayList<GWTLocationSpecificStatus>();
final Date to = new Date();
final Date from = new Date(to.getTime() - AVAILABILITY_MS);
final Collection<OnmsMonitoredService> services = m_monitoredServiceDao.findByApplication(app);
final List <GWTLocationMonitor> monitors = new ArrayList<GWTLocationMonitor>();
for (final OnmsLocationMonitor monitor : m_locationDao.findByApplication(app)) {
monitors.add(transformLocationMonitor(monitor));
for (final OnmsLocationSpecificStatus locationSpecificStatus : m_locationDao.getStatusChangesForLocationBetween(from, to, monitor.getDefinitionName())) {
if (services.contains(locationSpecificStatus.getMonitoredService())) {
statuses.add(transformLocationSpecificStatus(locationSpecificStatus));
}
}
}
ApplicationDetails details = new ApplicationDetails(applicationInfo, from, to, monitors, statuses);
LogUtils.warnf(this, "getApplicationDetails(%s) returning %s", app.getName(), details);
return details;
}
/** {@inheritDoc} */
@Transactional
public Collection<LocationInfo> getUpdatedLocationsBetween(final Date startDate, final Date endDate) {
waitForGeocoding("getApplicationDetails");
final Collection<LocationInfo> locations = new ArrayList<LocationInfo>();
final Map<String, OnmsMonitoringLocationDefinition> definitions = new HashMap<String, OnmsMonitoringLocationDefinition>();
// check for any monitors that have changed status
for (OnmsMonitoringLocationDefinition def : m_locationDao.findAllMonitoringLocationDefinitions()) {
for (OnmsLocationMonitor mon : m_locationDao.findByLocationDefinition(def)) {
final MonitorStatus status = m_monitorStatuses.get(mon.getDefinitionName());
if (status == null || !status.equals(mon.getStatus())) {
definitions.put(def.getName(), def);
m_monitorStatuses.put(def.getName(), mon.getStatus());
}
}
}
// check for any definitions that have status updates
for (final OnmsLocationSpecificStatus status : m_locationDao.getStatusChangesBetween(startDate, endDate)) {
final String definitionName = status.getLocationMonitor().getDefinitionName();
if (!definitions.containsKey(definitionName)) {
definitions.put(definitionName, m_locationDao.findMonitoringLocationDefinition(definitionName));
}
}
for (final OnmsMonitoringLocationDefinition def : definitions.values()) {
final LocationInfo location = getLocationInfo(def);
locations.add(location);
}
return locations;
}
/** {@inheritDoc} */
@Transactional
public GWTLatLng getLatLng(final OnmsMonitoringLocationDefinition def, boolean x) {
GWTLatLng latLng = null;
final String coordinateMatchString = "^\\s*[\\-\\d\\.]+\\s*,\\s*[\\-\\d\\.]+\\s*$";
// first, see if we already have coordinates
if (def.getCoordinates() != null && def.getCoordinates().matches(coordinateMatchString)) {
final String[] coordinates = def.getCoordinates().split(",");
latLng = new GWTLatLng(Double.valueOf(coordinates[0]), Double.valueOf(coordinates[1]));
}
// if not, see if geolocation is coordinates
if (latLng == null) {
LogUtils.debugf(this, "using geolocation: %s", def.getGeolocation());
if (def.getGeolocation() != null && def.getGeolocation().matches(coordinateMatchString)) {
final String[] coordinates = def.getGeolocation().split(",");
latLng = new GWTLatLng(Double.valueOf(coordinates[0]), Double.valueOf(coordinates[1]));
}
}
// otherwise, try to geocode it
if (latLng == null && def.getGeolocation() != null && !def.getGeolocation().equals("")) {
try {
latLng = m_geocoder.geocode(def.getGeolocation());
LogUtils.debugf(this, "got coordinates %s for geolocation %s", latLng.getCoordinates(), def.getGeolocation());
} catch (GeocoderException e) {
LogUtils.warnf(this, e, "unable to geocode %s", def.getGeolocation());
}
}
return latLng;
}
/** {@inheritDoc} */
@Transactional
public void handleAllMonitoringLocationDefinitions(final Collection<LocationDefHandler> handlers) {
waitForGeocoding("handleAllMonitoringLocationDefinitions");
final Collection<OnmsMonitoringLocationDefinition> definitions = m_locationDao.findAllMonitoringLocationDefinitions();
for (LocationDefHandler handler : handlers) {
handler.start(definitions.size());
}
for (final OnmsMonitoringLocationDefinition def : definitions) {
for (LocationDefHandler handler : handlers) {
handler.handle(def);
/*
* final LocationUpdatedRemoteEvent event = new LocationUpdatedRemoteEvent(m_locationDataService.getLocationInfo(def, m_includeStatus));
* getEventService().addEventUserSpecific(event);
*/
}
}
for (final LocationDefHandler handler : handlers) {
handler.finish();
}
m_locationDao.saveMonitoringLocationDefinitions(definitions);
}
/** {@inheritDoc} */
@Transactional
public void handleAllApplications(final Collection<ApplicationHandler> handlers) {
waitForGeocoding("handleAllApplications");
final Collection<OnmsApplication> apps = m_applicationDao.findAll();
for (final ApplicationHandler handler : handlers) {
handler.start(apps.size());
}
for (final OnmsApplication app : apps) {
for (final ApplicationHandler handler : handlers) {
handler.handle(app);
}
}
for (final ApplicationHandler handler : handlers) {
handler.finish();
}
}
/** {@inheritDoc} */
@Transactional
public Collection<ApplicationInfo> getApplicationsForLocation(final LocationInfo locationInfo) {
waitForGeocoding("getApplicationsForLocation");
final Map<String,ApplicationInfo> apps = new HashMap<String,ApplicationInfo>();
for (final OnmsLocationSpecificStatus status : m_locationDao.getMostRecentStatusChangesForLocation(locationInfo.getName())) {
for (final OnmsApplication app : status.getMonitoredService().getApplications()) {
if (!apps.containsKey(app.getName())) {
apps.put(app.getName(), getApplicationInfo(app));
}
}
}
return apps.values();
}
void waitForGeocoding(final String method) {
if (m_initializationLatch.getCount() > 0) {
LogUtils.warnf(this, "%s() waiting for geocoding to finish", method);
try {
m_initializationLatch.await();
} catch (InterruptedException e) {
LogUtils.warnf(this, e, "%s() interrupted while waiting for geocoding completion", method);
Thread.currentThread().interrupt();
}
}
}
/**
* <p>updateGeolocations</p>
*/
public void updateGeolocations() {
LogUtils.infof(this, "geolocating monitoring location definitions");
final Collection<OnmsMonitoringLocationDefinition> definitions = m_locationDao.findAllMonitoringLocationDefinitions();
for (final OnmsMonitoringLocationDefinition def : definitions) {
final GWTLatLng latLng = getLatLng(def, true);
if (latLng != null) {
def.setCoordinates(latLng.getCoordinates());
}
}
if (m_save) {
m_locationDao.saveMonitoringLocationDefinitions(definitions);
}
LogUtils.infof(this, "finished geolocating monitoring location definitions");
updateGeolocationsComplete();
}
/**
* <p>updateGeolocationsComplete</p>
*/
public void updateGeolocationsComplete() {
m_initializationLatch.countDown();
}
private static GWTPollResult transformPollResult(final PollStatus pollStatus) {
final GWTPollResult gResult = new GWTPollResult();
gResult.setReason(pollStatus.getReason());
gResult.setResponseTime(pollStatus.getResponseTime());
gResult.setStatus(pollStatus.getStatusName());
gResult.setTimestamp(pollStatus.getTimestamp());
return gResult;
}
private static GWTMonitoredService transformMonitoredService(final OnmsMonitoredService monitoredService) {
final GWTMonitoredService service = new GWTMonitoredService();
service.setId(monitoredService.getId());
final OnmsIpInterface ipi = monitoredService.getIpInterface();
if (ipi != null) {
service.setIpInterfaceId(ipi.getId());
if (ipi.getNode() != null) {
service.setNodeId(ipi.getNode().getId());
}
service.setIpAddress(str(ipi.getIpAddress()));
service.setHostname(ipi.getIpHostName());
final OnmsSnmpInterface snmpi = ipi.getSnmpInterface();
if (snmpi != null) {
service.setIfIndex(snmpi.getIfIndex());
}
}
service.setServiceName(monitoredService.getServiceName());
return service;
}
private static GWTLocationSpecificStatus transformLocationSpecificStatus(final OnmsLocationSpecificStatus status) {
final GWTLocationSpecificStatus gStatus = new GWTLocationSpecificStatus();
gStatus.setId(status.getId());
gStatus.setLocationMonitor(transformLocationMonitor(status.getLocationMonitor()));
gStatus.setPollResult(transformPollResult(status.getPollResult()));
gStatus.setMonitoredService(transformMonitoredService(status.getMonitoredService()));
return gStatus;
}
private static GWTLocationMonitor transformLocationMonitor(final OnmsLocationMonitor monitor) {
final GWTLocationMonitor gMonitor = new GWTLocationMonitor();
gMonitor.setId(monitor.getId());
gMonitor.setDefinitionName(monitor.getDefinitionName());
gMonitor.setName(monitor.getName());
gMonitor.setStatus(monitor.getStatus().toString());
gMonitor.setLastCheckInTime(monitor.getLastCheckInTime());
return gMonitor;
}
private static ApplicationInfo transformApplication(final Collection<OnmsMonitoredService> services, final OnmsApplication application) {
final ApplicationInfo app = new ApplicationInfo();
app.setId(application.getId());
app.setName(application.getName());
final Set<GWTMonitoredService> s = new TreeSet<GWTMonitoredService>();
final Set<String> locations = new TreeSet<String>();
for (final OnmsMonitoredService service : services) {
for (final OnmsApplication oa : service.getApplications()) {
locations.add(oa.getName());
}
s.add(transformMonitoredService(service));
}
app.setServices(s);
app.setLocations(locations);
return app;
}
private static interface StatusTracker {
public void onStatus(final OnmsLocationSpecificStatus status);
}
private static class AllMonitorStatusTracker implements StatusTracker {
private final Map<String, MonitorStatusTracker> m_trackers = new HashMap<String, MonitorStatusTracker>();
public void onStatus(final OnmsLocationSpecificStatus status) {
String defName = status.getLocationMonitor().getDefinitionName();
MonitorStatusTracker t = getMonitorStatusTracker(defName);
t.onStatus(status);
}
MonitorStatusTracker getMonitorStatusTracker(String defName) {
MonitorStatusTracker t = m_trackers.get(defName);
if (t == null) {
t = new MonitorStatusTracker(defName);
m_trackers.put(defName, t);
}
return t;
}
public Collection<GWTLocationSpecificStatus> drain(String defName) {
if (!m_trackers.containsKey(defName)) {
return Collections.emptyList();
}
return m_trackers.get(defName).drain();
}
}
private static class MonitorStatusTracker implements StatusTracker {
private transient final Map<Integer, OnmsLocationSpecificStatus> m_statuses = new HashMap<Integer, OnmsLocationSpecificStatus>();
private transient final String m_locationName;
public MonitorStatusTracker(final String locationName) {
m_locationName = locationName;
}
public void onStatus(final OnmsLocationSpecificStatus status) {
if (status.getLocationMonitor().getDefinitionName().equals(m_locationName)) {
LogUtils.tracef(this, "(added) status code for %s/%s is %d", status.getLocationMonitor().getDefinitionName(), status.getMonitoredService().getServiceName(), status.getStatusCode());
m_statuses.put(status.getMonitoredService().getId(), status);
} else {
LogUtils.tracef(this, "(skipped) status code for %s/%s is %d", status.getLocationMonitor().getDefinitionName(), status.getMonitoredService().getServiceName(), status.getStatusCode());
}
}
public Collection<GWTLocationSpecificStatus> drain() {
final Collection<GWTLocationSpecificStatus> statuses = new ArrayList<GWTLocationSpecificStatus>();
synchronized (m_statuses) {
for (OnmsLocationSpecificStatus status : m_statuses.values()) {
statuses.add(transformLocationSpecificStatus(status));
}
m_statuses.clear();
}
return statuses;
}
}
private static class ApplicationStatusTracker implements StatusTracker {
private String m_name;
private Map<String, Collection<OnmsLocationSpecificStatus>> m_statuses = new HashMap<String, Collection<OnmsLocationSpecificStatus>>();
public ApplicationStatusTracker(final String name) {
m_name = name;
}
public void onStatus(final OnmsLocationSpecificStatus status) {
if (status.getLocationMonitor().getDefinitionName().equals(m_name)) {
LogUtils.tracef(this, "(added) status code for %s/%s is %d", status.getLocationMonitor().getDefinitionName(), status.getMonitoredService().getServiceName(), status.getStatusCode());
for (OnmsApplication app : status.getMonitoredService().getApplications()) {
Collection<OnmsLocationSpecificStatus> statuses = m_statuses.get(app.getName());
if (statuses == null) {
statuses = new ArrayList<OnmsLocationSpecificStatus>();
}
statuses.add(status);
m_statuses.put(app.getName(), statuses);
}
} else {
LogUtils.tracef(this, "(skipped) status code for %s/%s is %d", status.getLocationMonitor().getDefinitionName(), status.getMonitoredService().getServiceName(), status.getStatusCode());
}
}
public Map<String, List<GWTLocationSpecificStatus>> drainStatuses() {
final Map<String, List<GWTLocationSpecificStatus>> statuses = new HashMap<String, List<GWTLocationSpecificStatus>>();
synchronized (m_statuses) {
for (final String app : statuses.keySet()) {
final List<GWTLocationSpecificStatus> s = new ArrayList<GWTLocationSpecificStatus>();
for (OnmsLocationSpecificStatus status : m_statuses.get(app)) {
s.add(transformLocationSpecificStatus(status));
}
statuses.put(app, s);
}
m_statuses.clear();
}
return statuses;
}
}
/**
* <p>getLocationMonitorDao</p>
*
* @return a {@link org.opennms.netmgt.dao.LocationMonitorDao} object.
*/
public LocationMonitorDao getLocationMonitorDao() {
return m_locationDao;
}
/**
* <p>getInfoForAllLocations</p>
*
* @return a {@link java.util.List} object.
*/
@Transactional
public List<LocationInfo> getInfoForAllLocations() {
waitForGeocoding("getInfoForAllLocations");
Map<String, StatusDetails> statusDetails = getStatusDetailsForAllLocations();
List<LocationInfo> locations = new ArrayList<LocationInfo>();
for(Map.Entry<String, StatusDetails> entry : statusDetails.entrySet()) {
OnmsMonitoringLocationDefinition def = getLocationMonitorDao().findMonitoringLocationDefinition(entry.getKey());
LocationInfo locationInfo = this.getLocationInfo(def, entry.getValue());
locations.add(locationInfo);
}
return locations;
}
public Map<String, StatusDetails> getStatusDetailsForAllLocations() {
final Collection<OnmsMonitoringLocationDefinition> definitions = getLocationMonitorDao().findAllMonitoringLocationDefinitions();
AllMonitorStatusTracker tracker = new AllMonitorStatusTracker();
MonitorTracker monTracker = new MonitorTracker();
for (OnmsLocationSpecificStatus status : m_locationDao.getAllMostRecentStatusChanges()) {
tracker.onStatus(status);
}
for(OnmsLocationMonitor monitor : m_locationDao.findAll()) {
monTracker.onMonitor(monitor);
}
Map<String, StatusDetails> statusDetails = new LinkedHashMap<String, StatusDetails>();
for (final OnmsMonitoringLocationDefinition def : definitions) {
LocationMonitorState monitorState = new LocationMonitorState(monTracker.drain(def.getName()), tracker.drain(def.getName()));
final StatusDetails monitorStatus = monitorState.getStatusDetails();
statusDetails.put(def.getName(), monitorStatus);
}
return statusDetails;
}
/**
* <p>getInfoForAllApplications</p>
*
* @return a {@link java.util.List} object.
*/
@Transactional
public List<ApplicationInfo> getInfoForAllApplications() {
waitForGeocoding("handleAllApplications");
Map<OnmsApplication, StatusDetails> statusDetails = getStatusDetailsForAllApplications();
final List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>();
for (Map.Entry<OnmsApplication, StatusDetails> entry : statusDetails.entrySet()) {
final ApplicationInfo appInfo = getApplicationInfo(entry.getKey(), entry.getValue());
appInfos.add(appInfo);
}
return appInfos;
}
private Map<OnmsApplication, StatusDetails> getStatusDetailsForAllApplications() {
final Collection<OnmsApplication> apps = m_applicationDao.findAll();
Map<OnmsApplication, StatusDetails> statusDetails = new LinkedHashMap<OnmsApplication, StatusDetails>();
for (final OnmsApplication app : apps) {
StatusDetails appStatusDetails = getStatusDetailsForApplication(app);
statusDetails.put(app, appStatusDetails);
}
return statusDetails;
}
}