Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,16 @@ public void deleteKey(String key) throws IOException {
proxy.deleteKey(volumeName, name, key);
}

/**
* Truncates key in the bucket.
* @param key Name of the key to be truncated.
* @param newLength New length of the key after truncate.
* @throws IOException
*/
public void truncateKey(String key, long newLength) throws IOException {
proxy.truncateKey(volumeName, name, key, newLength);
}

/**
* Deletes the given list of keys from the bucket.
* @param keyList List of the key name to be deleted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,17 @@ OzoneInputStream getKey(String volumeName, String bucketName, String keyName)
void deleteKey(String volumeName, String bucketName, String keyName)
throws IOException;

/**
* Truncates an existing key.
* @param volumeName Name of the Volume
* @param bucketName Name of the Bucket
* @param keyName Name of the Key
* @param newLength New length of the key after truncate.
* @throws IOException
*/
void truncateKey(String volumeName, String bucketName, String keyName,
long newLength) throws IOException;

/**
* Deletes keys through the list.
* @param volumeName Name of the Volume
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,22 @@ public void deleteKey(
ozoneManagerClient.deleteKey(keyArgs);
}

@Override
public void truncateKey(
String volumeName, String bucketName, String keyName, long newLength)
throws IOException {
verifyVolumeName(volumeName);
verifyBucketName(bucketName);
Preconditions.checkNotNull(keyName);
OmKeyArgs keyArgs = new OmKeyArgs.Builder()
.setVolumeName(volumeName)
.setBucketName(bucketName)
.setKeyName(keyName)
.setNewLength(newLength)
.build();
ozoneManagerClient.truncateKey(keyArgs);
}

@Override
public void deleteKeys(
String volumeName, String bucketName, List<String> keyNameList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ public static boolean isReadOnly(
case PurgeKeys:
case RecoverTrash:
case DeleteOpenKeys:
case TruncateKey:
return false;
default:
LOG.error("CmdType {} is not categorized as readOnly or not.", cmdType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum OMAction implements AuditAction {
DELETE_VOLUME,
DELETE_BUCKET,
DELETE_KEY,
TRUNCATE_KEY,
RENAME_KEY,
RENAME_KEYS,
SET_OWNER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ public enum ResultCodes {

PARTIAL_RENAME,

QUOTA_EXCEEDED
QUOTA_EXCEEDED,

INVALID_TRUNCATE_NEW_LENGTH

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ public final class OmKeyArgs implements Auditable {
private boolean refreshPipeline;
private boolean sortDatanodesInPipeline;
private List<OzoneAcl> acls;
private long newLength;

@SuppressWarnings("parameternumber")
private OmKeyArgs(String volumeName, String bucketName, String keyName,
long dataSize, ReplicationType type, ReplicationFactor factor,
List<OmKeyLocationInfo> locationInfoList, boolean isMultipart,
String uploadID, int partNumber,
Map<String, String> metadataMap, boolean refreshPipeline,
List<OzoneAcl> acls, boolean sortDatanode) {
List<OzoneAcl> acls, boolean sortDatanode, long newLength) {
this.volumeName = volumeName;
this.bucketName = bucketName;
this.keyName = keyName;
Expand All @@ -70,6 +71,7 @@ private OmKeyArgs(String volumeName, String bucketName, String keyName,
this.refreshPipeline = refreshPipeline;
this.acls = acls;
this.sortDatanodesInPipeline = sortDatanode;
this.newLength = newLength;
}

public boolean getIsMultipartKey() {
Expand Down Expand Up @@ -140,6 +142,10 @@ public boolean getSortDatanodes() {
return sortDatanodesInPipeline;
}

public long getNewLength() {
return newLength;
}

@Override
public Map<String, String> toAuditMap() {
Map<String, String> auditMap = new LinkedHashMap<>();
Expand Down Expand Up @@ -198,6 +204,7 @@ public static class Builder {
private boolean refreshPipeline;
private boolean sortDatanodesInPipeline;
private List<OzoneAcl> acls;
private long newLength;

public Builder setVolumeName(String volume) {
this.volumeName = volume;
Expand Down Expand Up @@ -274,11 +281,16 @@ public Builder setSortDatanodesInPipeline(boolean sort) {
return this;
}

public Builder setNewLength(long len) {
this.newLength = len;
return this;
}

public OmKeyArgs build() {
return new OmKeyArgs(volumeName, bucketName, keyName, dataSize, type,
factor, locationInfoList, isMultipartKey, multipartUploadID,
multipartUploadPartNumber, metadata, refreshPipeline, acls,
sortDatanodesInPipeline);
sortDatanodesInPipeline, newLength);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ OmKeyLocationInfo allocateBlock(OmKeyArgs args, long clientID,
*/
void deleteKeys(OmDeleteKeys deleteKeys) throws IOException;

/**
* Truncates an existing key.
*
* @param args the args of the key.
* @throws IOException
*/
void truncateKey(OmKeyArgs args) throws IOException;

/**
* Deletes an existing empty bucket from volume.
* @param volume - Name of the volume.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetAclResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetBucketPropertyRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetVolumePropertyRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TruncateKeyRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo;
import org.apache.hadoop.ozone.protocolPB.OMPBHelper;
Expand Down Expand Up @@ -775,6 +776,30 @@ public void deleteKeys(OmDeleteKeys deleteKeys) throws IOException {

}

/**
* Truncates an existing key.
*
* @param args the args of the key.
* @throws IOException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you please finish this java doc, there are many same issue in this PR.

For example if there is an I/O error while performing the call

*/
@Override
public void truncateKey(OmKeyArgs args) throws IOException {
TruncateKeyRequest.Builder req = TruncateKeyRequest.newBuilder();
KeyArgs keyArgs = KeyArgs.newBuilder()
.setVolumeName(args.getVolumeName())
.setBucketName(args.getBucketName())
.setKeyName(args.getKeyName())
.setNewLength(args.getNewLength())
.build();
req.setKeyArgs(keyArgs);

OMRequest omRequest = createOMRequest(Type.TruncateKey)
.setTruncateKeyRequest(req)
.build();

handleError(submitRequest(omRequest));
}

/**
* Deletes an existing empty bucket from volume.
* @param volume - Name of the volume.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SCM_BLOCK_SIZE;
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SCM_BLOCK_SIZE_DEFAULT;
import static org.apache.hadoop.ozone.OzoneConsts.GB;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_TRUNCATE_NEW_LENGTH;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NO_SUCH_MULTIPART_UPLOAD_ERROR;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_NOT_FOUND;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.PARTIAL_RENAME;
Expand Down Expand Up @@ -3499,4 +3500,34 @@ public void testDeletedKeyForGDPR() throws Exception {
deletedKeyMetadata.containsKey(OzoneConsts.GDPR_ALGORITHM));
}
}

@Test
public void testTruncateKey()
throws Exception {
String volumeName = UUID.randomUUID().toString();
String bucketName = UUID.randomUUID().toString();
String keyName = UUID.randomUUID().toString();
String value = "sample value";
store.createVolume(volumeName);
OzoneVolume volume = store.getVolume(volumeName);
volume.createBucket(bucketName);
OzoneBucket bucket = volume.getBucket(bucketName);
createTestKey(bucket, keyName, value);

String leftValue = "sample";
bucket.truncateKey(keyName, leftValue.length());
OzoneKey key = bucket.getKey(keyName);
Assert.assertEquals(keyName, key.getName());
OzoneInputStream is = bucket.readKey(keyName);
byte[] newValue = new byte[value.getBytes().length];
Assert.assertEquals(is.read(newValue), leftValue.length());
Assert.assertEquals(leftValue,
(new String(newValue)).substring(0, leftValue.length()));

OzoneTestUtils.expectOmException(INVALID_TRUNCATE_NEW_LENGTH,
() -> bucket.truncateKey(keyName, value.length()));

OzoneTestUtils.expectOmException(KEY_NOT_FOUND,
() -> bucket.truncateKey("nonExistedKey", value.length()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum Type {
DeleteKeys = 38;
RenameKeys = 39;
DeleteOpenKeys = 40;
TruncateKey = 41;

InitiateMultiPartUpload = 45;
CommitMultiPartUpload = 46;
Expand Down Expand Up @@ -130,6 +131,7 @@ message OMRequest {
optional DeleteKeysRequest deleteKeysRequest = 38;
optional RenameKeysRequest renameKeysRequest = 39;
optional DeleteOpenKeysRequest deleteOpenKeysRequest = 40;
optional TruncateKeyRequest truncateKeyRequest = 41;

optional MultipartInfoInitiateRequest initiateMultiPartUploadRequest = 45;
optional MultipartCommitUploadPartRequest commitMultiPartUploadRequest = 46;
Expand Down Expand Up @@ -203,6 +205,7 @@ message OMResponse {
optional AllocateBlockResponse allocateBlockResponse = 37;
optional DeleteKeysResponse deleteKeysResponse = 38;
optional RenameKeysResponse renameKeysResponse = 39;
optional TruncateKeyResponse truncateKeyResponse = 40;

optional MultipartInfoInitiateResponse initiateMultiPartUploadResponse = 45;
optional MultipartCommitUploadPartResponse commitMultiPartUploadResponse = 46;
Expand Down Expand Up @@ -318,6 +321,8 @@ enum Status {

QUOTA_EXCEEDED = 66;

INVALID_TRUNCATE_NEW_LENGTH = 67;

}

/**
Expand Down Expand Up @@ -725,6 +730,7 @@ message KeyArgs {

// This will be set by leader OM in HA and update the original request.
optional FileEncryptionInfoProto fileEncryptionInfo = 15;
optional uint64 newLength = 16;
}

message KeyLocation {
Expand Down Expand Up @@ -891,6 +897,14 @@ message DeleteKeyRequest {
required KeyArgs keyArgs = 1;
}

message TruncateKeyRequest {
required KeyArgs keyArgs = 1;
}

message TruncateKeyResponse {

}

message DeleteKeysRequest {
optional DeleteKeyArgs deleteKeys = 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class OMMetrics {
private @Metric MutableCounterLong numKeyLookup;
private @Metric MutableCounterLong numKeyRenames;
private @Metric MutableCounterLong numKeyDeletes;
private @Metric MutableCounterLong numKeyTruncates;
private @Metric MutableCounterLong numBucketLists;
private @Metric MutableCounterLong numKeyLists;
private @Metric MutableCounterLong numTrashKeyLists;
Expand Down Expand Up @@ -91,6 +92,7 @@ public class OMMetrics {
private @Metric MutableCounterLong numKeyLookupFails;
private @Metric MutableCounterLong numKeyRenameFails;
private @Metric MutableCounterLong numKeyDeleteFails;
private @Metric MutableCounterLong numKeyTruncateFails;
private @Metric MutableCounterLong numBucketListFails;
private @Metric MutableCounterLong numKeyListFails;
private @Metric MutableCounterLong numTrashKeyListFails;
Expand Down Expand Up @@ -491,6 +493,15 @@ public void incNumKeyDeletes() {
numKeyDeletes.incr();
}

public void incNumKeyTruncates() {
numKeyOps.incr();
numKeyTruncates.incr();
}

public void incNumKeyTruncateFails() {
numKeyTruncateFails.incr();
}

public void incNumKeyCommits() {
numKeyOps.incr();
numKeyCommits.incr();
Expand Down Expand Up @@ -710,11 +721,21 @@ public long getNumKeyDeletes() {
return numKeyDeletes.value();
}

@VisibleForTesting
public long getNumKeyTruncates() {
return numKeyTruncates.value();
}

@VisibleForTesting
public long getNumKeyDeletesFails() {
return numKeyDeleteFails.value();
}

@VisibleForTesting
public long getNumKeyTruncatesFails() {
return numKeyTruncateFails.value();
}

@VisibleForTesting
public long getNumBucketListFails() {
return numBucketListFails.value();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,18 @@ public void deleteKey(OmKeyArgs args) throws IOException {
}
}

/**
* Truncates an existing key.
*
* @param args - attributes of the key.
* @throws IOException
*/
@Override
public void truncateKey(OmKeyArgs args) throws IOException {
throw new UnsupportedOperationException("OzoneManager does not require " +
"this to be implemented. As truncate requests use a new approach");
}

/**
* Deletes an existing key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.apache.hadoop.ozone.om.request.key.OMKeyRenameRequest;
import org.apache.hadoop.ozone.om.request.key.OMKeysRenameRequest;
import org.apache.hadoop.ozone.om.request.key.OMTrashRecoverRequest;
import org.apache.hadoop.ozone.om.request.key.OMKeyTruncateRequest;
import org.apache.hadoop.ozone.om.request.key.acl.OMKeyAddAclRequest;
import org.apache.hadoop.ozone.om.request.key.acl.OMKeyRemoveAclRequest;
import org.apache.hadoop.ozone.om.request.key.acl.OMKeySetAclRequest;
Expand Down Expand Up @@ -160,6 +161,8 @@ public static OMClientRequest createClientRequest(OMRequest omRequest) {
return new S3GetSecretRequest(omRequest);
case RecoverTrash:
return new OMTrashRecoverRequest(omRequest);
case TruncateKey:
return new OMKeyTruncateRequest(omRequest);
default:
throw new IllegalStateException("Unrecognized write command " +
"type request" + cmdType);
Expand Down
Loading