/** * Bean responsible for the agent details display page. This bean will also provide a pagable list * of the failover servers for a particular agent. * * @author Jason Dobies */ public class ViewAgentUIBean extends PagedDataTableUIBean { public static final String MANAGED_BEAN_NAME = "ViewAgentUIBean"; private AgentManagerLocal agentManager = LookupUtil.getAgentManager(); private CloudManagerLocal cloudManager = LookupUtil.getCloudManager(); private Agent agent; public Agent getAgent() { if (agent == null) { hasPermission(); int agentId = FacesContextUtility.getRequiredRequestParameter("agentId", Integer.class); agent = agentManager.getAgentByID(agentId); } return agent; } @Override public DataModel getDataModel() { if (dataModel == null) { dataModel = new ViewAgentUIBeanDataModel(PageControlView.AgentFailoverListView, MANAGED_BEAN_NAME); } return dataModel; } private class ViewAgentUIBeanDataModel extends PagedListDataModel<FailoverListDetails> { private ViewAgentUIBeanDataModel(PageControlView view, String beanName) { super(view, beanName); } @Override public PageList<FailoverListDetails> fetchPage(PageControl pc) { int agentId = getAgent().getId(); PageList<FailoverListDetails> pageList = cloudManager.getFailoverListDetailsByAgentId(agentId, pc); return pageList; } } /** Throws a permission exception if the user is not allowed to access this functionality. */ private void hasPermission() { Subject subject = EnterpriseFacesContextUtility.getSubject(); if (!LookupUtil.getAuthorizationManager() .hasGlobalPermission(subject, Permission.MANAGE_INVENTORY)) { throw new PermissionException( "User [" + subject.getName() + "] does not have the proper permissions to view or manage agents"); } } }
/** * Backing bean for the left navigation tree for resources * * @author Greg Hinkle */ public class ResourceTreeModelUIBean { private static final Log log = LogFactory.getLog(ResourceTreeModelUIBean.class); private List<ResourceTreeNode> roots = new ArrayList<ResourceTreeNode>(); private ResourceTreeNode rootNode = null; private ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); private AgentManagerLocal agentManager = LookupUtil.getAgentManager(); private String nodeTitle; private void loadTree() { int searchId; Resource currentResource = EnterpriseFacesContextUtility.getResourceIfExists(); if (currentResource == null) { searchId = Integer.parseInt(FacesContextUtility.getOptionalRequestParameter("parent")); } else { searchId = currentResource.getId(); } Subject user = EnterpriseFacesContextUtility.getSubject(); long start = System.currentTimeMillis(); long monitorId = HibernatePerformanceMonitor.get().start(); Resource rootResource = resourceManager.getRootResourceForResource(searchId); long end = System.currentTimeMillis(); HibernatePerformanceMonitor.get().stop(monitorId, "ResourceTree root resource"); log.debug("Found root resource in " + (end - start)); Agent agent = agentManager.getAgentByResourceId( LookupUtil.getSubjectManager().getOverlord(), rootResource.getId()); start = System.currentTimeMillis(); monitorId = HibernatePerformanceMonitor.get().start(); List<ResourceFlyweight> resources = resourceManager.findResourcesByAgent( user, agent.getId(), PageControl.getUnlimitedInstance()); end = System.currentTimeMillis(); HibernatePerformanceMonitor.get().stop(monitorId, "ResourceTree agent resource"); log.debug("Loaded " + resources.size() + " raw resources in " + (end - start)); start = System.currentTimeMillis(); monitorId = HibernatePerformanceMonitor.get().start(); rootNode = load(rootResource.getId(), resources); end = System.currentTimeMillis(); HibernatePerformanceMonitor.get().stop(monitorId, "ResourceTree tree construction"); log.debug("Constructed tree in " + (end - start)); } public static ResourceTreeNode load(int rootId, List<ResourceFlyweight> resources) { ResourceFlyweight found = null; for (ResourceFlyweight res : resources) { if (res.getId() == rootId) { found = res; } } ResourceTreeNode root = new ResourceTreeNode(found); long start = System.currentTimeMillis(); load(root); return root; } public static void load(ResourceTreeNode parentNode) { if (parentNode.getData() instanceof ResourceFlyweight) { ResourceFlyweight parentResource = (ResourceFlyweight) parentNode.getData(); Map<Object, List<ResourceFlyweight>> children = new HashMap<Object, List<ResourceFlyweight>>(); for (ResourceFlyweight res : parentResource.getChildResources()) { if (res.getResourceType().getSubCategory() != null) { // These are children that have subcategories // Split them by if they are a sub-sub category or just a category ResourceSubCategoryFlyweight categoryKey = res.getResourceType().getSubCategory().getParentSubCategory(); if (categoryKey == null) { categoryKey = res.getResourceType().getSubCategory(); } addToList(children, categoryKey, res); } else { // These are children without categories of the parent resource // - Add them into groupings by their resource type addToList(children, res.getResourceType(), res); } } Set<String> dupResourceTypeNames = getDuplicateResourceTypeNames(children); for (Map.Entry<Object, List<ResourceFlyweight>> entry : children.entrySet()) { Object key = entry.getKey(); List<ResourceFlyweight> resources = entry.getValue(); double avail = 0; for (ResourceFlyweight res : resources) { avail += res.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP ? 1 : 0; } avail = avail / resources.size(); Object nodeData = null; if (key instanceof ResourceSubCategoryFlyweight) { nodeData = new AutoGroupCompositeFlyweight( avail, parentResource, (ResourceSubCategoryFlyweight) key, resources.size()); } else if (key instanceof ResourceTypeFlyweight) { ResourceTypeFlyweight typeKey = (ResourceTypeFlyweight) key; if (typeKey.isSingleton()) { nodeData = resources.get(0); } else { boolean isDupResourceTypeName = dupResourceTypeNames.contains(typeKey.getName()); nodeData = new AutoGroupCompositeFlyweight( avail, parentResource, typeKey, resources.size(), isDupResourceTypeName); } } ResourceTreeNode node = new ResourceTreeNode(nodeData, parentNode); load(node); if (!recursivelyLocked(node)) { parentNode.getChildren().add(node); } } } else { // ##################################################################################### AutoGroupCompositeFlyweight compositeParent = (AutoGroupCompositeFlyweight) parentNode.getData(); Map<Object, List<ResourceFlyweight>> children = new HashMap<Object, List<ResourceFlyweight>>(); log.debug("composite parent" + compositeParent); if (compositeParent != null) { MembersCategoryHint membersCategory = MembersCategoryHint.NONE; MembersAvailabilityHint membersAvailabilityHint = MembersAvailabilityHint.UP; for (ResourceFlyweight res : compositeParent.getParentResource().getChildResources()) { boolean process = false; if (compositeParent.getSubcategory() != null) { // parent is a sub category if (res.getResourceType().getSubCategory() != null && compositeParent .getSubcategory() .equals(res.getResourceType().getSubCategory().getParentSubCategory()) && compositeParent.getParentResource().equals(res.getParentResource())) { // A subSubCategory in a subcategory addToList(children, res.getResourceType().getSubCategory(), res); process = true; } else if (compositeParent .getSubcategory() .equals(res.getResourceType().getSubCategory()) && compositeParent.getParentResource().equals(res.getParentResource())) { // Direct entries in a subcategory... now group them by autogroup (type) addToList(children, res.getResourceType(), res); process = true; } } else if (compositeParent.getResourceType() != null) { if (compositeParent.getResourceType().equals(res.getResourceType()) && compositeParent.getParentResource().getId() == res.getParentResource().getId()) { addToList(children, res.getResourceType(), res); process = true; } } if (process) { // amend the overall category of all the members of the auto group. switch (membersCategory) { case NONE: // this is the first child, so let's use its category as a starting point membersCategory = MembersCategoryHint.fromResourceCategory(res.getResourceType().getCategory()); break; case MIXED: // this is the "final" state. The children type is not going to change // from this. break; default: // check if this child has the same category as its previous siblings. if (MembersCategoryHint.fromResourceCategory(res.getResourceType().getCategory()) != membersCategory) { membersCategory = MembersCategoryHint.MIXED; } } // amend the availability hint of the autogroup. If all resources are up, the hint is // UP, if some of the resources // are down, the hint is DOWN, if some of the resources' avail state is unknown, the // hint is UNKNOWN. // The down state has the highest priority. switch (membersAvailabilityHint) { case UP: membersAvailabilityHint = MembersAvailabilityHint.fromAvailabilityType( res.getCurrentAvailability().getAvailabilityType()); break; case UNKNOWN: if (res.getCurrentAvailability().getAvailabilityType() == AvailabilityType.DOWN) { membersAvailabilityHint = MembersAvailabilityHint.DOWN; } break; case DOWN:; // a "terminal" state... if some resource is down, the overall state is // going to be down as that is the most important information. } } } compositeParent.setMembersCategoryHint(membersCategory); compositeParent.setMembersAvailabilityHint(membersAvailabilityHint); } AutoGroupCompositeFlyweight compositeParentNode = (AutoGroupCompositeFlyweight) parentNode.getData(); for (Map.Entry<Object, List<ResourceFlyweight>> entry : children.entrySet()) { Object key = entry.getKey(); List<ResourceFlyweight> resources = entry.getValue(); if (compositeParentNode.getSubcategory() != null) { double avail = 0; for (ResourceFlyweight res : resources) { avail += res.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP ? 1 : 0; } avail = avail / resources.size(); Object nodeData = null; if (key instanceof ResourceSubCategoryFlyweight) { nodeData = new AutoGroupCompositeFlyweight( avail, compositeParent.getParentResource(), (ResourceSubCategoryFlyweight) key, resources.size()); } else if (key instanceof ResourceTypeFlyweight) { ResourceTypeFlyweight typeKey = (ResourceTypeFlyweight) key; if (typeKey.isSingleton()) { nodeData = resources.get(0); } else { nodeData = new AutoGroupCompositeFlyweight( avail, compositeParent.getParentResource(), typeKey, resources.size(), false); } } ResourceTreeNode node = new ResourceTreeNode(nodeData, parentNode); load(node); if (!recursivelyLocked(node)) { parentNode.getChildren().add(node); } } else { for (ResourceFlyweight res : resources) { ResourceTreeNode node = new ResourceTreeNode(res, parentNode); load(node); if (!recursivelyLocked(node)) { parentNode.getChildren().add(node); } } } } } } public static boolean recursivelyLocked(ResourceTreeNode node) { if (node.getData() instanceof ResourceFlyweight && !((ResourceFlyweight) node.getData()).isLocked()) { return false; } boolean allLocked = true; for (ResourceTreeNode child : node.getChildren()) { if (!recursivelyLocked(child)) allLocked = false; } return allLocked; } public ResourceTreeNode getTreeNode() { if (rootNode == null) { long start = System.currentTimeMillis(); loadTree(); log.debug("Loaded full tree in " + (System.currentTimeMillis() - start)); } return rootNode; } public List<ResourceTreeNode> getRoots() { if (roots.isEmpty()) { roots.add(getTreeNode()); } return roots; } public String getNodeTitle() { return nodeTitle; } public void setNodeTitle(String nodeTitle) { this.nodeTitle = nodeTitle; } private static Set<String> getDuplicateResourceTypeNames( Map<Object, List<ResourceFlyweight>> children) { Set<String> resourceTypeNames = new HashSet<String>(); Set<String> dupResourceTypeNames = new HashSet<String>(); for (Object rsc : children.keySet()) { if (rsc instanceof ResourceTypeFlyweight) { String resourceTypeName = ((ResourceTypeFlyweight) rsc).getName(); if (resourceTypeNames.contains(resourceTypeName)) { dupResourceTypeNames.add(resourceTypeName); } resourceTypeNames.add(resourceTypeName); } } return dupResourceTypeNames; } private static <K, V> void addToList(Map<K, List<V>> mapOfLists, K key, V value) { List<V> list = mapOfLists.get(key); if (list == null) { list = new ArrayList<V>(); mapOfLists.put(key, list); } list.add(value); } }
/** @author Jiri Kremser */ public class TopologyGWTServiceImpl extends AbstractGWTServiceImpl implements TopologyGWTService { private static final long serialVersionUID = 1L; private TopologyManagerLocal topologyManager = LookupUtil.getTopologyManager(); private AgentManagerLocal agentManager = LookupUtil.getAgentManager(); private PartitionEventManagerLocal partitionEventManager = LookupUtil.getPartitionEventManager(); private AffinityGroupManagerLocal affinityGroupManager = LookupUtil.getAffinityGroupManager(); @Override public PageList<ServerWithAgentCountComposite> getServers(PageControl pc) throws RuntimeException { try { return SerialUtility.prepare( topologyManager.getServerComposites(getSessionSubject(), pc), "TopologyGWTServiceImpl.getServers"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void deleteServers(int[] serverIds) throws RuntimeException { try { topologyManager.deleteServers(getSessionSubject(), ArrayUtils.toObject(serverIds)); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void updateServerManualMaintenance(int[] serverIds, boolean manualMaintenance) throws RuntimeException { try { topologyManager.updateServerManualMaintenance( getSessionSubject(), ArrayUtils.toObject(serverIds), manualMaintenance); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public List<FailoverListDetails> getFailoverListDetailsByAgentId(int agentId, PageControl pc) throws RuntimeException { try { return SerialUtility.prepare( topologyManager.getFailoverListDetailsByAgentId(getSessionSubject(), agentId, pc), "TopologyGWTServiceImpl.getFailoverListDetailsByAgentId"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public PageList<PartitionEvent> findPartitionEventsByCriteria(PartitionEventCriteria criteria) throws RuntimeException { try { return SerialUtility.prepare( partitionEventManager.findPartitionEventsByCriteria(getSessionSubject(), criteria), "TopologyGWTServiceImpl.findPartitionEventsByCriteria"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public PageList<Server> findServersByCriteria(ServerCriteria criteria) throws RuntimeException { try { return SerialUtility.prepare( topologyManager.findServersByCriteria(getSessionSubject(), criteria), "TopologyGWTServiceImpl.findServersByCriteria"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public PageList<Agent> findAgentsByCriteria(AgentCriteria criteria) throws RuntimeException { try { return SerialUtility.prepare( agentManager.findAgentsByCriteria(getSessionSubject(), criteria), "TopologyGWTServiceImpl.findAgentsByCriteria"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void cloudPartitionEventRequest() throws RuntimeException { try { partitionEventManager.cloudPartitionEventRequest( getSessionSubject(), PartitionEventType.ADMIN_INITIATED_PARTITION, ""); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void purgeAllEvents() throws RuntimeException { try { partitionEventManager.purgeAllEvents(getSessionSubject()); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void deletePartitionEvents(int[] eventIds) throws RuntimeException { try { partitionEventManager.deletePartitionEvents( getSessionSubject(), ArrayUtils.toObject(eventIds)); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public PageList<PartitionEventDetails> getPartitionEventDetails( int partitionEventId, PageControl pageControl) throws RuntimeException { try { return SerialUtility.prepare( partitionEventManager.getPartitionEventDetails( getSessionSubject(), partitionEventId, pageControl), "TopologyGWTServiceImpl.getPartitionEventDetails"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public PageList<AffinityGroupCountComposite> getAffinityGroupCountComposites( PageControl pageControl) throws RuntimeException { try { return SerialUtility.prepare( affinityGroupManager.getComposites(getSessionSubject(), pageControl), "TopologyGWTServiceImpl.getAffinityGroupCountComposites"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public int deleteAffinityGroups(int[] affinityGroupIds) throws RuntimeException { try { return affinityGroupManager.delete( getSessionSubject(), ArrayUtils.toObject(affinityGroupIds)); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public int createAffinityGroup(AffinityGroup affinityGroup) throws RuntimeException { try { return affinityGroupManager.create(getSessionSubject(), affinityGroup); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public AffinityGroup getAffinityGroupById(int affinityGroupId) throws RuntimeException { try { return SerialUtility.prepare( affinityGroupManager.getById(getSessionSubject(), affinityGroupId), "TopologyGWTServiceImpl.getAffinityGroupById"); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void addServersToGroup(int affinityGroupId, Integer[] serverIds) throws RuntimeException { try { affinityGroupManager.addServersToGroup(getSessionSubject(), affinityGroupId, serverIds); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void removeServersFromGroup(Integer[] serverIds) throws RuntimeException { try { affinityGroupManager.removeServersFromGroup(getSessionSubject(), serverIds); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void addAgentsToGroup(int affinityGroupId, Integer[] agentIds) throws RuntimeException { try { affinityGroupManager.addAgentsToGroup(getSessionSubject(), affinityGroupId, agentIds); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void removeAgentsFromGroup(Integer[] agentIds) throws RuntimeException { try { affinityGroupManager.removeAgentsFromGroup(getSessionSubject(), agentIds); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void updateServer(Server server) throws RuntimeException { try { topologyManager.updateServer(getSessionSubject(), server); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public void updateAffinityGroup(AffinityGroup affinityGroup) throws RuntimeException { try { affinityGroupManager.update(getSessionSubject(), affinityGroup); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } @Override public Integer getResourceIdOfAgent(int agentId) throws RuntimeException { try { return topologyManager.getResourceIdOfAgent(getSessionSubject(), agentId); } catch (Throwable t) { throw getExceptionToThrowToClient(t); } } }
@Override public Set<ResourceMeasurementScheduleRequest> postProcessNewlyCommittedResources( Set<Integer> resourceIds) { if (log.isDebugEnabled()) { log.debug("Post-processing " + resourceIds.size() + "newly committed resources"); log.debug("Ids were: " + resourceIds); } Subject overlord = LookupUtil.getSubjectManager().getOverlord(); AlertTemplateManagerLocal alertTemplateManager = LookupUtil.getAlertTemplateManager(); MeasurementScheduleManagerLocal scheduleManager = LookupUtil.getMeasurementScheduleManager(); AgentManagerLocal agentManager = LookupUtil.getAgentManager(); StatusManagerLocal statusManager = LookupUtil.getStatusManager(); long start = System.currentTimeMillis(); // do this in one fell swoop, instead of one resource at a time Set<ResourceMeasurementScheduleRequest> results = scheduleManager.findSchedulesForResourceAndItsDescendants( ArrayUtils.unwrapCollection(resourceIds), false); long time = (System.currentTimeMillis() - start); if (time >= 10000L) { log.info( "Performance: commit resource, create schedules timing: resourceCount/millis=" + resourceIds.size() + '/' + time); } else if (log.isDebugEnabled()) { log.debug( "Performance: commit resource, create schedules timing: resourceCount/millis=" + resourceIds.size() + '/' + time); } start = System.currentTimeMillis(); for (Integer resourceId : resourceIds) { // apply alert templates try { alertTemplateManager.updateAlertDefinitionsForResource(overlord, resourceId); } catch (AlertDefinitionCreationException adce) { /* should never happen because AlertDefinitionCreationException is only ever * thrown if updateAlertDefinitionsForResource isn't called as the overlord * * but we'll log it anyway, just in case, so it isn't just swallowed */ log.error(adce); } catch (Throwable t) { log.debug("Could not apply alert templates for resourceId = " + resourceId, t); } } try { if (resourceIds.size() > 0) { // they all come from the same agent, so pick any old one int anyResourceIdFromNewlyCommittedSet = resourceIds.iterator().next(); int agentId = agentManager.getAgentIdByResourceId(anyResourceIdFromNewlyCommittedSet); statusManager.updateByAgent(agentId); } } catch (Throwable t) { log.debug("Could not reload caches for newly committed resources", t); } time = (System.currentTimeMillis() - start); if (time >= 10000L) { log.info( "Performance: commit resource, apply alert templates timing: resourceCount/millis=" + resourceIds.size() + '/' + time); } else if (log.isDebugEnabled()) { log.debug( "Performance: commit resource, apply alert templates timing: resourceCount/millis=" + resourceIds.size() + '/' + time); } return results; }