/*
* RHQ Management Platform
* Copyright (C) 2005-2008 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 as published by
* the Free Software Foundation version 2 of the License.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.server.content.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import org.testng.annotations.Test;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageBits;
import org.rhq.core.domain.content.PackageBitsBlob;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.composite.LoadedPackageBitsComposite;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.content.ContentUIManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.test.TransactionCallback;
import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.enterprise.server.util.SessionTestHelper;
/**
* Test case for general {@link org.rhq.enterprise.server.content.ContentUIManagerBean} tests. Any tests that would
* require a large DB state prior to running are split off into their own test classes.
*
* @author Jason Dobies
*/
public class ContentUIManagerBeanTest extends AbstractEJB3Test {
private static final boolean ENABLE_TESTS = true;
private ContentUIManagerLocal contentUIManager;
private ContentManagerLocal contentManager;
// Setup --------------------------------------------
@Override
protected void beforeMethod() throws Exception {
contentUIManager = LookupUtil.getContentUIManager();
contentManager = LookupUtil.getContentManager();
}
// Test Cases --------------------------------------------
@Test(enabled = ENABLE_TESTS)
public void testPackageBits() throws Throwable {
executeInTransaction(new TransactionCallback() {
public void execute() throws Exception {
LoadedPackageBitsComposite composite;
try {
Resource resource = SessionTestHelper.createNewResource(em, "testPkgBitsResource");
PackageType pkgType = new PackageType("testPkgBitsPT", resource.getResourceType());
org.rhq.core.domain.content.Package pkg = new Package("testPkgBitsP", pkgType);
Architecture arch = new Architecture("testPkgArch");
PackageVersion pkgVer = new PackageVersion(pkg, "1", arch);
em.persist(pkgType);
em.persist(pkg);
em.persist(arch);
em.persist(pkgVer);
em.flush();
// test that no bits are available right now
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == null;
assert !composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// pretend we loaded the bits, but we stored them somewhere other then the DB
PackageBits packageBits = createPackageBits();
pkgVer.setPackageBits(packageBits);
pkgVer = em.merge(pkgVer);
em.flush();
// test that the bits are available, but are not stored in the DB
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// let's make sure there really is no data in the DB
packageBits = em.find(PackageBits.class, packageBits.getId());
assert packageBits != null;
assert packageBits.getBlob().getBits() == null;
// now lets store some bits in the DB
final String DATA = "testPackageBits data";
PackageBitsBlob packageBitsBlob = em.find(PackageBitsBlob.class, packageBits.getId());
packageBitsBlob.setBits(DATA.getBytes());
em.merge(packageBitsBlob);
em.flush();
// test that the bits are available and stored in the DB
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
// let's make sure the data really is in the DB
packageBits = em.find(PackageBits.class, packageBits.getId());
assert packageBits != null;
assert DATA.equals(new String(packageBits.getBlob().getBits()));
////////////////////////////////////////////////////
// create another package version and test with that
////////////////////////////////////////////////////
PackageVersion pkgVer2 = new PackageVersion(pkg, "2", arch);
em.persist(pkgVer2);
em.flush();
// first make sure the query still gets the right answer for the first pkgVer
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
// test that no bits are available right now
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer2.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer2.getId();
assert composite.getPackageBitsId() == null;
assert !composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// pretend we loaded the bits, but we stored them somewhere other then the DB
PackageBits packageBits2 = createPackageBits();
pkgVer2.setPackageBits(packageBits2);
pkgVer2 = em.merge(pkgVer2);
em.flush();
// make sure the query still gets the right answer for the first pkgVer
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
// test that the bits are available, but are not stored in the DB
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer2.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer2.getId();
assert composite.getPackageBitsId() == packageBits2.getId();
assert composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// let's make sure there really is no data in the DB
packageBits2 = em.find(PackageBits.class, packageBits2.getId());
assert packageBits2 != null;
assert packageBits2.getBlob().getBits() == null;
// now lets store some bits in the DB
final String DATA2 = "testPackageBits more data";
packageBits2.getBlob().setBits(DATA2.getBytes());
em.merge(packageBits2.getBlob());
em.flush();
// make sure the query still gets the right answer for the first pkgVer
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
// test that the bits are available and stored in the DB
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer2.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer2.getId();
assert composite.getPackageBitsId() == packageBits2.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
// let's make sure the data really is in the DB
packageBits2 = em.find(PackageBits.class, packageBits2.getId());
assert packageBits2 != null;
assert DATA2.equals(new String(packageBits2.getBlob().getBits()));
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException(t);
}
}
});
}
@Test(enabled = ENABLE_TESTS)
public void testPackageBitsBlobStream() throws Throwable {
executeInTransaction(new TransactionCallback() {
public void execute() throws Exception {
LoadedPackageBitsComposite composite;
try {
Resource resource = SessionTestHelper.createNewResource(em, "testPkgBitsLargeResource");
PackageType pkgType = new PackageType("testPkgBitsLargePT", resource.getResourceType());
org.rhq.core.domain.content.Package pkg = new Package("testPkgBitsLargeP", pkgType);
Architecture arch = new Architecture("testPkgLargeArch");
PackageVersion pkgVer = new PackageVersion(pkg, "1", arch);
em.persist(pkgType);
em.persist(pkg);
em.persist(arch);
em.persist(pkgVer);
em.flush();
// test that no bits are available right now
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == null;
assert !composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// pretend we loaded the bits, but we stored them somewhere other then the DB
PackageBits packageBits = createPackageBits();
pkgVer.setPackageBits(packageBits);
pkgVer = em.merge(pkgVer);
em.flush();
// test that the bits are available, but are not stored in the DB
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert !composite.isPackageBitsInDatabase();
// let's make sure there really is no data in the DB
packageBits = em.find(PackageBits.class, packageBits.getId());
assert packageBits != null;
assert packageBits.getBlob().getBits() == null;
// now lets store some bits in the DB using PreparedStatements and BLOB mechanism
// to simulate large file transfers where streaming is used instead of reading entire
// contents into memory every time.
// destination once pulled from db
File tempDir = getTempDir();
if (!tempDir.exists()) {
assertTrue("Unable to mkdirs " + tempDir + " for test.", tempDir.mkdirs());
}
File retrieved = new File(tempDir, "pulled.jar");
if (retrieved.exists()) {
assertTrue("Unable to delete " + retrieved.getPath() + " for test cleanup.", retrieved.delete());
}
//any jar should be fine. Use canned jar
InputStream originalBinaryStream = this.getClass().getClassLoader()
.getResourceAsStream("binary-blob-sample.jar");
String originalDigest = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
.calcDigestString(originalBinaryStream);
originalBinaryStream.close();
originalBinaryStream = this.getClass().getClassLoader()
.getResourceAsStream("binary-blob-sample.jar");
contentManager.updateBlobStream(originalBinaryStream, packageBits, null);
packageBits = em.find(PackageBits.class, packageBits.getId());
// test that the bits are available and stored in the DB: Reading the Blob
composite = contentUIManager.getLoadedPackageBitsComposite(pkgVer.getId());
assert composite != null;
assert composite.getPackageVersionId() == pkgVer.getId();
assert composite.getPackageBitsId() == packageBits.getId();
assert composite.isPackageBitsAvailable();
assert composite.isPackageBitsInDatabase();
FileOutputStream outputStream = new FileOutputStream(retrieved);
contentManager.writeBlobOutToStream(outputStream, packageBits, false);
//Check that db content equal to file system content
String newDigest = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
.calcDigestString(retrieved);
assertEquals("Uploaded and retrieved digests differ:", originalDigest, newDigest);
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException(t);
}
}
});
}
private PackageBits createPackageBits() {
PackageBits bits = null;
PackageBitsBlob blob = null;
// We have to work backwards to avoid constraint violations. PackageBits requires a PackageBitsBlob,
// so create and persist that first, getting the ID
blob = new PackageBitsBlob();
em.persist(blob);
// Now create the PackageBits entity and assign the Id and blob. Note, do not persist the
// entity, the row already exists. Just perform and flush the update.
bits = new PackageBits();
bits.setId(blob.getId());
bits.setBlob(blob);
em.flush();
// return the new PackageBits and associated PackageBitsBlob
return bits;
}
}