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 de1de9616a74..ec9ada89a9f1 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 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 818df7f5e976..d76ff51b66bb 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, 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 = + "" + + "" + + "remove logs after 30 days" + + "prefix/" + + "" + status + "" + + "30" + + "" + + ""; + return new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)); + } + private static InputStream withoutFilter() { String xml = "" +