public void testCombineOrdered_randomHashCodes() { Random random = new Random(7); List<HashCode> hashCodes = Lists.newArrayList(); for (int i = 0; i < 10; i++) { hashCodes.add(HashCodes.fromLong(random.nextLong())); } HashCode hashCode1 = Hashing.combineOrdered(hashCodes); Collections.shuffle(hashCodes, random); HashCode hashCode2 = Hashing.combineOrdered(hashCodes); assertFalse(hashCode1.equals(hashCode2)); }
@Test public void hashTest() throws Exception { String s1 = "abcdef"; String s2 = "12345"; HashCode hash1 = murmur3Hash.newHasher().putBytes(s1.getBytes()).hash(); System.out.println(hash1); HashCode hash2 = murmur3Hash.newHasher().putBytes(s2.getBytes()).hash(); System.out.println(hash2); HashCode hash3 = murmur3Hash.newHasher().putBytes(s1.getBytes()).hash(); System.out.println(hash3); System.out.println(hash1.equals(hash2)); System.out.println(hash1.equals(hash3)); }
private boolean haveSameContents(File file, final JarFile jar, final JarEntry entry) throws IOException { HashFunction hashFun = Hashing.md5(); HashCode fileHash = Files.hash(file, hashFun); HashCode streamHash = ByteStreams.hash( new InputSupplier<InputStream>() { public InputStream getInput() throws IOException { return jar.getInputStream(entry); } }, hashFun); return fileHash.equals(streamHash); }
@Override public void run() { for (Map.Entry<String, ConfigFileInfo> entry : watchedFileMap.entrySet()) { String filePath = entry.getKey(); ConfigFileInfo configFileInfo = entry.getValue(); try { File file = new File(filePath); long lastModified = file.lastModified(); Preconditions.checkArgument(lastModified > 0L); if (lastModified != configFileInfo.lastModifiedTimestampMillis) { configFileInfo.lastModifiedTimestampMillis = lastModified; ByteSource byteSource = Files.asByteSource(file); HashCode newContentHash = byteSource.hash(HASH_FUNCTION); if (!newContentHash.equals(configFileInfo.contentHash)) { configFileInfo.contentHash = newContentHash; LOG.info("File {} was modified at {}, notifying watchers.", filePath, lastModified); byte[] newContents = byteSource.read(); for (Function<byte[], Void> watchers : configFileInfo.changeWatchers) { try { watchers.apply(newContents); } catch (Exception e) { LOG.error( "Exception in watcher callback for {}, ignoring. New file contents were: {}", filePath, new String(newContents, Charsets.UTF_8), e); } } } else { LOG.info( "File {} was modified at {} but content hash is unchanged.", filePath, lastModified); } } else { LOG.debug("File {} not modified since {}", filePath, lastModified); } } catch (Exception e) { // We catch and log exceptions related to the update of any specific file, but // move on so others aren't affected. Issues can happen for example if the watcher // races with an external file replace operation; in that case, the next run should // pick up the update. // TODO: Consider adding a metric to track this so we can alert on failures. LOG.error("Config update check failed for {}", filePath, e); } } }
@Override public String putBlob(final String containerName, final Blob blob) throws IOException { String blobKey = blob.getMetadata().getName(); Payload payload = blob.getPayload(); filesystemContainerNameValidator.validate(containerName); filesystemBlobKeyValidator.validate(blobKey); if (getDirectoryBlobSuffix(blobKey) != null) { return putDirectoryBlob(containerName, blob); } File outputFile = getFileForBlobKey(containerName, blobKey); // TODO: should we use a known suffix to filter these out during list? String tmpBlobName = blobKey + "-" + UUID.randomUUID(); File tmpFile = getFileForBlobKey(containerName, tmpBlobName); Path tmpPath = tmpFile.toPath(); HashingInputStream his = null; try { Files.createParentDirs(tmpFile); his = new HashingInputStream(Hashing.md5(), payload.openStream()); long actualSize = Files.asByteSink(tmpFile).writeFrom(his); Long expectedSize = blob.getMetadata().getContentMetadata().getContentLength(); if (expectedSize != null && actualSize != expectedSize) { throw new IOException( "Content-Length mismatch, actual: " + actualSize + " expected: " + expectedSize); } HashCode actualHashCode = his.hash(); HashCode expectedHashCode = payload.getContentMetadata().getContentMD5AsHashCode(); if (expectedHashCode != null && !actualHashCode.equals(expectedHashCode)) { throw new IOException( "MD5 hash code mismatch, actual: " + actualHashCode + " expected: " + expectedHashCode); } payload.getContentMetadata().setContentMD5(actualHashCode); if (outputFile.exists()) { delete(outputFile); } UserDefinedFileAttributeView view = getUserDefinedFileAttributeView(tmpPath); if (view != null) { try { view.write(XATTR_CONTENT_MD5, ByteBuffer.wrap(actualHashCode.asBytes())); writeCommonMetadataAttr(view, blob); } catch (IOException e) { logger.debug("xattrs not supported on %s", tmpPath); } } setBlobAccess(containerName, tmpBlobName, BlobAccess.PRIVATE); if (!tmpFile.renameTo(outputFile)) { throw new RuntimeException("Could not rename file " + tmpFile + " to " + outputFile); } return base16().lowerCase().encode(actualHashCode.asBytes()); } catch (IOException ex) { if (tmpFile != null) { try { delete(tmpFile); } catch (IOException e) { logger.debug("Could not delete %s: %s", tmpFile, e); } } throw ex; } finally { closeQuietly(his); if (payload != null) { payload.release(); } } }