Projects >> eucalyptus >>545a84eb52f384f76b732cdd2e9969da954c3bef

Chunk
Conflicting content
package com.eucalyptus.objectstorage.providers.walrus;

import com.eucalyptus.objectstorage.exceptions.ObjectStorageException;
<<<<<<< HEAD
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataResponseType;
=======
import com.eucalyptus.objectstorage.exceptions.s3.AccessDeniedException;
import com.eucalyptus.objectstorage.exceptions.s3.BadDigestException;
import com.eucalyptus.objectstorage.exceptions.s3.BucketAlreadyExistsException;
import com.eucalyptus.objectstorage.exceptions.s3.BucketAlreadyOwnedByYouException;
import com.eucalyptus.objectstorage.exceptions.s3.EntityTooLargeException;
import com.eucalyptus.objectstorage.exceptions.s3.InlineDataTooLargeException;
import com.eucalyptus.objectstorage.exceptions.s3.InternalErrorException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidArgumentException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidBucketNameException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidTargetBucketForLoggingException;
import com.eucalyptus.objectstorage.exceptions.s3.NoSuchBucketException;
import com.eucalyptus.objectstorage.exceptions.s3.NoSuchKeyException;
import com.eucalyptus.objectstorage.exceptions.s3.NotImplementedException;
import com.eucalyptus.objectstorage.exceptions.s3.PreconditionFailedException;
import com.eucalyptus.objectstorage.exceptions.s3.S3Exception;
import com.eucalyptus.objectstorage.exceptions.s3.ServiceUnavailableException;
import com.eucalyptus.objectstorage.exceptions.s3.TooManyBucketsException;
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
import com.eucalyptus.objectstorage.msgs.ObjectStorageRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageResponseType;
import com.eucalyptus.util.Classes;
Solution content
package com.eucalyptus.objectstorage.providers.walrus;

import com.eucalyptus.objectstorage.exceptions.ObjectStorageException;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataResponseType;
import com.eucalyptus.objectstorage.exceptions.s3.AccessDeniedException;
import com.eucalyptus.objectstorage.exceptions.s3.BadDigestException;
import com.eucalyptus.objectstorage.exceptions.s3.BucketAlreadyExistsException;
import com.eucalyptus.objectstorage.exceptions.s3.BucketAlreadyOwnedByYouException;
import com.eucalyptus.objectstorage.exceptions.s3.EntityTooLargeException;
import com.eucalyptus.objectstorage.exceptions.s3.InlineDataTooLargeException;
import com.eucalyptus.objectstorage.exceptions.s3.InternalErrorException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidArgumentException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidBucketNameException;
import com.eucalyptus.objectstorage.exceptions.s3.InvalidTargetBucketForLoggingException;
import com.eucalyptus.objectstorage.exceptions.s3.NoSuchBucketException;
import com.eucalyptus.objectstorage.exceptions.s3.NoSuchKeyException;
import com.eucalyptus.objectstorage.exceptions.s3.NotImplementedException;
import com.eucalyptus.objectstorage.exceptions.s3.PreconditionFailedException;
import com.eucalyptus.objectstorage.exceptions.s3.S3Exception;
import com.eucalyptus.objectstorage.exceptions.s3.ServiceUnavailableException;
import com.eucalyptus.objectstorage.exceptions.s3.TooManyBucketsException;
import com.eucalyptus.objectstorage.msgs.ObjectStorageRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageResponseType;
import com.eucalyptus.util.Classes;
File
MessageMapper.java
Developer's decision
Concatenation
Kind of conflict
Import
Chunk
Conflicting content
package com.eucalyptus.objectstorage.providers.walrus;

<<<<<<< HEAD
import java.util.List;
import java.util.NoSuchElementException;

import com.eucalyptus.objectstorage.msgs.AbortMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.AbortMultipartUploadType;
import com.eucalyptus.objectstorage.msgs.CompleteMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.CompleteMultipartUploadType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataResponseType;
import com.eucalyptus.walrus.msgs.WalrusDataRequestType;
import com.eucalyptus.walrus.msgs.WalrusDataResponseType;
=======
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.context.ServiceDispatchException;
import com.eucalyptus.objectstorage.exceptions.s3.InternalErrorException;
import com.eucalyptus.objectstorage.exceptions.s3.S3Exception;
import com.eucalyptus.objectstorage.msgs.GetObjectResponseType;
import com.eucalyptus.objectstorage.msgs.GetObjectType;
import com.eucalyptus.objectstorage.msgs.HeadObjectResponseType;
import com.eucalyptus.objectstorage.msgs.HeadObjectType;
import com.eucalyptus.objectstorage.msgs.SetObjectAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetObjectAccessControlPolicyType;
import com.eucalyptus.objectstorage.providers.ObjectStorageProviders;
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
import org.apache.log4j.Logger;

import com.amazonaws.auth.AWSCredentials;
Solution content
package com.eucalyptus.objectstorage.providers.walrus;

import com.eucalyptus.auth.Accounts;
import com.eucalyptus.context.ServiceDispatchException;
import com.eucalyptus.objectstorage.exceptions.s3.InternalErrorException;
import com.eucalyptus.objectstorage.exceptions.s3.S3Exception;
import com.eucalyptus.objectstorage.msgs.AbortMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.AbortMultipartUploadType;
import com.eucalyptus.objectstorage.msgs.CompleteMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.CompleteMultipartUploadType;
import com.eucalyptus.objectstorage.msgs.GetObjectResponseType;
import com.eucalyptus.objectstorage.msgs.GetObjectType;
import com.eucalyptus.objectstorage.msgs.HeadObjectResponseType;
import com.eucalyptus.objectstorage.msgs.HeadObjectType;
import com.eucalyptus.objectstorage.msgs.InitiateMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.InitiateMultipartUploadType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataRequestType;
import com.eucalyptus.objectstorage.msgs.ObjectStorageDataResponseType;
import com.eucalyptus.objectstorage.msgs.SetObjectAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetObjectAccessControlPolicyType;
import com.eucalyptus.objectstorage.providers.ObjectStorageProviders;
import com.eucalyptus.walrus.msgs.WalrusDataRequestType;
import com.eucalyptus.walrus.msgs.WalrusDataResponseType;
import org.apache.log4j.Logger;

import com.amazonaws.auth.AWSCredentials;
File
WalrusProviderClient.java
Developer's decision
Manual
Kind of conflict
Import
Chunk
Conflicting content
import com.eucalyptus.objectstorage.msgs.SetBucketLoggingStatusType;
import com.eucalyptus.objectstorage.msgs.SetBucketVersioningStatusResponseType;
import com.eucalyptus.objectstorage.msgs.SetBucketVersioningStatusType;
<<<<<<< HEAD
import com.eucalyptus.objectstorage.msgs.SetRESTBucketAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetRESTBucketAccessControlPolicyType;
import com.eucalyptus.objectstorage.msgs.SetRESTObjectAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetRESTObjectAccessControlPolicyType;
import com.eucalyptus.objectstorage.msgs.InitiateMultipartUploadResponseType;
import com.eucalyptus.objectstorage.msgs.InitiateMultipartUploadType;
=======
import com.eucalyptus.objectstorage.msgs.SetBucketAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetBucketAccessControlPolicyType;
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
import com.eucalyptus.objectstorage.providers.s3.S3ProviderClient;
import com.eucalyptus.objectstorage.providers.s3.S3ProviderConfiguration;
import com.eucalyptus.objectstorage.util.S3Client;
Solution content
import com.eucalyptus.objectstorage.msgs.SetBucketLoggingStatusType;
import com.eucalyptus.objectstorage.msgs.SetBucketVersioningStatusResponseType;
import com.eucalyptus.objectstorage.msgs.SetBucketVersioningStatusType;
import com.eucalyptus.objectstorage.msgs.SetBucketAccessControlPolicyResponseType;
import com.eucalyptus.objectstorage.msgs.SetBucketAccessControlPolicyType;
import com.eucalyptus.objectstorage.providers.s3.S3ProviderClient;
import com.eucalyptus.objectstorage.providers.s3.S3ProviderConfiguration;
import com.eucalyptus.objectstorage.util.S3Client;
File
WalrusProviderClient.java
Developer's decision
Version 2
Kind of conflict
Import
Chunk
Conflicting content
			super( systemAdmin.getUserId(), Walrus.class );
		}

<<<<<<< HEAD
	    public  RES sendSyncA( final REQ request) throws Exception {
    			request.setEffectiveUserId( userId );
=======
	        public  RES sendSyncA( final REQ request) throws Exception {
    			// request.setEffectiveUserId( userId );
	        	request.setUser( systemAdmin );
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
    			return AsyncRequests.sendSync( configuration, request );
  		}
Solution content
			super( systemAdmin.getUserId(), Walrus.class );
		}

	        public  RES sendSyncA( final REQ request) throws Exception {
    			// request.setEffectiveUserId( userId );
	        	request.setUser( systemAdmin );
    			return AsyncRequests.sendSync( configuration, request );
  		}
File
WalrusProviderClient.java
Developer's decision
Version 2
Kind of conflict
Comment
Method invocation
Method signature
Chunk
Conflicting content
		throw new EucalyptusCloudException("Unable to obtain reply from dispatcher.");
	}

<<<<<<< HEAD
    private  ObjResp proxyDataRequest(ObjReq request, Class walrusRequestClass, Class walrusResponseClass) throws EucalyptusCloudException {
        ObjectStorageException osge = null;
        try  {
            WalrusClient c = getEnabledWalrusClient(request.getEffectiveUserId());
            WalReq walrusRequest = MessageMapper.INSTANCE.proxyWalrusDataRequest(walrusRequestClass, request);
            WalResp walrusResponse = c.sendSyncADataReq(walrusRequest);
            ObjResp reply = MessageMapper.INSTANCE.proxyWalrusDataResponse(request, walrusResponse);
            return reply;
        } catch(ServiceDispatchException e) {
            Throwable rootCause = e.getRootCause();
            if(rootCause != null) {
                if (rootCause instanceof WalrusException) {
                    osge = MessageMapper.INSTANCE.proxyWalrusException((WalrusException)rootCause);
                } else {
                    throw new EucalyptusCloudException(rootCause);
                }
            }
        } catch(Exception e) {
            throw new EucalyptusCloudException(e);
        }
        if(osge != null) {
            throw osge;
        }
        throw new EucalyptusCloudException("Unable to obtain reply from dispatcher.");
=======
    private static S3Exception mapWalrusExceptionToS3Exception(EucalyptusCloudException ex) {
        if(ex instanceof S3Exception) {
            return (S3Exception) ex;
        } else {
            LOG.debug("Mapping excepion from Walrus to 500-InternalError", ex);
            InternalErrorException s3Ex = new InternalErrorException();
            s3Ex.initCause(ex);
            return s3Ex;
        }
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
    }

	/*
Solution content
		throw new EucalyptusCloudException("Unable to obtain reply from dispatcher.");
	}

    private static S3Exception mapWalrusExceptionToS3Exception(EucalyptusCloudException ex) {
        if(ex instanceof S3Exception) {
            return (S3Exception) ex;
        } else {
            LOG.debug("Mapping excepion from Walrus to 500-InternalError", ex);
            InternalErrorException s3Ex = new InternalErrorException();
            s3Ex.initCause(ex);
            return s3Ex;
        }
    }

    private  ObjResp proxyDataRequest(ObjReq request, Class walrusRequestClass, Class walrusResponseClass) throws EucalyptusCloudException {
        ObjectStorageException osge = null;
        try  {
            WalrusClient c = getEnabledWalrusClient(request.getEffectiveUserId());
            WalReq walrusRequest = MessageMapper.INSTANCE.proxyWalrusDataRequest(walrusRequestClass, request);
            WalResp walrusResponse = c.sendSyncADataReq(walrusRequest);
            ObjResp reply = MessageMapper.INSTANCE.proxyWalrusDataResponse(request, walrusResponse);
            return reply;
        } catch(ServiceDispatchException e) {
            Throwable rootCause = e.getRootCause();
            if(rootCause != null) {
                if (rootCause instanceof WalrusException) {
                    osge = MessageMapper.INSTANCE.proxyWalrusException((WalrusException)rootCause);
                } else {
                    throw new EucalyptusCloudException(rootCause);
                }
            }
        } catch(Exception e) {
            throw new EucalyptusCloudException(e);
        }
        if(osge != null) {
            throw osge;
        }
        throw new EucalyptusCloudException("Unable to obtain reply from dispatcher.");
    }


	/*
File
WalrusProviderClient.java
Developer's decision
Manual
Kind of conflict
If statement
Method signature
Throw statement
Try statement
Variable
Chunk
Conflicting content
                    objectInfo.setGrants(grantInfos);
		} else {
			db.rollback();

			db.rollback();
            accessControlList = new AccessControlList();
        }

<<<<<<< HEAD
        String key = bucketName + "." + objectKey;
        String randomKey = request.getRandomKey();
        WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);
        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            long objSize = 0;
            try {
                objSize = Long.valueOf(request.getContentLength());
            } catch (NumberFormatException e) {
                LOG.error("Invalid content length " + request.getContentLength());
                // TODO(wenye): should handle this properly.
                objSize = 1L;
            }
            if (ctx.hasAdministrativePrivileges()
                    || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
                    PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
                if (logData != null) {
                    reply.setLogData(logData);
                }
                String objectName = null;
                String versionId = null;
                Long oldObjectSize = 0L;
                ObjectInfo objectInfo = null;
                if (bucket.isVersioningEnabled()) {
                    // If versioning, add new object with new version id and
                    // make it the 'latest' version.
                    objectInfo = new ObjectInfo(bucketName, objectKey);
                    objectInfo.setOwnerId(account.getAccountNumber());
                    List grantInfos = new ArrayList();
                    objectInfo.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                    objectName = UUID.randomUUID().toString();
                    objectInfo.setObjectName(objectName);
                    objectInfo.setSize(0L);
                    versionId = UUID.randomUUID().toString().replaceAll("-", "");
                    reply.setVersionId(versionId);
                } else {
                    // If no versioning enabled, put using a null version id,
                    // this will replace any previous 'null' versioned object
                    // but not one with a version id.
                    versionId = WalrusProperties.NULL_VERSION_ID;
                    ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
                    searchObject.setVersionId(versionId);
                    EntityWrapper dbObject = db.recast(ObjectInfo.class);
                    try {
                        ObjectInfo foundObject = dbObject.getUniqueEscape(searchObject);
                        if (!foundObject.canWrite(account.getAccountNumber())) {
                            // Found existing object, but don't have write
                            // access
                            db.rollback();
                            messenger.removeQueue(key, randomKey);
                            throw new AccessDeniedException("Key", objectKey, logData);
                        }
                        objectName = foundObject.getObjectName();
                        oldObjectSize = foundObject.getSize() == null ? 0L : foundObject.getSize();
                        // Fix for EUCA-2275:
                        // If an existing object is overwritten, the size
                        // difference must be taken into account. Size of the
                        // already existing object was ignored before
                        oldBucketSize = -oldObjectSize;
                    } catch (AccessDeniedException ex) {
                        throw ex;
                    } catch (EucalyptusCloudException ex) {
                        // No existing object found
                        objectInfo = new ObjectInfo(bucketName, objectKey);
                        objectInfo.setOwnerId(account.getAccountNumber());
                        List grantInfos = new ArrayList();
                        objectInfo.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                        objectInfo.setGrants(grantInfos);
                        objectName = UUID.randomUUID().toString();
                        objectInfo.setObjectName(objectName);
                        objectInfo.setSize(0L);
                    }
                }

                String bucketOwnerId = bucket.getOwnerId();
                db.commit();
                // writes are unconditional
                WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);
=======
                            /* the reporting is now done in the OSG
							try {
								fireObjectCreationEvent(bucketName, objectKey, versionId, ctx.getUser().getUserId(), size, oldObjectSize);
							} catch (Exception ex) {
								LOG.debug("Failed to fire reporting event for walrus PUT object operation", ex);
							}
                            */

							break;
						} else {
							assert (WalrusDataMessage.isData(dataMessage));
							byte[] data = dataMessage.getPayload();
							// start writing object (but do not commit yet)
							try {
								if (fileIO != null)
									fileIO.write(data);
							} catch (IOException ex) {
								LOG.error(ex);
							}
							// calculate md5 on the fly
							size += data.length;
							if (digest != null) {
								digest.update(data);
							}
						}
					}
				} catch (InterruptedException ex) {
					LOG.error(ex, ex);
					messenger.removeQueue(key, randomKey);
					throw new EucalyptusCloudException("Transfer interrupted: " + key + "." + randomKey);
				}
			} else {
				db.rollback();
				messenger.removeQueue(key, randomKey);
				throw new AccessDeniedException("Bucket", bucketName, logData);
			}
			messenger.removeQueue(key, randomKey);
			throw new NoSuchBucketException(bucketName);
		}

		reply.setEtag(md5);
		reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
		return reply;
	}

	private void cleanupTempObject(Context ctx, String bucketName,
			String tempObjectName) {
		ObjectDeleter objectDeleter = new ObjectDeleter(bucketName,
				tempObjectName,
				null,
				null,
				-1L,
				ctx.getUser().getName(),
				ctx.getUser().getUserId(),
				ctx.getAccount().getName(),
				ctx.getAccount().getAccountNumber());
		Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
	}

	private void incrementBucketSize(String bucketName, String objectKey, Long oldBucketSize, Long size) throws EucalyptusCloudException, RollbackException,
			NoSuchBucketException, EntityTooLargeException {
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		try {
			BucketInfo searchBucket = new BucketInfo(bucketName);
			BucketInfo bucket = null;
			try {
				bucket = db.getUniqueEscape(searchBucket);
			} catch (EucalyptusCloudException ex) {
				LOG.error(ex);
				throw new NoSuchBucketException(bucketName);
			}
			Long bucketSize = bucket.getBucketSize();
			long newSize = bucketSize + oldBucketSize + size;
			if (WalrusProperties.shouldEnforceUsageLimits && !Contexts.lookup().hasAdministrativePrivileges()) {
				if (newSize > (WalrusInfo.getWalrusInfo().getStorageMaxBucketSizeInMB() * WalrusProperties.M)) {
					throw new EntityTooLargeException("Key", objectKey);
				}
			}
			bucket.setBucketSize(newSize);
			db.commit();
		} catch (RollbackException ex) {
			throw ex;
		} catch (EucalyptusCloudException ex) {
			db.rollback();
			throw ex;
		}
	}

	@Override
	public PostObjectResponseType postObject(PostObjectType request)
			throws EucalyptusCloudException {
		PostObjectResponseType reply = (PostObjectResponseType) request
				.getReply();

		String bucketName = request.getBucket();
		String key = request.getKey();
		PutObjectType putObject = new PutObjectType();
		putObject.setUserId(Contexts.lookup().getUserFullName().getUserId());
		putObject.setBucket(bucketName);
		putObject.setKey(key);
		putObject.setRandomKey(request.getRandomKey());
		putObject.setAccessControlList(request.getAccessControlList());
		putObject.setContentType(request.getContentType());
		putObject.setContentLength(request.getContentLength());
		putObject.setEffectiveUserId(request.getEffectiveUserId());
		putObject.setCredential(request.getCredential());
		putObject.setIsCompressed(request.getIsCompressed());
		putObject.setMetaData(request.getMetaData());
		putObject.setStorageClass(request.getStorageClass());

		PutObjectResponseType putObjectResponse = putObject(putObject);

		String etag = putObjectResponse.getEtag();
		reply.setEtag(etag);
		reply.setLastModified(putObjectResponse.getLastModified());
		reply.set_return(putObjectResponse.get_return());
		reply.setMetaData(putObjectResponse.getMetaData());
		reply.setErrorCode(putObjectResponse.getErrorCode());
		reply.setStatusMessage(putObjectResponse.getStatusMessage());
		reply.setLogData(putObjectResponse.getLogData());

		String successActionRedirect = request.getSuccessActionRedirect();
		if (successActionRedirect != null) {
			try {
				java.net.URI addrUri = new URL(successActionRedirect).toURI();
				InetAddress.getByName(addrUri.getHost());
			} catch (Exception ex) {
				LOG.warn(ex);
			}
			String paramString = "bucket=" + bucketName + "&key=" + key + "&etag=quot;" + etag + "quot;";
			reply.setRedirectUrl(successActionRedirect + "?" + paramString);
		} else {
			Integer successActionStatus = request.getSuccessActionStatus();
			if (successActionStatus != null) {
				if ((successActionStatus == 200) || (successActionStatus == 201)) {
					reply.setSuccessCode(successActionStatus);
					if (successActionStatus == 200) {
						return reply;
					} else {
						reply.setBucket(bucketName);
						reply.setKey(key);
						reply.setLocation(Topology.lookup(Walrus.class).getUri().getHost() + "/" + bucketName + "/" + key);
					}
				} else {
					reply.setSuccessCode(204);
					return reply;
				}
			}
		}
		return reply;
	}

	@Override
	public PutObjectInlineResponseType putObjectInline(
			PutObjectInlineType request) throws EucalyptusCloudException {
		PutObjectInlineResponseType reply = (PutObjectInlineResponseType) request
				.getReply();
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();

		String bucketName = request.getBucket();
		String objectKey = request.getKey();

		String md5 = "";
		Long oldBucketSize = 0L;
		Date lastModified;

		AccessControlList accessControlList = request.getAccessControlList();
		if (accessControlList == null) {
			accessControlList = new AccessControlList();
		}

		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfo = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfo);

		if (bucketList.size() > 0) {
			BucketInfo bucket = bucketList.get(0);
			BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
			long objSize = 0;
			try {
				objSize = Long.valueOf(request.getContentLength());
			} catch (NumberFormatException e) {
				LOG.error("Invalid content length " + request.getContentLength());
				// TODO(wenye): should handle this properly.
				objSize = 1L;
			}
			if (ctx.hasAdministrativePrivileges()
					|| (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
							PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
				EntityWrapper dbObject = db.recast(ObjectInfo.class);
				ObjectInfo searchObjectInfo = new ObjectInfo();
				searchObjectInfo.setBucketName(bucketName);

				ObjectInfo foundObject = null;
				List objectInfos = dbObject.queryEscape(searchObjectInfo);
				for (ObjectInfo objectInfo : objectInfos) {
					if (objectInfo.getObjectKey().equals(objectKey)) {
						// key (object) exists. check perms
						if (!objectInfo.canWrite(account.getAccountNumber())) {
							db.rollback();
							throw new AccessDeniedException("Key", objectKey, logData);
						}
						foundObject = objectInfo;
						oldBucketSize = -foundObject.getSize();
						break;
					}
				}
				// write object to bucket
				String objectName;
				Long oldObjectSize = 0L;
				if (foundObject == null) {
					// not found. create an object info
					foundObject = new ObjectInfo(bucketName, objectKey);
					foundObject.setOwnerId(account.getAccountNumber());
					List grantInfos = new ArrayList();
					foundObject.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
					foundObject.setGrants(grantInfos);
					objectName = UUID.randomUUID().toString();
					foundObject.setObjectName(objectName);
					dbObject.add(foundObject);
				} else {
					// object already exists. see if we can modify acl
					if (ctx.hasAdministrativePrivileges() || foundObject.canWriteACP(account.getAccountNumber())) {
						List grantInfos = foundObject.getGrants();
						foundObject.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
					}
					objectName = foundObject.getObjectName();
					oldObjectSize = foundObject.getSize();
				}
				foundObject.setObjectKey(objectKey);
				try {
					// writes are unconditional
					if (request.getBase64Data().getBytes().length > WalrusProperties.MAX_INLINE_DATA_SIZE) {
						db.rollback();
						throw new InlineDataTooLargeException(bucketName + "/" + objectKey);
					}
					byte[] base64Data = Hashes.base64decode(request.getBase64Data()).getBytes();
					foundObject.setObjectName(objectName);
					Long size = (long) base64Data.length;

					// Fix for EUCA-2275:
					// Moved up policy and bucket size checks on the temporary
					// object. The object is committed (written) only after it
					// clears the checks.
					// So the fix ensures that no files are orphaned and does
					// not overwrite existing data when policy or bucket size
					// checks fail

					if (!ctx.hasAdministrativePrivileges()
							&& !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT,
									ctx.getUser(), oldBucketSize + size)) {
						db.rollback();
						LOG.error("Quota exceeded in Walrus putObject");
						throw new EntityTooLargeException("Key", objectKey, logData);
					}
					boolean success = false;
					int retryCount = 0;
					do {
						try {
							incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
							success = true;
						} catch (EntityTooLargeException ex) {
							db.rollback();
							throw ex;
						} catch (NoSuchBucketException ex) {
							db.rollback();
							throw ex;
						} catch (RollbackException ex) {
							retryCount++;
							LOG.trace("retrying update: " + bucketName);
						} catch (EucalyptusCloudException ex) {
							db.rollback();
							throw ex;
						}
					} while (!success && (retryCount < 5));

					try {
						FileIO fileIO = storageManager.prepareForWrite(bucketName, objectName);
						if (fileIO != null) {
							fileIO.write(base64Data);
							fileIO.finish();
						}
					} catch (Exception ex) {
						db.rollback();
						throw new EucalyptusCloudException(ex);
					}
					md5 = Hashes.getHexString(Digest.MD5.get().digest(base64Data));
					foundObject.setEtag(md5);
					foundObject.setSize(size);
					// Add meta data if specified
					if (request.getMetaData() != null)
						foundObject.replaceMetaData(request.getMetaData());

					// TODO: add support for other storage classes
					foundObject.setStorageClass("STANDARD");
					lastModified = new Date();
					foundObject.setLastModified(lastModified);
					if (logData != null) {
						updateLogData(bucket, logData);
						logData.setObjectSize(size);
						reply.setLogData(logData);
					}

                    /* the reporting is now done in the OSG
					try {
						fireObjectCreationEvent(foundObject.getBucketName(), foundObject.getObjectKey(), foundObject.getVersionId(), ctx.getUser().getUserId(),
								foundObject.getSize(), oldObjectSize);
					} catch (Exception ex) {
						LOG.debug("Failed to fire reporting event for walrus inline PUT object operation", ex);
					}
                    */
					/* SOAP */
				} catch (Exception ex) {
					LOG.error(ex);
					db.rollback();
					throw new EucalyptusCloudException(bucketName);
				}
			} else {
				db.rollback();
				throw new AccessDeniedException("Bucket", bucketName, logData);
			}
		} else {
			throw new NoSuchBucketException(bucketName);
		}

		db.commit();

		reply.setEtag(md5);
		reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
		return reply;
	}

	@Override
	public AddObjectResponseType addObject(AddObjectType request)
			throws EucalyptusCloudException {

		AddObjectResponseType reply = (AddObjectResponseType) request.getReply();
		String bucketName = request.getBucket();
		String key = request.getKey();
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();
		String objectName = request.getObjectName();

		AccessControlList accessControlList = request.getAccessControlList();
		if (accessControlList == null) {
			accessControlList = new AccessControlList();
		}

		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfo = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfo);

		if (bucketList.size() > 0) {
			BucketInfo bucket = bucketList.get(0);
			if (ctx.hasAdministrativePrivileges()
					|| (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
							PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucket.getBucketName(), null)))) {
				EntityWrapper dbObject = db.recast(ObjectInfo.class);
				ObjectInfo searchObjectInfo = new ObjectInfo();
				searchObjectInfo.setBucketName(bucketName);
				List objectInfos = dbObject.queryEscape(searchObjectInfo);
				for (ObjectInfo objectInfo : objectInfos) {
					if (objectInfo.getObjectKey().equals(key)) {
						// key (object) exists.
						db.rollback();
						throw new EucalyptusCloudException("object already exists " + key);
					}
				}
				// write object to bucket
				ObjectInfo objectInfo = new ObjectInfo(bucketName, key);
				objectInfo.setObjectName(objectName);
				List grantInfos = new ArrayList();
				objectInfo.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
				objectInfo.setGrants(grantInfos);
				dbObject.add(objectInfo);

				objectInfo.setObjectKey(key);
				objectInfo.setOwnerId(account.getAccountNumber());
				objectInfo.setSize(storageManager.getSize(bucketName, objectName));
				objectInfo.setEtag(request.getEtag());
				objectInfo.setLastModified(new Date());
				objectInfo.setStorageClass("STANDARD");
			} else {
				db.rollback();
				throw new AccessDeniedException("Bucket", bucketName);
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		db.commit();
		return reply;
	}

	@Override
	public DeleteObjectResponseType deleteObject(DeleteObjectType request)
			throws EucalyptusCloudException {
		DeleteObjectResponseType reply = (DeleteObjectResponseType) request
				.getReply();
		String bucketName = request.getBucket();
		String objectKey = request.getKey();
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();

		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		try {
			BucketInfo bucketInfos = new BucketInfo(bucketName);
			BucketInfo bucketInfo = null;
			try {
				bucketInfo = db.uniqueResultEscape(bucketInfos);
			} catch(NoSuchElementException e) {
				//Nothing to do, object cannot exist if bucket does not.
				bucketInfo = null;
			} catch(TransactionException e) {
				LOG.error("Transaction error looking up bucket: " + bucketName,e);
				throw new EucalyptusCloudException(e);
			}

			if(bucketInfo != null) {
				BucketLogData logData = bucketInfo.getLoggingEnabled() ? request.getLogData() : null;
				if (ctx.hasAdministrativePrivileges()
						|| (bucketInfo.canWrite(account.getAccountNumber()) && (bucketInfo.isGlobalWrite() || Lookups
								.checkPrivilege(PolicySpec.S3_DELETEOBJECT, PolicySpec.VENDOR_S3,
										PolicySpec.S3_RESOURCE_BUCKET, bucketInfo.getBucketName(), null)))) {

					EntityWrapper dbObject = db.recast(ObjectInfo.class);

					if (bucketInfo.isVersioningEnabled()) {
						// Versioning is enabled, look for delete marker. If one
						// is
						// present, do nothing. Otherwise place delete marker.
						ObjectInfo searchDeletedObjectInfo = new ObjectInfo(bucketName, objectKey);
						searchDeletedObjectInfo.setDeleted(true);
						searchDeletedObjectInfo.setLast(true);
						try {
							dbObject.getUniqueEscape(searchDeletedObjectInfo);
							db.rollback();
							// Delete marker already exists, nothing to do here
							LOG.debug("Object " + objectKey + " has a delete marker in bucket " + bucketName
									+ " that is marked latest. Nothing to delete");
						} catch (NoSuchEntityException ex) {
							// No such key found, nothing to do here
							LOG.debug("Object " + objectKey + " not found in bucket " + bucketName
									+ ". Nothing to delete");
						} catch (EucalyptusCloudException ex) {
							ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
							searchObjectInfo.setLast(true);
							List objectInfos = dbObject.queryEscape(searchObjectInfo);
							for (ObjectInfo objInfo : objectInfos) {
								objInfo.setLast(false);
							}
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a

                try {
                    WalrusDataMessage dataMessage;
Solution content
            accessControlList = new AccessControlList();
        }

        String key = bucketName + "." + objectKey;
        String randomKey = request.getRandomKey();
        WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            long objSize = 0;
            try {
                objSize = Long.valueOf(request.getContentLength());
            } catch (NumberFormatException e) {
                LOG.error("Invalid content length " + request.getContentLength());
                // TODO(wenye): should handle this properly.
                objSize = 1L;
            }
            if (ctx.hasAdministrativePrivileges()
                    || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT,
                    PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
                if (logData != null) {
                    reply.setLogData(logData);
                }
                String objectName = null;
                String versionId = null;
                Long oldObjectSize = 0L;
                ObjectInfo objectInfo = null;
                if (bucket.isVersioningEnabled()) {
                    // If versioning, add new object with new version id and
                    // make it the 'latest' version.
                    objectInfo = new ObjectInfo(bucketName, objectKey);
                    objectInfo.setOwnerId(account.getAccountNumber());
                    List grantInfos = new ArrayList();
                    objectInfo.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                    objectInfo.setGrants(grantInfos);
                    objectName = UUID.randomUUID().toString();
                    objectInfo.setObjectName(objectName);
                    objectInfo.setSize(0L);
                    versionId = UUID.randomUUID().toString().replaceAll("-", "");
                    reply.setVersionId(versionId);
                } else {
                    // If no versioning enabled, put using a null version id,
                    // this will replace any previous 'null' versioned object
                    // but not one with a version id.
                    versionId = WalrusProperties.NULL_VERSION_ID;
                    ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
                    searchObject.setVersionId(versionId);
                    EntityWrapper dbObject = db.recast(ObjectInfo.class);
                    try {
                        ObjectInfo foundObject = dbObject.getUniqueEscape(searchObject);
                        if (!foundObject.canWrite(account.getAccountNumber())) {
                            // Found existing object, but don't have write
                            // access
                            db.rollback();
                            messenger.removeQueue(key, randomKey);
                            throw new AccessDeniedException("Key", objectKey, logData);
                        }
                        objectName = foundObject.getObjectName();
                        oldObjectSize = foundObject.getSize() == null ? 0L : foundObject.getSize();
                        // Fix for EUCA-2275:
                        // If an existing object is overwritten, the size
                        // difference must be taken into account. Size of the
                        // already existing object was ignored before
                        oldBucketSize = -oldObjectSize;
                    } catch (AccessDeniedException ex) {
                        throw ex;
                    } catch (EucalyptusCloudException ex) {
                        // No existing object found
                        objectInfo = new ObjectInfo(bucketName, objectKey);
                        objectInfo.setOwnerId(account.getAccountNumber());
                        List grantInfos = new ArrayList();
                        objectInfo.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                        objectInfo.setGrants(grantInfos);
                        objectName = UUID.randomUUID().toString();
                        objectInfo.setObjectName(objectName);
                        objectInfo.setSize(0L);
                    }
                }

                String bucketOwnerId = bucket.getOwnerId();
                db.commit();
                // writes are unconditional
                WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);

                try {
                    WalrusDataMessage dataMessage;
File
WalrusFSManager.java
Developer's decision
Version 1
Kind of conflict
Annotation
Assert statement
Break statement
Cast expression
Catch clause
Comment
For statement
If statement
Method declaration
Method invocation
Method signature
Return statement
Throw statement
Try statement
Variable
Chunk
Conflicting content
                        Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
                    }

<<<<<<< HEAD
                    if (logData != null) {
                        updateLogData(bucketInfo, logData);
                        reply.setLogData(logData);
                    }
                } else {
                    db.rollback();
                    throw new AccessDeniedException("Key", objectKey, logData);
                }
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        reply.setStatus(HttpResponseStatus.NO_CONTENT);
        reply.setStatusMessage("NO CONTENT");
        db.commit();
        return reply;
    }

    public static InetAddress getBucketIp(String bucket) throws EucalyptusCloudException {
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        try {
            BucketInfo searchBucket = new BucketInfo(bucket);
            db.getUniqueEscape(searchBucket);
            return WalrusProperties.getWalrusAddress();
        } catch (EucalyptusCloudException ex) {
            throw ex;
        } finally {
            db.rollback();
        }
    }

    @Override
    public void fastDeleteObject(DeleteObjectType request) throws EucalyptusCloudException {
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfos = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfos);
        if (bucketList.size() > 0) {
            BucketInfo bucketInfo = bucketList.get(0);
            BucketLogData logData = bucketInfo.getLoggingEnabled() ? request.getLogData() : null;
            ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
            searchObjectInfo.setVersionId(WalrusProperties.NULL_VERSION_ID);
            EntityWrapper dbObject = db.recast(ObjectInfo.class);
            List objectInfos = dbObject.queryEscape(searchObjectInfo);
            if (objectInfos.size() > 0) {
                ObjectInfo foundObject = objectInfos.get(0);
                dbObject.delete(foundObject);
                String objectName = foundObject.getObjectName();
                for (GrantInfo grantInfo : foundObject.getGrants()) {
                    db.delete(grantInfo);
                }
                Long size = foundObject.getSize();
                try {
                    storageManager.deleteObject(bucketName, objectName);
                } catch (IOException ex) {
                    LOG.error(ex, ex);
                }
                boolean success = false;
                int retryCount = 0;
                do {
                    try {
                        decrementBucketSize(bucketName, size);
                        success = true;
                    } catch (NoSuchBucketException ex) {
                        db.rollback();
                        throw ex;
                    } catch (RollbackException ex) {
                        retryCount++;
                        LOG.trace("retrying update: " + bucketName);
                    } catch (EucalyptusCloudException ex) {
                        db.rollback();
                        throw ex;
                    }
                } while (!success && (retryCount < 5));

            } else {
                db.rollback();
                throw new NoSuchEntityException(objectKey, logData);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
    }

    @Override
    public void fastDeleteBucket(DeleteBucketType request) throws EucalyptusCloudException {
        String bucketName = request.getBucket();
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo searchBucket = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(searchBucket);

        if (bucketList.size() > 0) {
            BucketInfo bucketFound = bucketList.get(0);
            EntityWrapper dbObject = db.recast(ObjectInfo.class);
            ObjectInfo searchObject = new ObjectInfo();
            searchObject.setBucketName(bucketName);
            searchObject.setDeleted(false);
            List objectInfos = dbObject.queryEscape(searchObject);
            if (objectInfos.size() == 0) {
                db.delete(bucketFound);
                // Actually remove the bucket from the backing store
                try {
                    storageManager.deleteBucket(bucketName);
                } catch (IOException ex) {
                    // set exception code in reply
                    LOG.error(ex);
                }
            } else {
                db.rollback();
                throw new BucketNotEmptyException(bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
    }

    /**
     * Fire creation and possibly a related delete event.
     *
     * If an object (version) is being overwritten then there will not be a corresponding delete event so we fire one prior to the create event.
     */
    private void fireObjectCreationEvent(final String bucketName, final String objectKey, final String version, final String userId, final Long size,
                                         final Long oldSize) {
        try {
            if (oldSize != null && oldSize > 0) {
                fireObjectUsageEvent(S3ObjectAction.OBJECTDELETE, bucketName, objectKey, version, userId, oldSize);
            }

			/* Send an event to reporting to report this S3 usage. */
            if (size != null && size > 0) {
						decrementBucketSize(bucketName, size);
                fireObjectUsageEvent(S3ObjectAction.OBJECTCREATE, bucketName, objectKey, version, userId, size);
            }
        } catch (final Exception e) {
            LOG.error(e, e);
        }
    }
=======
						boolean success = false;
						int retryCount = 0;
						do {
							try {
								decrementBucketSize(bucketName, size);
								success = true;
							} catch (NoSuchBucketException ex) {
								db.rollback();
								throw ex;
							} catch (RollbackException ex) {
								retryCount++;
								LOG.trace("retrying update: " + bucketName);
							} catch (EucalyptusCloudException ex) {
								db.rollback();
								throw ex;
							}
						} while (!success && (retryCount < 5));

						ObjectDeleter objectDeleter = new ObjectDeleter(
								bucketName, objectName,
								foundObject.getObjectKey(),
								foundObject.getVersionId(),
								size, 
								ctx.getUser().getName(),
								ctx.getUser().getUserId(),
								ctx.getAccount().getName(),
								ctx.getAccount().getAccountNumber());
						Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
					}
					
					if (logData != null) {
						updateLogData(bucketInfo, logData);
						reply.setLogData(logData);
					}
				} else {
					db.rollback();
					throw new AccessDeniedException("Key", objectKey, logData);
				}
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		
		reply.setStatus(HttpResponseStatus.NO_CONTENT);
		reply.setStatusMessage("NO CONTENT");
		db.commit();
		return reply;
	}

	public static InetAddress getBucketIp(String bucket) throws EucalyptusCloudException {
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		try {
			BucketInfo searchBucket = new BucketInfo(bucket);
			db.getUniqueEscape(searchBucket);
			return WalrusProperties.getWalrusAddress();
		} catch (EucalyptusCloudException ex) {
			throw ex;
		} finally {
			db.rollback();
		}
	}

	@Override
	public void fastDeleteObject(DeleteObjectType request) throws EucalyptusCloudException {
		String bucketName = request.getBucket();
		String objectKey = request.getKey();
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfos = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfos);
		if (bucketList.size() > 0) {
			BucketInfo bucketInfo = bucketList.get(0);
			BucketLogData logData = bucketInfo.getLoggingEnabled() ? request.getLogData() : null;
			ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
			searchObjectInfo.setVersionId(WalrusProperties.NULL_VERSION_ID);
			EntityWrapper dbObject = db.recast(ObjectInfo.class);
			List objectInfos = dbObject.queryEscape(searchObjectInfo);
			if (objectInfos.size() > 0) {
				ObjectInfo foundObject = objectInfos.get(0);
				dbObject.delete(foundObject);
				String objectName = foundObject.getObjectName();
				for (GrantInfo grantInfo : foundObject.getGrants()) {
					db.delete(grantInfo);
				}
				Long size = foundObject.getSize();
				try {
					storageManager.deleteObject(bucketName, objectName);
				} catch (IOException ex) {
					LOG.error(ex, ex);
				}
				boolean success = false;
				int retryCount = 0;
				do {
					try {
						success = true;
					} catch (NoSuchBucketException ex) {
						db.rollback();
						throw ex;
					} catch (RollbackException ex) {
						retryCount++;
						LOG.trace("retrying update: " + bucketName);
					} catch (EucalyptusCloudException ex) {
						db.rollback();
						throw ex;
					}
				} while (!success && (retryCount < 5));

			} else {
				db.rollback();
				throw new NoSuchEntityException(objectKey, logData);
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		db.commit();
	}

	@Override
	public void fastDeleteBucket(DeleteBucketType request) throws EucalyptusCloudException {
		String bucketName = request.getBucket();
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo searchBucket = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(searchBucket);

		if (bucketList.size() > 0) {
			BucketInfo bucketFound = bucketList.get(0);
			EntityWrapper dbObject = db.recast(ObjectInfo.class);
			ObjectInfo searchObject = new ObjectInfo();
			searchObject.setBucketName(bucketName);
			searchObject.setDeleted(false);
			List objectInfos = dbObject.queryEscape(searchObject);
			if (objectInfos.size() == 0) {
				db.delete(bucketFound);
				// Actually remove the bucket from the backing store
				try {
					storageManager.deleteBucket(bucketName);
				} catch (IOException ex) {
					// set exception code in reply
					LOG.error(ex);
				}
			} else {
				db.rollback();
				throw new BucketNotEmptyException(bucketName);
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		db.commit();
	}

	/**
	 * Fire creation and possibly a related delete event.
	 * 
	 * If an object (version) is being overwritten then there will not be a corresponding delete event so we fire one prior to the create event.
	 */
		String uploadId = request.getUploadId();
	private void fireObjectCreationEvent(final String bucketName, final String objectKey, final String version, final String userId, final Long size,
			final Long oldSize) {
        // now a no-op, reporting is done in the OSG
	}

	private static void fireObjectUsageEvent(S3ObjectAction actionInfo, String bucketName, String objectKey, String version, String ownerUserId,
			Long sizeInBytes) {
        // now a no-op, reporting is done in the OSG
	}
	
	public InitiateMultipartUploadResponseType initiateMultipartUpload(InitiateMultipartUploadType request) throws EucalyptusCloudException {
		InitiateMultipartUploadResponseType reply = (InitiateMultipartUploadResponseType) request.getReply();
		
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();
		String bucketName = request.getBucket();
		String objectKey = request.getKey();
		
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfo = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfo);
		if (bucketList.size() > 0) {
			BucketInfo bucket = bucketList.get(0);
			
			if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || 
					Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
				
				EntityWrapper dbObject = db.recast(ObjectInfo.class);
				ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
				List objectInfos = dbObject.queryEscape(searchObjectInfo);
				
				if(objectInfos.size() == 1 && objectInfos.get(0).getUploadId() == null) {
					throw new EucalyptusCloudException("A single part upload exists for the same bucket and key, intiate multipart uplaod with a different key for now");
				}
				
				if (Iterables.any(objectInfos,  new Predicate(){

					@Override
					public boolean apply(@Nullable ObjectInfo arg0) {
						return arg0.getPartNumber() != null || arg0.getManifest();
					}
					
				})){
					throw new EucalyptusCloudException("Multipart upload is in progress for the same bucket and key, either abort or complete the upload");
				}
			
			
				// Create a manifest object entity
				String objectName;
				ObjectInfo manifest = new ObjectInfo(bucketName, objectKey);
				manifest.setOwnerId(account.getAccountNumber());
				objectName = UUID.randomUUID().toString();
				manifest.setObjectName(objectName);
				manifest.setUploadId(Crypto.generateAlphanumericId(64, ""));
				manifest.setManifest(Boolean.TRUE);
				manifest.setUploadComplete(Boolean.FALSE);
				manifest.setCleanup(Boolean.FALSE);
				manifest.setSize(0L);
				manifest.setVersionId(UUID.randomUUID().toString().replaceAll("-", ""));
				dbObject.add(manifest);
				
				try {
					dbObject.commit();
				} catch (RollbackException ex) {
					dbObject.rollback();
					LOG.error("Error comitting new object entity to database", ex);
				}
				
				reply.setUploadId(manifest.getUploadId()); 
			} else {
				db.rollback();
				throw new AccessDeniedException("Bucket", bucketName);
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		
		reply.setBucket(bucketName);
		reply.setKey(objectKey);
		return reply;
	}
	
	public UploadPartResponseType uploadPart(UploadPartType request) throws EucalyptusCloudException {
		UploadPartResponseType reply = (UploadPartResponseType) request.getReply();
		
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();
		String bucketName = request.getBucket();
		String objectKey = request.getKey();
		String key = bucketName + "." + objectKey;
		String randomKey = request.getRandomKey();
		Integer partNumber = Integer.parseInt(request.getPartNumber());
		WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();
		Date lastModified = null;
		String md5 = new String();
		Long oldBucketSize = 0L; //TODO compute this correctly later
		
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfo = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfo);
		
		if(bucketList.size() > 0) {
			BucketInfo bucket = bucketList.get(0);
			BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
			long objSize = 0;
			
			try {
				objSize = Long.valueOf(request.getContentLength());
			} catch (NumberFormatException e) {
				LOG.error("Invalid content length " + request.getContentLength());
				// TODO(wenye): should handle this properly.
				objSize = 1L;
			}
			
			if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || 
					Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
				
				if (logData != null) {
					reply.setLogData(logData);
				}
				String objectName = null;
				String versionId = null;
				Long oldObjectSize = 0L;
				ObjectInfo objectInfo = null;
				
				try {
					objectName = UUID.randomUUID().toString();
					ObjectInfo searchManifest = new ObjectInfo(bucketName, objectKey);
					searchManifest.setUploadId(uploadId);
					searchManifest.setManifest(Boolean.TRUE);
					searchManifest.setUploadComplete(Boolean.FALSE);
					searchManifest.setCleanup(Boolean.FALSE);
					
					EntityWrapper dbObject = db.recast(ObjectInfo.class);
					ObjectInfo foundManifest = dbObject.uniqueResultEscape(searchManifest);
					
					if (foundManifest != null) {
						versionId = foundManifest.getVersionId(); 
						objectInfo = new ObjectInfo(bucketName, objectKey);
						objectInfo.setOwnerId(account.getAccountNumber());
						objectInfo.setObjectName(objectName);
						objectInfo.setUploadId(uploadId);
						objectInfo.setPartNumber(partNumber);
						objectInfo.setManifest(Boolean.FALSE);
						objectInfo.setUploadComplete(Boolean.FALSE);
						objectInfo.setCleanup(Boolean.FALSE);
						objectInfo.setVersionId(versionId);
						dbObject.add(objectInfo);
					} else {
						throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
					}
					
					String bucketOwnerId = bucket.getOwnerId();
					dbObject.commit();
				} catch (Exception ex) {
					throw new EucalyptusCloudException(ex);
				}
					
				// writes are unconditional
				WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);
				
				try {
					WalrusDataMessage dataMessage;
					String tempObjectName = objectName;
					MessageDigest digest = null;
					long size = 0;
					FileIO fileIO = null;
					while ((dataMessage = putQueue.take()) != null) {
						if (putQueue.getInterrupted()) {
							if (WalrusDataMessage.isEOF(dataMessage)) {
								WalrusMonitor monitor = messenger.getMonitor(key);
								if (monitor.getLastModified() == null) {
									LOG.trace("Monitor wait: " + key
											+ " random: " + randomKey);
									synchronized (monitor) {
										monitor.wait();
									}
								}
								LOG.trace("Monitor resume: " + key + " random: " + randomKey);
								lastModified = monitor.getLastModified();
								md5 = monitor.getMd5();
								// ok we are done here
								if (fileIO != null) {
									fileIO.finish();
								}
								ObjectDeleter objectDeleter = new ObjectDeleter(bucketName, tempObjectName, null, null,-1L, 
										ctx.getUser().getName(), 
										ctx.getUser().getUserId(), 
										ctx.getAccount().getName(), 
										ctx.getAccount().getAccountNumber());
								Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
								LOG.info("Transfer interrupted: " + key);
								messenger.removeQueue(key, randomKey);
								break;
							}
							continue;
						}
						if (WalrusDataMessage.isStart(dataMessage)) {
							tempObjectName = UUID.randomUUID().toString();
							digest = Digest.MD5.get();
							try {
								fileIO = storageManager.prepareForWrite(bucketName, tempObjectName);
							} catch (Exception ex) {
								messenger.removeQueue(key, randomKey);
								throw new EucalyptusCloudException(ex);
							}
						} else if (WalrusDataMessage.isEOF(dataMessage)) {
							if (digest != null) {
								md5 = Hashes.bytesToHex(digest.digest());
							} else {
								WalrusMonitor monitor = messenger.getMonitor(key);
								md5 = monitor.getMd5();
								lastModified = monitor.getLastModified();
								if (md5 == null) {
									LOG.error("ETag did not match for: " + randomKey + " Computed MD5 is null");
									throw new ContentMismatchException(bucketName + "/" + objectKey);
								}
								break;
							}
							String contentMD5 = request.getContentMD5();
							if (contentMD5 != null) {
								String contentMD5AsHex = Hashes.bytesToHex(Base64.decode(contentMD5));
								if (!contentMD5AsHex.equals(md5)) {
									if (fileIO != null) {
										fileIO.finish();
									}
									cleanupTempObject(ctx, bucketName, tempObjectName);
									messenger.removeQueue(key, randomKey);
									LOG.error("ETag did not match for: " + randomKey + " Expected: " + contentMD5AsHex + " Computed: " + md5);
									throw new ContentMismatchException(bucketName + "/" + objectKey);
								}
							}
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a

    private static void fireObjectUsageEvent(S3ObjectAction actionInfo, String bucketName, String objectKey, String version, String ownerUserId,
                                             Long sizeInBytes) {
Solution content
                }
                    }
                    LOG.error(ex, ex);
                        Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
                    }

                    if (logData != null) {
                        updateLogData(bucketInfo, logData);
                        reply.setLogData(logData);
                    }
                } else {
                    db.rollback();
                    throw new AccessDeniedException("Key", objectKey, logData);
                }
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        reply.setStatus(HttpResponseStatus.NO_CONTENT);
        reply.setStatusMessage("NO CONTENT");
        db.commit();
        return reply;
    }

    public static InetAddress getBucketIp(String bucket) throws EucalyptusCloudException {
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        try {
            BucketInfo searchBucket = new BucketInfo(bucket);
            db.getUniqueEscape(searchBucket);
            return WalrusProperties.getWalrusAddress();
        } catch (EucalyptusCloudException ex) {
            throw ex;
        } finally {
            db.rollback();
        }
    }

    @Override
    public void fastDeleteObject(DeleteObjectType request) throws EucalyptusCloudException {
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfos = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfos);
        if (bucketList.size() > 0) {
            BucketInfo bucketInfo = bucketList.get(0);
            BucketLogData logData = bucketInfo.getLoggingEnabled() ? request.getLogData() : null;
            ObjectInfo searchObjectInfo = new ObjectInfo(bucketName, objectKey);
            searchObjectInfo.setVersionId(WalrusProperties.NULL_VERSION_ID);
            EntityWrapper dbObject = db.recast(ObjectInfo.class);
            List objectInfos = dbObject.queryEscape(searchObjectInfo);
            if (objectInfos.size() > 0) {
                ObjectInfo foundObject = objectInfos.get(0);
                dbObject.delete(foundObject);
                String objectName = foundObject.getObjectName();
                for (GrantInfo grantInfo : foundObject.getGrants()) {
                    db.delete(grantInfo);
                }
                Long size = foundObject.getSize();
                try {
                    storageManager.deleteObject(bucketName, objectName);
                } catch (IOException ex) {
                boolean success = false;
                int retryCount = 0;
                do {
                    try {
                        decrementBucketSize(bucketName, size);
                        success = true;
                    } catch (NoSuchBucketException ex) {
                        db.rollback();
                        throw ex;
                    } catch (RollbackException ex) {
                        retryCount++;
                        LOG.trace("retrying update: " + bucketName);
                    } catch (EucalyptusCloudException ex) {
                        db.rollback();
                        throw ex;
                    }
                } while (!success && (retryCount < 5));

            } else {
                db.rollback();
                throw new NoSuchEntityException(objectKey, logData);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
    }

    @Override
    public void fastDeleteBucket(DeleteBucketType request) throws EucalyptusCloudException {
        String bucketName = request.getBucket();
        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo searchBucket = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(searchBucket);

        if (bucketList.size() > 0) {
            BucketInfo bucketFound = bucketList.get(0);
            EntityWrapper dbObject = db.recast(ObjectInfo.class);
            ObjectInfo searchObject = new ObjectInfo();
            searchObject.setBucketName(bucketName);
            searchObject.setDeleted(false);
            List objectInfos = dbObject.queryEscape(searchObject);
            if (objectInfos.size() == 0) {
                db.delete(bucketFound);
                // Actually remove the bucket from the backing store
                try {
                    storageManager.deleteBucket(bucketName);
                } catch (IOException ex) {
                    // set exception code in reply
                    LOG.error(ex);
                }
            } else {
                db.rollback();
                throw new BucketNotEmptyException(bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        db.commit();
    }

    public InitiateMultipartUploadResponseType initiateMultipartUpload(InitiateMultipartUploadType request) throws EucalyptusCloudException {
        InitiateMultipartUploadResponseType reply = (InitiateMultipartUploadResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);
        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                AccessControlList accessControlList = request.getAccessControlList();
                if (accessControlList == null) {
                    accessControlList = new AccessControlList();
                }

                EntityWrapper dbPart = db.recast(PartInfo.class);
                // Create a manifest object entity
                PartInfo manifest = PartInfo.create(bucketName, objectKey, account);
                manifest.setStorageClass("STANDARD");
                manifest.setContentEncoding(request.getContentEncoding());
                manifest.setContentType(request.getContentType());
                List grantInfos = new ArrayList();
                manifest.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                manifest.setGrants(grantInfos);
                manifest.replaceMetaData(request.getMetaData());
                manifest.setObjectName(null);

                dbPart.add(manifest);
                try {
                    dbPart.commit();
                } catch (RollbackException ex) {
                    dbPart.rollback();
                    LOG.error("Error comitting new object entity to database", ex);
                }

                reply.setUploadId(manifest.getUploadId());
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        reply.setBucket(bucketName);
        reply.setKey(objectKey);
        return reply;
    }

    public UploadPartResponseType uploadPart(UploadPartType request) throws EucalyptusCloudException {
        UploadPartResponseType reply = (UploadPartResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        String key = bucketName + "." + objectKey;
        String randomKey = request.getRandomKey();
        String uploadId = request.getUploadId();
        Integer partNumber = Integer.parseInt(request.getPartNumber());
        WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();
        Date lastModified = null;
        String md5 = new String();
        Long oldBucketSize = 0L; //TODO compute this correctly later

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if(bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            long objSize = 0;

            try {
                objSize = Long.valueOf(request.getContentLength());
            } catch (NumberFormatException e) {
                LOG.error("Invalid content length " + request.getContentLength());
                //TODO: FIXME This should be a MissingContentLengthException
                throw new EucalyptusCloudException("Missing Content-Length");
            }

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                            try {
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                String objectName = null;
                PartInfo partInfo = null;

                try {
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(uploadId);
                    searchManifest.setCleanup(Boolean.FALSE);

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);
                    partInfo =  PartInfo.create(bucketName, objectKey, account);
                    partInfo.setUploadId(uploadId);
                    partInfo.setPartNumber(partNumber);
                    partInfo.setCleanup(Boolean.FALSE);
                    objectName = partInfo.getObjectName();
                    dbPart.add(partInfo);

                    dbPart.commit();
                } catch (Exception ex) {
                    throw new EucalyptusCloudException(ex);
                }

                // writes are unconditional
                WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);

                try {
                    WalrusDataMessage dataMessage;
                    String tempObjectName = objectName;
                    MessageDigest digest = null;
                    long size = 0;
                    FileIO fileIO = null;
                    while ((dataMessage = putQueue.take()) != null) {
                        if (putQueue.getInterrupted()) {
                            if (WalrusDataMessage.isEOF(dataMessage)) {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                if (monitor.getLastModified() == null) {
                                    LOG.trace("Monitor wait: " + key
                                            + " random: " + randomKey);
                                    synchronized (monitor) {
                                        monitor.wait();
                                    }
                                }
                                LOG.trace("Monitor resume: " + key + " random: " + randomKey);
                                lastModified = monitor.getLastModified();
                                md5 = monitor.getMd5();
                                // ok we are done here
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                ObjectDeleter objectDeleter = new ObjectDeleter(bucketName, tempObjectName, null, null, null,-1L,
                                        ctx.getUser().getName(),
                                        ctx.getUser().getUserId(),
                                        ctx.getAccount().getName(),
                                        ctx.getAccount().getAccountNumber());
                                Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
                                LOG.info("Transfer interrupted: " + key);
                                messenger.removeQueue(key, randomKey);
                                break;
                            }
                            continue;
                        }
                        if (WalrusDataMessage.isStart(dataMessage)) {
                            tempObjectName = UUID.randomUUID().toString();
                            digest = Digest.MD5.get();
                                fileIO = storageManager.prepareForWrite(bucketName, tempObjectName);
                            } catch (Exception ex) {
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(ex);
                            }
                        } else if (WalrusDataMessage.isEOF(dataMessage)) {
                            if (digest != null) {
                                md5 = Hashes.bytesToHex(digest.digest());
                            } else {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                md5 = monitor.getMd5();
                                lastModified = monitor.getLastModified();
                                if (md5 == null) {
                                    LOG.error("ETag did not match for: " + randomKey + " Computed MD5 is null");
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                                break;
                            }
                            String contentMD5 = request.getContentMD5();
                            if (contentMD5 != null) {
                                String contentMD5AsHex = Hashes.bytesToHex(Base64.decode(contentMD5));
                                if (!contentMD5AsHex.equals(md5)) {
                                    if (fileIO != null) {
                                        fileIO.finish();
                                    }
                                    cleanupTempObject(ctx, bucketName, tempObjectName);
                                    messenger.removeQueue(key, randomKey);
                                    LOG.error("ETag did not match for: " + randomKey + " Expected: " + contentMD5AsHex + " Computed: " + md5);
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                            }

                            // Fix for EUCA-2275:
                            // Moved up policy and bucket size checks on the temporary object. The temp object is committed (renamed) only after it clears the checks.
                            // If any of the checks fail, temp object is cleaned up and the process errors out. If the PUT request is overwriting an existing object, the object is left untouched.
                            // So the fix ensures proper clean up of temp files (no orphaned files) and does not overwrite existing data when policy or bucket size checks fail

                            if (!ctx.hasAdministrativePrivileges() &&
                                    !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT, ctx.getUser(), oldBucketSize + size)) {
                                // dbObject.rollback();
                                cleanupTempObject(ctx, bucketName, tempObjectName);
                                messenger.removeQueue(key, randomKey);
                                LOG.error("Quota exceeded for Walrus putObject");
                                throw new EntityTooLargeException("Key", objectKey);
                            }
                            // commit object
                            try {
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                storageManager.renameObject(bucketName, tempObjectName, objectName);
                            } catch (IOException ex) {
                                LOG.error(ex);
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(objectKey);
                            }
                            lastModified = new Date();
                            PartInfo searchPart = new PartInfo(bucketName, objectKey);
                            //objectName is guaranteed to be unique
                            searchPart.setObjectName(objectName);
                            searchPart.setPartNumber(partNumber);
                            searchPart.setUploadId(uploadId);
                            EntityWrapper dbPart = EntityWrapper.get(PartInfo.class);
                            PartInfo foundPart = null;
                            try {
                                foundPart = dbPart.getUniqueEscape(searchPart);
                            } catch (EucalyptusCloudException ex) {
                                dbPart.rollback();
                        if(foundParts != null && foundParts.size() > 0) {
                                throw new EucalyptusCloudException("Unable to update part: " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " partNumber: " + partNumber);
                            }
                            foundPart.setEtag(md5);
                            foundPart.setSize(size);
                            foundPart.setLastModified(lastModified);
                            foundPart.setCleanup(false);
                            foundPart.setStorageClass("STANDARD");
                            reply.setSize(size);
                            try {
                                dbPart.commit();
                            } catch (RollbackException ex) {
                                dbPart.rollback();
                                LOG.error(ex, ex);
                            }

                            // restart all interrupted puts
                            WalrusMonitor monitor = messenger.getMonitor(key);
                            synchronized (monitor) {
                                monitor.setLastModified(lastModified);
                                monitor.setMd5(md5);
                                monitor.notifyAll();
                            }
                            // messenger.removeMonitor(key);
                            messenger.clearQueues(key);
                            messenger.removeQueue(key, randomKey);
                            LOG.info("Transfer complete: " + key + " uploadId: " + uploadId + " partNumber: " + partNumber);

                            break;
                        } else {
                            assert (WalrusDataMessage.isData(dataMessage));
                            byte[] data = dataMessage.getPayload();
                            // start writing object (but do not commit yet)
                            try {
                                if (fileIO != null)
                                    fileIO.write(data);
                            } catch (IOException ex) {
                                LOG.error(ex);
                            }
                            // calculate md5 on the fly
                            size += data.length;
                            if (digest != null) {
                                digest.update(data);
                            }
                        }
                    }
                } catch (Exception ex) {
                    LOG.error(ex, ex);
                    db.rollback();
                    messenger.removeQueue(key, randomKey);
                    throw new EucalyptusCloudException("Transfer interrupted: " + key + "." + randomKey);
                }

            } else {
                db.rollback();
                messenger.removeQueue(key, randomKey);
                throw new AccessDeniedException("Bucket", bucketName, logData);
            }
        } else {
            db.rollback();
            messenger.removeQueue(key, randomKey);
            throw new NoSuchBucketException(bucketName);
        }

        reply.setEtag(md5);
        reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
        return reply;
    }

    public CompleteMultipartUploadResponseType completeMultipartUpload(CompleteMultipartUploadType request) throws EucalyptusCloudException {
        CompleteMultipartUploadResponseType reply = (CompleteMultipartUploadResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        List requestParts = request.getParts();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

                    if (foundManifest != null) {
            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                    if (foundManifest != null) {
                        long oldBucketSize = 0L;
                        long oldObjectSize = 0L;
                        //check if we can write to the object if it already exists
                        String versionId = null;
                        if (bucket.isVersioningEnabled()) {
                            versionId = foundManifest.getVersionId();
                        } else {
                            versionId = WalrusProperties.NULL_VERSION_ID;
                            ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
                            searchObject.setVersionId(versionId);
                            EntityWrapper dbObject = db.recast(ObjectInfo.class);
                            try {
                                ObjectInfo foundObject = dbObject.getUniqueEscape(searchObject);
                                if (!foundObject.canWrite(account.getAccountNumber())) {
                                    // Found existing object, but don't have write
                                    // access
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                //check if we can write ACP
                                if(foundManifest.getGrants().size() > 0 && (!foundObject.canWriteACP(account.getAccountNumber()))) {
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                oldObjectSize = foundObject.getSize() == null ? 0L : foundObject.getSize();
                                // Fix for EUCA-2275:
                                // If an existing object is overwritten, the size
                                // difference must be taken into account. Size of the
                                // already existing object was ignored before
                                oldBucketSize = -oldObjectSize;
                            } catch (AccessDeniedException ex) {
                                throw ex;
                            } catch (EucalyptusCloudException ex) {
                                // No existing object found
                            }
                        }

                        // Look for the parts
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        partCriteria = dbPart.createCriteria(PartInfo.class);
                        partCriteria.add(Example.create(searchManifest));
                        partCriteria.add(Restrictions.isNotNull("partNumber"));

                        List foundParts = partCriteria.list();

                        String eTagString = "";
                        long size = 0;
                            if(requestParts != null && requestParts.size() > foundParts.size()) {
                                throw new EucalyptusCloudException("One or more parts has not been uploaded yet. Either upload the part or fix the manifest");
                            } else {
                                // Create a hashmap
                                Map partsMap = new HashMap(foundParts.size());
                                for(PartInfo foundPart : foundParts) {
                                    partsMap.put(foundPart.getPartNumber(), foundPart);
                                }

                                PartInfo lookupPart = null;
                                for(Part requestPart : requestParts){
                                    if((lookupPart = partsMap.get(requestPart.getPartNumber())) != null) {
                                        lookupPart.setCleanup(Boolean.FALSE);
                                        eTagString += lookupPart.getEtag();
                                        size += lookupPart.getSize();
                                        partsMap.remove(lookupPart.getPartNumber());
                                    } else {
                                        //TODO: This needs to be an InvalidPart exception
                                        throw new EucalyptusCloudException("Part not found");
                                    }
                                }
                                MessageDigest digest = Digest.MD5.get();
                                digest.update(eTagString.getBytes());
                                final String eTag = "uuid-" + Hashes.bytesToHex(digest.digest());
                                foundManifest.setEtag(eTag);
                                foundManifest.setCleanup(Boolean.FALSE);


                                if (!ctx.hasAdministrativePrivileges()
                                        && !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT,
                                        ctx.getUser(), oldBucketSize + size)) {
                                    // dbObject.rollback();
                                    LOG.error("Quota exceeded for Walrus putObject");
                                    throw new EntityTooLargeException("Key", objectKey);
                                }

                                boolean success = false;
                                int retryCount = 0;
                                do {
                                    try {
                                        incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
                                        success = true;
                                    } catch (EntityTooLargeException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (NoSuchBucketException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (RollbackException ex) {
                                        retryCount++;
                                        LOG.trace("retrying update: " + bucketName);
                                    } catch (EucalyptusCloudException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    }
                                } while (!success && (retryCount < 5));

                                ObjectInfo objectInfo = new ObjectInfo(bucketName, objectKey);
                                objectInfo.setCleanup(false);
                                objectInfo.setEtag(eTag);
                                objectInfo.setUploadId(foundManifest.getUploadId());
                                objectInfo.setDeleted(false);
                                objectInfo.setSize(size);
                                objectInfo.setLastModified(new Date());
                                objectInfo.setVersionId(versionId);
                                objectInfo.setStorageClass(foundManifest.getStorageClass());
                                objectInfo.setContentDisposition(foundManifest.getContentDisposition());
                                objectInfo.setContentType(foundManifest.getContentType());
                                objectInfo.setLast(true);
                                objectInfo.setDeleted(false);
                                objectInfo.updateGrants(foundManifest);
                                EntityWrapper dbOject = db.recast(ObjectInfo.class);
                                dbOject.add(objectInfo);

                                //cleanup unused parts
                                Set keys = partsMap.keySet();
                                for (Integer key : keys) {
                                    partsMap.get(key).markForCleanup();
                                }

                                db.commit();
                                reply.setEtag(foundManifest.getEtag()); // TODO figure out etag correctly
                                reply.setLocation("Walrus" + foundManifest.getBucketName() + "/" + foundManifest.getObjectKey());
                                reply.setBucket(foundManifest.getBucketName());
                                reply.setKey(foundManifest.getObjectKey());
                                //fire cleanup
                                firePartsCleanupTask(foundManifest.getBucketName(), request.getKey(), request.getUploadId());
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found in the database");
                        }

                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        reply.setLocation(request.getBucket() + '/' + request.getKey());
        reply.setBucket(request.getBucket());
        reply.setKey(request.getKey());
        return reply;
    }

    public AbortMultipartUploadResponseType abortMultipartUpload(AbortMultipartUploadType request) throws EucalyptusCloudException {
        AbortMultipartUploadResponseType reply = (AbortMultipartUploadResponseType) request.getReply();
        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                        // Look for the parts
                        foundManifest.markForCleanup();
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        List foundParts = dbPart.queryEscape(searchPart);
                        if(foundParts != null && foundParts.size() > 0) {
                            for (PartInfo part : foundParts) {
                                part.markForCleanup();
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found for upload: " + request.getUploadId());
                        }
                        db.commit();

                        //fire cleanup
                        firePartsCleanupTask(foundManifest.getBucketName(), foundManifest.getObjectKey(), request.getUploadId());
                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        return reply;
    }


    private void firePartsCleanupTask(final String bucketName, final String objectKey, final String uploadId) {
        try {
            MPU_EXECUTOR.submit(new Runnable() {
                public void run() {
                    try {
                        doPartCleanup(bucketName, objectKey, uploadId);
                    } catch (final Throwable f) {
                        LOG.error("Error during part cleanup for " + bucketName + "/" + objectKey + " uploadId: " + uploadId, f);
                    }
                }
            });
        } catch (final Throwable f) {
            LOG.warn("Error cleaning parts for " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " .", f);
        }
    }

    private void doPartCleanup(String bucketName, String objectKey, String uploadId) {
        //get all parts
        PartInfo searchPart = new PartInfo(bucketName, objectKey);
        searchPart.setCleanup(true);
        searchPart.setUploadId(uploadId);
        List parts;
        EntityTransaction db = Entities.get(PartInfo.class);
        try {
            parts = Entities.query(searchPart);
            if(parts.size() > 0) {
                for (PartInfo part : parts) {
                    if (part.getObjectName() != null) {
                        try {
                            storageManager.deleteObject(bucketName, part.getObjectName());
                        } catch (IOException e) {
                            LOG.error("Unable to delete part on disk: " + e.getMessage());
                        }
                    }
                    LOG.info("Garbage collecting part: " + part.getBucketName() + "/" + part.getObjectName() + " partNumber: " + part.getPartNumber() + " uploadId: " + part.getUploadId());
                    if (part.getGrants() != null) {
                        for (GrantInfo grant : part.getGrants()) {
                            Entities.delete(grant);
                        }
                    }
                    Entities.delete(part);
                }
            }
        } finally {
            db.commit();
        }

    }

}
File
WalrusFSManager.java
Developer's decision
Manual
Kind of conflict
Annotation
Cast expression
Comment
Do statement
If statement
Method declaration
Method invocation
Method signature
Return statement
Throw statement
Try statement
Variable
While statement
Chunk
Conflicting content

	}
            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

<<<<<<< HEAD
                AccessControlList accessControlList = request.getAccessControlList();
                if (accessControlList == null) {
                    accessControlList = new AccessControlList();
                }

                EntityWrapper dbPart = db.recast(PartInfo.class);
                // Create a manifest object entity
                PartInfo manifest = PartInfo.create(bucketName, objectKey, account);
                manifest.setStorageClass("STANDARD");
                manifest.setContentEncoding(request.getContentEncoding());
                manifest.setContentType(request.getContentType());
                List grantInfos = new ArrayList();
                manifest.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                manifest.setGrants(grantInfos);
                manifest.replaceMetaData(request.getMetaData());
                manifest.setObjectName(null);

                dbPart.add(manifest);
                try {
                    dbPart.commit();
                } catch (RollbackException ex) {
                    dbPart.rollback();
                    LOG.error("Error comitting new object entity to database", ex);
                }

                reply.setUploadId(manifest.getUploadId());
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        reply.setBucket(bucketName);
        reply.setKey(objectKey);
        return reply;
    }

    public UploadPartResponseType uploadPart(UploadPartType request) throws EucalyptusCloudException {
        UploadPartResponseType reply = (UploadPartResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        String key = bucketName + "." + objectKey;
        String randomKey = request.getRandomKey();
        String uploadId = request.getUploadId();
        Integer partNumber = Integer.parseInt(request.getPartNumber());
        WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();
        Date lastModified = null;
        String md5 = new String();
        Long oldBucketSize = 0L; //TODO compute this correctly later

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if(bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            long objSize = 0;

            try {
                objSize = Long.valueOf(request.getContentLength());
            } catch (NumberFormatException e) {
                LOG.error("Invalid content length " + request.getContentLength());
                //TODO: FIXME This should be a MissingContentLengthException
                throw new EucalyptusCloudException("Missing Content-Length");
            }

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                String objectName = null;
                PartInfo partInfo = null;

                try {
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(uploadId);
                    searchManifest.setCleanup(Boolean.FALSE);

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);
                    partInfo =  PartInfo.create(bucketName, objectKey, account);
                    partInfo.setUploadId(uploadId);
                    partInfo.setPartNumber(partNumber);
                    partInfo.setCleanup(Boolean.FALSE);
                    objectName = partInfo.getObjectName();
                    dbPart.add(partInfo);

                    dbPart.commit();
                } catch (Exception ex) {
                    throw new EucalyptusCloudException(ex);
                }

                // writes are unconditional
                WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);

                try {
	
                    WalrusDataMessage dataMessage;
                    String tempObjectName = objectName;
                    MessageDigest digest = null;
                    long size = 0;
                    FileIO fileIO = null;
                    while ((dataMessage = putQueue.take()) != null) {
                        if (putQueue.getInterrupted()) {
                            if (WalrusDataMessage.isEOF(dataMessage)) {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                if (monitor.getLastModified() == null) {
                                    LOG.trace("Monitor wait: " + key
                                            + " random: " + randomKey);
                                    synchronized (monitor) {
                                        monitor.wait();
                                    }
                                }
                                LOG.trace("Monitor resume: " + key + " random: " + randomKey);
                                lastModified = monitor.getLastModified();
                                md5 = monitor.getMd5();
                                // ok we are done here
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                ObjectDeleter objectDeleter = new ObjectDeleter(bucketName, tempObjectName, null, null, null,-1L,
                                        ctx.getUser().getName(),
                                        ctx.getUser().getUserId(),
                                        ctx.getAccount().getName(),
                                        ctx.getAccount().getAccountNumber());
                                Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
                                LOG.info("Transfer interrupted: " + key);
                                messenger.removeQueue(key, randomKey);
                                break;
                            }
                            continue;
                        }
                        if (WalrusDataMessage.isStart(dataMessage)) {
                            tempObjectName = UUID.randomUUID().toString();
                            digest = Digest.MD5.get();
                            try {
                                fileIO = storageManager.prepareForWrite(bucketName, tempObjectName);
                            } catch (Exception ex) {
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(ex);
                            }
                        } else if (WalrusDataMessage.isEOF(dataMessage)) {
                            if (digest != null) {
                                md5 = Hashes.bytesToHex(digest.digest());
                            } else {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                md5 = monitor.getMd5();
                                lastModified = monitor.getLastModified();
                                if (md5 == null) {
                                    LOG.error("ETag did not match for: " + randomKey + " Computed MD5 is null");
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                                break;
                            }
                            String contentMD5 = request.getContentMD5();
                            if (contentMD5 != null) {
                                String contentMD5AsHex = Hashes.bytesToHex(Base64.decode(contentMD5));
                                if (!contentMD5AsHex.equals(md5)) {
                                    if (fileIO != null) {
                                        fileIO.finish();
                                    }
                                    cleanupTempObject(ctx, bucketName, tempObjectName);
                                    messenger.removeQueue(key, randomKey);
                                    LOG.error("ETag did not match for: " + randomKey + " Expected: " + contentMD5AsHex + " Computed: " + md5);
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                            }

                            // Fix for EUCA-2275:
                            // Moved up policy and bucket size checks on the temporary object. The temp object is committed (renamed) only after it clears the checks.
                            // If any of the checks fail, temp object is cleaned up and the process errors out. If the PUT request is overwriting an existing object, the object is left untouched.
                            // So the fix ensures proper clean up of temp files (no orphaned files) and does not overwrite existing data when policy or bucket size checks fail

                            if (!ctx.hasAdministrativePrivileges() &&
                                    !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT, ctx.getUser(), oldBucketSize + size)) {
                                // dbObject.rollback();
                                cleanupTempObject(ctx, bucketName, tempObjectName);
                                messenger.removeQueue(key, randomKey);
                                LOG.error("Quota exceeded for Walrus putObject");
                                throw new EntityTooLargeException("Key", objectKey);
                            }
                            // commit object
                            try {
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                storageManager.renameObject(bucketName, tempObjectName, objectName);
                            } catch (IOException ex) {
                                LOG.error(ex);
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(objectKey);
                            }
                            lastModified = new Date();
                            PartInfo searchPart = new PartInfo(bucketName, objectKey);
                            //objectName is guaranteed to be unique
                            searchPart.setObjectName(objectName);
                            searchPart.setPartNumber(partNumber);
                            searchPart.setUploadId(uploadId);
                            EntityWrapper dbPart = EntityWrapper.get(PartInfo.class);
                            PartInfo foundPart = null;
                            try {
                                foundPart = dbPart.getUniqueEscape(searchPart);
                            } catch (EucalyptusCloudException ex) {
                                dbPart.rollback();
                                throw new EucalyptusCloudException("Unable to update part: " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " partNumber: " + partNumber);
                            }
                            foundPart.setEtag(md5);
                            foundPart.setSize(size);
                            foundPart.setLastModified(lastModified);
                            foundPart.setCleanup(false);
                            foundPart.setStorageClass("STANDARD");
                            reply.setSize(size);
                            try {
                                dbPart.commit();
                            } catch (RollbackException ex) {
                                dbPart.rollback();
                                LOG.error(ex, ex);
                            }

                            // restart all interrupted puts
                            WalrusMonitor monitor = messenger.getMonitor(key);
                            synchronized (monitor) {
                                monitor.setLastModified(lastModified);
                                monitor.setMd5(md5);
                                monitor.notifyAll();
                            }
                            // messenger.removeMonitor(key);
                            messenger.clearQueues(key);
                            messenger.removeQueue(key, randomKey);
                            LOG.info("Transfer complete: " + key + " uploadId: " + uploadId + " partNumber: " + partNumber);

							/*try {
								fireObjectCreationEvent(bucketName, objectKey, versionId, ctx.getUser().getUserId(), size, oldObjectSize);
							} catch (Exception ex) {
								LOG.debug("Failed to fire reporting event for walrus PUT object operation", ex);
							}*/

                            break;
                        } else {
                            assert (WalrusDataMessage.isData(dataMessage));
                            byte[] data = dataMessage.getPayload();
                            // start writing object (but do not commit yet)
                            try {
                                if (fileIO != null)
                                    fileIO.write(data);
                            } catch (IOException ex) {
                                LOG.error(ex);
                            }
                            // calculate md5 on the fly
                            size += data.length;
                            if (digest != null) {
                                digest.update(data);
                            }
                        }
                    }
                } catch (Exception ex) {
                    LOG.error(ex, ex);
                    db.rollback();
                    messenger.removeQueue(key, randomKey);
                    throw new EucalyptusCloudException("Transfer interrupted: " + key + "." + randomKey);
                }

            } else {
                db.rollback();
                messenger.removeQueue(key, randomKey);
                throw new AccessDeniedException("Bucket", bucketName, logData);
            }
        } else {
            db.rollback();
            messenger.removeQueue(key, randomKey);
            throw new NoSuchBucketException(bucketName);
        }

        reply.setEtag(md5);
        reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
        return reply;
    }

                                throw ex;
    public CompleteMultipartUploadResponseType completeMultipartUpload(CompleteMultipartUploadType request) throws EucalyptusCloudException {
        CompleteMultipartUploadResponseType reply = (CompleteMultipartUploadResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        List requestParts = request.getParts();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                    if (foundManifest != null) {
                        long oldBucketSize = 0L;
                        long oldObjectSize = 0L;
                        //check if we can write to the object if it already exists
                        String versionId = null;
                        if (bucket.isVersioningEnabled()) {
                            versionId = foundManifest.getVersionId();
                        } else {
}
                            versionId = WalrusProperties.NULL_VERSION_ID;
                            ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
                            searchObject.setVersionId(versionId);
                            EntityWrapper dbObject = db.recast(ObjectInfo.class);
                            try {
                                ObjectInfo foundObject = dbObject.getUniqueEscape(searchObject);
                                if (!foundObject.canWrite(account.getAccountNumber())) {
                                    // Found existing object, but don't have write
                                    // access
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                //check if we can write ACP
                                if(foundManifest.getGrants().size() > 0 && (!foundObject.canWriteACP(account.getAccountNumber()))) {
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                oldObjectSize = foundObject.getSize() == null ? 0L : foundObject.getSize();
                                // Fix for EUCA-2275:
                                // If an existing object is overwritten, the size
                                // difference must be taken into account. Size of the
                                // already existing object was ignored before
                                oldBucketSize = -oldObjectSize;
                            } catch (AccessDeniedException ex) {
                            } catch (EucalyptusCloudException ex) {
                                // No existing object found
                            }
                        }

                        // Look for the parts
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        partCriteria = dbPart.createCriteria(PartInfo.class);
                        partCriteria.add(Example.create(searchManifest));
                        partCriteria.add(Restrictions.isNotNull("partNumber"));

                        List foundParts = partCriteria.list();

                        String eTagString = "";
                        long size = 0;
                        if(foundParts != null && foundParts.size() > 0) {
                            if(requestParts != null && requestParts.size() > foundParts.size()) {
                                throw new EucalyptusCloudException("One or more parts has not been uploaded yet. Either upload the part or fix the manifest");
                            } else {
                                // Create a hashmap
                                Map partsMap = new HashMap(foundParts.size());
                                for(PartInfo foundPart : foundParts) {
                                    partsMap.put(foundPart.getPartNumber(), foundPart);
                                }

                                PartInfo lookupPart = null;
                                for(Part requestPart : requestParts){
                                    if((lookupPart = partsMap.get(requestPart.getPartNumber())) != null) {
                                        lookupPart.setCleanup(Boolean.FALSE);
                                        eTagString += lookupPart.getEtag();
                                        size += lookupPart.getSize();
                                        partsMap.remove(lookupPart.getPartNumber());
                                    } else {
                                        //TODO: This needs to be an InvalidPart exception
                                        throw new EucalyptusCloudException("Part not found");
                                    }
                                }
                                MessageDigest digest = Digest.MD5.get();
                                digest.update(eTagString.getBytes());
                                final String eTag = "uuid-" + Hashes.bytesToHex(digest.digest());
                                foundManifest.setEtag(eTag);
                                foundManifest.setCleanup(Boolean.FALSE);


                                if (!ctx.hasAdministrativePrivileges()
                                        && !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT,
                                        ctx.getUser(), oldBucketSize + size)) {
                                    // dbObject.rollback();
                                    LOG.error("Quota exceeded for Walrus putObject");
                                    throw new EntityTooLargeException("Key", objectKey);
                                }

                                boolean success = false;
                                int retryCount = 0;
                                do {
                                    try {
                                        incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
                                        success = true;
                                    } catch (EntityTooLargeException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (NoSuchBucketException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (RollbackException ex) {
                                        retryCount++;
                                        LOG.trace("retrying update: " + bucketName);
                                    } catch (EucalyptusCloudException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    }
                                } while (!success && (retryCount < 5));
                                ObjectInfo objectInfo = new ObjectInfo(bucketName, objectKey);
                                objectInfo.setCleanup(false);
                                objectInfo.setEtag(eTag);
                                objectInfo.setUploadId(foundManifest.getUploadId());
                                objectInfo.setDeleted(false);
                                objectInfo.setSize(size);
                                objectInfo.setLastModified(new Date());
                                objectInfo.setVersionId(versionId);
                                objectInfo.setStorageClass(foundManifest.getStorageClass());
                                objectInfo.setContentDisposition(foundManifest.getContentDisposition());
                                objectInfo.setContentType(foundManifest.getContentType());
                                objectInfo.setLast(true);
                                objectInfo.setDeleted(false);
                                objectInfo.updateGrants(foundManifest);
                                EntityWrapper dbOject = db.recast(ObjectInfo.class);
                                dbOject.add(objectInfo);

                                //cleanup unused parts
                                Set keys = partsMap.keySet();
                                for (Integer key : keys) {
                                    partsMap.get(key).markForCleanup();
                                }

                                db.commit();
                                reply.setEtag(foundManifest.getEtag()); // TODO figure out etag correctly
                                reply.setLocation("Walrus" + foundManifest.getBucketName() + "/" + foundManifest.getObjectKey());
                                reply.setBucket(foundManifest.getBucketName());
                                reply.setKey(foundManifest.getObjectKey());
                                //fire cleanup
                                firePartsCleanupTask(foundManifest.getBucketName(), request.getKey(), request.getUploadId());
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found in the database");
                        }

                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        reply.setLocation(request.getBucket() + '/' + request.getKey());
        reply.setBucket(request.getBucket());
        reply.setKey(request.getKey());
        return reply;
    }

    public AbortMultipartUploadResponseType abortMultipartUpload(AbortMultipartUploadType request) throws EucalyptusCloudException {
        AbortMultipartUploadResponseType reply = (AbortMultipartUploadResponseType) request.getReply();
        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                    if (foundManifest != null) {
                        // Look for the parts
                        foundManifest.markForCleanup();
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        List foundParts = dbPart.queryEscape(searchPart);
                        if(foundParts != null && foundParts.size() > 0) {
                            for (PartInfo part : foundParts) {
                                part.markForCleanup();
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found for upload: " + request.getUploadId());
                        }
                        db.commit();

                        //fire cleanup
                        firePartsCleanupTask(foundManifest.getBucketName(), foundManifest.getObjectKey(), request.getUploadId());
                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        return reply;
    }

    private void firePartsCleanupTask(final String bucketName, final String objectKey, final String uploadId) {
        try {
            MPU_EXECUTOR.submit(new Runnable() {
                public void run() {
                    try {
                        doPartCleanup(bucketName, objectKey, uploadId);
                    } catch (final Throwable f) {
                        LOG.error("Error during part cleanup for " + bucketName + "/" + objectKey + " uploadId: " + uploadId, f);
                    }
                }
            });
        } catch (final Throwable f) {
            LOG.warn("Error cleaning parts for " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " .", f);
        }
    }

    private void doPartCleanup(String bucketName, String objectKey, String uploadId) {
        //get all parts
        PartInfo searchPart = new PartInfo(bucketName, objectKey);
        searchPart.setCleanup(true);
        searchPart.setUploadId(uploadId);
        List parts;
        EntityTransaction db = Entities.get(PartInfo.class);
        try {
            parts = Entities.query(searchPart);
            if(parts.size() > 0) {
                for (PartInfo part : parts) {
                    if (part.getObjectName() != null) {
                        try {
                            storageManager.deleteObject(bucketName, part.getObjectName());
                        } catch (IOException e) {
                            LOG.error("Unable to delete part on disk: " + e.getMessage());
                        }
                    }
                    LOG.info("Garbage collecting part: " + part.getBucketName() + "/" + part.getObjectName() + " partNumber: " + part.getPartNumber() + " uploadId: " + part.getUploadId());
                    if (part.getGrants() != null) {
                        for (GrantInfo grant : part.getGrants()) {
                            Entities.delete(grant);
                        }
                    }
                    Entities.delete(part);
                }
            }
        } finally {
            db.commit();
        }

    }
=======
                            /* the reporting is now done in the OSG
							try {
								fireObjectCreationEvent(bucketName, objectKey, versionId, ctx.getUser().getUserId(), size, oldObjectSize);
							} catch (Exception ex) {
								LOG.debug("Failed to fire reporting event for walrus PUT object operation", ex);
							}
                            */
							break;
						} else {
							assert (WalrusDataMessage.isData(dataMessage));
							byte[] data = dataMessage.getPayload();
							// start writing object (but do not commit yet)
							try {
								if (fileIO != null)
									fileIO.write(data);
							} catch (IOException ex) {
								LOG.error(ex);
							}
							// calculate md5 on the fly
							size += data.length;
							if (digest != null) {
								digest.update(data);
							}
						}
					}
				} catch (Exception ex) {
					LOG.error(ex, ex);
					db.rollback();
					messenger.removeQueue(key, randomKey);
					throw new EucalyptusCloudException("Transfer interrupted: " + key + "." + randomKey);
				}
				
			} else {
				db.rollback();
				messenger.removeQueue(key, randomKey);
				throw new AccessDeniedException("Bucket", bucketName, logData);
			}
		} else {
			db.rollback();
			messenger.removeQueue(key, randomKey);
			throw new NoSuchBucketException(bucketName);
		}
		
		reply.setEtag(md5); // TODO figure out etag correctly
		reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
		return reply;
	public CompleteMultipartUploadResponseType completeMultipartUpload(CompleteMultipartUploadType request) throws EucalyptusCloudException {
		CompleteMultipartUploadResponseType reply = (CompleteMultipartUploadResponseType) request.getReply();
		
		Context ctx = Contexts.lookup();
		Account account = ctx.getAccount();
		String bucketName = request.getBucket();
		String objectKey = request.getKey();
		List requestParts = request.getParts();
		
		EntityWrapper db = EntityWrapper.get(BucketInfo.class);
		BucketInfo bucketInfo = new BucketInfo(bucketName);
		List bucketList = db.queryEscape(bucketInfo);
		
		if (bucketList.size() > 0) {
			BucketInfo bucket = bucketList.get(0);
			
			if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() || 
					Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {
				
				try {
					// Find the manifest entity
					ObjectInfo searchManifest = new ObjectInfo(bucketName, objectKey);
					searchManifest.setUploadId(request.getUploadId());
					searchManifest.setManifest(Boolean.TRUE);
					
					EntityWrapper dbObject = db.recast(ObjectInfo.class);
					ObjectInfo foundManifest = dbObject.uniqueResultEscape(searchManifest);
					
					if (foundManifest != null) {
						// Look for the parts
						ObjectInfo searchPart = new ObjectInfo(bucketName, objectKey);
						searchPart.setUploadId(request.getUploadId());
						searchPart.setManifest(Boolean.FALSE);

						List foundParts = dbObject.queryEscape(searchPart);
						
						if(foundParts != null && foundParts.size() > 0) {
							if(requestParts != null && requestParts.size() > foundParts.size()) {
								throw new EucalyptusCloudException("One or more parts has not been uploaded yet. Either upload the part or fix the manifest");
							} else {
								// Create a hashmap 
								Map partsMap = new HashMap(foundParts.size());
								for(ObjectInfo foundPart : foundParts) {
									foundPart.setCleanup(Boolean.TRUE);
									foundPart.setUploadComplete(Boolean.TRUE);
									partsMap.put(foundPart.getPartNumber(), foundPart);
								}
								
								ObjectInfo lookupPart = null;
								for(Part requestPart : requestParts){
									if((lookupPart = partsMap.get(requestPart.getPartNumber())) != null) {
										lookupPart.setCleanup(Boolean.FALSE);
									} else {
										throw new EucalyptusCloudException("Part not found");
									}
								}
								foundManifest.setCleanup(Boolean.FALSE);
								foundManifest.setUploadComplete(Boolean.TRUE);
								db.commit();
							}
						} else {
							throw new EucalyptusCloudException("No parts found in the database");
						}
						
					} else {
						throw new EucalyptusCloudException("Multipart upload ID is invalid.");
					}
				} catch (Exception ex) {
					db.rollback();
					throw new EucalyptusCloudException(ex);
				}
			} else {
				db.rollback();
				throw new AccessDeniedException("Bucket", bucketName);
			}
		} else {
			db.rollback();
			throw new NoSuchBucketException(bucketName);
		}
		
		reply.setLocation(request.getBucket() + '/' + request.getKey());
		reply.setBucket(request.getBucket());
		reply.setKey(request.getKey());
		reply.setEtag(Crypto.generateAlphanumericId(16, "")); // TODO figure out etag correctly
		return reply;
	}
	
	public AbortMultipartUploadResponseType abortMultipartUpload(AbortMultipartUploadType request) {
		AbortMultipartUploadResponseType reply = (AbortMultipartUploadResponseType) request.getReply();
		return reply;
	}
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
Solution content
            } else {
            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                AccessControlList accessControlList = request.getAccessControlList();
                if (accessControlList == null) {
                    accessControlList = new AccessControlList();
                }

                EntityWrapper dbPart = db.recast(PartInfo.class);
                // Create a manifest object entity
                PartInfo manifest = PartInfo.create(bucketName, objectKey, account);
                manifest.setStorageClass("STANDARD");
                manifest.setContentEncoding(request.getContentEncoding());
                manifest.setContentType(request.getContentType());
                List grantInfos = new ArrayList();
                manifest.addGrants(account.getAccountNumber(), bucket.getOwnerId(), grantInfos, accessControlList);
                manifest.setGrants(grantInfos);
                manifest.replaceMetaData(request.getMetaData());
                manifest.setObjectName(null);
                dbPart.add(manifest);
                try {
                    dbPart.commit();
                } catch (RollbackException ex) {
                    dbPart.rollback();
                    LOG.error("Error comitting new object entity to database", ex);
                }

                reply.setUploadId(manifest.getUploadId());
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        reply.setBucket(bucketName);
        reply.setKey(objectKey);
        return reply;
    }

    public UploadPartResponseType uploadPart(UploadPartType request) throws EucalyptusCloudException {
        UploadPartResponseType reply = (UploadPartResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        String key = bucketName + "." + objectKey;
        String randomKey = request.getRandomKey();
        String uploadId = request.getUploadId();
        Integer partNumber = Integer.parseInt(request.getPartNumber());
        WalrusDataMessenger messenger = WalrusRESTBinding.getWriteMessenger();
        Date lastModified = null;
        String md5 = new String();
        Long oldBucketSize = 0L; //TODO compute this correctly later

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if(bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);
            BucketLogData logData = bucket.getLoggingEnabled() ? request.getLogData() : null;
            long objSize = 0;

            try {
                objSize = Long.valueOf(request.getContentLength());
            } catch (NumberFormatException e) {
                LOG.error("Invalid content length " + request.getContentLength());
                //TODO: FIXME This should be a MissingContentLengthException
                throw new EucalyptusCloudException("Missing Content-Length");
            }

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                String objectName = null;
                PartInfo partInfo = null;

                try {
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(uploadId);
                    searchManifest.setCleanup(Boolean.FALSE);

                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);
                    partInfo =  PartInfo.create(bucketName, objectKey, account);
                    partInfo.setUploadId(uploadId);
                    partInfo.setPartNumber(partNumber);
                    partInfo.setCleanup(Boolean.FALSE);
                    objectName = partInfo.getObjectName();
                    dbPart.add(partInfo);

                    dbPart.commit();
                } catch (Exception ex) {
                    throw new EucalyptusCloudException(ex);
                }

                // writes are unconditional
                WalrusDataQueue putQueue = messenger.getQueue(key, randomKey);

                try {
                    WalrusDataMessage dataMessage;
                    String tempObjectName = objectName;
                    MessageDigest digest = null;
                    long size = 0;
                    FileIO fileIO = null;
                    while ((dataMessage = putQueue.take()) != null) {
                        if (putQueue.getInterrupted()) {
                            if (WalrusDataMessage.isEOF(dataMessage)) {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                if (monitor.getLastModified() == null) {
                                    LOG.trace("Monitor wait: " + key
                                            + " random: " + randomKey);
                                    synchronized (monitor) {
                                        monitor.wait();
                                    }
                                }
                                LOG.trace("Monitor resume: " + key + " random: " + randomKey);
                                lastModified = monitor.getLastModified();
                                md5 = monitor.getMd5();
                                // ok we are done here
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                ObjectDeleter objectDeleter = new ObjectDeleter(bucketName, tempObjectName, null, null, null,-1L,
                                        ctx.getUser().getName(),
                                        ctx.getUser().getUserId(),
                                        ctx.getAccount().getName(),
                                        ctx.getAccount().getAccountNumber());
                                Threads.lookup(Walrus.class, WalrusFSManager.ObjectDeleter.class).limitTo(10).submit(objectDeleter);
                                LOG.info("Transfer interrupted: " + key);
                                messenger.removeQueue(key, randomKey);
                                break;
                            }
                            continue;
                        }
                        if (WalrusDataMessage.isStart(dataMessage)) {
                            tempObjectName = UUID.randomUUID().toString();
                            digest = Digest.MD5.get();
                            try {
                                fileIO = storageManager.prepareForWrite(bucketName, tempObjectName);
                            } catch (Exception ex) {
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(ex);
                            }
                        } else if (WalrusDataMessage.isEOF(dataMessage)) {
                            if (digest != null) {
                                md5 = Hashes.bytesToHex(digest.digest());
                            } else {
                                WalrusMonitor monitor = messenger.getMonitor(key);
                                md5 = monitor.getMd5();
                                lastModified = monitor.getLastModified();
                                if (md5 == null) {
                                    LOG.error("ETag did not match for: " + randomKey + " Computed MD5 is null");
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                                break;
                            }
                            String contentMD5 = request.getContentMD5();
                            if (contentMD5 != null) {
                                String contentMD5AsHex = Hashes.bytesToHex(Base64.decode(contentMD5));
                                if (!contentMD5AsHex.equals(md5)) {
                                    if (fileIO != null) {
                                        fileIO.finish();
                                    }
                                    cleanupTempObject(ctx, bucketName, tempObjectName);
                                    messenger.removeQueue(key, randomKey);
                                    LOG.error("ETag did not match for: " + randomKey + " Expected: " + contentMD5AsHex + " Computed: " + md5);
                                    throw new ContentMismatchException(bucketName + "/" + objectKey);
                                }
                            }

                            // Fix for EUCA-2275:
                            // Moved up policy and bucket size checks on the temporary object. The temp object is committed (renamed) only after it clears the checks.
                            // If any of the checks fail, temp object is cleaned up and the process errors out. If the PUT request is overwriting an existing object, the object is left untouched.
                            // So the fix ensures proper clean up of temp files (no orphaned files) and does not overwrite existing data when policy or bucket size checks fail

                            if (!ctx.hasAdministrativePrivileges() &&
                                    !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT, ctx.getUser(), oldBucketSize + size)) {
                                // dbObject.rollback();
                                cleanupTempObject(ctx, bucketName, tempObjectName);
                                messenger.removeQueue(key, randomKey);
                                LOG.error("Quota exceeded for Walrus putObject");
                                throw new EntityTooLargeException("Key", objectKey);
                            }
                            // commit object
                            try {
                                if (fileIO != null) {
                                    fileIO.finish();
                                }
                                storageManager.renameObject(bucketName, tempObjectName, objectName);
                            } catch (IOException ex) {
                                LOG.error(ex);
                                messenger.removeQueue(key, randomKey);
                                throw new EucalyptusCloudException(objectKey);
                            }
                            lastModified = new Date();
                            PartInfo searchPart = new PartInfo(bucketName, objectKey);
                            //objectName is guaranteed to be unique
                            searchPart.setObjectName(objectName);
                            searchPart.setPartNumber(partNumber);
                            searchPart.setUploadId(uploadId);
                            EntityWrapper dbPart = EntityWrapper.get(PartInfo.class);
                            PartInfo foundPart = null;
                            try {
                                foundPart = dbPart.getUniqueEscape(searchPart);
                            } catch (EucalyptusCloudException ex) {
                                dbPart.rollback();
                                throw new EucalyptusCloudException("Unable to update part: " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " partNumber: " + partNumber);
                            }
                            foundPart.setEtag(md5);
                            foundPart.setSize(size);
                            foundPart.setLastModified(lastModified);
                            foundPart.setCleanup(false);
                            foundPart.setStorageClass("STANDARD");
                            reply.setSize(size);
                            try {

                                dbPart.commit();
                            } catch (RollbackException ex) {
                                dbPart.rollback();
                                LOG.error(ex, ex);
                            }

                            // restart all interrupted puts
                            WalrusMonitor monitor = messenger.getMonitor(key);
                            synchronized (monitor) {
                                monitor.setLastModified(lastModified);
                                monitor.setMd5(md5);
                                monitor.notifyAll();
                            }
                            // messenger.removeMonitor(key);
                            messenger.clearQueues(key);
                            messenger.removeQueue(key, randomKey);
                            LOG.info("Transfer complete: " + key + " uploadId: " + uploadId + " partNumber: " + partNumber);

                            break;
                        } else {
                            assert (WalrusDataMessage.isData(dataMessage));
                            byte[] data = dataMessage.getPayload();
                            // start writing object (but do not commit yet)
                            try {
                                if (fileIO != null)
                                    fileIO.write(data);
                            } catch (IOException ex) {
                                LOG.error(ex);
                            }
                            // calculate md5 on the fly
                            size += data.length;
                            if (digest != null) {
                                digest.update(data);
                            }
                        }
                    }
                } catch (Exception ex) {
                    LOG.error(ex, ex);
                    db.rollback();
                    messenger.removeQueue(key, randomKey);
                    throw new EucalyptusCloudException("Transfer interrupted: " + key + "." + randomKey);
                }

            } else {
                db.rollback();
                messenger.removeQueue(key, randomKey);
                throw new AccessDeniedException("Bucket", bucketName, logData);
            }
        } else {
            db.rollback();
            messenger.removeQueue(key, randomKey);
            throw new NoSuchBucketException(bucketName);
        }

        reply.setEtag(md5);
        reply.setLastModified(DateUtils.format(lastModified.getTime(), DateUtils.RFC822_DATETIME_PATTERN));
        return reply;
    }

    public CompleteMultipartUploadResponseType completeMultipartUpload(CompleteMultipartUploadType request) throws EucalyptusCloudException {
        CompleteMultipartUploadResponseType reply = (CompleteMultipartUploadResponseType) request.getReply();

        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();
        List requestParts = request.getParts();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                    if (foundManifest != null) {
                        long oldBucketSize = 0L;
                        long oldObjectSize = 0L;
                        //check if we can write to the object if it already exists
                        String versionId = null;
                        if (bucket.isVersioningEnabled()) {
                            versionId = foundManifest.getVersionId();
                        } else {
                            versionId = WalrusProperties.NULL_VERSION_ID;
                            ObjectInfo searchObject = new ObjectInfo(bucketName, objectKey);
                            searchObject.setVersionId(versionId);
                            EntityWrapper dbObject = db.recast(ObjectInfo.class);
                            try {
                                ObjectInfo foundObject = dbObject.getUniqueEscape(searchObject);
                                if (!foundObject.canWrite(account.getAccountNumber())) {
                                    // Found existing object, but don't have write
                                    // access
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                //check if we can write ACP
                                if(foundManifest.getGrants().size() > 0 && (!foundObject.canWriteACP(account.getAccountNumber()))) {
                                    db.rollback();
                                    throw new AccessDeniedException("Key", objectKey);
                                }
                                oldObjectSize = foundObject.getSize() == null ? 0L : foundObject.getSize();
                                // Fix for EUCA-2275:
                                // If an existing object is overwritten, the size
                                // difference must be taken into account. Size of the
                                // already existing object was ignored before
                                oldBucketSize = -oldObjectSize;
                            } catch (AccessDeniedException ex) {
                                throw ex;
                            } catch (EucalyptusCloudException ex) {
                                // No existing object found
                            }
                        }

                        // Look for the parts
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        partCriteria = dbPart.createCriteria(PartInfo.class);
                        partCriteria.add(Example.create(searchManifest));
                        partCriteria.add(Restrictions.isNotNull("partNumber"));

                        List foundParts = partCriteria.list();

                        String eTagString = "";
                        long size = 0;
                        if(foundParts != null && foundParts.size() > 0) {
                            if(requestParts != null && requestParts.size() > foundParts.size()) {
                                throw new EucalyptusCloudException("One or more parts has not been uploaded yet. Either upload the part or fix the manifest");
                            } else {
                                // Create a hashmap
                                Map partsMap = new HashMap(foundParts.size());
                                for(PartInfo foundPart : foundParts) {
                                    partsMap.put(foundPart.getPartNumber(), foundPart);
                                }

                                PartInfo lookupPart = null;
                                for(Part requestPart : requestParts){
                                    if((lookupPart = partsMap.get(requestPart.getPartNumber())) != null) {
                                        lookupPart.setCleanup(Boolean.FALSE);
                                        eTagString += lookupPart.getEtag();
                                        size += lookupPart.getSize();
                                        partsMap.remove(lookupPart.getPartNumber());
                                    } else {
                                        //TODO: This needs to be an InvalidPart exception
                                        throw new EucalyptusCloudException("Part not found");
                                    }
                                }
                                MessageDigest digest = Digest.MD5.get();
                                digest.update(eTagString.getBytes());
                                final String eTag = "uuid-" + Hashes.bytesToHex(digest.digest());
                                foundManifest.setEtag(eTag);
                                foundManifest.setCleanup(Boolean.FALSE);


                                if (!ctx.hasAdministrativePrivileges()
                                        && !Permissions.canAllocate(PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_OBJECT, bucketName, PolicySpec.S3_PUTOBJECT,
                                        ctx.getUser(), oldBucketSize + size)) {
                                    // dbObject.rollback();
                                    LOG.error("Quota exceeded for Walrus putObject");
                                    throw new EntityTooLargeException("Key", objectKey);
                                }

                                boolean success = false;
                                int retryCount = 0;
                                do {
                                    try {
                                        incrementBucketSize(bucketName, objectKey, oldBucketSize, size);
                                        success = true;
                                    } catch (EntityTooLargeException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (NoSuchBucketException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    } catch (RollbackException ex) {
                                        retryCount++;
                                        LOG.trace("retrying update: " + bucketName);
                                    } catch (EucalyptusCloudException ex) {
                                        // dbObject.rollback();
                                        throw ex;
                                    }
                                } while (!success && (retryCount < 5));

                                ObjectInfo objectInfo = new ObjectInfo(bucketName, objectKey);
                                objectInfo.setCleanup(false);
                                objectInfo.setEtag(eTag);
                                objectInfo.setUploadId(foundManifest.getUploadId());
                                objectInfo.setDeleted(false);
                                objectInfo.setSize(size);
                                objectInfo.setLastModified(new Date());
                                objectInfo.setVersionId(versionId);
                                objectInfo.setStorageClass(foundManifest.getStorageClass());
                                objectInfo.setContentDisposition(foundManifest.getContentDisposition());
                                objectInfo.setContentType(foundManifest.getContentType());
                                objectInfo.setLast(true);
                                objectInfo.setDeleted(false);
                                objectInfo.updateGrants(foundManifest);
                                EntityWrapper dbOject = db.recast(ObjectInfo.class);
                                dbOject.add(objectInfo);

                                //cleanup unused parts
                                Set keys = partsMap.keySet();
                                for (Integer key : keys) {
                                    partsMap.get(key).markForCleanup();
                                }
                                db.commit();
                                reply.setEtag(foundManifest.getEtag()); // TODO figure out etag correctly
                                reply.setLocation("Walrus" + foundManifest.getBucketName() + "/" + foundManifest.getObjectKey());
                                reply.setBucket(foundManifest.getBucketName());
                                reply.setKey(foundManifest.getObjectKey());
                                //fire cleanup
                                firePartsCleanupTask(foundManifest.getBucketName(), request.getKey(), request.getUploadId());
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found in the database");
                        }

                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }
        reply.setLocation(request.getBucket() + '/' + request.getKey());
        reply.setBucket(request.getBucket());
        reply.setKey(request.getKey());
        return reply;
    }

    public AbortMultipartUploadResponseType abortMultipartUpload(AbortMultipartUploadType request) throws EucalyptusCloudException {
        AbortMultipartUploadResponseType reply = (AbortMultipartUploadResponseType) request.getReply();
        Context ctx = Contexts.lookup();
        Account account = ctx.getAccount();
        String bucketName = request.getBucket();
        String objectKey = request.getKey();

        EntityWrapper db = EntityWrapper.get(BucketInfo.class);
        BucketInfo bucketInfo = new BucketInfo(bucketName);
        List bucketList = db.queryEscape(bucketInfo);

        if (bucketList.size() > 0) {
            BucketInfo bucket = bucketList.get(0);

            if(ctx.hasAdministrativePrivileges() || (bucket.canWrite(account.getAccountNumber()) && (bucket.isGlobalWrite() ||
                    Lookups.checkPrivilege(PolicySpec.S3_PUTOBJECT, PolicySpec.VENDOR_S3, PolicySpec.S3_RESOURCE_BUCKET, bucketName, null)))) {

                try {
                    // Find the manifest entity

                    EntityWrapper dbPart = db.recast(PartInfo.class);
                    PartInfo searchManifest = new PartInfo(bucketName, objectKey);
                    searchManifest.setUploadId(request.getUploadId());
                    searchManifest.setCleanup(Boolean.FALSE);

                    Criteria partCriteria = dbPart.createCriteria(PartInfo.class);
                    partCriteria.add(Example.create(searchManifest));
                    partCriteria.add(Restrictions.isNull("partNumber"));

                    List found = partCriteria.list();
                    if (found.size() == 0) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multipart upload ID is invalid. Intitiate a multipart upload request before uploading the parts");
                    }
                    if (found.size() > 1) {
                        db.rollback();
                        throw new EucalyptusCloudException("Multiple manifests found for same uploadId");
                    }

                    PartInfo foundManifest = found.get(0);

                    if (foundManifest != null) {
                        // Look for the parts
                        foundManifest.markForCleanup();
                        PartInfo searchPart = new PartInfo(bucketName, objectKey);
                        searchPart.setUploadId(request.getUploadId());

                        List foundParts = dbPart.queryEscape(searchPart);
                        if(foundParts != null && foundParts.size() > 0) {
                            for (PartInfo part : foundParts) {
                                part.markForCleanup();
                            }
                        } else {
                            throw new EucalyptusCloudException("No parts found for upload: " + request.getUploadId());
                        }
                        db.commit();

                        //fire cleanup
                        firePartsCleanupTask(foundManifest.getBucketName(), foundManifest.getObjectKey(), request.getUploadId());
                    } else {
                        throw new EucalyptusCloudException("Multipart upload ID is invalid.");
                    }
                } catch (Exception ex) {
                    db.rollback();
                    throw new EucalyptusCloudException(ex);
                }
            } else {
                db.rollback();
                throw new AccessDeniedException("Bucket", bucketName);
            }
        } else {
            db.rollback();
            throw new NoSuchBucketException(bucketName);
        }

        return reply;
    }


    private void firePartsCleanupTask(final String bucketName, final String objectKey, final String uploadId) {
        try {
            MPU_EXECUTOR.submit(new Runnable() {
                public void run() {
                    try {
                        doPartCleanup(bucketName, objectKey, uploadId);
                    } catch (final Throwable f) {
                        LOG.error("Error during part cleanup for " + bucketName + "/" + objectKey + " uploadId: " + uploadId, f);
                    }
                }
            });
        } catch (final Throwable f) {
            LOG.warn("Error cleaning parts for " + bucketName + "/" + objectKey + " uploadId: " + uploadId + " .", f);
        }
    }

    private void doPartCleanup(String bucketName, String objectKey, String uploadId) {
        //get all parts
        PartInfo searchPart = new PartInfo(bucketName, objectKey);
        searchPart.setCleanup(true);
        searchPart.setUploadId(uploadId);
        List parts;
        EntityTransaction db = Entities.get(PartInfo.class);
        try {
            parts = Entities.query(searchPart);
            if(parts.size() > 0) {
                for (PartInfo part : parts) {
                    if (part.getObjectName() != null) {
                        try {
                            storageManager.deleteObject(bucketName, part.getObjectName());
                        } catch (IOException e) {
                            LOG.error("Unable to delete part on disk: " + e.getMessage());
                        }
                    }
                    LOG.info("Garbage collecting part: " + part.getBucketName() + "/" + part.getObjectName() + " partNumber: " + part.getPartNumber() + " uploadId: " + part.getUploadId());
                    if (part.getGrants() != null) {
                        for (GrantInfo grant : part.getGrants()) {
                            Entities.delete(grant);
                        }
                    }
                    Entities.delete(part);
                }
            }
        } finally {
            db.commit();
        }

    }

}
File
WalrusFSManager.java
Developer's decision
Combination
Kind of conflict
Assert statement
Break statement
Catch clause
Comment
If statement
Method declaration
Method invocation
Return statement
Throw statement
Try statement
Variable
Chunk
Conflicting content
	}

	private void setRequiredParams(final GroovyObject msg, Context context) throws Exception {
<<<<<<< HEAD
		User user = context.getUser( );
		if ( user != null && !user.equals( Principals.nobodyUser( ) ) ) {
			try {
				AccessKey accessKey = null;
				final Set queryIdCreds = context.getSubject( ).getPublicCredentials( QueryIdCredential.class );
				if ( !queryIdCreds.isEmpty( ) ) {
					try {
						accessKey = AccessKeys.lookupAccessKey( Iterables.getOnlyElement( queryIdCreds ).getQueryId( ),
								context.getHttpRequest( ).getHeader( WalrusProperties.X_AMZ_SECURITY_TOKEN ) );
					} catch ( final AuthException e ) {
						throw new EucalyptusCloudException( "Error finding access key", e );
					}
				}
			} catch ( Exception ex ) {
				LOG.error( ex, ex );
				msg.setProperty( "accessKeyID", Accounts.getFirstActiveAccessKeyId( user ) );
			}
		}
=======
>>>>>>> 2b88afc1831d36dcdd53595f60c738380252791a
		msg.setProperty("timeStamp", new Date());
	}
Solution content
	}

	private void setRequiredParams(final GroovyObject msg, Context context) throws Exception {
		msg.setProperty("timeStamp", new Date());
	}
File
WalrusRESTBinding.java
Developer's decision
Version 2
Kind of conflict
If statement
Method invocation
Variable