protected String createPrefix(final Path directory) { // Keys can be listed by prefix. By choosing a common prefix // for the names of related keys and marking these keys with // a special character that delimits hierarchy, you can use the list // operation to select and browse keys hierarchically String prefix = StringUtils.EMPTY; if(!containerService.isContainer(directory)) { // Restricts the response to only contain results that begin with the // specified prefix. If you omit this optional argument, the value // of Prefix for your query will be the empty string. // In other words, the results will be not be restricted by prefix. prefix = containerService.getKey(directory); if(!prefix.endsWith(String.valueOf(Path.DELIMITER))) { prefix += Path.DELIMITER; } } return prefix; } }
@Override public String getKey(final Path file) { final String key = super.getKey(file); if(!file.isRoot() && !this.isContainer(file) && file.isDirectory()) { return key.concat(String.valueOf(Path.DELIMITER)).concat(PLACEHOLDER); } return key; } }
/** * @param file File in origin container * @param origin Distribution URL * @return URL to file in distribution */ private URI toUrl(final Path file, final URI origin) { final StringBuilder b = new StringBuilder(String.format("%s://%s", origin.getScheme(), origin.getHost())); if(distribution.getMethod().equals(Distribution.CUSTOM)) { b.append(Path.DELIMITER).append(URIEncoder.encode(PathRelativizer.relativize(origin.getRawPath(), file.getAbsolute()))); } else { if(StringUtils.isNotEmpty(origin.getRawPath())) { b.append(origin.getRawPath()); } if(StringUtils.isNotEmpty(containerService.getKey(file))) { b.append(Path.DELIMITER).append(URIEncoder.encode(containerService.getKey(file))); } } return URI.create(b.toString()).normalize(); }
@Override public String getKey(final Path file) { final String key = super.getKey(file); if(!file.isRoot() && !this.isContainer(file) && file.isDirectory()) { return key.concat(String.valueOf(Path.DELIMITER)); } return key; } }
@Override public String getKey(final Path file) { final String key = super.getKey(file); if(!file.isRoot() && !this.isContainer(file) && file.isDirectory()) { return key.concat(String.valueOf(Path.DELIMITER)); } return key; } }
/** * @param file File in origin container * @return CNAME to distribution */ private List<DescriptiveUrl> toCnameUrl(final Path file) { final List<DescriptiveUrl> urls = new ArrayList<DescriptiveUrl>(); for(String cname : distribution.getCNAMEs()) { final StringBuilder b = new StringBuilder(); b.append(String.format("%s://%s", distribution.getMethod().getScheme(), cname)).append(distribution.getMethod().getContext()); if(StringUtils.isNotEmpty(containerService.getKey(file))) { b.append(Path.DELIMITER).append(URIEncoder.encode(containerService.getKey(file))); } urls.add(new DescriptiveUrl(URI.create(b.toString()).normalize(), DescriptiveUrl.Type.cname, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString(distribution.getMethod().toString(), "S3")))); } return urls; } }
containerService.getContainer(file).getName(), overall.getMime(), containerService.getKey(file), manifest, Collections.emptyMap());
protected String copy(final Path source, final S3Object destination, final TransferStatus status) throws BackgroundException { try { // Copying object applying the metadata of the original final Map<String, Object> stringObjectMap = session.getClient().copyVersionedObject(source.attributes().getVersionId(), containerService.getContainer(source).getName(), containerService.getKey(source), destination.getBucketName(), destination, false); final Map complete = (Map) stringObjectMap.get(Constants.KEY_FOR_COMPLETE_METADATA); return (String) complete.get(Constants.AMZ_VERSION_ID); } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Cannot copy {0}", e, source); } }
/** * @return The ETag returned by the server for the uploaded object */ @Override public StorageObject call(final AbstractHttpEntity entity) throws BackgroundException { try { // Previous final HashMap<String, String> headers = new HashMap<>(status.getMetadata()); final String checksum = session.getClient().storeObject( regionService.lookup(file), containerService.getContainer(file).getName(), containerService.getKey(file), entity, headers, null); if(log.isDebugEnabled()) { log.debug(String.format("Saved object %s with checksum %s", file, checksum)); } final StorageObject stored = new StorageObject(containerService.getKey(file)); stored.setMd5sum(checksum); stored.setSize(status.getLength()); return stored; } catch(GenericException e) { throw new SwiftExceptionMappingService().map("Upload {0} failed", e, file); } catch(IOException e) { throw new DefaultIOExceptionMappingService().map("Upload {0} failed", e, file); } }
@Override public DescriptiveUrlBag toUrl(final Path file) { if(file.isVolume()) { return DescriptiveUrlBag.empty(); } final DescriptiveUrlBag list = new DescriptiveUrlBag(); if(file.isFile()) { final String download = String.format("%s/file/%s/%s", session.getClient().getDownloadUrl(), URIEncoder.encode(containerService.getContainer(file).getName()), URIEncoder.encode(containerService.getKey(file))); list.add(new DescriptiveUrl(URI.create(download), DescriptiveUrl.Type.http, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), Scheme.https.name().toUpperCase(Locale.ROOT)))); } return list; } }
@Override public MultipartPart call() throws BackgroundException { try { final HttpRange range = HttpRange.byLength(offset, length); final MultipartPart part = session.getClient().multipartUploadPartCopy(multipart, partNumber, containerService.getContainer(source).getName(), containerService.getKey(source), null, null, null, null, range.getStart(), range.getEnd(), source.attributes().getVersionId()); if(log.isInfoEnabled()) { log.info(String.format("Received response %s for part number %d", part, partNumber)); } // Populate part with response data that is accessible via the object's metadata return new MultipartPart(partNumber, null == part.getLastModified() ? new Date(System.currentTimeMillis()) : part.getLastModified(), null == part.getEtag() ? StringUtils.EMPTY : part.getEtag(), part.getSize()); } catch(S3ServiceException e) { throw new S3ExceptionMappingService().map("Cannot copy {0}", e, source); } } });
@Override public InputStream open() throws IOException { try { return session.getClient().getObjectImpl( false, containerService.getContainer(file).getName(), containerService.getKey(file), null, null, null, null, null, null, file.attributes().getVersionId(), new HashMap<String, Object>(), chunk.getParameters()) .getDataInputStream(); } catch(ServiceException e) { throw new IOException(e.getMessage(), e); } } });
/** * Add default metadata. Do not add checksum as object metadata must remain constant for all chunks. */ protected S3Object getDetails(final Path file, final TransferStatus status) { final S3Object object = new S3Object(containerService.getKey(file)); final String mime = status.getMime(); if(StringUtils.isNotBlank(mime)) { object.setContentType(mime); } final Checksum checksum = status.getChecksum(); if(Checksum.NONE != checksum) { switch(checksum.algorithm) { case md5: // Set checksum on our own to avoid jets3t setting AWS metadata for MD5 as metadata must remain // constant for all chunks object.addMetadata("Content-MD5", ServiceUtils.toBase64(ServiceUtils.fromHex(checksum.hash))); break; } } return object; }
@Override public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { try { final HttpRange range = HttpRange.withStatus(status); final RequestEntityRestStorageService client = session.getClient(); final S3Object object = client.getVersionedObject( file.attributes().getVersionId(), containerService.getContainer(file).getName(), containerService.getKey(file), null, // ifModifiedSince null, // ifUnmodifiedSince null, // ifMatch null, // ifNoneMatch status.isAppend() ? range.getStart() : null, status.isAppend() ? (range.getEnd() == -1 ? null : range.getEnd()) : null); if(log.isDebugEnabled()) { log.debug(String.format("Reading stream with content length %d", object.getContentLength())); } return object.getDataInputStream(); } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Download {0} failed", e, file); } }
@Override public void revert(final Path file) throws BackgroundException { final Ds3Client client = new SpectraClientBuilder().wrap(session.getClient(), session.getHost()); final Path container = containerService.getContainer(file); try { client.undeleteObjectSpectraS3(new UndeleteObjectSpectraS3Request(container.getName(), containerService.getKey(file))); } catch(IOException e) { throw new DefaultIOExceptionMappingService().map("Cannot revert file", e, file); } }
@Override public Path copy(final Path source, final Path target, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { try { session.getClient().copyObject(regionService.lookup(source), containerService.getContainer(source).getName(), containerService.getKey(source), containerService.getContainer(target).getName(), containerService.getKey(target)); // Copy original file attributes return new Path(target.getParent(), target.getName(), target.getType(), new PathAttributes(source.attributes())); } catch(GenericException e) { throw new SwiftExceptionMappingService().map("Cannot copy {0}", e, source); } catch(IOException e) { throw new DefaultIOExceptionMappingService().map("Cannot copy {0}", e, source); } }
@Override public Path copy(final Path source, final Path copy, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { try { final CloudBlob target = session.getClient().getContainerReference(containerService.getContainer(copy).getName()) .getAppendBlobReference(containerService.getKey(copy)); final CloudBlob blob = session.getClient().getContainerReference(containerService.getContainer(source).getName()) .getBlobReferenceFromServer(containerService.getKey(source)); final BlobRequestOptions options = new BlobRequestOptions(); options.setStoreBlobContentMD5(PreferencesFactory.get().getBoolean("azure.upload.md5")); final URI s = session.getHost().getCredentials().isTokenAuthentication() ? URI.create(blob.getUri().toString() + session.getHost().getCredentials().getToken()) : blob.getUri(); final String id = target.startCopy(s, AccessCondition.generateEmptyCondition(), AccessCondition.generateEmptyCondition(), options, context); if(log.isDebugEnabled()) { log.debug(String.format("Started copy for %s with copy operation ID %s", copy, id)); } // Copy original file attributes return new Path(copy.getParent(), copy.getName(), copy.getType(), new PathAttributes(source.attributes())); } catch(StorageException e) { throw new AzureExceptionMappingService().map("Cannot copy {0}", e, source); } catch(URISyntaxException e) { throw new NotfoundException(e.getMessage(), e); } }
private DescriptiveUrl createSignedUrl(final Path file, int seconds) { final CloudBlob blob; try { if(!session.isConnected()) { return DescriptiveUrl.EMPTY; } blob = session.getClient().getContainerReference(containerService.getContainer(file).getName()) .getBlobReferenceFromServer(containerService.getKey(file)); } catch(URISyntaxException | StorageException e) { return DescriptiveUrl.EMPTY; } final String token; try { token = blob.generateSharedAccessSignature(this.getPolicy(seconds), null); } catch(InvalidKeyException | StorageException e) { return DescriptiveUrl.EMPTY; } return new DescriptiveUrl(URI.create(String.format("%s://%s%s?%s", Scheme.https.name(), session.getHost().getHostname(), URIEncoder.encode(file.getAbsolute()), token)), DescriptiveUrl.Type.signed, MessageFormat.format(LocaleFactory.localizedString("{0} URL"), LocaleFactory.localizedString("Pre-Signed", "S3")) + " (" + MessageFormat.format(LocaleFactory.localizedString("Expires {0}", "S3") + ")", UserDateFormatterFactory.get().getShortFormat(this.getExpiry(seconds)))); }
@Override public void invalidate(final Path container, final Distribution.Method method, final List<Path> files, final LoginCallback prompt) throws BackgroundException { try { for(Path file : files) { if(containerService.isContainer(file)) { session.getClient().purgeCDNContainer(regionService.lookup(containerService.getContainer(file)), container.getName(), null); } else { session.getClient().purgeCDNObject(regionService.lookup(containerService.getContainer(file)), container.getName(), containerService.getKey(file), null); } } } catch(GenericException e) { throw new SwiftExceptionMappingService().map("Cannot write CDN configuration", e); } catch(IOException e) { throw new DefaultIOExceptionMappingService().map("Cannot write CDN configuration", e); } } }
@Override public Map<String, String> getMetadata(final Path file) throws BackgroundException { try { if(containerService.isContainer(file)) { final ContainerMetadata meta = session.getClient().getContainerMetaData(regionService.lookup(file), containerService.getContainer(file).getName()); return meta.getMetaData(); } else { final ObjectMetadata meta = session.getClient().getObjectMetaData(regionService.lookup(file), containerService.getContainer(file).getName(), containerService.getKey(file)); return meta.getMetaData(); } } catch(GenericException e) { throw new SwiftExceptionMappingService().map("Failure to read attributes of {0}", e, file); } catch(IOException e) { throw new DefaultIOExceptionMappingService().map("Failure to read attributes of {0}", e, file); } }