/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program 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 version 2 of the License. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.gui.discovery; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.faces.application.FacesMessage; import javax.faces.model.DataModel; import javax.faces.model.SelectItem; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.composite.DisambiguationReport; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.core.util.IntExtractor; import org.rhq.enterprise.gui.common.framework.PagedDataTableUIBean; import org.rhq.enterprise.gui.common.paging.PageControlView; import org.rhq.enterprise.gui.common.paging.PagedListDataModel; import org.rhq.enterprise.gui.common.paging.ResourceNameDisambiguatingPagedListDataModel; import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility; import org.rhq.enterprise.server.discovery.DiscoveryBossLocal; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.disambiguation.DefaultDisambiguationUpdateStrategies; import org.rhq.enterprise.server.util.LookupUtil; public class AutoDiscoveryQueueUIBean extends PagedDataTableUIBean { private final Log log = LogFactory.getLog(AutoDiscoveryQueueUIBean.class); public static final String MANAGED_BEAN_NAME = "AutoDiscoveryQueueUIBean"; private DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss(); private ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); private Map<DisambiguationReport<Resource>, List<DisambiguationReport<Resource>>> platformsAndServers = new HashMap<DisambiguationReport<Resource>, List<DisambiguationReport<Resource>>>(); private static final IntExtractor<Resource> RESOURCE_ID_EXTRACTOR = new IntExtractor<Resource>() { public int extract(Resource object) { return object.getId(); } }; public AutoDiscoveryQueueUIBean() { } @Override public DataModel getDataModel() { if (dataModel == null) { dataModel = new AutoDiscoveryQueueDataModel(PageControlView.AutoDiscoveryPlatformList, MANAGED_BEAN_NAME); } return dataModel; } @Override public SelectItem[] getPageSizes() { return new SelectItem[] { new SelectItem("10", "10"), new SelectItem("25", "25"), new SelectItem("50", "50"), new SelectItem("75", "75"), new SelectItem("100", "100") }; } @Override public int getMinimumPageSize() { return 10; } public Map<DisambiguationReport<Resource>, List<DisambiguationReport<Resource>>> getPlatformsAndServers() { return platformsAndServers; } public String rebuildTable() { // this method is called when the table needs to be rebuilt - clear out our session to start anew getExpandedPlatforms().clear(); getSelectedResources().clear(); return "sort"; } public String importResources() { Subject subject = EnterpriseFacesContextUtility.getSubject(); int platformCount = 0; int serverCount = 0; try { Map<Integer, Boolean> selectedResources = getSelectedResources(); // do it one platform at a time so we give each its own transaction List<DisambiguationReport<Resource>> platform = new ArrayList<DisambiguationReport<Resource>>(1); for (Map.Entry<Integer, Boolean> selected : selectedResources.entrySet()) { // if current 'selected' is a platform, import the selected things for that platform DisambiguationReport<Resource> resource = findResource(selected.getKey()); if ((resource != null) && selected.getValue().booleanValue() && platformsAndServers.containsKey(resource)) { platform.clear(); platform.add(resource); if (resource.getOriginal().getInventoryStatus() == InventoryStatus.NEW) { platformCount++; } List<DisambiguationReport<Resource>> allServers = platformsAndServers.get(resource); List<DisambiguationReport<Resource>> servers = new ArrayList<DisambiguationReport<Resource>>(); for (DisambiguationReport<Resource> server : allServers) { if (selectedResources.containsKey(server.getOriginal().getId()) && selectedResources.get(server.getOriginal().getId()).booleanValue() && (server.getOriginal().getInventoryStatus() == InventoryStatus.NEW)) { serverCount++; servers.add(server); } } log.debug("AIQueue import: platform=" + platform + "| servers=" + servers); // TODO: Why do we update the platform's status even when it was already COMMITTED?? (ips, 07/10/08) discoveryBoss.updateInventoryStatus(subject, getOriginals(platform), getOriginals(servers), InventoryStatus.COMMITTED); } } FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Imported [" + platformCount + "] platforms and [" + serverCount + "] servers."); getSelectedResources().clear(); } catch (Exception e) { FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Import failed.", e); log.error("Import failed", e); } return "success"; } public String ignoreResources() { Subject subject = EnterpriseFacesContextUtility.getSubject(); int serverCount = 0; try { // do it one platform at a time so we give each its own transaction List<DisambiguationReport<Resource>> platform = new ArrayList<DisambiguationReport<Resource>>(1); Map<Integer, Boolean> selectedResources = getSelectedResources(); for (Map.Entry<Integer, Boolean> selected : selectedResources.entrySet()) { // if current 'selected' is a platform, ignore the selected things for that platform DisambiguationReport<Resource> resource = findResource(selected.getKey()); if ((resource != null) && selected.getValue().booleanValue() && platformsAndServers.containsKey(resource)) { List<DisambiguationReport<Resource>> allServers = platformsAndServers.get(resource); List<DisambiguationReport<Resource>> servers = new ArrayList<DisambiguationReport<Resource>>(); for (DisambiguationReport<Resource> server : allServers) { if (selectedResources.containsKey(server.getOriginal().getId()) && selectedResources.get(server.getOriginal().getId()).booleanValue() && (server.getOriginal().getInventoryStatus() == InventoryStatus.NEW)) { serverCount++; servers.add(server); } } log.debug("AIQueue ignore: platform=" + platform + "| servers=" + servers); discoveryBoss.updateInventoryStatus(subject, getOriginals(platform), getOriginals(servers), InventoryStatus.IGNORED); } } FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Ignored [" + serverCount + "] servers."); getSelectedResources().clear(); } catch (Exception e) { FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Ignore failed.", e); log.error("Ignore failed", e); } return "success"; } public String unignoreResources() { Subject subject = EnterpriseFacesContextUtility.getSubject(); int serverCount = 0; try { // do it one platform at a time so we give each its own transaction List<DisambiguationReport<Resource>> platform = new ArrayList<DisambiguationReport<Resource>>(1); Map<Integer, Boolean> selectedResources = getSelectedResources(); for (Map.Entry<Integer, Boolean> selected : selectedResources.entrySet()) { // if current 'selected' is a platform, unignore its servers; otherwise, just go on to the next DisambiguationReport<Resource> resource = findResource(selected.getKey()); if ((resource != null) && selected.getValue().booleanValue() && platformsAndServers.containsKey(resource)) { if (resource.getOriginal().getInventoryStatus() != InventoryStatus.COMMITTED) { FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN, "Cannot un-ignore servers from an uncommitted platform [" + resource.getOriginal().getName() + "]. Aborting."); break; } List<DisambiguationReport<Resource>> allServers = platformsAndServers.get(resource); List<DisambiguationReport<Resource>> servers = new ArrayList<DisambiguationReport<Resource>>(); for (DisambiguationReport<Resource> server : allServers) { if (selectedResources.containsKey(server.getOriginal().getId()) && selectedResources.get(server.getOriginal().getId()).booleanValue() && (server.getOriginal().getInventoryStatus() == InventoryStatus.IGNORED)) { serverCount++; servers.add(server); } } log.debug("AIQueue unignore: platform=" + platform + "| servers=" + servers); discoveryBoss.updateInventoryStatus(subject, getOriginals(platform), getOriginals(servers), InventoryStatus.NEW); } } FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Un-ignored [" + serverCount + "] servers."); getSelectedResources().clear(); } catch (Exception e) { FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Un-ignore failed.", e); log.error("Unignore failed", e); } return "success"; } private Map<Integer, Boolean> getSelectedResources() { return FacesContextUtility.getManagedBean(AutoDiscoverySessionUIBean.class).getSelectedResources(); } private Map<Integer, Boolean> getExpandedPlatforms() { return FacesContextUtility.getManagedBean(AutoDiscoverySessionUIBean.class).getExpandedMap(); } private DisambiguationReport<Resource> findResource(Integer id) { for (Map.Entry<DisambiguationReport<Resource>, List<DisambiguationReport<Resource>>> entry : platformsAndServers.entrySet()) { DisambiguationReport<Resource> platform = entry.getKey(); List<DisambiguationReport<Resource>> servers = entry.getValue(); if (platform.getOriginal().getId() == id.intValue()) { return platform; } for (DisambiguationReport<Resource> server : servers) { if (server.getOriginal().getId() == id.intValue()) { return server; } } } return null; } private EnumSet<InventoryStatus> getShowNewIgnoreEnumSet() { AutoDiscoverySessionUIBean bean = FacesContextUtility.getManagedBean(AutoDiscoverySessionUIBean.class); String showNewIgnore = bean.getShowNewIgnore(); if ("BOTH".equals(showNewIgnore)) { return EnumSet.of(InventoryStatus.NEW, InventoryStatus.IGNORED); } else if (InventoryStatus.NEW.name().equals(showNewIgnore)) { return EnumSet.of(InventoryStatus.NEW); } else if (InventoryStatus.IGNORED.name().equals(showNewIgnore)) { return EnumSet.of(InventoryStatus.IGNORED); } return EnumSet.of(InventoryStatus.NEW); } private class AutoDiscoveryQueueDataModel extends PagedListDataModel<DisambiguationReport<Resource>> { public AutoDiscoveryQueueDataModel(PageControlView view, String beanName) { super(view, beanName); } public PageList<DisambiguationReport<Resource>> fetchPage(PageControl pc) { Subject subject = EnterpriseFacesContextUtility.getSubject(); EnumSet<InventoryStatus> newIgnoredSet = getShowNewIgnoreEnumSet(); platformsAndServers.clear(); PageList<Resource> queuedPlatforms = discoveryBoss.getQueuedPlatforms(subject, newIgnoredSet, pc); List<DisambiguationReport<Resource>> disambiguatedQueuedPlatforms = resourceManager.disambiguate(queuedPlatforms, RESOURCE_ID_EXTRACTOR, DefaultDisambiguationUpdateStrategies.getDefault()); PageList<DisambiguationReport<Resource>> disambiguatedQueuedPlaformsPageList = new PageList<DisambiguationReport<Resource>>(disambiguatedQueuedPlatforms, queuedPlatforms.getTotalSize(), queuedPlatforms.getPageControl()); for (DisambiguationReport<Resource> platform : disambiguatedQueuedPlatforms) { List<DisambiguationReport<Resource>> queuedServers = new ArrayList<DisambiguationReport<Resource>>(); for (InventoryStatus status : newIgnoredSet) { List<Resource> childServers = discoveryBoss.getQueuedPlatformChildServers(subject, status, platform.getOriginal()); List<DisambiguationReport<Resource>> disambiguatedChildServers = resourceManager.disambiguate(childServers, RESOURCE_ID_EXTRACTOR, DefaultDisambiguationUpdateStrategies.getDefault()); queuedServers.addAll(disambiguatedChildServers); } platformsAndServers.put(platform, queuedServers); } // In order to be able to expandAll/collapseAll, the expandedPlatforms map must have all platforms in it. // Prepare the expandedPlatforms, maintaining prior state for platforms that were already in the map. Map<Integer, Boolean> expandedPlatforms = getExpandedPlatforms(); Map<Integer, Boolean> newExpandedPlatforms = new HashMap<Integer, Boolean>(); for (DisambiguationReport<Resource> platform : platformsAndServers.keySet()) { Boolean expanded = expandedPlatforms.get(platform.getOriginal().getId()); newExpandedPlatforms.put(platform.getOriginal().getId(), (expanded != null) ? expanded : Boolean.FALSE); } expandedPlatforms.clear(); expandedPlatforms.putAll(newExpandedPlatforms); return disambiguatedQueuedPlaformsPageList; } } private static <T> List<T> getOriginals(List<DisambiguationReport<T>> reports) { List<T> ret = new ArrayList<T>(); for(DisambiguationReport<T> report : reports) { ret.add(report.getOriginal()); } return ret; } }