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; } }