modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatVHostComponent.java | 2 modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatWarComponent.java | 23 + modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/helper/FileContentDelegate.java | 129 +++++++--- 3 files changed, 110 insertions(+), 44 deletions(-)
New commits: commit ab1896c5792445fae10ea0b503f3dfe5d61180a0 Author: Stefan Negrea snegrea@redhat.com Date: Tue Dec 13 09:40:15 2011 -0600
[BZ 761593] Compute SHA256 for content that was deployed outside RHQ or for default content delivered with the server.
diff --git a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatVHostComponent.java b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatVHostComponent.java index f605e2d..0024cf8 100644 --- a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatVHostComponent.java +++ b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatVHostComponent.java @@ -302,7 +302,7 @@ public class TomcatVHostComponent extends MBeanResourceComponent<TomcatServerCom return; }
- FileContentDelegate fileContent = new FileContentDelegate(deployDir, details.getPackageTypeName()); + FileContentDelegate fileContent = new FileContentDelegate(deployDir); fileContent.createContent(path, tempFile, explodeOnDeploy);
// Resource key is a canonical objectName similar to: diff --git a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatWarComponent.java b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatWarComponent.java index 504403b..27591ba 100644 --- a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatWarComponent.java +++ b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/TomcatWarComponent.java @@ -508,7 +508,7 @@ public class TomcatWarComponent extends MBeanResourceComponent<TomcatVHostCompon log.warn("Failed to create app backup but proceeding with redeploy of " + appFile.getPath() + ": " + e); }
- FileContentDelegate contentDelegate = new FileContentDelegate(appFile.getParentFile(), packageDetails.getName()); + FileContentDelegate contentDelegate = new FileContentDelegate(appFile.getParentFile());
try { // Write the new bits for the application. If successful Tomcat will pick it up and complete the deploy. @@ -650,13 +650,20 @@ public class TomcatWarComponent extends MBeanResourceComponent<TomcatVHostCompon File app = new File(file.getPath()); if (app.isDirectory()) { File manifestFile = new File(app.getAbsolutePath(), "META-INF/MANIFEST.MF"); - InputStream manifestStream = new FileInputStream(manifestFile); - Manifest manifest = null; - try { - manifest = new Manifest(manifestStream); - sha256 = manifest.getMainAttributes().getValue("RHQ-Sha256"); - } finally { - manifestStream.close(); + if (manifestFile.exists()) { + InputStream manifestStream = new FileInputStream(manifestFile); + Manifest manifest = null; + try { + manifest = new Manifest(manifestStream); + sha256 = manifest.getMainAttributes().getValue("RHQ-Sha256"); + } finally { + manifestStream.close(); + } + } + + if (sha256 == null || sha256.trim().isEmpty()) { + FileContentDelegate fileContentDelegate = new FileContentDelegate(app); + sha256 = fileContentDelegate.calculateSHAForCotent(app); } } else { sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(app); diff --git a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/helper/FileContentDelegate.java b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/helper/FileContentDelegate.java index a93eddf..5699ab4 100644 --- a/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/helper/FileContentDelegate.java +++ b/modules/plugins/tomcat/src/main/java/org/jboss/on/plugins/tomcat/helper/FileContentDelegate.java @@ -30,6 +30,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Set; +import java.util.Stack; import java.util.jar.Attributes; import java.util.jar.Manifest;
@@ -49,24 +50,18 @@ import org.rhq.core.util.file.FileUtil; * @author Jason Dobies */ public class FileContentDelegate { - // Attributes --------------------------------------------
private File deployDirectory; - private String packageTypeName;
- // Constructors -------------------------------------------- - - public FileContentDelegate(File directory, String packageTypeName) { + public FileContentDelegate(File directory) { this.deployDirectory = directory; - this.packageTypeName = packageTypeName; - } - - // Public -------------------------------------------- - - public String getPackageTypeName() { - return packageTypeName; }
+ /** + * Getter for deployment directory. + * + * @return deploy directory + */ public File getDirectory() { return deployDirectory; } @@ -85,30 +80,8 @@ public class FileContentDelegate { try { if (unzip) { ZipUtil.unzipFile(content, destination); - - File manifestFile = new File(destination, "META-INF/MANIFEST.MF"); - Manifest manifest; - if (manifestFile.exists()) { - FileInputStream inputStream = new FileInputStream(manifestFile); - try { - manifest = new Manifest(inputStream); - } finally { - inputStream.close(); - } - } else { - manifest = new Manifest(); - } - - Attributes attribs = manifest.getMainAttributes(); String sha = new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(content); - attribs.putValue("RHQ-Sha256", sha); - - FileOutputStream outputStream = new FileOutputStream(manifestFile); - try { - manifest.write(outputStream); - } finally { - outputStream.close(); - } + writeSHAToManifest(destination, sha); } else { InputStream contentStream = new BufferedInputStream(new FileInputStream(content)); FileUtil.writeFile(contentStream, destination); @@ -118,6 +91,50 @@ public class FileContentDelegate { } }
+ /** + * Calculate SHA256 for the content of an exploded war deployment. This method should be used to + * compute the SHA256 for content deployed outside RHQ or for the initial content delivered + * with the server. + * + * @param deploymentDirectory app deployment folder + * @return + */ + public String calculateSHAForCotent(File deploymentDirectory) { + String sha = null; + try { + if (deploymentDirectory.isDirectory()) { + MessageDigestGenerator messageDigest = new MessageDigestGenerator(MessageDigestGenerator.SHA_256); + + Stack<File> unvisitedFolders = new Stack<File>(); + unvisitedFolders.add(deploymentDirectory); + while (!unvisitedFolders.empty()) { + for (File file : unvisitedFolders.pop().listFiles()) { + if (file.isDirectory()) { + unvisitedFolders.add(file); + } else { + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(file); + messageDigest.add(inputStream); + } finally { + if (inputStream != null) { + inputStream.close(); + } + } + } + } + } + + sha = messageDigest.getDigestString(); + writeSHAToManifest(deploymentDirectory, sha); + } + } catch (IOException e) { + throw new RuntimeException("Error creating artifact for contentFile: " + deploymentDirectory, e); + } + + return sha; + } + public File getPath(PackageDetails details) { /* JBNADM-2022 - It still needs to be determined if it is the responsibility of the plugin container or the * plugin to be concerned with path information in the package name. For now, it's the plugin's @@ -181,4 +198,46 @@ public class FileContentDelegate { */ return null; } + + /** + * Write the SHA256 to the manifest using the RHQ-Sha256 attribute tag. + * + * @param deploymentFolder app deployment folder + * @param sha SHA256 + * @throws IOException + */ + private void writeSHAToManifest(File deploymentFolder, String sha) throws IOException { + File manifestFile = new File(deploymentFolder, "META-INF/MANIFEST.MF"); + Manifest manifest; + if (manifestFile.exists()) { + FileInputStream inputStream = new FileInputStream(manifestFile); + try { + manifest = new Manifest(inputStream); + } finally { + inputStream.close(); + } + } else { + manifest = new Manifest(); + manifestFile.getParentFile().mkdirs(); + manifestFile.createNewFile(); + } + + Attributes attribs = manifest.getMainAttributes(); + + //The main section of the manifest file does not get saved if both of + //these two attributes are missing. Please see Attributes implementation. + if (!attribs.containsKey(Attributes.Name.MANIFEST_VERSION.toString()) + && !attribs.containsKey(Attributes.Name.SIGNATURE_VERSION.toString())) { + attribs.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0"); + } + + attribs.putValue("RHQ-Sha256", sha); + + FileOutputStream outputStream = new FileOutputStream(manifestFile); + try { + manifest.write(outputStream); + } finally { + outputStream.close(); + } + } } \ No newline at end of file
rhq-commits@lists.fedorahosted.org