public static void assertFileContent(String message, byte[] expected, File f) throws Exception { assertEquals(message, bytesToHexString(expected), bytesToHexString(hashFile(f))); }
public static byte[] copy(final InputStream is, final File target) throws IOException { if(! target.getParentFile().exists()) { target.getParentFile().mkdirs(); // Hmm } try (final OutputStream os = new FileOutputStream(target)){ return HashUtils.copyAndGetHash(is, os); } catch (IOException e) { throw PatchLogger.ROOT_LOGGER.cannotCopyFiles(is.toString(), target.getAbsolutePath(), e.getMessage(), e); } }
public static byte[] getAbsentModuleContentHash(final ModuleItem item) throws IOException { final byte[] content = getAbsentModuleContent(item); return HashUtils.hashBytes(content); } }
@Override public byte[] getMetadataHash() { try { if (cachedMetadataHash == null) { cachedMetadataHash = HashUtils.hashFile(file); } return cachedMetadataHash; } catch (IOException e) { throw processingError(e, "failed to generate hash"); } }
private static void writeModuleItem(final XMLExtendedStreamWriter writer, final DistributionModuleItem item, final Element element) throws XMLStreamException { writer.writeEmptyElement(element.name); writer.writeAttribute(Attribute.NAME.name, item.getName()); writer.writeAttribute(Attribute.SLOT.name, item.getSlot()); writer.writeAttribute(Attribute.COMPARISON_HASH.name, HashUtils.bytesToHexString(item.getComparisonHash())); writer.writeAttribute(Attribute.METADATA_HASH.name, HashUtils.bytesToHexString(item.getMetadataHash())); }
case HASH: if (modificationType == ModificationType.REMOVE) { targetHash = hexStringToByteArray(reader.getAttributeValue(i)); } else { hash = hexStringToByteArray(reader.getAttributeValue(i)); hash = hexStringToByteArray(reader.getAttributeValue(i)); } else { targetHash = hexStringToByteArray(reader.getAttributeValue(i));
public static byte[] hashFile(File file) throws IOException { synchronized (DIGEST) { DIGEST.reset(); updateDigest(DIGEST, file); return DIGEST.digest(); } }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { // Copy the new module resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); if(sourceDir.exists()) { // Recursively copy module contents (incl. native libs) IoUtils.copyFile(sourceDir, targetDir); } else { // ADD an absent module // this situation happens when merging ADD and REMOVE modifications // which results in an ADD of an absent module if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final Path moduleXml = targetDir.toPath().resolve(MODULE_XML); final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem)); Files.copy(is, moduleXml, StandardCopyOption.REPLACE_EXISTING); } // return contentItem.getContentHash(); return HashUtils.hashFile(targetDir); }
private static void writeChildren(final XMLExtendedStreamWriter writer, final Collection<DistributionContentItem> items) throws XMLStreamException { if (items == null || items.size() == 0) { return; } for (final DistributionContentItem item : items) { writer.writeStartElement(Element.NODE.name); writer.writeAttribute(Attribute.NAME.name, item.getName()); if (item.isLeaf()) { writer.writeAttribute(Attribute.COMPARISON_HASH.name, HashUtils.bytesToHexString(item.getComparisonHash())); writer.writeAttribute(Attribute.METADATA_HASH.name, HashUtils.bytesToHexString(item.getMetadataHash())); } writer.writeAttribute(Attribute.DIRECTORY.name, String.valueOf(!item.isLeaf())); // Recurse final Collection<DistributionContentItem> children = item.getChildren(); writeChildren(writer, children); writer.writeEndElement(); } }
case HASH: if (modificationType == ModificationType.REMOVE) { targetHash = hexStringToByteArray(reader.getAttributeValue(i)); } else { hash = hexStringToByteArray(reader.getAttributeValue(i)); hash = hexStringToByteArray(reader.getAttributeValue(i)); } else { targetHash = hexStringToByteArray(reader.getAttributeValue(i));
public static byte[] hashFile(File file) throws IOException { synchronized (DIGEST) { DIGEST.reset(); updateDigest(DIGEST, file); return DIGEST.digest(); } }
@Override public boolean prepare(PatchingTaskContext context) throws IOException { // we create the backup in any case, since it is possible that the task // will be processed anyhow if the user specified OVERRIDE_ALL policy. // If the task is undone, the patch history will be deleted (including this backup). backup(target, backup, Arrays.asList(item.getPath()), rollback, context); // See if the hash matches the metadata boolean isEmptyDirectory = false; if (target.isDirectory()) { final File[] children = target.listFiles(); if (children == null || children.length == 0) { isEmptyDirectory = true; } } final byte[] expected = description.getModification().getTargetHash(); final byte[] actual = isEmptyDirectory ? NO_CONTENT : HashUtils.hashFile(target); return Arrays.equals(expected, actual); }
protected void assertRestoredConfig(File baseDir, String xmlName, byte[] updatedHash, byte[] originalHash) throws IOException { File rolledBackXmlFile = assertFileExists(baseDir, "configuration", xmlName); assertEquals(bytesToHexString(updatedHash), bytesToHexString(hashFile(rolledBackXmlFile))); File restoredXmlFile = assertFileExists(baseDir, "configuration", "restored-configuration", xmlName); assertEquals(bytesToHexString(originalHash), bytesToHexString(hashFile(restoredXmlFile))); }
protected static void writeSlottedItem(final XMLExtendedStreamWriter writer, Element element, ContentModification modification) throws XMLStreamException { writer.writeEmptyElement(element.name); final ModuleItem item = (ModuleItem) modification.getItem(); final ModificationType type = modification.getType(); writer.writeAttribute(Attribute.NAME.name, item.getName()); if (!MAIN_SLOT.equals(item.getSlot())) { writer.writeAttribute(Attribute.SLOT.name, item.getSlot()); } byte[] hash = item.getContentHash(); if (hash.length > 0 && type != ModificationType.REMOVE) { writer.writeAttribute(Attribute.HASH.name, bytesToHexString(hash)); } if(type == ModificationType.REMOVE) { final byte[] existingHash = modification.getTargetHash(); if (existingHash.length > 0) { writer.writeAttribute(Attribute.HASH.name, bytesToHexString(existingHash)); } } else if(type == ModificationType.MODIFY) { final byte[] existingHash = modification.getTargetHash(); if (existingHash.length > 0) { writer.writeAttribute(Attribute.NEW_HASH.name, bytesToHexString(existingHash)); } } }
return new DistributionModuleItem(name, slot, hexStringToByteArray(comparison), hexStringToByteArray(metadata));
private static void updateDigest(MessageDigest digest, File file) throws IOException { if (file.isDirectory()) { File[] childList = file.listFiles(); if (childList != null) { Map<String, File> sortedChildren = new TreeMap<String, File>(); for (File child : childList) { sortedChildren.put(child.getName(), child); } for (File child : sortedChildren.values()) { updateDigest(digest, child); } } } else { // jar index files are generated by JBoss modules at runtime (a pristine AS7 installation does not have them). // they are skipped when computing checksum to avoid different checksum for the same JBoss module depending on // whether the AS7 installation has been started or not. if (file.getName().endsWith(".jar.index")) { return; } try (FileInputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis)){ byte[] bytes = new byte[8192]; int read; while ((read = bis.read(bytes)) > -1) { digest.update(bytes, 0, read); } } } }
public static byte[] copy(final InputStream is, final File target) throws IOException { if(! target.getParentFile().exists()) { target.getParentFile().mkdirs(); // Hmm } try (final OutputStream os = new FileOutputStream(target)){ return HashUtils.copyAndGetHash(is, os); } catch (IOException e) { throw PatchLogger.ROOT_LOGGER.cannotCopyFiles(is.toString(), target.getAbsolutePath(), e.getMessage(), e); } }
public static byte[] getAbsentModuleContentHash(final ModuleItem item) throws IOException { final byte[] content = getAbsentModuleContent(item); return HashUtils.hashBytes(content); } }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { // Copy the new module resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); if(sourceDir.exists()) { // Recursively copy module contents (incl. native libs) IoUtils.copyFile(sourceDir, targetDir); } else { // ADD an absent module // this situation happens when merging ADD and REMOVE modifications // which results in an ADD of an absent module if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final Path moduleXml = targetDir.toPath().resolve(MODULE_XML); final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem)); Files.copy(is, moduleXml, StandardCopyOption.REPLACE_EXISTING); } // return contentItem.getContentHash(); return HashUtils.hashFile(targetDir); }
private void checkApplyPatchAndRollbackRestoresBackupConfiguration(File patchDir, Patch patch) throws Exception { createPatchXMLFile(patchDir, patch); File zippedPatch = createZippedPatchFile(patchDir, patch.getPatchId()); Identity identityBeforePatch = loadInstalledIdentity().getIdentity(); PatchingResult result = executePatch(zippedPatch); assertPatchHasBeenApplied(result, patch); // check the AS7 config files have been backed up File backupAppclientXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "appclient", "appclient.xml"); assertFileContent(originalAppClientHash, backupAppclientXmlFile); File backupStandaloneXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "standalone", "standalone.xml"); assertFileContent(originalStandaloneHash, backupStandaloneXmlFile); File backupDomainXmlFile = assertFileExists(env.getInstalledImage().getPatchHistoryDir(patch.getPatchId()), "configuration", "domain", "domain.xml"); assertFileContent(originalDomainHash, backupDomainXmlFile); // let's change the standalone.xml file dump(standaloneXmlFile, "<updated standalone configuration with changes from the added module>"); byte[] updatedStandaloneXmlFile = hashFile(standaloneXmlFile); tree(tempDir); PatchingResult rollbackResult = rollback(patch.getPatchId()); assertPatchHasBeenRolledBack(rollbackResult, identityBeforePatch); File rolledBackStandaloneXmlFile = assertFileExists(env.getInstalledImage().getStandaloneDir(), "configuration", "standalone.xml"); assertEquals("updated content was " + bytesToHexString(updatedStandaloneXmlFile), bytesToHexString(originalStandaloneHash), bytesToHexString(hashFile(rolledBackStandaloneXmlFile))); }