package org.rhq.enterprise.server.inventory; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.rhq.core.domain.criteria.ResourceTypeCriteria; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.ResourceType; import org.rhq.enterprise.server.RHQConstants; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.resource.metadata.ResourceMetadataManagerLocal; import org.rhq.enterprise.server.util.BatchIterator; /** * This API could not be added directly {@link org.rhq.enterprise.server.resource.ResourceTypeManagerBean} because it * would create a circular dependency with {@link org.rhq.enterprise.server.resource.ResourceManagerBean}, resulting * in a deployment failure. */ @Stateless public class InventoryManagerBean implements InventoryManagerLocal { @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) EntityManager entityMgr; @EJB private SubjectManagerLocal subjectMgr; @EJB private ResourceTypeManagerLocal resourceTypeMgr; @EJB private ResourceManagerLocal resourceMgr; @EJB private ResourceMetadataManagerLocal metadataMgr; @Override @SuppressWarnings("unchecked") @TransactionAttribute(TransactionAttributeType.REQUIRED) public int markTypesDeleted(List<Integer> resourceTypeIds, boolean uninventoryResources) { int typesDeleted = 0; Query query = entityMgr.createNamedQuery(ResourceType.QUERY_MARK_TYPES_DELETED); BatchIterator<Integer> batchIterator = new BatchIterator<Integer>(resourceTypeIds); for (List<Integer> typeIdsBatch : batchIterator) { query.setParameter("resourceTypeIds", typeIdsBatch); typesDeleted += query.executeUpdate(); if (uninventoryResources) { List<Integer> resourceIds = resourceMgr.findIdsByTypeIds(typeIdsBatch); resourceMgr.uninventoryResources(subjectMgr.getOverlord(), toIntArray(resourceIds)); } } return typesDeleted; } private int[] toIntArray(List<Integer> list) { int[] array = new int[list.size()]; int i = 0; for (Integer integer : list) { array[i++] = integer; } return array; } @Override public List<ResourceType> getDeletedTypes() { ResourceTypeCriteria criteria = new ResourceTypeCriteria(); criteria.addFilterDeleted(true); // we'll get all deleted types ... criteria.addFilterIgnored(null); // ... whether they are ignored or not criteria.clearPaging();//disable paging as the code assumes all the results will be returned. return resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.getOverlord(), criteria); } @Override public boolean isReadyForPermanentRemoval(ResourceType resourceType) { if (!resourceType.isDeleted()) { return false; } Number count = (Number) entityMgr.createQuery("select count(r) from Resource r where r.resourceType = :type") .setParameter("type", resourceType).getSingleResult(); boolean isReady = (count.intValue() == 0); // if resources still exist make sure they are all awaiting async uninventory, just in case something is lingering if (!isReady) { Query query = entityMgr .createQuery("select r.id from Resource r where r.resourceType = :type and not r.inventoryStatus = :status"); query.setParameter("type", resourceType); query.setParameter("status", InventoryStatus.UNINVENTORIED); List<Integer> rs = query.getResultList(); if (!rs.isEmpty()) { try { resourceMgr.uninventoryResources(subjectMgr.getOverlord(), toIntArray(rs)); } catch (Throwable t) { throw new RuntimeException("Failed to uninventory resources", t); } } } return isReady; } @Override public void purgeDeletedResourceType(ResourceType resourceType) { try { metadataMgr.completeRemoveResourceType(subjectMgr.getOverlord(), resourceType); } catch (Exception e) { throw new RuntimeException("Failed to purge resource types", e); } } }