This is an automated email from the ASF dual-hosted git repository.

ivandika3 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new c0c3241ff57 HDDS-16115. Reject invalid lifecycle rule Status values 
(#10980)
c0c3241ff57 is described below

commit c0c3241ff57c7981658c8bb1c6e3c97fd3f97b05
Author: Shuo Huang <[email protected]>
AuthorDate: Mon Aug 17 11:59:42 2026 +0800

    HDDS-16115. Reject invalid lifecycle rule Status values (#10980)
---
 .../s3/endpoint/S3LifecycleConfiguration.java      | 12 ++++++++--
 .../endpoint/TestS3LifecycleConfigurationPut.java  | 28 +++++++++++++++++++++-
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3LifecycleConfiguration.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3LifecycleConfiguration.java
index de1de9616a7..ec9ada89a9f 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3LifecycleConfiguration.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3LifecycleConfiguration.java
@@ -25,6 +25,7 @@
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.ozone.client.OzoneBucket;
 import org.apache.hadoop.ozone.client.OzoneLifecycleConfiguration;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
@@ -44,6 +45,9 @@
 @XmlRootElement(name = "LifecycleConfiguration",
     namespace = "http://s3.amazonaws.com/doc/2006-03-01/";)
 public class S3LifecycleConfiguration {
+  private static final String STATUS_ENABLED = "Enabled";
+  private static final String STATUS_DISABLED = "Disabled";
+
   @XmlElement(name = "Rule")
   private List<Rule> rules = new ArrayList<>();
 
@@ -312,13 +316,17 @@ public OmLifecycleConfiguration 
toOmLifecycleConfiguration(OzoneBucket ozoneBuck
    * @return OmLCRule internal rule representation
    */
   private OmLCRule convertToOmRule(Rule rule) throws OMException, OS3Exception 
{
-    if (rule.getStatus() == null || rule.getStatus().isEmpty()) {
+    String status = rule.getStatus();
+    if (StringUtils.isEmpty(status)) {
       throw S3ErrorTable.newError(S3ErrorTable.MALFORMED_XML,
           "The Status element is required in LifecycleConfiguration");
     }
+    if (!STATUS_ENABLED.equals(status) && !STATUS_DISABLED.equals(status)) {
+      throw S3ErrorTable.newError(S3ErrorTable.MALFORMED_XML);
+    }
 
     OmLCRule.Builder builder = new OmLCRule.Builder()
-        .setEnabled("Enabled".equals(rule.getStatus()))
+        .setEnabled(STATUS_ENABLED.equals(status))
         .setId(rule.getId())
         .setPrefix(rule.getPrefix());
 
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationPut.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationPut.java
index 818df7f5e97..d76ff51b66b 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationPut.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationPut.java
@@ -56,6 +56,8 @@
 import org.apache.hadoop.ozone.s3.util.S3Consts;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.mockito.Mockito;
 
 /**
@@ -137,6 +139,16 @@ public void testPutLifecycleConfigurationWithoutStatus() 
throws Exception {
     }
   }
 
+  @ParameterizedTest
+  @ValueSource(strings = {"enabled", "disabled", "invalid"})
+  public void testPutLifecycleConfigurationWithInvalidStatus(String status)
+      throws Exception {
+    OS3Exception ex = assertThrows(OS3Exception.class,
+        () -> bucketEndpoint.put("bucket1", withStatus(status)));
+    assertEquals(HTTP_BAD_REQUEST, ex.getHttpCode());
+    assertEquals(MALFORMED_XML.getCode(), ex.getCode());
+  }
+
   private void testInvalidLifecycleConfiguration(Supplier<InputStream> 
inputStream,
       int expectedHttpCode, String expectedErrorCode) throws Exception {
     try {
@@ -170,7 +182,8 @@ public void testPutInvalidExpirationDateLCC() throws 
Exception {
 
   @Test
   public void testPutValidLifecycleConfiguration() throws Exception {
-    assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", 
onePrefix()).getStatus());
+    assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", 
withStatus("Enabled")).getStatus());
+    assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", 
withStatus("Disabled")).getStatus());
     assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", 
emptyPrefix()).getStatus());
     assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", oneTag()).getStatus());
     assertEquals(HTTP_OK, bucketEndpoint.put("bucket1", 
twoTagsInAndOperator()).getStatus());
@@ -304,6 +317,19 @@ private static InputStream withoutStatus() {
     return new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
   }
 
+  private static InputStream withStatus(String status) {
+    String xml =
+        "<LifecycleConfiguration 
xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\";>" +
+            "<Rule>" +
+            "<ID>remove logs after 30 days</ID>" +
+            "<Prefix>prefix/</Prefix>" +
+            "<Status>" + status + "</Status>" +
+            "<Expiration><Days>30</Days></Expiration>" +
+            "</Rule>" +
+            "</LifecycleConfiguration>";
+    return new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
+  }
+
   private static InputStream withoutFilter() {
     String xml =
             "<LifecycleConfiguration 
xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\";>" +


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to