diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/util/UUIDv7.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/util/UUIDv7.java new file mode 100644 index 000000000000..2a5f8f84b6db --- /dev/null +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/util/UUIDv7.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.util; + +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.UUID; + +/** + * Utility class for generating UUIDv7. + * https://antonz.org/uuidv7/ + */ +public final class UUIDv7 { + private static final ThreadLocal GENERATOR = ThreadLocal.withInitial(SecureRandom::new); + + // Private constructor to prevent instantiation + private UUIDv7() { + } + + public static UUID randomUUID() { + byte[] value = randomBytes(); + ByteBuffer buf = ByteBuffer.wrap(value); + long high = buf.getLong(); + long low = buf.getLong(); + return new UUID(high, low); + } + + public static byte[] randomBytes() { + // random bytes + byte[] value = new byte[16]; + GENERATOR.get().nextBytes(value); + + // current timestamp in ms + ByteBuffer timestamp = ByteBuffer.allocate(Long.BYTES); + timestamp.putLong(System.currentTimeMillis()); + + // timestamp + System.arraycopy(timestamp.array(), 2, value, 0, 6); + + // version and variant + value[6] = (byte) ((value[6] & 0x0F) | 0x70); + value[8] = (byte) ((value[8] & 0x3F) | 0x80); + + return value; + } +} diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java index 9d9bc72eb235..17b62367db35 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java @@ -673,13 +673,10 @@ public void testListMultipartUploads() { uploadIds.add(uploadId1); String uploadId2 = initiateMultipartUpload(bucketName, multipartKey1, null, null, null); uploadIds.add(uploadId2); - // TODO: Currently, Ozone sorts based on uploadId instead of MPU init time within the same key. - // Remove this sorting step once HDDS-11532 has been implemented - Collections.sort(uploadIds); + String uploadId3 = initiateMultipartUpload(bucketName, multipartKey2, null, null, null); uploadIds.add(uploadId3); - // TODO: Add test for max uploads threshold and marker once HDDS-11530 has been implemented ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName); MultipartUploadListing result = s3Client.listMultipartUploads(listMultipartUploadsRequest); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/util/OMMultipartUploadUtils.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/util/OMMultipartUploadUtils.java index 3c42d50b2bf7..9bee8b144036 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/util/OMMultipartUploadUtils.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/util/OMMultipartUploadUtils.java @@ -20,12 +20,12 @@ import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX; import java.io.IOException; -import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.hdds.utils.UniqueId; import org.apache.hadoop.ozone.om.OMMetadataManager; import org.apache.hadoop.ozone.om.helpers.BucketLayout; import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; +import org.apache.hadoop.ozone.util.UUIDv7; /** * Utility class related to OM Multipart Upload. @@ -41,7 +41,7 @@ private OMMultipartUploadUtils() { * @return multipart upload ID */ public static String getMultipartUploadId() { - return UUID.randomUUID() + "-" + UniqueId.next(); + return UUIDv7.randomUUID() + "-" + UniqueId.next(); } /**