/** * Returns a {@link File} object that links to the blob * * @param container * @param blobKey * @return */ public File getFileForBlobKey(String container, String blobKey) { filesystemContainerNameValidator.validate(container); filesystemBlobKeyValidator.validate(blobKey); String fileName = buildPathStartingFromBaseDir(container, blobKey); File blobFile = new File(fileName); return blobFile; }
@Override public void removeBlob(final String container, final String blobKey) { filesystemContainerNameValidator.validate(container); filesystemBlobKeyValidator.validate(blobKey); String fileName = buildPathStartingFromBaseDir(container, blobKey); logger.debug("Deleting blob %s", fileName); File fileToBeDeleted = new File(fileName); if (fileToBeDeleted.isDirectory()) { try { UserDefinedFileAttributeView view = getUserDefinedFileAttributeView(fileToBeDeleted.toPath()); if (view != null) { for (String s : view.list()) { view.delete(s); } } } catch (IOException e) { logger.debug("Could not delete attributes from %s: %s", fileToBeDeleted, e); } } try { delete(fileToBeDeleted); } catch (IOException e) { logger.debug("Could not delete %s: %s", fileToBeDeleted, e); } // now examine if the key of the blob is a complex key (with a directory structure) // and eventually remove empty directory removeDirectoriesTreeOfBlobKey(container, blobKey); }
@Override public void deleteContainer(String container) { filesystemContainerNameValidator.validate(container); if (!containerExists(container)) { return; } deleteDirectory(container, null); }
@Override public boolean blobExists(String container, String key) { filesystemContainerNameValidator.validate(container); filesystemBlobKeyValidator.validate(key); try { return buildPathAndChecksIfBlobExists(container, key); } catch (IOException e) { logger.error(e, "An error occurred while checking key %s in container %s", container, key); throw Throwables.propagate(e); } }
@Override public boolean createContainerInLocation( String container, Location location, CreateContainerOptions options) { // TODO: implement location logger.debug("Creating container %s", container); filesystemContainerNameValidator.validate(container); boolean created = createDirectoryWithResult(container, null); if (created) { setContainerAccess( container, options.isPublicRead() ? ContainerAccess.PUBLIC_READ : ContainerAccess.PRIVATE); } return created; }
@Override public void clearContainer(String container, ListContainerOptions options) { filesystemContainerNameValidator.validate(container); if (options.getDir() != null) { container += denormalize("/" + options.getDir()); } try { File containerFile = openFolder(container); File[] children = containerFile.listFiles(); if (null != children) { for (File child : children) if (options.isRecursive() || child.isFile()) { Utils.deleteRecursively(child); } } } catch (IOException e) { logger.error(e, "An error occurred while clearing container %s", container); Throwables.propagate(e); } }
/** * Returns all the blobs key inside a container * * @param container * @return * @throws IOException */ @Override public Iterable<String> getBlobKeysInsideContainer(String container) throws IOException { filesystemContainerNameValidator.validate(container); // check if container exists // TODO maybe an error is more appropriate Set<String> blobNames = Sets.newHashSet(); if (!containerExists(container)) { return blobNames; } File containerFile = openFolder(container); final int containerPathLength = containerFile.getAbsolutePath().length() + 1; populateBlobKeysInContainer( containerFile, blobNames, new Function<String, String>() { @Override public String apply(String string) { return string.substring(containerPathLength); } }); return blobNames; }
public boolean createContainer(String container) { filesystemContainerNameValidator.validate(container); return createContainerInLocation(container, null, CreateContainerOptions.NONE); }
@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(); } } }
@Override public boolean containerExists(String container) { filesystemContainerNameValidator.validate(container); return directoryExists(container, null); }