示例#1
0
/**
 * 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;
  }