220
241
public void check() throws EucalyptusCloudException {
221
File bukkitDir = new File(WalrusInfo.getWalrusInfo().getStorageDir());
222
if (!bukkitDir.exists()) {
223
if (!bukkitDir.mkdirs()) {
242
String bukkitDir = WalrusInfo.getWalrusInfo().getStorageDir();
243
File bukkits = new File(WalrusInfo.getWalrusInfo().getStorageDir());
244
if (!bukkits.exists()) {
245
if (!bukkits.mkdirs()) {
224
246
LOG.fatal("Unable to make bucket root directory: "
225
+ WalrusInfo.getWalrusInfo().getStorageDir());
226
248
throw new EucalyptusCloudException(
227
"Invalid bucket root directory");
249
"Invalid bucket root directory");
229
} else if (!bukkitDir.canWrite()) {
251
} else if (!bukkits.canWrite()) {
230
252
LOG.fatal("Cannot write to bucket root directory: "
231
+ WalrusInfo.getWalrusInfo().getStorageDir());
232
254
throw new EucalyptusCloudException("Invalid bucket root directory");
234
EntityWrapper<BucketInfo> db = WalrusControl.getEntityWrapper();
235
BucketInfo bucketInfo = new BucketInfo();
236
List<BucketInfo> bucketInfos = db.query(bucketInfo);
237
for (BucketInfo bucket : bucketInfos) {
238
if (!storageManager.bucketExists(bucket.getBucketName()))
239
bucket.setHidden(true);
241
bucket.setHidden(false);
257
SystemUtil.setEucaReadWriteOnly(bukkitDir);
258
} catch (EucalyptusCloudException ex) {
246
263
public ListAllMyBucketsResponseType listAllMyBuckets(
247
264
ListAllMyBucketsType request) throws EucalyptusCloudException {
248
265
ListAllMyBucketsResponseType reply = (ListAllMyBucketsResponseType) request
250
String userId = request.getUserId();
252
if (userId == null) {
253
throw new AccessDeniedException("no such user");
256
EntityWrapper<BucketInfo> db = WalrusControl.getEntityWrapper();
257
BucketInfo searchBucket = new BucketInfo();
258
searchBucket.setOwnerId(userId);
259
searchBucket.setHidden(false);
260
List<BucketInfo> bucketInfoList = db.query(searchBucket);
262
ArrayList<BucketListEntry> buckets = new ArrayList<BucketListEntry>();
264
for (BucketInfo bucketInfo : bucketInfoList) {
265
if (request.isAdministrator()) {
266
EntityWrapper<WalrusSnapshotInfo> dbSnap = db
267
.recast(WalrusSnapshotInfo.class);
268
WalrusSnapshotInfo walrusSnapInfo = new WalrusSnapshotInfo();
269
walrusSnapInfo.setSnapshotBucket(bucketInfo.getBucketName());
270
List<WalrusSnapshotInfo> walrusSnaps = dbSnap
271
.query(walrusSnapInfo);
272
if (walrusSnaps.size() > 0)
275
buckets.add(new BucketListEntry(bucketInfo.getBucketName(),
276
DateUtils.format(bucketInfo.getCreationDate().getTime(),
277
DateUtils.ISO8601_DATETIME_PATTERN)
267
Context ctx = Contexts.lookup();
268
Account account = ctx.getAccount();
270
if (account == null) {
271
throw new AccessDeniedException("no such account");
273
EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);
281
CanonicalUserType owner = new CanonicalUserType(Users
282
.lookupUser(userId).getQueryId(), userId);
283
ListAllMyBucketsList bucketList = new ListAllMyBucketsList();
284
reply.setOwner(owner);
285
bucketList.setBuckets(buckets);
286
reply.setBucketList(bucketList);
287
} catch (Exception ex) {
290
throw new AccessDeniedException("User: " + userId + " not found");
275
BucketInfo searchBucket = new BucketInfo();
276
searchBucket.setOwnerId(account.getAccountNumber());
277
searchBucket.setHidden(false);
278
List<BucketInfo> bucketInfoList = db.query(searchBucket);
280
ArrayList<BucketListEntry> buckets = new ArrayList<BucketListEntry>();
282
for (BucketInfo bucketInfo : bucketInfoList) {
283
if (ctx.hasAdministrativePrivileges() ||
284
Lookups.checkPrivilege(PolicySpec.S3_LISTALLMYBUCKETS,
285
PolicySpec.VENDOR_S3,
286
PolicySpec.S3_RESOURCE_BUCKET,
287
bucketInfo.getBucketName(),
288
bucketInfo.getOwnerId())) {
289
EntityWrapper<WalrusSnapshotInfo> dbSnap = EntityWrapper.get(WalrusSnapshotInfo.class);
291
WalrusSnapshotInfo walrusSnapInfo = new WalrusSnapshotInfo();
292
walrusSnapInfo.setSnapshotBucket(bucketInfo.getBucketName());
293
List<WalrusSnapshotInfo> walrusSnaps = dbSnap
294
.query(walrusSnapInfo);
296
if (walrusSnaps.size() > 0)
298
} catch (Exception eee) {
303
buckets.add(new BucketListEntry(bucketInfo.getBucketName(),
304
DateUtils.format(bucketInfo.getCreationDate().getTime(),
305
DateUtils.ISO8601_DATETIME_PATTERN)
309
CanonicalUserType owner = new CanonicalUserType(account.getName(), account.getAccountNumber());
310
ListAllMyBucketsList bucketList = new ListAllMyBucketsList();
311
reply.setOwner(owner);
312
bucketList.setBuckets(buckets);
313
reply.setBucketList(bucketList);
314
} catch (Exception ex) {
317
throw new AccessDeniedException("Account: " + account.getName() + " not found", ex);
320
} catch (EucalyptusCloudException e) {
323
} catch (Exception e) {
296
330
public CreateBucketResponseType createBucket(CreateBucketType request)
297
throws EucalyptusCloudException {
331
throws EucalyptusCloudException {
298
332
CreateBucketResponseType reply = (CreateBucketResponseType) request
300
String userId = request.getUserId();
334
Context ctx = Contexts.lookup();
335
Account account = ctx.getAccount();
302
337
String bucketName = request.getBucket();
303
338
String locationConstraint = request.getLocationConstraint();
305
if (userId == null) {
340
if (account == null) {
306
341
throw new AccessDeniedException("Bucket", bucketName);
309
344
AccessControlListType accessControlList = request
310
.getAccessControlList();
345
.getAccessControlList();
311
346
if (accessControlList == null) {
312
347
accessControlList = new AccessControlListType();
342
377
throw new BucketAlreadyExistsException(bucketName);
344
// create bucket and set its acl
345
BucketInfo bucket = new BucketInfo(userId, bucketName, new Date());
346
ArrayList<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
347
bucket.addGrants(userId, grantInfos, accessControlList);
348
bucket.setGrants(grantInfos);
349
bucket.setBucketSize(0L);
350
bucket.setLoggingEnabled(false);
351
bucket.setVersioning(WalrusProperties.VersioningStatus.Disabled
353
bucket.setHidden(false);
354
if (locationConstraint != null)
355
bucket.setLocation(locationConstraint);
357
bucket.setLocation("US");
359
// call the storage manager to save the bucket to disk
361
storageManager.createBucket(bucketName);
362
if (WalrusProperties.trackUsageStatistics)
363
walrusStatistics.incrementBucketCount();
364
} catch (IOException ex) {
379
if (ctx.hasAdministrativePrivileges() || (
380
Permissions.isAuthorized(PolicySpec.VENDOR_S3,
381
PolicySpec.S3_RESOURCE_BUCKET,
384
PolicySpec.S3_CREATEBUCKET,
386
Permissions.canAllocate(PolicySpec.VENDOR_S3,
387
PolicySpec.S3_RESOURCE_BUCKET,
389
PolicySpec.S3_CREATEBUCKET,
392
// create bucket and set its acl
393
BucketInfo bucket = new BucketInfo(account.getAccountNumber(), ctx.getUser( ).getUserId( ), bucketName, new Date());
394
ArrayList<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
395
bucket.addGrants(account.getAccountNumber(), grantInfos, accessControlList);
396
bucket.setGrants(grantInfos);
397
bucket.setBucketSize(0L);
398
bucket.setLoggingEnabled(false);
399
bucket.setVersioning(WalrusProperties.VersioningStatus.Disabled
401
bucket.setHidden(false);
402
if (locationConstraint != null)
403
bucket.setLocation(locationConstraint);
405
bucket.setLocation("US");
406
// call the storage manager to save the bucket to disk
410
storageManager.createBucket(bucketName);
411
if (WalrusProperties.trackUsageStatistics)
412
walrusStatistics.incrementBucketCount();
413
} catch (IOException ex) {
415
throw new BucketAlreadyExistsException(bucketName);
416
} catch (Exception ex) {
419
if (Exceptions.isCausedBy(ex, ConstraintViolationException.class)) {
420
throw new BucketAlreadyExistsException(bucketName);
422
throw new EucalyptusCloudException("Unable to create bucket: " + bucketName);
425
QueueSender queueSender = QueueFactory.getInstance().getSender(QueueIdentifier.S3);
426
queueSender.send(new S3Event(true, ctx.getUser().getUserId(),
427
ctx.getUser().getName(), ctx.getAccount().getAccountNumber(),
428
ctx.getAccount().getName()));
431
LOG.error( "Not authorized to create bucket by " + ctx.getUserFullName( ) );
367
throw new EucalyptusCloudException("Unable to create bucket: "
373
if(WalrusProperties.enableVirtualHosting) {
374
if(checkDNSNaming(bucketName)) {
375
UpdateARecordType updateARecord = new UpdateARecordType();
376
updateARecord.setUserId(userId);
378
String address = null;
380
walrusUri = new URI(SystemConfiguration.getWalrusUrl());
381
address = walrusUri.getHost();
382
} catch (URISyntaxException e) {
383
throw new EucalyptusCloudException("Could not get Walrus URL");
385
String zone = WalrusProperties.WALRUS_SUBDOMAIN + ".";
386
updateARecord.setAddress(address);
387
updateARecord.setName(bucketName + "." + zone);
388
updateARecord.setTtl(604800);
389
updateARecord.setZone(zone);
391
ServiceDispatcher.lookupSingle(Component.dns).send(updateARecord);
392
LOG.info("Mapping " + updateARecord.getName() + " to " + address);
393
} catch(Exception ex) {
394
LOG.error("Could not update DNS record", ex);
397
LOG.error("Bucket: " + bucketName + " fails to meet DNS requirements. Unable to create DNS mapping.");
433
throw new AccessDeniedException("Bucket", bucketName);
401
436
reply.setBucket(bucketName);
405
440
private boolean checkBucketName(String bucketName) {
406
if(!(bucketName.matches("^[A-Za-z0-9].*") || bucketName.contains(".") ||
407
bucketName.contains("-")))
441
if(!bucketName.matches("^[A-Za-z0-9][A-Za-z0-9._-]+"))
409
443
if(bucketName.length() < 3 || bucketName.length() > 255)
688
716
String randomKey = request.getRandomKey();
689
717
WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();
691
EntityWrapper<BucketInfo> db = WalrusControl.getEntityWrapper();
719
EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);
692
720
BucketInfo bucketInfo = new BucketInfo(bucketName);
693
721
List<BucketInfo> bucketList = db.query(bucketInfo);
695
723
if (bucketList.size() > 0) {
696
724
BucketInfo bucket = bucketList.get(0);
697
BucketLogData logData = bucket.getLoggingEnabled() ? request
698
.getLogData() : null;
699
if (bucket.canWrite(userId)) {
701
reply.setLogData(logData);
704
ObjectInfo objectInfo = null;
705
if (bucket.isVersioningEnabled()) {
706
objectInfo = new ObjectInfo(bucketName, objectKey);
707
objectInfo.setOwnerId(userId);
708
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
709
objectInfo.addGrants(userId, grantInfos, accessControlList);
710
objectInfo.setGrants(grantInfos);
711
objectName = UUID.randomUUID().toString();
712
objectInfo.setObjectName(objectName);
713
objectInfo.setSize(0L);
714
versionId = UUID.randomUUID().toString().replaceAll("-", "");
716
versionId = WalrusProperties.NULL_VERSION_ID;
725
BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
728
objSize = Long.valueOf( request.getContentLength( ) );
729
} catch ( NumberFormatException e ) {
730
LOG.error( "Invalid content length " + request.getContentLength( ) );
731
// TODO(wenye): should handle this properly.
734
if (ctx.hasAdministrativePrivileges() || (
735
bucket.canWrite(account.getAccountNumber()) &&
736
(bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
737
PolicySpec.VENDOR_S3,
738
PolicySpec.S3_RESOURCE_BUCKET,
742
reply.setLogData(logData);
745
ObjectInfo objectInfo = null;
746
if (bucket.isVersioningEnabled()) {
747
objectInfo = new ObjectInfo(bucketName, objectKey);
748
objectInfo.setOwnerId(account.getAccountNumber());
749
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
750
objectInfo.addGrants(account.getAccountNumber(), grantInfos, accessControlList);
751
objectInfo.setGrants(grantInfos);
752
objectName = UUID.randomUUID().toString();
753
objectInfo.setObjectName(objectName);
754
objectInfo.setSize(0L);
755
versionId = UUID.randomUUID().toString().replaceAll("-", "");
757
versionId = WalrusProperties.NULL_VERSION_ID;
758
ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
759
searchObject.setVersionId(versionId);
760
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
762
ObjectInfo foundObject = dbObject.getUnique(searchObject);
763
if (!foundObject.canWrite(account.getAccountNumber())) {
765
messenger.removeQueue(key, randomKey);
766
throw new AccessDeniedException("Key", objectKey,
769
objectName = foundObject.getObjectName();
770
} catch(AccessDeniedException ex) {
772
} catch(EucalyptusCloudException ex) {
773
objectInfo = new ObjectInfo(bucketName, objectKey);
774
objectInfo.setOwnerId(account.getAccountNumber());
775
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
776
objectInfo.addGrants(account.getAccountNumber(), grantInfos, accessControlList);
777
objectInfo.setGrants(grantInfos);
778
objectName = UUID.randomUUID().toString();
779
objectInfo.setObjectName(objectName);
780
objectInfo.setSize(0L);
783
if (bucket.isVersioningEnabled()) {
784
reply.setVersionId(versionId);
787
// writes are unconditional
788
WalrusDataQueue<WalrusDataMessage> putQueue = messenger
789
.getQueue(key, randomKey);
792
WalrusDataMessage dataMessage;
793
String tempObjectName = objectName;
794
MessageDigest digest = null;
796
FileIO fileIO = null;
797
while ((dataMessage = putQueue.take()) != null) {
798
if(putQueue.getInterrupted()) {
799
if(WalrusDataMessage.isEOF(dataMessage)) {
800
WalrusMonitor monitor = messenger.getMonitor(key);
801
if(monitor.getLastModified() == null) {
802
LOG.trace("Monitor wait: " + key + " random: " + randomKey);
803
synchronized (monitor) {
807
LOG.trace("Monitor resume: " + key + " random: " + randomKey);
808
lastModified = monitor.getLastModified();
809
md5 = monitor.getMd5();
810
//ok we are done here
813
ObjectDeleter objectDeleter = new ObjectDeleter(bucketName,
816
ctx.getUser().getName(),
817
ctx.getUser().getUserId(),
818
ctx.getAccount().getName(),
819
ctx.getAccount().getAccountNumber());
820
Threads.lookup(Walrus.class, WalrusManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
821
LOG.info("Transfer interrupted: "+ key);
822
messenger.removeQueue(key, randomKey);
827
if (WalrusDataMessage.isStart(dataMessage)) {
828
tempObjectName = UUID.randomUUID().toString();
829
digest = Digest.MD5.get();
831
fileIO = storageManager.prepareForWrite(
832
bucketName, tempObjectName);
833
} catch (Exception ex) {
834
messenger.removeQueue(key, randomKey);
835
throw new EucalyptusCloudException(ex);
837
} else if (WalrusDataMessage.isEOF(dataMessage)) {
838
if (digest != null) {
839
md5 = Hashes.bytesToHex(digest.digest());
841
WalrusMonitor monitor = messenger.getMonitor(key);
842
md5 = monitor.getMd5();
843
lastModified = monitor.getLastModified();
845
LOG.error("ETag did not match for: " + randomKey + " Computed MD5 is null");
846
throw new ContentMismatchException(bucketName + "/" + objectKey);
850
String contentMD5 = request.getContentMD5();
851
if (contentMD5 != null) {
852
String contentMD5AsHex = Hashes.bytesToHex(Base64.decode(contentMD5));
853
if(!contentMD5AsHex.equals(md5)) {
856
ObjectDeleter objectDeleter = new ObjectDeleter(bucketName,
859
ctx.getUser().getName(),
860
ctx.getUser().getUserId(),
861
ctx.getAccount().getName(),
862
ctx.getAccount().getAccountNumber());
863
Threads.lookup(Walrus.class, WalrusManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
864
messenger.removeQueue(key, randomKey);
865
LOG.error("ETag did not match for: " + randomKey + " Expected: " + contentMD5AsHex + " Computed: " + md5);
866
throw new ContentMismatchException(bucketName + "/" + objectKey);
873
storageManager.renameObject(bucketName,
874
tempObjectName, objectName);
875
} catch (IOException ex) {
877
messenger.removeQueue(key, randomKey);
878
throw new EucalyptusCloudException(objectKey);
880
lastModified = new Date();
717
881
ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
718
searchObject.setVersionId(versionId);
719
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
882
searchObject.setVersionId(versionId);
883
EntityWrapper<ObjectInfo> dbObject = EntityWrapper.get(ObjectInfo.class);
884
ObjectInfo foundObject;
721
ObjectInfo foundObject = dbObject.getUnique(searchObject);
722
if (!foundObject.canWrite(userId)) {
724
messenger.removeQueue(key, randomKey);
725
throw new AccessDeniedException("Key", objectKey,
728
objectName = foundObject.getObjectName();
729
} catch(AccessDeniedException ex) {
731
} catch(EucalyptusCloudException ex) {
732
objectInfo = new ObjectInfo(bucketName, objectKey);
733
objectInfo.setOwnerId(userId);
734
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
735
objectInfo.addGrants(userId, grantInfos, accessControlList);
736
objectInfo.setGrants(grantInfos);
737
objectName = UUID.randomUUID().toString();
738
objectInfo.setObjectName(objectName);
739
objectInfo.setSize(0L);
744
// writes are unconditional
745
WalrusDataQueue<WalrusDataMessage> putQueue = messenger
746
.getQueue(key, randomKey);
749
WalrusDataMessage dataMessage;
750
String tempObjectName = objectName;
751
MessageDigest digest = null;
753
FileIO fileIO = null;
754
while ((dataMessage = putQueue.take()) != null) {
755
if(putQueue.getInterrupted()) {
756
if(WalrusDataMessage.isEOF(dataMessage)) {
757
WalrusMonitor monitor = messenger.getMonitor(key);
758
if(monitor.getLastModified() == null) {
759
synchronized (monitor) {
763
lastModified = monitor.getLastModified();
764
md5 = monitor.getMd5();
765
//ok we are done here
768
ObjectDeleter objectDeleter = new ObjectDeleter(bucketName, tempObjectName, -1L);
769
objectDeleter.start();
770
LOG.info("Transfer interrupted: "+ key);
771
messenger.removeQueue(key, randomKey);
886
foundObject = dbObject.getUnique(searchObject);
887
if (ctx.hasAdministrativePrivileges() || foundObject.canWriteACP(account.getAccountNumber())) {
888
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
889
foundObject.addGrants(account.getAccountNumber(), grantInfos,
891
foundObject.setGrants(grantInfos);
776
if (WalrusDataMessage.isStart(dataMessage)) {
777
tempObjectName = UUID.randomUUID().toString();
778
digest = Digest.MD5.get();
780
fileIO = storageManager.prepareForWrite(
781
bucketName, tempObjectName);
782
} catch (Exception ex) {
783
messenger.removeQueue(key, randomKey);
784
throw new EucalyptusCloudException(ex);
786
} else if (WalrusDataMessage.isEOF(dataMessage)) {
791
storageManager.renameObject(bucketName,
792
tempObjectName, objectName);
793
} catch (IOException ex) {
795
messenger.removeQueue(key, randomKey);
796
throw new EucalyptusCloudException(objectKey);
799
md5 = Hashes.bytesToHex(digest.digest());
800
lastModified = new Date();
801
ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
802
searchObject.setVersionId(versionId);
803
EntityWrapper<ObjectInfo> dbObject = WalrusControl.getEntityWrapper();
804
List<ObjectInfo> objectInfos = dbObject.query(new ObjectInfo(bucketName, objectKey));
805
for(ObjectInfo objInfo : objectInfos) {
806
objInfo.setLast(false);
808
ObjectInfo foundObject;
810
foundObject = dbObject.getUnique(searchObject);
811
if (foundObject.canWriteACP(userId)) {
812
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
813
foundObject.addGrants(userId, grantInfos,
815
foundObject.setGrants(grantInfos);
817
if (WalrusProperties.enableTorrents) {
818
EntityWrapper<TorrentInfo> dbTorrent = dbObject
893
if (WalrusProperties.enableTorrents) {
894
EntityWrapper<TorrentInfo> dbTorrent = dbObject
819
895
.recast(TorrentInfo.class);
820
TorrentInfo torrentInfo = new TorrentInfo(bucketName,
822
List<TorrentInfo> torrentInfos = dbTorrent
896
TorrentInfo torrentInfo = new TorrentInfo(bucketName,
898
List<TorrentInfo> torrentInfos = dbTorrent
823
899
.query(torrentInfo);
824
if (torrentInfos.size() > 0) {
825
TorrentInfo foundTorrentInfo = torrentInfos.get(0);
826
TorrentClient torrentClient = Torrents
900
if (torrentInfos.size() > 0) {
901
TorrentInfo foundTorrentInfo = torrentInfos.get(0);
902
TorrentClient torrentClient = Torrents
827
903
.getClient(bucketName + objectKey);
828
if (torrentClient != null) {
831
dbTorrent.delete(foundTorrentInfo);
835
.warn("Bittorrent support has been disabled. Please check pre-requisites");
837
} catch (EucalyptusCloudException ex) {
838
if(objectInfo != null) {
839
foundObject = objectInfo;
842
throw new EucalyptusCloudException("Unable to update object: " + bucketName + "/" + objectKey);
845
foundObject.setVersionId(versionId);
846
foundObject.replaceMetaData(request.getMetaData());
847
foundObject.setEtag(md5);
848
foundObject.setSize(size);
849
foundObject.setLastModified(lastModified);
850
foundObject.setStorageClass("STANDARD");
851
foundObject.setContentType(request
853
foundObject.setContentDisposition(request
854
.getContentDisposition());
855
foundObject.setLast(true);
856
foundObject.setDeleted(false);
858
ObjectInfo deleteMarker = new ObjectInfo(bucketName, objectKey);
859
deleteMarker.setDeleted(true);
861
ObjectInfo foundDeleteMarker = dbObject.getUnique(deleteMarker);
862
dbObject.delete(foundDeleteMarker);
863
} catch(EucalyptusCloudException ex) {
864
//no delete marker found.
865
LOG.trace("No delete marker found for: " + bucketName + "/" + objectKey);
867
if (bucket.isVersioningEnabled()) {
868
reply.setVersionId(versionId);
870
EntityWrapper<BucketInfo> dbBucket = dbObject.recast(BucketInfo.class);
872
bucket = dbBucket.getUnique(new BucketInfo(bucketName));
873
} catch(EucalyptusCloudException e) {
876
throw new NoSuchBucketException(bucketName);
878
Long bucketSize = bucket.getBucketSize();
879
long newSize = bucketSize + oldBucketSize
881
if (WalrusProperties.shouldEnforceUsageLimits
882
&& !request.isAdministrator()) {
883
if (newSize > (WalrusInfo.getWalrusInfo().getStorageMaxBucketSizeInMB() * WalrusProperties.M)) {
884
messenger.removeQueue(key, randomKey);
886
throw new EntityTooLargeException(
890
bucket.setBucketSize(newSize);
891
if (WalrusProperties.trackUsageStatistics) {
892
walrusStatistics.updateBytesIn(size);
893
walrusStatistics.updateSpaceUsed(size);
895
if (logData != null) {
896
logData.setObjectSize(size);
897
updateLogData(bucket, logData);
899
if(objectInfo != null)
900
dbObject.add(foundObject);
902
if (logData != null) {
903
logData.setTurnAroundTime(Long
904
.parseLong(new String(dataMessage
907
// restart all interrupted puts
908
WalrusMonitor monitor = messenger.getMonitor(key);
909
synchronized (monitor) {
910
monitor.setLastModified(lastModified);
914
messenger.removeMonitor(key);
904
if (torrentClient != null) {
907
dbTorrent.delete(foundTorrentInfo);
911
.warn("Bittorrent support has been disabled. Please check pre-requisites");
913
} catch (EucalyptusCloudException ex) {
914
if(objectInfo != null) {
915
foundObject = objectInfo;
918
throw new EucalyptusCloudException("Unable to update object: " + bucketName + "/" + objectKey);
921
foundObject.setVersionId(versionId);
922
foundObject.replaceMetaData(request.getMetaData());
923
foundObject.setEtag(md5);
924
foundObject.setSize(size);
925
foundObject.setLastModified(lastModified);
926
foundObject.setStorageClass("STANDARD");
927
foundObject.setContentType(request
929
foundObject.setContentDisposition(request
930
.getContentDisposition());
931
foundObject.setLast(true);
932
foundObject.setDeleted(false);
934
if (!ctx.hasAdministrativePrivileges() &&
935
!Permissions.canAllocate(PolicySpec.VENDOR_S3,
936
PolicySpec.S3_RESOURCE_OBJECT,
938
PolicySpec.S3_PUTOBJECT,
940
oldBucketSize + size)) {
942
LOG.error("Quota exceeded for Walrus putObject");
943
throw new EntityTooLargeException("Key", objectKey);
945
boolean success = false;
949
incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
951
} catch (EntityTooLargeException ex) {
915
952
messenger.removeQueue(key, randomKey);
916
LOG.info("Transfer complete: " + key);
919
assert (WalrusDataMessage.isData(dataMessage));
920
byte[] data = dataMessage.getPayload();
921
// start writing object (but do not commit yet)
925
} catch (IOException ex) {
955
} catch (NoSuchBucketException ex) {
958
} catch (RollbackException ex) {
960
LOG.trace("retrying update: " + bucketName);
961
} catch (EucalyptusCloudException ex) {
965
} while(!success && (retryCount < 5));
966
if (WalrusProperties.trackUsageStatistics) {
967
walrusStatistics.updateBytesIn(size);
968
walrusStatistics.updateSpaceUsed(size);
970
if (logData != null) {
971
logData.setObjectSize(size);
972
updateLogData(bucket, logData);
974
if(objectInfo != null) {
975
dbObject.add(foundObject);
981
} catch (RollbackException ex) {
986
dbObject = EntityWrapper.get(ObjectInfo.class);
987
List<ObjectInfo> objectInfos = dbObject.query(new ObjectInfo(bucketName, objectKey));
988
for(ObjectInfo objInfo : objectInfos) {
990
if (objInfo.getLast()) {
991
lastModified = objInfo.getLastModified();
992
md5 = objInfo.getEtag();
928
// calculate md5 on the fly
934
} catch (InterruptedException ex) {
996
if (!versionId.equals(objInfo.getVersionId())) {
997
objInfo.setLast(false);
1002
dbObject = EntityWrapper.get(ObjectInfo.class);
1003
ObjectInfo deleteMarker = new ObjectInfo(bucketName, objectKey);
1004
deleteMarker.setDeleted(true);
1006
ObjectInfo foundDeleteMarker = dbObject.getUnique(deleteMarker);
1007
dbObject.delete(foundDeleteMarker);
1008
} catch(EucalyptusCloudException ex) {
1009
//no delete marker found.
1010
LOG.trace("No delete marker found for: " + bucketName + "/" + objectKey);
1014
if (logData != null) {
1015
logData.setTurnAroundTime(Long
1016
.parseLong(new String(dataMessage
1019
// restart all interrupted puts
1020
WalrusMonitor monitor = messenger.getMonitor(key);
1021
synchronized (monitor) {
1022
monitor.setLastModified(lastModified);
1023
monitor.setMd5(md5);
1024
monitor.notifyAll();
1026
//messenger.removeMonitor(key);
1027
messenger.clearQueues(key);
936
1028
messenger.removeQueue(key, randomKey);
937
throw new EucalyptusCloudException("Transfer interrupted: "
938
+ key + "." + randomKey);
1029
LOG.info("Transfer complete: " + key);
1030
QueueSender queueSender =
1031
QueueFactory.getInstance()
1032
.getSender(QueueIdentifier.S3);
1033
queueSender.send(new S3Event(true,
1034
size / WalrusProperties.M,
1035
ctx.getUser().getUserId(),
1036
ctx.getUser().getName(),
1037
ctx.getAccount().getAccountNumber(),
1038
ctx.getAccount().getName()));
1041
assert (WalrusDataMessage.isData(dataMessage));
1042
byte[] data = dataMessage.getPayload();
1043
// start writing object (but do not commit yet)
1047
} catch (IOException ex) {
1050
// calculate md5 on the fly
1051
size += data.length;
1053
digest.update(data);
942
messenger.removeQueue(key, randomKey);
943
throw new AccessDeniedException("Bucket", bucketName, logData);
1056
} catch (InterruptedException ex) {
1058
messenger.removeQueue(key, randomKey);
1059
throw new EucalyptusCloudException("Transfer interrupted: "
1060
+ key + "." + randomKey);
1064
messenger.removeQueue(key, randomKey);
1065
throw new AccessDeniedException("Bucket", bucketName, logData);
947
1069
messenger.removeQueue(key, randomKey);
1036
1190
Date lastModified;
1038
1192
AccessControlListType accessControlList = request
1039
.getAccessControlList();
1193
.getAccessControlList();
1040
1194
if (accessControlList == null) {
1041
1195
accessControlList = new AccessControlListType();
1044
EntityWrapper<BucketInfo> db = WalrusControl.getEntityWrapper();
1198
EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);
1045
1199
BucketInfo bucketInfo = new BucketInfo(bucketName);
1046
1200
List<BucketInfo> bucketList = db.query(bucketInfo);
1048
1202
if (bucketList.size() > 0) {
1049
1203
BucketInfo bucket = bucketList.get(0);
1050
BucketLogData logData = bucket.getLoggingEnabled() ? request
1051
.getLogData() : null;
1052
if (bucket.canWrite(userId)) {
1053
EntityWrapper<ObjectInfo> dbObject = db
1204
BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
1207
objSize = Long.valueOf( request.getContentLength( ) );
1208
} catch ( NumberFormatException e ) {
1209
LOG.error( "Invalid content length " + request.getContentLength( ) );
1210
// TODO(wenye): should handle this properly.
1213
if (ctx.hasAdministrativePrivileges() || (
1214
bucket.canWrite(account.getAccountNumber()) &&
1215
(bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
1216
PolicySpec.VENDOR_S3,
1217
PolicySpec.S3_RESOURCE_BUCKET,
1220
EntityWrapper<ObjectInfo> dbObject = db
1054
1221
.recast(ObjectInfo.class);
1055
ObjectInfo searchObjectInfo = new ObjectInfo();
1056
searchObjectInfo.setBucketName(bucketName);
1222
ObjectInfo searchObjectInfo = new ObjectInfo();
1223
searchObjectInfo.setBucketName(bucketName);
1058
ObjectInfo foundObject = null;
1059
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
1060
for (ObjectInfo objectInfo : objectInfos) {
1061
if (objectInfo.getObjectKey().equals(objectKey)) {
1062
// key (object) exists. check perms
1063
if (!objectInfo.canWrite(userId)) {
1065
throw new AccessDeniedException("Key", objectKey,
1068
foundObject = objectInfo;
1069
oldBucketSize = -foundObject.getSize();
1073
// write object to bucket
1075
if (foundObject == null) {
1076
// not found. create an object info
1077
foundObject = new ObjectInfo(bucketName, objectKey);
1078
foundObject.setOwnerId(userId);
1079
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
1081
.addGrants(userId, grantInfos, accessControlList);
1082
foundObject.setGrants(grantInfos);
1083
objectName = UUID.randomUUID().toString();
1084
foundObject.setObjectName(objectName);
1085
dbObject.add(foundObject);
1087
// object already exists. see if we can modify acl
1088
if (foundObject.canWriteACP(userId)) {
1089
List<GrantInfo> grantInfos = foundObject.getGrants();
1090
foundObject.addGrants(userId, grantInfos,
1093
objectName = foundObject.getObjectName();
1095
foundObject.setObjectKey(objectKey);
1225
ObjectInfo foundObject = null;
1226
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
1227
for (ObjectInfo objectInfo : objectInfos) {
1228
if (objectInfo.getObjectKey().equals(objectKey)) {
1229
// key (object) exists. check perms
1230
if (!objectInfo.canWrite(account.getAccountNumber())) {
1232
throw new AccessDeniedException("Key", objectKey,
1235
foundObject = objectInfo;
1236
oldBucketSize = -foundObject.getSize();
1240
// write object to bucket
1242
if (foundObject == null) {
1243
// not found. create an object info
1244
foundObject = new ObjectInfo(bucketName, objectKey);
1245
foundObject.setOwnerId(account.getAccountNumber());
1246
List<GrantInfo> grantInfos = new ArrayList<GrantInfo>();
1248
.addGrants(account.getAccountNumber(), grantInfos, accessControlList);
1249
foundObject.setGrants(grantInfos);
1250
objectName = UUID.randomUUID().toString();
1251
foundObject.setObjectName(objectName);
1252
dbObject.add(foundObject);
1254
// object already exists. see if we can modify acl
1255
if (ctx.hasAdministrativePrivileges() || foundObject.canWriteACP(account.getAccountNumber())) {
1256
List<GrantInfo> grantInfos = foundObject.getGrants();
1257
foundObject.addGrants(account.getAccountNumber(), grantInfos,
1260
objectName = foundObject.getObjectName();
1262
foundObject.setObjectKey(objectKey);
1264
// writes are unconditional
1265
if (request.getBase64Data().getBytes().length > WalrusProperties.MAX_INLINE_DATA_SIZE) {
1267
throw new InlineDataTooLargeException(bucketName + "/"
1270
byte[] base64Data = Hashes.base64decode(
1271
request.getBase64Data()).getBytes();
1272
foundObject.setObjectName(objectName);
1274
FileIO fileIO = storageManager.prepareForWrite(
1275
bucketName, objectName);
1276
if (fileIO != null) {
1277
fileIO.write(base64Data);
1280
} catch (Exception ex) {
1282
throw new EucalyptusCloudException(ex);
1284
md5 = Hashes.getHexString(Digest.MD5.get().digest(
1286
foundObject.setEtag(md5);
1287
Long size = (long) base64Data.length;
1288
foundObject.setSize(size);
1289
if (!ctx.hasAdministrativePrivileges() &&
1290
!Permissions.canAllocate(PolicySpec.VENDOR_S3,
1291
PolicySpec.S3_RESOURCE_OBJECT,
1293
PolicySpec.S3_PUTOBJECT,
1295
oldBucketSize + size)) {
1297
LOG.error("Quota exceeded in Walrus putObject");
1298
throw new EntityTooLargeException("Key", objectKey, logData);
1300
boolean success = false;
1097
// writes are unconditional
1098
if (request.getBase64Data().getBytes().length > WalrusProperties.MAX_INLINE_DATA_SIZE) {
1100
throw new InlineDataTooLargeException(bucketName + "/"
1103
byte[] base64Data = Hashes.base64decode(
1104
request.getBase64Data()).getBytes();
1105
foundObject.setObjectName(objectName);
1107
FileIO fileIO = storageManager.prepareForWrite(
1108
bucketName, objectName);
1109
if (fileIO != null) {
1110
fileIO.write(base64Data);
1113
} catch (Exception ex) {
1115
throw new EucalyptusCloudException(ex);
1117
md5 = Hashes.getHexString(Digest.MD5.get().digest(
1119
foundObject.setEtag(md5);
1120
Long size = (long) base64Data.length;
1121
foundObject.setSize(size);
1122
if (WalrusProperties.shouldEnforceUsageLimits
1123
&& !request.isAdministrator()) {
1124
Long bucketSize = bucket.getBucketSize();
1125
long newSize = bucketSize + oldBucketSize + size;
1126
if (newSize > (WalrusInfo.getWalrusInfo().getStorageMaxBucketSizeInMB() * WalrusProperties.M)) {
1128
throw new EntityTooLargeException("Key", objectKey,
1131
bucket.setBucketSize(newSize);
1133
if (WalrusProperties.trackUsageStatistics) {
1134
walrusStatistics.updateBytesIn(size);
1135
walrusStatistics.updateSpaceUsed(size);
1137
// Add meta data if specified
1138
if (request.getMetaData() != null)
1139
foundObject.replaceMetaData(request.getMetaData());
1304
incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
1306
} catch (EntityTooLargeException ex) {
1309
} catch (NoSuchBucketException ex) {
1312
} catch (RollbackException ex) {
1314
LOG.trace("retrying update: " + bucketName);
1315
} catch (EucalyptusCloudException ex) {
1319
} while(!success && (retryCount < 5));
1320
if (WalrusProperties.trackUsageStatistics) {
1321
walrusStatistics.updateBytesIn(size);
1322
walrusStatistics.updateSpaceUsed(size);
1324
// Add meta data if specified
1325
if (request.getMetaData() != null)
1326
foundObject.replaceMetaData(request.getMetaData());
1141
// TODO: add support for other storage classes
1142
foundObject.setStorageClass("STANDARD");
1143
lastModified = new Date();
1144
foundObject.setLastModified(lastModified);
1145
if (logData != null) {
1146
updateLogData(bucket, logData);
1147
logData.setObjectSize(size);
1148
reply.setLogData(logData);
1150
} catch (Exception ex) {
1153
throw new EucalyptusCloudException(bucketName);
1157
throw new AccessDeniedException("Bucket", bucketName, logData);
1328
// TODO: add support for other storage classes
1329
foundObject.setStorageClass("STANDARD");
1330
lastModified = new Date();
1331
foundObject.setLastModified(lastModified);
1332
if (logData != null) {
1333
updateLogData(bucket, logData);
1334
logData.setObjectSize(size);
1335
reply.setLogData(logData);
1337
QueueSender queueSender =
1338
QueueFactory.getInstance()
1339
.getSender(QueueIdentifier.S3);
1340
queueSender.send(new S3Event(true,
1341
size / WalrusProperties.M,
1342
ctx.getUser().getUserId(),
1343
ctx.getUser().getName(),
1344
ctx.getAccount().getAccountNumber(),
1345
ctx.getAccount().getName()));
1346
} catch (Exception ex) {
1349
throw new EucalyptusCloudException(bucketName);
1353
throw new AccessDeniedException("Bucket", bucketName, logData);
1161
1357
throw new NoSuchBucketException(bucketName);
1236
1439
public DeleteObjectResponseType deleteObject(DeleteObjectType request)
1237
throws EucalyptusCloudException {
1238
DeleteObjectResponseType reply = (DeleteObjectResponseType) request
1440
throws EucalyptusCloudException {
1441
DeleteObjectResponseType reply = (DeleteObjectResponseType) request.getReply();
1240
1442
String bucketName = request.getBucket();
1241
1443
String objectKey = request.getKey();
1242
String userId = request.getUserId();
1444
Context ctx = Contexts.lookup();
1445
Account account = ctx.getAccount();
1244
EntityWrapper<BucketInfo> db = WalrusControl.getEntityWrapper();
1447
EntityWrapper<BucketInfo> db = EntityWrapper.get(BucketInfo.class);
1245
1448
BucketInfo bucketInfos = new BucketInfo(bucketName);
1246
1449
List<BucketInfo> bucketList = db.query(bucketInfos);
1248
1451
if (bucketList.size() > 0) {
1249
1452
BucketInfo bucketInfo = bucketList.get(0);
1250
BucketLogData logData = bucketInfo.getLoggingEnabled() ? request
1251
.getLogData() : null;
1253
if(bucketInfo.isVersioningEnabled()) {
1254
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
1255
ObjectInfo searchDeletedObjectInfo = new ObjectInfo(bucketName, objectKey);
1256
searchDeletedObjectInfo.setDeleted(true);
1258
dbObject.getUnique(searchDeletedObjectInfo);
1260
throw new NoSuchEntityException(objectKey, logData);
1261
} catch(NoSuchEntityException ex) {
1263
} catch(EucalyptusCloudException ex) {
1264
ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
1265
searchObjectInfo.setLast(true);
1266
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
1267
for(ObjectInfo objInfo : objectInfos) {
1268
objInfo.setLast(false);
1453
BucketLogData logData = bucketInfo.getLoggingEnabled() ? request.getLogData() : null;
1454
if (ctx.hasAdministrativePrivileges() || (
1455
bucketInfo.canWrite(account.getAccountNumber()) &&
1456
(bucketInfo.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_DELETEOBJECT,
1457
PolicySpec.VENDOR_S3,
1458
PolicySpec.S3_RESOURCE_BUCKET,
1459
bucketInfo.getBucketName(),
1461
if(bucketInfo.isVersioningEnabled()) {
1462
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
1463
ObjectInfo searchDeletedObjectInfo = new ObjectInfo(bucketName, objectKey);
1464
searchDeletedObjectInfo.setDeleted(true);
1466
dbObject.getUnique(searchDeletedObjectInfo);
1468
throw new NoSuchEntityException(objectKey, logData);
1469
} catch(NoSuchEntityException ex) {
1471
} catch(EucalyptusCloudException ex) {
1472
ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
1473
searchObjectInfo.setLast(true);
1474
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
1475
for(ObjectInfo objInfo : objectInfos) {
1476
objInfo.setLast(false);
1478
ObjectInfo deleteMarker = new ObjectInfo(bucketName, objectKey);
1479
deleteMarker.setDeleted(true);
1480
deleteMarker.setLast(true);
1481
deleteMarker.setOwnerId(account.getAccountNumber());
1482
deleteMarker.setLastModified(new Date());
1483
deleteMarker.setVersionId(UUID.randomUUID().toString().replaceAll("-", ""));
1484
dbObject.add(deleteMarker);
1485
reply.setCode("200");
1486
reply.setDescription("OK");
1489
//versioning disabled or suspended.
1490
ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
1491
searchObjectInfo.setVersionId(WalrusProperties.NULL_VERSION_ID);
1492
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
1493
List<ObjectInfo>objectInfos = dbObject.query(searchObjectInfo);
1494
if (objectInfos.size() > 0) {
1495
ObjectInfo nullObject = objectInfos.get(0);
1496
dbObject.delete(nullObject);
1497
String objectName = nullObject.getObjectName();
1498
for (GrantInfo grantInfo : nullObject.getGrants()) {
1499
db.delete(grantInfo);
1501
Long size = nullObject.getSize();
1502
boolean success = false;
1506
decrementBucketSize(bucketName, size);
1508
} catch (NoSuchBucketException ex) {
1511
} catch (RollbackException ex) {
1513
LOG.trace("retrying update: " + bucketName);
1514
} catch (EucalyptusCloudException ex) {
1270
ObjectInfo deleteMarker = new ObjectInfo(bucketName,
1518
} while(!success && (retryCount < 5));
1519
ObjectDeleter objectDeleter = new ObjectDeleter(bucketName,
1522
ctx.getUser().getName(),
1523
ctx.getUser().getUserId(),
1524
ctx.getAccount().getName(),
1525
ctx.getAccount().getAccountNumber());
1526
Threads.lookup(Walrus.class, WalrusManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
1527
reply.setCode("200");
1528
reply.setDescription("OK");
1529
if (logData != null) {
1530
updateLogData(bucketInfo, logData);
1531
reply.setLogData(logData);
1533
if(bucketInfo.isVersioningSuspended()) {
1535
ObjectInfo deleteMarker = new ObjectInfo(bucketName, objectKey);
1272
1536
deleteMarker.setDeleted(true);
1273
1537
deleteMarker.setLast(true);
1274
deleteMarker.setOwnerId(userId);
1538
deleteMarker.setOwnerId(account.getAccountNumber());
1275
1539
deleteMarker.setLastModified(new Date());
1276
1540
deleteMarker.setVersionId(UUID.randomUUID().toString().replaceAll("-", ""));
1277
1541
dbObject.add(deleteMarker);
1278
reply.setCode("200");
1279
reply.setDescription("OK");
1282
//versioning disabled or suspended.
1283
ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
1284
searchObjectInfo.setVersionId(WalrusProperties.NULL_VERSION_ID);
1285
EntityWrapper<ObjectInfo> dbObject = db.recast(ObjectInfo.class);
1286
List<ObjectInfo>objectInfos = dbObject.query(searchObjectInfo);
1287
if (objectInfos.size() > 0) {
1288
ObjectInfo nullObject = objectInfos.get(0);
1289
if(nullObject.canWrite(userId)) {
1290
dbObject.delete(nullObject);
1291
String objectName = nullObject.getObjectName();
1292
for (GrantInfo grantInfo : nullObject
1294
db.getEntityManager().remove(grantInfo);
1296
Long size = nullObject.getSize();
1297
bucketInfo.setBucketSize(bucketInfo
1300
ObjectDeleter objectDeleter = new ObjectDeleter(
1301
bucketName, objectName, size);
1302
objectDeleter.start();
1303
reply.setCode("200");
1304
reply.setDescription("OK");
1305
if (logData != null) {
1306
updateLogData(bucketInfo, logData);
1307
reply.setLogData(logData);
1309
if(bucketInfo.isVersioningSuspended()) {
1311
ObjectInfo deleteMarker = new ObjectInfo(bucketName,
1313
deleteMarker.setDeleted(true);
1314
deleteMarker.setLast(true);
1315
deleteMarker.setOwnerId(userId);
1316
deleteMarker.setLastModified(new Date());
1317
deleteMarker.setVersionId(UUID.randomUUID().toString().replaceAll("-", ""));
1318
dbObject.add(deleteMarker);
1322
throw new AccessDeniedException("Key", objectKey, logData);
1326
throw new NoSuchEntityException(objectKey, logData);
1545
throw new NoSuchEntityException(objectKey, logData);
1550
throw new AccessDeniedException("Bucket", bucketName, logData);
1331
1554
throw new NoSuchBucketException(bucketName);
2732
3099
if (bucketList.size() > 0) {
2733
3100
BucketInfo bucket = bucketList.get(0);
2734
BucketLogData logData = bucket.getLoggingEnabled() ? request
2735
.getLogData() : null;
2736
if (bucket.canRead(userId)) {
2737
if (bucket.isVersioningDisabled()) {
2739
throw new EucalyptusCloudException(
2740
"Versioning has not been enabled for bucket: "
3101
BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
3102
if (ctx.hasAdministrativePrivileges() || (
3103
bucket.canRead(account.getAccountNumber()) &&
3104
(bucket.isGlobalRead() || Lookups.checkPrivilege(PolicySpec.S3_LISTBUCKETVERSIONS,
3105
PolicySpec.VENDOR_S3,
3106
PolicySpec.S3_RESOURCE_BUCKET,
3109
if (bucket.isVersioningDisabled()) {
3111
throw new EucalyptusCloudException(
3112
"Versioning has not been enabled for bucket: "
2743
if (logData != null) {
2744
updateLogData(bucket, logData);
2745
reply.setLogData(logData);
2747
if (request.isAdministrator()) {
2748
EntityWrapper<WalrusSnapshotInfo> dbSnap = db
3115
if (logData != null) {
3116
updateLogData(bucket, logData);
3117
reply.setLogData(logData);
3119
if (Contexts.lookup().hasAdministrativePrivileges()) {
3120
EntityWrapper<WalrusSnapshotInfo> dbSnap = db
2749
3121
.recast(WalrusSnapshotInfo.class);
2750
WalrusSnapshotInfo walrusSnapInfo = new WalrusSnapshotInfo();
2751
walrusSnapInfo.setSnapshotBucket(bucketName);
2752
List<WalrusSnapshotInfo> walrusSnaps = dbSnap
3122
WalrusSnapshotInfo walrusSnapInfo = new WalrusSnapshotInfo();
3123
walrusSnapInfo.setSnapshotBucket(bucketName);
3124
List<WalrusSnapshotInfo> walrusSnaps = dbSnap
2753
3125
.query(walrusSnapInfo);
2754
if (walrusSnaps.size() > 0) {
2756
throw new NoSuchBucketException(bucketName);
2759
reply.setName(bucketName);
2760
reply.setIsTruncated(false);
2762
reply.setMaxKeys(maxKeys);
2763
reply.setPrefix(prefix);
2764
reply.setKeyMarker(keyMarker);
2765
reply.setVersionIdMarker(versionIdMarker);
2766
if (delimiter != null)
2767
reply.setDelimiter(delimiter);
2768
EntityWrapper<ObjectInfo> dbObject = db
3126
if (walrusSnaps.size() > 0) {
3128
throw new NoSuchBucketException(bucketName);
3131
reply.setName(bucketName);
3132
reply.setIsTruncated(false);
3134
reply.setMaxKeys(maxKeys);
3135
reply.setPrefix(prefix);
3136
reply.setKeyMarker(keyMarker);
3137
reply.setVersionIdMarker(versionIdMarker);
3138
if (delimiter != null)
3139
reply.setDelimiter(delimiter);
3140
EntityWrapper<ObjectInfo> dbObject = db
2769
3141
.recast(ObjectInfo.class);
2770
ObjectInfo searchObjectInfo = new ObjectInfo();
2771
searchObjectInfo.setBucketName(bucketName);
2772
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
2773
if (objectInfos.size() > 0) {
2774
int howManyProcessed = 0;
2775
if (keyMarker != null || objectInfos.size() < maxKeys)
2776
Collections.sort(objectInfos);
2777
ArrayList<VersionEntry> versions = new ArrayList<VersionEntry>();
2778
ArrayList<DeleteMarkerEntry> deleteMarkers = new ArrayList<DeleteMarkerEntry>();
2780
for (ObjectInfo objectInfo : objectInfos) {
2781
String objectKey = objectInfo.getObjectKey();
2783
if(keyMarker != null) { if(objectKey.compareTo(keyMarker)
2784
<= 0) continue; } else if (versionIdMarker != null) {
2785
if(!objectInfo.getVersionId().equals(versionIdMarker))
2789
if (prefix != null) {
2790
if (!objectKey.startsWith(prefix)) {
2793
if (delimiter != null) {
2794
String[] parts = objectKey.substring(
2795
prefix.length()).split(delimiter);
2796
if (parts.length > 1) {
2797
String prefixString = parts[0]
2799
boolean foundPrefix = false;
2800
for (PrefixEntry prefixEntry : prefixes) {
2801
if (prefixEntry.getPrefix().equals(
2808
prefixes.add(new PrefixEntry(
2811
if (howManyProcessed++ >= maxKeys) {
2812
reply.setIsTruncated(true);
2823
if (howManyProcessed++ >= maxKeys) {
2824
reply.setIsTruncated(true);
2828
if (!objectInfo.getDeleted()) {
2829
VersionEntry versionEntry = new VersionEntry();
2830
versionEntry.setKey(objectKey);
2832
.setVersionId(objectInfo.getVersionId());
2833
versionEntry.setEtag(objectInfo.getEtag());
2834
versionEntry.setLastModified(DateUtils.format(
2835
objectInfo.getLastModified().getTime(),
2836
DateUtils.ISO8601_DATETIME_PATTERN)
2838
String displayName = objectInfo.getOwnerId();
2840
User userInfo = Users.lookupUser(displayName);
2841
versionEntry.setOwner(new CanonicalUserType(
2842
userInfo.getQueryId(), displayName));
2843
} catch (NoSuchUserException e) {
2845
throw new AccessDeniedException("Bucket",
2846
bucketName, logData);
2848
versionEntry.setSize(objectInfo.getSize());
2849
versionEntry.setStorageClass(objectInfo
2850
.getStorageClass());
2851
versionEntry.setIsLatest(objectInfo.getLast());
2852
versions.add(versionEntry);
2854
DeleteMarkerEntry deleteMarkerEntry = new DeleteMarkerEntry();
2855
deleteMarkerEntry.setKey(objectKey);
2856
deleteMarkerEntry.setVersionId(objectInfo
2858
deleteMarkerEntry.setLastModified(DateUtils.format(
2859
objectInfo.getLastModified().getTime(),
2860
DateUtils.ISO8601_DATETIME_PATTERN)
2862
String displayName = objectInfo.getOwnerId();
2864
User userInfo = Users.lookupUser(displayName);
2866
.setOwner(new CanonicalUserType(
2867
userInfo.getQueryId(),
2869
} catch (NoSuchUserException e) {
2871
throw new AccessDeniedException("Bucket",
2872
bucketName, logData);
2874
deleteMarkerEntry.setIsLatest(objectInfo.getLast());
2875
deleteMarkers.add(deleteMarkerEntry);
2878
reply.setVersions(versions);
2879
reply.setDeleteMarkers(deleteMarkers);
2880
if (prefix != null) {
2881
reply.setCommonPrefixes(prefixes);
2886
throw new AccessDeniedException("Bucket", bucketName, logData);
3142
ObjectInfo searchObjectInfo = new ObjectInfo();
3143
searchObjectInfo.setBucketName(bucketName);
3144
List<ObjectInfo> objectInfos = dbObject.query(searchObjectInfo);
3145
if (objectInfos.size() > 0) {
3146
int howManyProcessed = 0;
3147
if (keyMarker != null || objectInfos.size() < maxKeys)
3148
Collections.sort(objectInfos);
3149
ArrayList<VersionEntry> versions = new ArrayList<VersionEntry>();
3150
ArrayList<DeleteMarkerEntry> deleteMarkers = new ArrayList<DeleteMarkerEntry>();
3152
for (ObjectInfo objectInfo : objectInfos) {
3153
String objectKey = objectInfo.getObjectKey();
3155
if(keyMarker != null) { if(objectKey.compareTo(keyMarker)
3156
<= 0) continue; } else if (versionIdMarker != null) {
3157
if(!objectInfo.getVersionId().equals(versionIdMarker))
3161
if (prefix != null) {
3162
if (!objectKey.startsWith(prefix)) {
3165
if (delimiter != null) {
3166
String[] parts = objectKey.substring(
3167
prefix.length()).split(delimiter);
3168
if (parts.length > 1) {
3169
String prefixString = parts[0]
3171
boolean foundPrefix = false;
3172
for (PrefixEntry prefixEntry : prefixes) {
3173
if (prefixEntry.getPrefix().equals(
3180
prefixes.add(new PrefixEntry(
3183
if (howManyProcessed++ >= maxKeys) {
3184
reply.setIsTruncated(true);
3195
if (howManyProcessed++ >= maxKeys) {
3196
reply.setIsTruncated(true);
3200
if (!objectInfo.getDeleted()) {
3201
VersionEntry versionEntry = new VersionEntry();
3202
versionEntry.setKey(objectKey);
3204
.setVersionId(objectInfo.getVersionId());
3205
versionEntry.setEtag(objectInfo.getEtag());
3206
versionEntry.setLastModified(DateUtils.format(
3207
objectInfo.getLastModified().getTime(),
3208
DateUtils.ISO8601_DATETIME_PATTERN)
3210
// displayName is actually the owner account ID
3211
String displayName = objectInfo.getOwnerId();
3213
versionEntry.setOwner(new CanonicalUserType(Accounts.lookupAccountById(displayName).getName(), displayName));
3214
} catch (AuthException e) {
3216
throw new AccessDeniedException("Bucket",
3217
bucketName, logData);
3219
versionEntry.setSize(objectInfo.getSize());
3220
versionEntry.setStorageClass(objectInfo
3221
.getStorageClass());
3222
versionEntry.setIsLatest(objectInfo.getLast());
3223
versions.add(versionEntry);
3225
DeleteMarkerEntry deleteMarkerEntry = new DeleteMarkerEntry();
3226
deleteMarkerEntry.setKey(objectKey);
3227
deleteMarkerEntry.setVersionId(objectInfo
3229
deleteMarkerEntry.setLastModified(DateUtils.format(
3230
objectInfo.getLastModified().getTime(),
3231
DateUtils.ISO8601_DATETIME_PATTERN)
3233
String displayName = objectInfo.getOwnerId();
3235
User userInfo = Accounts.lookupUserById(displayName);
3237
.setOwner(new CanonicalUserType(Accounts.getFirstActiveAccessKeyId( userInfo ),
3239
} catch (AuthException e) {
3241
throw new AccessDeniedException("Bucket",
3242
bucketName, logData);
3244
deleteMarkerEntry.setIsLatest(objectInfo.getLast());
3245
deleteMarkers.add(deleteMarkerEntry);
3248
reply.setVersions(versions);
3249
reply.setDeleteMarkers(deleteMarkers);
3250
if (prefix != null) {
3251
reply.setCommonPrefixes(prefixes);
3256
throw new AccessDeniedException("Bucket", bucketName, logData);
2890
3260
throw new NoSuchBucketException(bucketName);