@Test public void testMoveVersioned() throws Exception { final Path container = new Path("versioning-test-us-east-1-cyberduck", EnumSet.of(Path.Type.directory, Path.Type.volume)); Path test = new Path(container, new AsciiRandomStringService().random(), EnumSet.of(Path.Type.file)); assertNotNull(new S3TouchFeature(session).touch(test, new TransferStatus().withMime("text/plain")).attributes().getVersionId()); assertTrue(new S3FindFeature(session).find(test)); final S3WriteFeature feature = new S3WriteFeature(session); final byte[] content = new RandomStringGenerator.Builder().build().generate(10).getBytes(StandardCharsets.UTF_8); final TransferStatus status = new TransferStatus().withMime("text/plain"); status.setLength(content.length); status.setChecksum(new SHA256ChecksumCompute().compute(new ByteArrayInputStream(content), status)); final HttpResponseOutputStream<StorageObject> out = feature.write(test, status, new DisabledConnectionCallback()); new StreamCopier(status, status).transfer(new ByteArrayInputStream(content), out); out.close(); final AttributedList<Path> list = new S3ListService(session).list(container, new DisabledListProgressListener()); for(Path path : list) { if(new SimplePathPredicate(test).test(path)) { test = path; break; } } final Path renamed = new Path(container, String.format("%s-renamed", test.getName()), EnumSet.of(Path.Type.file)); new S3MoveFeature(session).move(test, renamed, new TransferStatus(), new Delete.DisabledCallback(), new DisabledConnectionCallback()); assertTrue(new S3FindFeature(session).find(test)); assertTrue(new S3FindFeature(session).find(renamed)); for(Path path : new S3ListService(session).list(container, new DisabledListProgressListener())) { if(new SimplePathPredicate(test).test(path)) { assertTrue(path.attributes().isDuplicate()); assertTrue(new S3AttributesFinderFeature(session, true).find(path).isDuplicate()); assertTrue(new S3AttributesFinderFeature(session, false).find(path).isDuplicate()); break; } } final Map<String, String> metadata = new S3MetadataFeature(session, new S3AccessControlListFeature(session)).getMetadata(renamed); assertFalse(metadata.isEmpty()); assertEquals("text/plain", metadata.get("Content-Type")); new S3DefaultDeleteFeature(session).delete(Collections.singletonList(renamed), new DisabledLoginCallback(), new Delete.DisabledCallback()); }
@Override public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { Path copy; if(source.attributes().getCustom().containsKey(KEY_DELETE_MARKER)) { copy = new Path(renamed); copy.attributes().setVersionId(null); delete.delete(Collections.singletonMap(copy, status), connectionCallback, callback); try { final VersionOrDeleteMarkersChunk marker = session.getClient().listVersionedObjectsChunked(containerService.getContainer(renamed).getName(), containerService.getKey(renamed), String.valueOf(Path.DELIMITER), 1, null, null, false); if(marker.getItems().length == 1) { final BaseVersionOrDeleteMarker markerObject = marker.getItems()[0]; copy.attributes().withVersionId(markerObject.getVersionId()).setCustom(Collections.singletonMap(KEY_DELETE_MARKER, Boolean.TRUE.toString())); delete.delete(Collections.singletonMap(source, status), connectionCallback, callback); } else { throw new NotfoundException(String.format("Unable to find delete marker %s", renamed.getName())); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Failure to read attributes of {0}", e, renamed); } } else { try { copy = new S3ThresholdCopyFeature(session, accessControlListFeature).copy(source, renamed, status.length(source.attributes().getSize()), connectionCallback); delete.delete(Collections.singletonMap(new Path(source).withAttributes(new PathAttributes(source.attributes()).withVersionId(null)), status), connectionCallback, callback); } catch(NotfoundException e) { if(source.getType().contains(Path.Type.placeholder)) { copy = session.getFeature(Directory.class).mkdir(renamed, source.attributes().getRegion(), new TransferStatus()); } else { throw e; } } } return copy; }
S3MoveFeature implements Move { @Override public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { Path copy; if(source.attributes().getCustom().containsKey(KEY_DELETE_MARKER)) { copy = new Path(renamed); copy.attributes().setVersionId(null); delete.delete(Collections.singletonMap(copy, status), connectionCallback, callback); try { final VersionOrDeleteMarkersChunk marker = session.getClient().listVersionedObjectsChunked(containerService.getContainer(renamed).getName(), containerService.getKey(renamed), String.valueOf(Path.DELIMITER), 1, null, null, false); if(marker.getItems().length == 1) { final BaseVersionOrDeleteMarker markerObject = marker.getItems()[0]; copy.attributes().withVersionId(markerObject.getVersionId()).setCustom(Collections.singletonMap(KEY_DELETE_MARKER, Boolean.TRUE.toString())); delete.delete(Collections.singletonMap(source, status), connectionCallback, callback); } else { throw new NotfoundException(String.format("Unable to find delete marker %s", renamed.getName())); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Failure to read attributes of {0}", e, renamed); } } else { try { copy = new S3ThresholdCopyFeature(session, accessControlListFeature).copy(source, renamed, status.length(source.attributes().getSize()), connectionCallback); delete.delete(Collections.singletonMap(new Path(source).withAttributes(new PathAttributes(source.attributes()).withVersionId(null)), status), connectionCallback, callback); } catch(NotfoundException e) { if(source.getType().contains(Path.Type.placeholder)) { copy = session.getFeature(Directory.class).mkdir(renamed, source.attributes().getRegion(), new TransferStatus()); } else { throw e; } } } return copy; } }
S3MoveFeature implements Move { @Override public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { Path copy; if(source.attributes().getCustom().containsKey(KEY_DELETE_MARKER)) { copy = new Path(renamed); copy.attributes().setVersionId(null); delete.delete(Collections.singletonMap(copy, status), connectionCallback, callback); try { final VersionOrDeleteMarkersChunk marker = session.getClient().listVersionedObjectsChunked(containerService.getContainer(renamed).getName(), containerService.getKey(renamed), String.valueOf(Path.DELIMITER), 1, null, null, false); if(marker.getItems().length == 1) { final BaseVersionOrDeleteMarker markerObject = marker.getItems()[0]; copy.attributes().withVersionId(markerObject.getVersionId()).setCustom(Collections.singletonMap(KEY_DELETE_MARKER, Boolean.TRUE.toString())); delete.delete(Collections.singletonMap(source, status), connectionCallback, callback); } else { throw new NotfoundException(String.format("Unable to find delete marker %s", renamed.getName())); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Failure to read attributes of {0}", e, renamed); } } else { try { copy = new S3ThresholdCopyFeature(session, accessControlListFeature).copy(source, renamed, status.length(source.attributes().getSize()), connectionCallback); delete.delete(Collections.singletonMap(new Path(source).withAttributes(new PathAttributes(source.attributes()).withVersionId(null)), status), connectionCallback, callback); } catch(NotfoundException e) { if(source.getType().contains(Path.Type.placeholder)) { copy = session.getFeature(Directory.class).mkdir(renamed, source.attributes().getRegion(), new TransferStatus()); } else { throw e; } } } return copy; } S3MoveFeature(final S3Session session);  S3MoveFeature(final S3Session session, final S3AccessControlListFeature accessControlListFeature); }
S3MoveFeature implements Move { @Override public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { Path copy; if(source.attributes().getCustom().containsKey(KEY_DELETE_MARKER)) { copy = new Path(renamed); copy.attributes().setVersionId(null); delete.delete(Collections.singletonMap(copy, status), connectionCallback, callback); try { final VersionOrDeleteMarkersChunk marker = session.getClient().listVersionedObjectsChunked(containerService.getContainer(renamed).getName(), containerService.getKey(renamed), String.valueOf(Path.DELIMITER), 1, null, null, false); if(marker.getItems().length == 1) { final BaseVersionOrDeleteMarker markerObject = marker.getItems()[0]; copy.attributes().withVersionId(markerObject.getVersionId()).setCustom(Collections.singletonMap(KEY_DELETE_MARKER, Boolean.TRUE.toString())); delete.delete(Collections.singletonMap(source, status), connectionCallback, callback); } else { throw new NotfoundException(String.format("Unable to find delete marker %s", renamed.getName())); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Failure to read attributes of {0}", e, renamed); } } else { try { copy = new S3ThresholdCopyFeature(session, accessControlListFeature).copy(source, renamed, status.length(source.attributes().getSize()), connectionCallback); delete.delete(Collections.singletonMap(new Path(source).withAttributes(new PathAttributes(source.attributes()).withVersionId(null)), status), connectionCallback, callback); } catch(NotfoundException e) { if(source.getType().contains(Path.Type.placeholder)) { copy = session.getFeature(Directory.class).mkdir(renamed, source.attributes().getRegion(), new TransferStatus()); } else { throw e; } } } return copy; } S3MoveFeature(final S3Session session);  S3MoveFeature(final S3Session session, final S3AccessControlListFeature accessControlListFeature); @Override Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback); @Override boolean isSupported(final Path source, final Path target); }
S3MoveFeature implements Move { @Override public Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { Path copy; if(source.attributes().getCustom().containsKey(KEY_DELETE_MARKER)) { copy = new Path(renamed); copy.attributes().setVersionId(null); delete.delete(Collections.singletonMap(copy, status), connectionCallback, callback); try { final VersionOrDeleteMarkersChunk marker = session.getClient().listVersionedObjectsChunked(containerService.getContainer(renamed).getName(), containerService.getKey(renamed), String.valueOf(Path.DELIMITER), 1, null, null, false); if(marker.getItems().length == 1) { final BaseVersionOrDeleteMarker markerObject = marker.getItems()[0]; copy.attributes().withVersionId(markerObject.getVersionId()).setCustom(Collections.singletonMap(KEY_DELETE_MARKER, Boolean.TRUE.toString())); delete.delete(Collections.singletonMap(source, status), connectionCallback, callback); } else { throw new NotfoundException(String.format("Unable to find delete marker %s", renamed.getName())); } } catch(ServiceException e) { throw new S3ExceptionMappingService().map("Failure to read attributes of {0}", e, renamed); } } else { try { copy = new S3ThresholdCopyFeature(session, accessControlListFeature).copy(source, renamed, status.length(source.attributes().getSize()), connectionCallback); delete.delete(Collections.singletonMap(new Path(source).withAttributes(new PathAttributes(source.attributes()).withVersionId(null)), status), connectionCallback, callback); } catch(NotfoundException e) { if(source.getType().contains(Path.Type.placeholder)) { copy = session.getFeature(Directory.class).mkdir(renamed, source.attributes().getRegion(), new TransferStatus()); } else { throw e; } } } return copy; } S3MoveFeature(final S3Session session);  S3MoveFeature(final S3Session session, final S3AccessControlListFeature accessControlListFeature); @Override Path move(final Path source, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback); @Override boolean isSupported(final Path source, final Path target);  }