/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-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.web.svclayer.support;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.opennms.netmgt.config.siteStatusViews.Category;
import org.opennms.netmgt.config.siteStatusViews.RowDef;
import org.opennms.netmgt.config.siteStatusViews.Rows;
import org.opennms.netmgt.config.siteStatusViews.View;
import org.opennms.netmgt.dao.CategoryDao;
import org.opennms.netmgt.dao.NodeDao;
import org.opennms.netmgt.dao.SiteStatusViewConfigDao;
import org.opennms.netmgt.model.AggregateStatusDefinition;
import org.opennms.netmgt.model.AggregateStatusView;
import org.opennms.netmgt.model.OnmsCategory;
import org.opennms.netmgt.model.OnmsNode;
import org.opennms.web.api.Util;
import org.opennms.web.svclayer.AggregateStatus;
import org.opennms.web.svclayer.SiteStatusViewService;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.orm.ObjectRetrievalFailureException;
/**
* This service layer class creates a collection that represents the current
* status of devices per site (a column from the asset table such as building,
* floor, etc.) The status per site is broken down into rows of categories from
* the categories table.
*
* example:
*
* site: HQBLDB
*
* |Routers/Switches | 1 of 20 |
* |Servers | 0 of 200 |
* |Hubs/APs | 5 of 30 |
*
* @author <a href="mailto:david@opennms.org">David Hustace</a>
* @author <a href="mailto:dj@opennms.org">DJ Gregor</a>
* @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a>
* @author <a href="mailto:david@opennms.org">David Hustace</a>
* @author <a href="mailto:dj@opennms.org">DJ Gregor</a>
* @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a>
* @author <a href="mailto:david@opennms.org">David Hustace</a>
* @author <a href="mailto:dj@opennms.org">DJ Gregor</a>
* @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a>
* @version $Id: $
* @since 1.8.1
*/
public class DefaultSiteStatusViewService implements SiteStatusViewService {
private NodeDao m_nodeDao;
private CategoryDao m_categoryDao;
private SiteStatusViewConfigDao m_siteStatusViewConfigDao;
/**
* {@inheritDoc}
*
* This creator looks up a configured status view by name and calls the creator that
* accepts the AggregateStatusView model object.
* @see org.opennms.web.svclayer.SiteStatusViewService#createAggregateStatusView(java.lang.String)
*/
public AggregateStatusView createAggregateStatusView(String statusViewName) {
AggregateStatusView statusView = new AggregateStatusView();
statusViewName = (statusViewName == null ? m_siteStatusViewConfigDao.getDefaultView().getName() : statusViewName);
View view = m_siteStatusViewConfigDao.getView(statusViewName);
statusView.setName(statusViewName);
statusView.setColumnName(view.getColumnName());
statusView.setColumnValue(view.getColumnValue());
statusView.setTableName(view.getTableName());
Set<AggregateStatusDefinition> statusDefs =
getAggregateStatusDefinitionsForView(view);
statusView.setStatusDefinitions(statusDefs);
return statusView;
}
private Set<AggregateStatusDefinition> getAggregateStatusDefinitionsForView(View view) {
Set<AggregateStatusDefinition> statusDefs = new LinkedHashSet<AggregateStatusDefinition>();
List<RowDef> rowDefs = view.getRows().getRowDefCollection();
//Loop over the defined site status rows
for (RowDef rowDef : rowDefs) {
AggregateStatusDefinition def = new AggregateStatusDefinition();
def.setName(rowDef.getLabel());
def.setReportCategory(rowDef.getReportCategory());
Set<OnmsCategory> categories = getCategoriesForRowDef(rowDef);
def.setCategories(categories);
statusDefs.add(def);
}
return statusDefs;
}
private Set<OnmsCategory> getCategoriesForRowDef(RowDef rowDef) {
Set<OnmsCategory> categories = new LinkedHashSet<OnmsCategory>();
//Loop over the defined categories and create model categories (OnmsCategory)
List<Category> cats = rowDef.getCategoryCollection();
for (Category cat : cats) {
OnmsCategory category = m_categoryDao.findByName(cat.getName());
if (category == null) {
throw new ObjectRetrievalFailureException(OnmsCategory.class, cat.getName(), "Unable to locate OnmsCategory named: "+cat.getName()+" as specified in the site status view configuration file", null);
}
categories.add(category);
}
return categories;
}
/**
* {@inheritDoc}
*
* Use the node id to find the value assciated with column defined in the view. The view defines a column
* and column value to be used by default. This method determines the column value using the value associated
* with the asset record for the given nodeid.
* @see org.opennms.web.svclayer.SiteStatusViewService#createAggregateStatusesUsingNodeId(int, java.lang.String)
*/
public Collection<AggregateStatus> createAggregateStatusesUsingNodeId(int nodeId, String viewName) {
OnmsNode node = m_nodeDao.load(nodeId);
//TODO this is a hack. need to use reflection to get the right column instead of building.
return createAggregateStatuses(createAggregateStatusView(viewName), node.getAssetRecord().getBuilding());
}
/**
* {@inheritDoc}
*
* This creator is used when wanting to use a different value than the defined column value defined
* for the requested view.
* @see org.opennms.web.svclayer.SiteStatusViewService#createAggregateStatuses(org.opennms.netmgt.model.AggregateStatusView, java.lang.String)
*/
public Collection<AggregateStatus> createAggregateStatuses(AggregateStatusView statusView, String statusSite) {
if (statusView == null) {
throw new IllegalArgumentException("statusView argument cannot be null");
}
statusView.setColumnValue(statusSite);
return createAggregateStatusUsingAssetColumn(statusView);
}
/**
* <p>createAggregateStatusUsingAssetColumn</p>
*
* @param statusView a {@link org.opennms.netmgt.model.AggregateStatusView} object.
* @return a {@link java.util.Collection} object.
*/
public Collection<AggregateStatus> createAggregateStatusUsingAssetColumn(AggregateStatusView statusView) {
if (statusView == null) {
throw new IllegalArgumentException("statusView argument cannot be null");
}
/*
* We'll return this collection populated with all the aggregated statuss for the
* devices in the building (site) by for each group of categories.
*/
Collection<AggregateStatus> stati = new ArrayList<AggregateStatus>();
/*
* Iterate over the status definitions and create aggregated statuss
*/
for (AggregateStatusDefinition statusDef : statusView.getStatusDefinitions()) {
Collection<OnmsNode> nodes = m_nodeDao.findAllByVarCharAssetColumnCategoryList(statusView.getColumnName(), statusView.getColumnValue(), statusDef.getCategories());
AggregateStatus status = new AggregateStatus(new HashSet<OnmsNode>(nodes));
status.setLabel(statusDef.getName());
status.setLink(createNodePageUrl(statusView, status));
stati.add(status);
}
return stati;
}
private String createNodePageUrl(AggregateStatusView statusView, AggregateStatus status) {
if (status.getDownEntityCount() == 0) {
StringBuffer buf = new StringBuffer("element/nodeList.htm?");
buf.append("statusViewName=");
buf.append(Util.encode(statusView.getName()));
buf.append('&');
buf.append("statusSite=");
buf.append(Util.encode(statusView.getColumnValue()));
buf.append('&');
buf.append("statusRowLabel=");
buf.append(Util.encode(status.getLabel()));
return buf.toString();
} else if (status.getDownEntityCount() == 1) {
OnmsNode node = status.getDownNodes().iterator().next();
StringBuffer buf = new StringBuffer("element/node.jsp?");
buf.append("node=");
buf.append(node.getId());
return buf.toString();
} else {
StringBuffer buf = new StringBuffer("element/nodeList.htm?");
buf.append("statusViewName=");
buf.append(Util.encode(statusView.getName()));
buf.append('&');
buf.append("statusSite=");
buf.append(Util.encode(statusView.getColumnValue()));
buf.append('&');
buf.append("statusRowLabel=");
buf.append(Util.encode(status.getLabel()));
buf.append('&');
buf.append("nodesWithDownAggregateStatus");
return buf.toString();
}
}
/**
* <p>getNodeDao</p>
*
* @return a {@link org.opennms.netmgt.dao.NodeDao} object.
*/
public NodeDao getNodeDao() {
return m_nodeDao;
}
/**
* <p>setNodeDao</p>
*
* @param nodeDao a {@link org.opennms.netmgt.dao.NodeDao} object.
*/
public void setNodeDao(NodeDao nodeDao) {
m_nodeDao = nodeDao;
}
/**
* <p>setCategoryDao</p>
*
* @param dao a {@link org.opennms.netmgt.dao.CategoryDao} object.
*/
public void setCategoryDao(CategoryDao dao) {
m_categoryDao = dao;
}
/**
* <p>setSiteStatusViewConfigDao</p>
*
* @param dao a {@link org.opennms.netmgt.dao.SiteStatusViewConfigDao} object.
*/
public void setSiteStatusViewConfigDao(SiteStatusViewConfigDao dao) {
m_siteStatusViewConfigDao = dao;
}
/** {@inheritDoc} */
public Collection<AggregateStatus> createAggregateStatuses(AggregateStatusView statusView) {
if (! "assets".equalsIgnoreCase("assets")) {
throw new IllegalArgumentException("statusView only currently supports asset table columns");
}
return createAggregateStatusUsingAssetColumn(statusView);
}
/** {@inheritDoc} */
public AggregateStatus getAggregateStatus(String statusViewName, String statusSite, String rowLabel) {
AggregateStatusView statusView = createAggregateStatusView(statusViewName);
Collection<AggregateStatus> stati = createAggregateStatuses(statusView, statusSite);
for (AggregateStatus status : stati) {
if (status.getLabel().equals(rowLabel)) {
return status;
}
}
throw new DataRetrievalFailureException("Unable to locate row: "+rowLabel+" for status view: "+statusViewName);
}
/** {@inheritDoc} */
public Collection<OnmsNode> getNodes(String statusViewName, String statusSite, String rowLabel) {
if (statusViewName == null) {
statusViewName = m_siteStatusViewConfigDao.getDefaultView().getName();
}
View view = m_siteStatusViewConfigDao.getView(statusViewName);
RowDef rowDef = getRowDef(view, rowLabel);
Set<OnmsCategory> categories = getCategoriesForRowDef(rowDef);
return m_nodeDao.findAllByVarCharAssetColumnCategoryList(view.getColumnName(), statusSite, categories);
}
private RowDef getRowDef(View view, String rowLabel) {
Rows rows = view.getRows();
Collection<RowDef> rowDefs = rows.getRowDefCollection();
for (RowDef rowDef : rowDefs) {
if (rowDef.getLabel().equals(rowLabel)) {
return rowDef;
}
}
throw new DataRetrievalFailureException("Unable to locate row: "+rowLabel+" for status view: "+view.getName());
}
}