-
Notifications
You must be signed in to change notification settings - Fork 587
HDDS-10527. Rewrite key atomically #6385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
5fe2ff7
aa3bd32
9799ba5
5040d2b
6f45e67
0635134
c151122
908f9cd
3c9c0e2
17b5ff1
0fe12c5
ae4044c
7bb59e9
8890ed8
a360d45
3f3a49d
736740a
525685c
112e2e1
bcd1a28
4e6a97c
247620a
c6bc7e7
b91a051
9dc6d31
80e1802
bb7b74f
a87e092
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,11 +70,19 @@ public class OzoneKey { | |
| * Constructs OzoneKey from OmKeyInfo. | ||
| * | ||
| */ | ||
adoroszlai marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * The object and update ID of an existing key. These will be null | ||
| * if the key is not yet created on OM and read from OM. | ||
errose28 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| private final Long objectID; | ||
| private final Long updateID; | ||
|
||
|
|
||
| @SuppressWarnings("parameternumber") | ||
| public OzoneKey(String volumeName, String bucketName, | ||
| String keyName, long size, long creationTime, | ||
| long modificationTime, ReplicationConfig replicationConfig, | ||
| boolean isFile) { | ||
| boolean isFile, Long objectID, Long updateID) { | ||
adoroszlai marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| this.volumeName = volumeName; | ||
| this.bucketName = bucketName; | ||
| this.name = keyName; | ||
|
|
@@ -83,15 +91,17 @@ public OzoneKey(String volumeName, String bucketName, | |
| this.modificationTime = Instant.ofEpochMilli(modificationTime); | ||
| this.replicationConfig = replicationConfig; | ||
| this.isFile = isFile; | ||
| this.objectID = objectID; | ||
| this.updateID = updateID; | ||
| } | ||
|
|
||
| @SuppressWarnings("parameternumber") | ||
| public OzoneKey(String volumeName, String bucketName, | ||
| String keyName, long size, long creationTime, | ||
| long modificationTime, ReplicationConfig replicationConfig, | ||
| Map<String, String> metadata, boolean isFile) { | ||
| Map<String, String> metadata, boolean isFile, Long objectID, Long updateID) { | ||
| this(volumeName, bucketName, keyName, size, creationTime, | ||
| modificationTime, replicationConfig, isFile); | ||
| modificationTime, replicationConfig, isFile, objectID, updateID); | ||
| this.metadata.putAll(metadata); | ||
| } | ||
|
|
||
|
|
@@ -179,6 +189,16 @@ public ReplicationConfig getReplicationConfig() { | |
| return replicationConfig; | ||
| } | ||
|
|
||
| @JsonIgnore | ||
| public Long getObjectID() { | ||
errose28 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return objectID; | ||
| } | ||
|
|
||
| @JsonIgnore | ||
| public Long getUpdateID() { | ||
| return updateID; | ||
| } | ||
|
|
||
| /** | ||
| * Returns indicator if key is a file. | ||
| * @return file | ||
|
|
@@ -191,7 +211,7 @@ public static OzoneKey fromKeyInfo(OmKeyInfo keyInfo) { | |
| return new OzoneKey(keyInfo.getVolumeName(), keyInfo.getBucketName(), | ||
| keyInfo.getKeyName(), keyInfo.getDataSize(), keyInfo.getCreationTime(), | ||
| keyInfo.getModificationTime(), keyInfo.getReplicationConfig(), | ||
| keyInfo.getMetadata(), keyInfo.isFile()); | ||
| keyInfo.getMetadata(), keyInfo.isFile(), keyInfo.getObjectID(), keyInfo.getUpdateID()); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1378,26 +1378,7 @@ public OzoneOutputStream createKey( | |
| ReplicationConfig replicationConfig, | ||
| Map<String, String> metadata) | ||
| throws IOException { | ||
| verifyVolumeName(volumeName); | ||
| verifyBucketName(bucketName); | ||
| if (checkKeyNameEnabled) { | ||
| HddsClientUtils.verifyKeyName(keyName); | ||
| } | ||
| HddsClientUtils.checkNotNull(keyName); | ||
| if (omVersion | ||
| .compareTo(OzoneManagerVersion.ERASURE_CODED_STORAGE_SUPPORT) < 0) { | ||
| if (replicationConfig != null && | ||
| replicationConfig.getReplicationType() | ||
| == HddsProtos.ReplicationType.EC) { | ||
| throw new IOException("Can not set the replication of the key to" | ||
| + " Erasure Coded replication, as OzoneManager does not support" | ||
| + " Erasure Coded replication."); | ||
| } | ||
| } | ||
|
|
||
| if (replicationConfig != null) { | ||
| replicationConfigValidator.validate(replicationConfig); | ||
| } | ||
| createKeyPreChecks(volumeName, bucketName, keyName, replicationConfig); | ||
|
|
||
| OmKeyArgs.Builder builder = new OmKeyArgs.Builder() | ||
| .setVolumeName(volumeName) | ||
|
|
@@ -1420,6 +1401,70 @@ public OzoneOutputStream createKey( | |
| return createOutputStream(openKey); | ||
| } | ||
|
|
||
| @Override | ||
| public OzoneOutputStream overWriteKey(OzoneKeyDetails keyToOverwrite, ReplicationConfig replicationConfig) | ||
| throws IOException { | ||
| if (keyToOverwrite == null) { | ||
| throw new IllegalArgumentException("KeyToOverwrite cannot be null"); | ||
| } | ||
| if (keyToOverwrite.getObjectID() == null) { | ||
| throw new IllegalArgumentException("KeyToOverwrite ObjectID cannot be null"); | ||
| } | ||
| if (keyToOverwrite.getUpdateID() == null) { | ||
| throw new IllegalArgumentException("KeyToOverwrite UpdateID cannot be null"); | ||
| } | ||
| createKeyPreChecks(keyToOverwrite.getVolumeName(), keyToOverwrite.getBucketName(), | ||
| keyToOverwrite.getName(), replicationConfig); | ||
|
|
||
| OmKeyArgs.Builder builder = new OmKeyArgs.Builder() | ||
| .setVolumeName(keyToOverwrite.getVolumeName()) | ||
| .setBucketName(keyToOverwrite.getBucketName()) | ||
| .setKeyName(keyToOverwrite.getName()) | ||
| .setDataSize(keyToOverwrite.getDataSize()) | ||
| .setReplicationConfig(replicationConfig) | ||
| .addAllMetadataGdpr(keyToOverwrite.getMetadata()) | ||
| // TODO - if we are effectively cloning a key, probably the ACLs should | ||
| // be copied over server side. I am not too sure how this works. | ||
| .setAcls(getAclList()) | ||
|
||
| .setLatestVersionLocation(getLatestVersionLocation) | ||
| .setOverwriteObjectID(keyToOverwrite.getObjectID()) | ||
| .setOverwriteUpdateID(keyToOverwrite.getUpdateID()); | ||
|
|
||
| OpenKeySession openKey = ozoneManagerClient.openKey(builder.build()); | ||
| // For bucket with layout OBJECT_STORE, when create an empty file (size=0), | ||
| // OM will set DataSize to OzoneConfigKeys#OZONE_SCM_BLOCK_SIZE, | ||
| // which will cause S3G's atomic write length check to fail, | ||
| // so reset size to 0 here. | ||
| if (isS3GRequest.get() && keyToOverwrite.getDataSize() == 0) { | ||
| openKey.getKeyInfo().setDataSize(0); | ||
| } | ||
| return createOutputStream(openKey); | ||
| } | ||
|
|
||
| private void createKeyPreChecks(String volumeName, String bucketName, String keyName, | ||
| ReplicationConfig replicationConfig) throws IOException { | ||
| verifyVolumeName(volumeName); | ||
| verifyBucketName(bucketName); | ||
| if (checkKeyNameEnabled) { | ||
| HddsClientUtils.verifyKeyName(keyName); | ||
| } | ||
| HddsClientUtils.checkNotNull(keyName); | ||
| if (omVersion | ||
| .compareTo(OzoneManagerVersion.ERASURE_CODED_STORAGE_SUPPORT) < 0) { | ||
| if (replicationConfig != null && | ||
| replicationConfig.getReplicationType() | ||
| == HddsProtos.ReplicationType.EC) { | ||
| throw new IOException("Can not set the replication of the key to" | ||
| + " Erasure Coded replication, as OzoneManager does not support" | ||
| + " Erasure Coded replication."); | ||
| } | ||
| } | ||
|
|
||
| if (replicationConfig != null) { | ||
| replicationConfigValidator.validate(replicationConfig); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public OzoneDataStreamOutput createStreamKey( | ||
| String volumeName, String bucketName, String keyName, long size, | ||
|
|
@@ -1643,7 +1688,9 @@ public List<OzoneKey> listKeys(String volumeName, String bucketName, | |
| key.getCreationTime(), | ||
| key.getModificationTime(), | ||
| key.getReplicationConfig(), | ||
| key.isFile())) | ||
| key.isFile(), | ||
| null, | ||
| null)) | ||
errose28 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| .collect(Collectors.toList()); | ||
| } else { | ||
| List<OmKeyInfo> keys = ozoneManagerClient.listKeys( | ||
|
|
@@ -1656,7 +1703,9 @@ public List<OzoneKey> listKeys(String volumeName, String bucketName, | |
| key.getCreationTime(), | ||
| key.getModificationTime(), | ||
| key.getReplicationConfig(), | ||
| key.isFile())) | ||
| key.isFile(), | ||
| key.getObjectID(), | ||
| key.getUpdateID())) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
|
|
@@ -1707,7 +1756,8 @@ private OzoneKeyDetails getOzoneKeyDetails(OmKeyInfo keyInfo) { | |
| keyInfo.getModificationTime(), ozoneKeyLocations, | ||
| keyInfo.getReplicationConfig(), keyInfo.getMetadata(), | ||
| keyInfo.getFileEncryptionInfo(), | ||
| () -> getInputStreamWithRetryFunction(keyInfo), keyInfo.isFile()); | ||
| () -> getInputStreamWithRetryFunction(keyInfo), keyInfo.isFile(), | ||
| keyInfo.getObjectID(), keyInfo.getUpdateID()); | ||
| } | ||
|
|
||
| @Override | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.