package org.rhq.enterprise.server.plugin.pc.content;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageVersion;
public class TestContentProvider implements ContentProvider, PackageSource, RepoSource, DistributionSource {
/**
* Packages returned in a call to
* {@link #synchronizePackages(String, PackageSyncReport, Collection)} will
* indicate they are of this type. Any test attempting to call this
* synchronize method should be sure to create a package type of this name
* in the database prior to calling it.
*/
public static final String PACKAGE_TYPE_NAME = "testContentProviderFakePackage";
/**
* In order to create a package type (as needed to create the type indicated
* in {@link #PACKAGE_TYPE_NAME}), the package type must be created as part
* of this resource type.
*/
public static final String RESOURCE_TYPE_NAME = "testContentProviderFakeResourceType";
/**
* In order to create a resource type (as needed to create the type
* indicated in {@link #RESOURCE_TYPE_NAME}), this resource type plugin name
* should be used.
*/
public static final String RESOURCE_TYPE_PLUGIN_NAME = "testContentProviderFakeResourceTypePlugin";
public static final String EXISTING_IMPORTED_REPO_NAME = "testRepoImportedExisting";
public static final String EXISTING_CANDIDATE_REPO_NAME = "testRepoCandidateExisting";
/**
* This content source will return packages when asked to synchronize a
* repo with this name.
*/
public static final String REPO_WITH_PACKAGES = EXISTING_IMPORTED_REPO_NAME;
/**
* This content source will return distributions when asked to synchronize
* a repo with this name.
*/
public static final String REPO_WITH_DISTRIBUTIONS = EXISTING_IMPORTED_REPO_NAME;
/**
* Collection of packages that will be returned from calling
* {@link #synchronizePackages(String, PackageSyncReport, Collection)}
* passing in a repo with the name {@link #REPO_WITH_PACKAGES}.
*/
public static final Map<ContentProviderPackageDetailsKey, ContentProviderPackageDetails> PACKAGES = new HashMap<ContentProviderPackageDetailsKey, ContentProviderPackageDetails>(
2);
static {
ContentProviderPackageDetailsKey key1 = new ContentProviderPackageDetailsKey("package1", "version1",
PACKAGE_TYPE_NAME, "noarch", RESOURCE_TYPE_NAME, RESOURCE_TYPE_PLUGIN_NAME);
ContentProviderPackageDetails details1 = new ContentProviderPackageDetails(key1);
details1.setFileName("filename1");
details1.setFileSize(4L);
details1.setLocation("foo1");
PACKAGES.put(key1, details1);
ContentProviderPackageDetailsKey key2 = new ContentProviderPackageDetailsKey("package2", "version2",
PACKAGE_TYPE_NAME, "noarch", RESOURCE_TYPE_NAME, RESOURCE_TYPE_PLUGIN_NAME);
ContentProviderPackageDetails details2 = new ContentProviderPackageDetails(key2);
details2.setFileName("filename2");
details2.setFileSize(4L);
details2.setLocation("foo2");
PACKAGES.put(key2, details2);
}
/**
* Number of associated distribution files: 2
*/
public static final String DISTRIBUTION_1_LABEL = "distribution1";
/**
* Number of associated distribution files: 1
*/
public static final String DISTRIBUTION_2_LABEL = "distribution2";
public static final Map<String, DistributionDetails> DISTRIBUTIONS = new HashMap<String, DistributionDetails>(2);
static {
// Note: The type "kickstart" should already be in the database from
// installation
/*
* Note: The md5 sums below will be used to determine if the file needs
* to be loaded through a call to getPackageBits. I set these to an
* invalid MD5 so they will *always* be downloaded.
*/
DistributionDetails dis1 = new DistributionDetails(DISTRIBUTION_1_LABEL, "kickstart");
dis1.setDistributionPath("/kstrees");
DistributionFileDetails file11 = new DistributionFileDetails("dist1file1", System.currentTimeMillis(), "zzz");
DistributionFileDetails file12 = new DistributionFileDetails("dist1file2", System.currentTimeMillis(), "zzz");
dis1.addFile(file11);
dis1.addFile(file12);
DISTRIBUTIONS.put(dis1.getLabel(), dis1);
DistributionDetails dis2 = new DistributionDetails(DISTRIBUTION_2_LABEL, "kickstart");
dis2.setDistributionPath("/kstrees");
DistributionFileDetails file21 = new DistributionFileDetails("dist2file1", System.currentTimeMillis(), "zzz");
dis2.addFile(file21);
DISTRIBUTIONS.put(dis2.getLabel(), dis2);
}
public static final int PACKAGE_COUNT_FOR_BITS = PACKAGES.size() + 3; // packages
// +
// number
// of
// distro
// files
/**
* If <code>true</code>, the call to {@link #testConnection()} will throw an
* exception.
*/
private boolean failTest = false;
// Set this value if you want the packageSync step to take a while
private int longRunningSynchSleep = 0;
/**
* Holds a list of all repo names that were passed into calls to
* {@link #synchronizePackages(String, PackageSyncReport, Collection)} to
* track when and with what data these calls are made.
*/
private List<String> logSynchronizePackagesRepos = new ArrayList<String>();
/**
* Holds a list of all locations passed into calls to
* {@link #getInputStream(String)}.
*/
private List<String> logGetInputStreamLocations = new ArrayList<String>();
/**
* Holds a list of all repo names that were passed into calls to
* {@link #synchronizeDistribution(String, DistributionSyncReport, Collection)}
* .
*/
private List<String> logSynchronizeDistroRepos = new ArrayList<String>();
public void initialize(Configuration configuration) throws Exception {
// No-op
}
public void shutdown() {
// No-op
}
public void testConnection() throws Exception {
if (failTest) {
throw new Exception("Mock content source configured to fail the connection test");
}
System.out.println("Connection tested.");
}
public RepoImportReport importRepos() throws Exception {
RepoImportReport report = new RepoImportReport();
// Create a repo group in the system
RepoGroupDetails group1 = new RepoGroupDetails("testRepoGroup", "family");
report.addRepoGroup(group1);
// Simple repo
RepoDetails repo1 = new RepoDetails("testRepo1");
repo1.setDescription("First test repo");
report.addRepo(repo1);
// Repo belonging to a group that was created in the sync
RepoDetails repo2 = new RepoDetails("testRepo2");
repo2.setRepoGroup("testRepoGroup");
report.addRepo(repo2);
// Repo with a parent repo created in this sync
// Parent explicitly added to this list *after* this child to ensure
// that's not a problem
RepoDetails repo3 = new RepoDetails("testRepo3");
report.addRepo(repo3);
RepoDetails repo4 = new RepoDetails("testRepo4");
repo4.setParentRepoName("testRepo3");
report.addRepo(repo4);
// Repo that was already imported in the system
RepoDetails repo5 = new RepoDetails(EXISTING_IMPORTED_REPO_NAME);
report.addRepo(repo5);
// Repo that was already a candidate in the system
RepoDetails repo6 = new RepoDetails(EXISTING_CANDIDATE_REPO_NAME);
report.addRepo(repo6);
return report;
}
public void synchronizePackages(String repoName, PackageSyncReport report,
Collection<ContentProviderPackageDetails> existingPackages) throws SyncException, InterruptedException {
logSynchronizePackagesRepos.add(repoName);
if (!REPO_WITH_PACKAGES.equals(repoName)) {
return;
}
// For each package this provider wants to introduce, make sure it
// doesn't exist already.
// This basically means the report will only ever contain "added"
// packages and will only do so
// on the first call to this method. This will likely be changed as new
// requirements emerge.
for (ContentProviderPackageDetails pkg : PACKAGES.values()) {
ContentProviderPackageDetails existingPackage = findDetailsByKey(pkg.getContentProviderPackageDetailsKey(),
existingPackages);
if (existingPackage == null) {
report.addNewPackage(pkg);
}
}
System.out.println(this.getClass().getSimpleName() + ".synchronizePackages sleeping for "
+ this.longRunningSynchSleep + " seconds");
Thread.sleep(this.longRunningSynchSleep);
}
public InputStream getInputStream(String location) throws Exception {
logGetInputStreamLocations.add(location);
String seed = "Test Bits " + System.currentTimeMillis();
ByteArrayInputStream bais = new ByteArrayInputStream(seed.getBytes());
BufferedInputStream bis = new BufferedInputStream(bais);
return bis;
}
public void synchronizeDistribution(String repoName, DistributionSyncReport report,
Collection<DistributionDetails> existingDistros) throws SyncException, InterruptedException {
logSynchronizeDistroRepos.add(repoName);
if (!REPO_WITH_DISTRIBUTIONS.equals(repoName)) {
return;
}
for (DistributionDetails distro : DISTRIBUTIONS.values()) {
boolean existing = false;
for (DistributionDetails existingDistro : existingDistros) {
if (distro.getLabel().equals(existingDistro.getLabel())) {
existing = true;
break;
}
}
if (!existing) {
report.addDistro(distro);
}
}
System.out.println(this.getClass().getSimpleName() + ".synchronizeDistribution sleeping for "
+ this.longRunningSynchSleep + " seconds");
Thread.sleep(this.longRunningSynchSleep);
}
public String getDistFileRemoteLocation(String repoName, String label, String relativeFilename) {
return "foo";
}
/**
* Returns a list of repo names that were used to all calls to
* {@link #synchronizePackages(String, PackageSyncReport, Collection)}
* either since the creation of this instance or the last call to
* {@link #reset()}.
*
* @return handle to the actual list used to capture these names; be careful
* about iterating this list while making other calls against this
* instance
*/
public List<String> getLogSynchronizePackagesRepos() {
return logSynchronizePackagesRepos;
}
/**
* Returns a list of locations passed into all calls to
* {@link #getInputStream(String)} since the creation of this instance or
* the lsat call to {@link #reset()}.
*
* @return handle to the actual list used to capture these names; be careful
* about iterating this list while making other calls against this
* instance
*/
public List<String> getLogGetInputStreamLocations() {
return logGetInputStreamLocations;
}
/**
* Indicate how long you want the provider to sleep during the PackageSync
* step
*
* @param longRunningSynchSleep
*/
public void setLongRunningSynchSleep(int longRunningSynchSleep) {
this.longRunningSynchSleep = longRunningSynchSleep;
}
/**
* Rests the logging of calls made into this instance.
*/
public void reset() {
logGetInputStreamLocations.clear();
logSynchronizePackagesRepos.clear();
logSynchronizeDistroRepos.clear();
}
private ContentProviderPackageDetails findDetailsByKey(ContentProviderPackageDetailsKey key,
Collection<ContentProviderPackageDetails> packages) {
for (ContentProviderPackageDetails pkg : packages) {
if (pkg.getContentProviderPackageDetailsKey().equals(key)) {
return pkg;
}
}
return null;
}
public SyncProgressWeight getSyncProgressWeight() {
return SyncProgressWeight.DEFAULT_WEIGHTS;
}
}