/*
* RHQ Management Platform
* Copyright (C) 2009 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, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* 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 and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.enterprise.server.plugin.pc.content;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.transaction.TransactionManager;
import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.ContentSource;
import org.rhq.core.domain.content.ContentSourceType;
import org.rhq.core.domain.content.PackageVersionContentSource;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.content.RepoGroup;
import org.rhq.core.domain.content.RepoRelationship;
import org.rhq.core.domain.content.RepoRepoGroup;
import org.rhq.core.domain.content.RepoRepoRelationship;
import org.rhq.core.domain.criteria.RepoCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Jason Dobies
*/
public class ContentProviderManagerSyncContentProviderTest extends AbstractEJB3Test {
private static final String CUSTOM_IMPORTED_REPO_NAME = "customImportedRepo";
private static final String PREVIOUS_CANDIDATE_REPO_NAME = "testPreviousCandidate";
private TestContentServerPluginService pluginService;
// The following variables need to be cleaned up at the end of the test
private ContentSourceType testSourceType;
private ContentSource syncSource; // Source that is syncced in this test
private ContentSource nonSyncSource; // Existing source NOT being syncced in this test
private Repo nonCandidateOnOtherSource; // Should NOT appear in the sync packages call since its a different source
private List<Integer> reposToDelete = new ArrayList<Integer>();
private List<Integer> repoGroupsToDelete = new ArrayList<Integer>();
private Integer repoId;
private Integer relatedRepoId;
@Override
protected void beforeMethod() throws Exception {
// Plugin service setup
prepareScheduler();
pluginService = new TestContentServerPluginService(this);
// Because of the (current) transaction settings of some of the nested methods (i.e. REQUIRES_NEW),
// this test must commit its data and clean up after itself, as compared to simply rolling back the
// transaction at the end.
TransactionManager tx = getTransactionManager();
tx.begin();
EntityManager entityManager = getEntityManager();
ContentSourceManagerLocal contentManager = LookupUtil.getContentSourceManager();
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject overlord = subjectManager.getOverlord();
// Create a sample content source type that will be used in this test
testSourceType = new ContentSourceType("testType");
entityManager.persist(testSourceType);
entityManager.flush();
//need to actually commit the tx so that the subsequent code can see the new entry in
//the database
tx.commit();
tx.begin();
//new entity manager associated with the new tx
entityManager = getEntityManager();
// Add a content source to sync in this test
syncSource = new ContentSource("testSource1", testSourceType);
contentManager.simpleCreateContentSource(overlord, syncSource);
entityManager.flush();
// Add an extra content source that isn't being syncced
nonSyncSource = new ContentSource("testSource2", testSourceType);
contentManager.simpleCreateContentSource(overlord, nonSyncSource);
entityManager.flush();
// Add existing repo against other source (this shouldn't show up in the request for packages)
nonCandidateOnOtherSource = new Repo("nonCandidateOnOtherSource");
nonCandidateOnOtherSource.setCandidate(false);
nonCandidateOnOtherSource.addContentSource(nonSyncSource);
repoManager.createRepo(overlord, nonCandidateOnOtherSource);
tx.commit();
}
@Override
protected void afterMethod() throws Exception {
try {
// Transactional stuff
TransactionManager tx = getTransactionManager();
tx.begin();
EntityManager entityManager = getEntityManager();
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject overlord = subjectManager.getOverlord();
// Delete the repo relationships
entityManager.createNamedQuery(RepoRepoRelationship.DELETE_BY_REPO_ID).setParameter("repoId", repoId)
.executeUpdate();
entityManager.createNamedQuery(RepoRelationship.DELETE_BY_RELATED_REPO_ID)
.setParameter("relatedRepoId", relatedRepoId).executeUpdate();
// Delete any repos that were created in this test
for (Integer repoId : reposToDelete) {
repoManager.deleteRepo(overlord, repoId);
}
reposToDelete.clear();
// Delete any repo groups that were created in this test
for (Integer repoGroupId : repoGroupsToDelete) {
repoManager.deleteRepoGroup(overlord, repoGroupId);
}
repoGroupsToDelete.clear();
// First disassociate packages from the content source
entityManager.createNamedQuery(PackageVersionContentSource.DELETE_BY_CONTENT_SOURCE_ID)
.setParameter("contentSourceId", syncSource.getId()).executeUpdate();
// Delete the existing repos
nonCandidateOnOtherSource = entityManager.find(Repo.class, nonCandidateOnOtherSource.getId());
entityManager.remove(nonCandidateOnOtherSource);
// Delete the source that was created
syncSource = entityManager.find(ContentSource.class, syncSource.getId());
entityManager.remove(syncSource);
nonSyncSource = entityManager.find(ContentSource.class, nonSyncSource.getId());
entityManager.remove(nonSyncSource);
// Delete the fake source type
testSourceType = entityManager.find(ContentSourceType.class, testSourceType.getId());
entityManager.remove(testSourceType);
tx.commit();
} finally {
// Plugin service teardown
unprepareServerPluginService();
unprepareScheduler();
}
}
@Test
@SuppressWarnings("unchecked")
public void synchronizeContentSource() throws Exception {
try {
getTransactionManager().begin();
// Setup
// --------------------------------------------
RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject overlord = subjectManager.getOverlord();
// -> Add an already imported repo to the system so it already exists when the report introduces it
Repo existingImportedRepo = new Repo(TestContentProvider.EXISTING_IMPORTED_REPO_NAME);
existingImportedRepo.setCandidate(false);
repoManager.createRepo(overlord, existingImportedRepo);
// -> Add an already imported repo that wasn't introduced from the report; a user created repo
Repo customImportedRepo = new Repo(CUSTOM_IMPORTED_REPO_NAME);
customImportedRepo.setCandidate(false);
customImportedRepo.addContentSource(syncSource);
repoManager.createRepo(overlord, customImportedRepo);
// -> Simulate a candidate repo from a previous import that will be in this report as well
Repo existingCandidateRepo = new Repo(TestContentProvider.EXISTING_CANDIDATE_REPO_NAME);
existingCandidateRepo.setCandidate(true);
repoManager.createRepo(overlord, existingCandidateRepo);
// -> Simulate a candidate repo from a previous import that will *NOT* be in this report
Repo previousRepo = new Repo(PREVIOUS_CANDIDATE_REPO_NAME);
previousRepo.setCandidate(true);
previousRepo.addContentSource(syncSource);
repoManager.createRepo(overlord, previousRepo);
// Test
// --------------------------------------------
// TestContentProviderManager providerManager = new TestContentProviderManager();
pluginService.getContentProviderManager().testConnection(syncSource.getId());
boolean completed = pluginService.getContentProviderManager()
.synchronizeContentProvider(syncSource.getId());
assert completed;
// Verify RepoGroups
RepoGroup repoGroup = repoManager.getRepoGroupByName("testRepoGroup");
assert repoGroup != null;
repoGroupsToDelete.add(repoGroup.getId());
// Verify Repos
// --------------------------------------------
List<Repo> retrievedRepos;
// -> Simple Repo
retrievedRepos = repoManager.getRepoByName("testRepo1");
assert retrievedRepos.size() == 1;
assert retrievedRepos.get(0).isCandidate();
reposToDelete.add(retrievedRepos.get(0).getId());
// -> Repo in a group
retrievedRepos = repoManager.getRepoByName("testRepo2");
assert retrievedRepos.size() == 1;
assert retrievedRepos.get(0).isCandidate();
reposToDelete.add(retrievedRepos.get(0).getId());
Repo repoInGroup = retrievedRepos.get(0);
RepoCriteria findWithRepoGroup = new RepoCriteria();
findWithRepoGroup.fetchRepoRepoGroups(true);
findWithRepoGroup.addFilterId(repoInGroup.getId());
PageList<Repo> repoPageList = repoManager.findReposByCriteria(overlord, findWithRepoGroup);
repoInGroup = repoPageList.get(0);
Set<RepoRepoGroup> repoGroups = repoInGroup.getRepoRepoGroups();
assert repoGroups.size() == 1;
RepoRepoGroup repoRepoGroup = repoGroups.iterator().next();
assert repoRepoGroup.getRepoRepoGroupPK().getRepoGroup().getName().equals("testRepoGroup");
assert repoRepoGroup.getRepoRepoGroupPK().getRepo().getName().equals("testRepo2");
// -> Repo with a parent
retrievedRepos = repoManager.getRepoByName("testRepo3");
assert retrievedRepos.size() == 1;
assert retrievedRepos.get(0).isCandidate();
reposToDelete.add(retrievedRepos.get(0).getId());
relatedRepoId = retrievedRepos.get(0).getId();
retrievedRepos = repoManager.getRepoByName("testRepo4");
assert retrievedRepos.size() == 1;
assert retrievedRepos.get(0).isCandidate();
reposToDelete.add(retrievedRepos.get(0).getId());
repoId = retrievedRepos.get(0).getId();
RepoCriteria findWithRelationships = new RepoCriteria();
findWithRelationships.addFilterName("testRepo4");
findWithRelationships.fetchRepoRepoRelationships(true);
PageList<Repo> childRepoList = repoManager.findReposByCriteria(overlord, findWithRelationships);
assert childRepoList.size() == 1;
Repo childRepo = childRepoList.get(0);
Set<RepoRepoRelationship> childRepoRepoRelationship = childRepo.getRepoRepoRelationships();
assert childRepoRepoRelationship.size() == 1;
// -> Repo that was already imported in the system (make sure there is still only one)
retrievedRepos = repoManager.getRepoByName(TestContentProvider.EXISTING_IMPORTED_REPO_NAME);
assert retrievedRepos.size() == 1;
reposToDelete.add(retrievedRepos.get(0).getId());
// -> Repo that was imported but not in the report (i.e. a user created repo)
retrievedRepos = repoManager.getRepoByName(CUSTOM_IMPORTED_REPO_NAME);
assert retrievedRepos.size() == 1;
reposToDelete.add(retrievedRepos.get(0).getId());
// -> Repo that was already a candidate in the system (make sure it's not added again)
retrievedRepos = repoManager.getRepoByName(TestContentProvider.EXISTING_CANDIDATE_REPO_NAME);
assert retrievedRepos.size() == 1;
reposToDelete.add(retrievedRepos.get(0).getId());
// -> Make sure a repo that was previously a candidate of this content source but did not
// come back in the latest sync is removed
retrievedRepos = repoManager.getRepoByName(PREVIOUS_CANDIDATE_REPO_NAME);
assert retrievedRepos.size() == 0;
// -> Non-existent repo
retrievedRepos = repoManager.getRepoByName("testRepoFoo");
assert retrievedRepos.size() == 0;
getTransactionManager().commit();
} catch (Throwable t) {
getTransactionManager().rollback();
}
}
}