This is an automated email from the ASF dual-hosted git repository.
sammichen pushed a commit to branch HDDS-8342
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-8342 by this push:
new f81b36593c HDDS-12781. Implement LifecycleConfiguration proto (#8276)
f81b36593c is described below
commit f81b36593cc6a20dfdfc54f33a77894b7dd18f09
Author: XiChen <[email protected]>
AuthorDate: Fri May 9 14:16:17 2025 +0800
HDDS-12781. Implement LifecycleConfiguration proto (#8276)
Co-contributed by Mohanad Elsafty ([email protected])
---
.../apache/hadoop/ozone/om/helpers/OmLCAction.java | 6 ++
.../hadoop/ozone/om/helpers/OmLCExpiration.java | 33 +++++++++
.../apache/hadoop/ozone/om/helpers/OmLCFilter.java | 49 ++++++++++++-
.../apache/hadoop/ozone/om/helpers/OmLCRule.java | 55 +++++++++++++++
.../ozone/om/helpers/OmLifecycleConfiguration.java | 81 ++++++++++++++++++++--
.../om/helpers/OmLifecycleRuleAndOperator.java | 36 ++++++++++
.../ozone/om/helpers/TestOmLCExpiration.java | 28 ++++++++
.../hadoop/ozone/om/helpers/TestOmLCFilter.java | 44 ++++++++++++
.../hadoop/ozone/om/helpers/TestOmLCRule.java | 51 ++++++++++++++
.../om/helpers/TestOmLifeCycleConfiguration.java | 32 +++++++++
.../om/helpers/TestOmLifecycleRuleAndOperator.java | 37 ++++++++++
.../src/main/proto/OmClientProtocol.proto | 71 +++++++++++++++++++
.../apache/hadoop/ozone/om/OMMetadataManager.java | 3 +
.../hadoop/ozone/om/OmMetadataManagerImpl.java | 23 +++++-
.../hadoop/ozone/om/codec/OMDBDefinition.java | 11 ++-
15 files changed, 549 insertions(+), 11 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCAction.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCAction.java
index d466a11218..427bf87908 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCAction.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCAction.java
@@ -18,6 +18,7 @@
package org.apache.hadoop.ozone.om.helpers;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleAction;
/**
* Interface that encapsulates lifecycle rule actions.
@@ -26,6 +27,11 @@
*/
public interface OmLCAction {
+ /**
+ * Creates LifecycleAction protobuf from OmLCAction.
+ */
+ LifecycleAction getProtobuf();
+
/**
* Validates the action configuration.
* Each concrete action implementation must define its own validation logic.
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCExpiration.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCExpiration.java
index 06d39acd2d..bb4564d7c5 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCExpiration.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCExpiration.java
@@ -17,6 +17,7 @@
package org.apache.hadoop.ozone.om.helpers;
+import jakarta.annotation.Nullable;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@@ -24,6 +25,8 @@
import net.jcip.annotations.Immutable;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleAction;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleExpiration;
/**
* A class that encapsulates lifecycle rule expiration action.
@@ -44,10 +47,12 @@ private OmLCExpiration(Builder builder) {
this.date = builder.date;
}
+ @Nullable
public Integer getDays() {
return days;
}
+ @Nullable
public String getDate() {
return date;
}
@@ -124,6 +129,34 @@ private void validateExpirationDate(String expirationDate)
throws OMException {
}
}
+ @Override
+ public LifecycleAction getProtobuf() {
+ LifecycleExpiration.Builder builder = LifecycleExpiration.newBuilder();
+
+ if (date != null) {
+ builder.setDate(date);
+ }
+ if (days != null) {
+ builder.setDays(days);
+ }
+
+ return LifecycleAction.newBuilder().setExpiration(builder).build();
+ }
+
+ public static OmLCExpiration getFromProtobuf(
+ LifecycleExpiration lifecycleExpiration) throws OMException {
+ OmLCExpiration.Builder builder = new Builder();
+
+ if (lifecycleExpiration.hasDate()) {
+ builder.setDate(lifecycleExpiration.getDate());
+ }
+ if (lifecycleExpiration.hasDays()) {
+ builder.setDays(lifecycleExpiration.getDays());
+ }
+
+ return builder.build();
+ }
+
@Override
public String toString() {
return "OmLCExpiration{" +
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCFilter.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCFilter.java
index 8ef0df6bbd..4c68849cb4 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCFilter.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCFilter.java
@@ -22,6 +22,8 @@
import net.jcip.annotations.Immutable;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleFilter;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleFilterTag;
/**
* A class that encapsulates lifecycle rule filter.
@@ -58,7 +60,7 @@ private OmLCFilter(Builder builder) {
*/
public void valid() throws OMException {
boolean hasPrefix = prefix != null;
- boolean hasTag = tagKey != null && tagValue != null;
+ boolean hasTag = hasTag();
boolean hasAndOperator = andOperator != null;
if ((hasPrefix && (hasTag || hasAndOperator)) || (hasTag &&
hasAndOperator)) {
@@ -83,7 +85,46 @@ public String getPrefix() {
@Nullable
public Pair<String, String> getTag() {
- return Pair.of(tagKey, tagValue);
+ if (hasTag()) {
+ return Pair.of(tagKey, tagValue);
+ }
+ return null;
+ }
+
+ public LifecycleFilter getProtobuf() {
+ LifecycleFilter.Builder filterBuilder = LifecycleFilter.newBuilder();
+
+ if (prefix != null) {
+ filterBuilder.setPrefix(prefix);
+ }
+ if (hasTag()) {
+ filterBuilder.setTag(LifecycleFilterTag.newBuilder()
+ .setKey(tagKey)
+ .setValue(tagValue)
+ .build());
+ }
+ if (andOperator != null) {
+ filterBuilder.setAndOperator(andOperator.getProtobuf());
+ }
+
+ return filterBuilder.build();
+ }
+
+ public static OmLCFilter getFromProtobuf(LifecycleFilter lifecycleFilter)
throws OMException {
+ OmLCFilter.Builder builder = new Builder();
+
+ if (lifecycleFilter.hasPrefix()) {
+ builder.setPrefix(lifecycleFilter.getPrefix());
+ }
+ if (lifecycleFilter.hasTag()) {
+ builder.setTag(lifecycleFilter.getTag().getKey(),
lifecycleFilter.getTag().getValue());
+ }
+ if (lifecycleFilter.hasAndOperator()) {
+ builder.setAndOperator(
+
OmLifecycleRuleAndOperator.getFromProtobuf(lifecycleFilter.getAndOperator()));
+ }
+
+ return builder.build();
}
@Override
@@ -96,6 +137,10 @@ public String toString() {
'}';
}
+ private boolean hasTag() {
+ return tagKey != null && tagValue != null;
+ }
+
/**
* Builder of OmLCFilter.
*/
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCRule.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCRule.java
index 96f8769f39..e6f3af4b1d 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCRule.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLCRule.java
@@ -17,6 +17,7 @@
package org.apache.hadoop.ozone.om.helpers;
+import jakarta.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -24,6 +25,8 @@
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleAction;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleRule;
/**
* A class that encapsulates lifecycle rule.
@@ -76,6 +79,7 @@ public String getId() {
return id;
}
+ @Nullable
public String getPrefix() {
return prefix;
}
@@ -93,6 +97,7 @@ public List<OmLCAction> getActions() {
*
* @return the expiration action if present, null otherwise
*/
+ @Nullable
public OmLCExpiration getExpiration() {
for (OmLCAction action : actions) {
if (action instanceof OmLCExpiration) {
@@ -102,6 +107,7 @@ public OmLCExpiration getExpiration() {
return null;
}
+ @Nullable
public OmLCFilter getFilter() {
return filter;
}
@@ -160,6 +166,48 @@ public void valid() throws OMException {
}
}
+ public LifecycleRule getProtobuf() {
+ LifecycleRule.Builder builder = LifecycleRule.newBuilder()
+ .setId(id)
+ .setEnabled(enabled);
+
+ if (prefix != null) {
+ builder.setPrefix(prefix);
+ }
+ if (actions != null) {
+ for (OmLCAction action : actions) {
+ builder.addAction(action.getProtobuf());
+ }
+ }
+ if (filter != null) {
+ builder.setFilter(filter.getProtobuf());
+ }
+
+ return builder.build();
+ }
+
+ public static OmLCRule getFromProtobuf(LifecycleRule lifecycleRule) throws
OMException {
+ Builder builder = new Builder()
+ .setEnabled(lifecycleRule.getEnabled());
+
+ if (lifecycleRule.hasId()) {
+ builder.setId(lifecycleRule.getId());
+ }
+ if (lifecycleRule.hasPrefix()) {
+ builder.setPrefix(lifecycleRule.getPrefix());
+ }
+ for (LifecycleAction lifecycleAction : lifecycleRule.getActionList()) {
+ if (lifecycleAction.hasExpiration()) {
+
builder.addAction(OmLCExpiration.getFromProtobuf(lifecycleAction.getExpiration()));
+ }
+ }
+ if (lifecycleRule.hasFilter()) {
+ builder.setFilter(OmLCFilter.getFromProtobuf(lifecycleRule.getFilter()));
+ }
+
+ return builder.build();
+ }
+
@Override
public String toString() {
return "OmLCRule{" +
@@ -206,6 +254,13 @@ public Builder setAction(OmLCAction lcAction) {
return this;
}
+ public Builder addAction(OmLCAction lcAction) {
+ if (lcAction != null) {
+ this.actions.add(lcAction);
+ }
+ return this;
+ }
+
public Builder setActions(List<OmLCAction> lcAction) {
if (lcAction != null) {
this.actions = new ArrayList<>();
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleConfiguration.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleConfiguration.java
index 348ed106ff..f6488a9bd7 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleConfiguration.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleConfiguration.java
@@ -25,16 +25,32 @@
import java.util.stream.Collectors;
import net.jcip.annotations.Immutable;
import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.hdds.utils.db.Codec;
+import org.apache.hadoop.hdds.utils.db.CopyObject;
+import org.apache.hadoop.hdds.utils.db.DelegatedCodec;
+import org.apache.hadoop.hdds.utils.db.Proto2Codec;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.audit.Auditable;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleConfiguration;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleRule;
/**
* A class that encapsulates lifecycle configuration.
*/
@Immutable
public final class OmLifecycleConfiguration extends WithObjectID
- implements Auditable {
+ implements Auditable, CopyObject<OmLifecycleConfiguration> {
+
+ private static final Codec<OmLifecycleConfiguration> CODEC = new
DelegatedCodec<>(
+ Proto2Codec.get(LifecycleConfiguration.getDefaultInstance()),
+ OmLifecycleConfiguration::getFromProtobuf,
+ OmLifecycleConfiguration::getProtobuf,
+ OmLifecycleConfiguration.class);
+
+ public static Codec<OmLifecycleConfiguration> getCodec() {
+ return CODEC;
+ }
// Ref:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/intro-lifecycle-rules.html#intro-lifecycle-rule-id
public static final int LC_MAX_RULES = 1000;
@@ -120,13 +136,11 @@ private boolean hasNoDuplicateID() {
}
public Builder toBuilder() {
- return new Builder()
- .setVolume(volume)
+ return new Builder(this)
+ .setVolume(this.volume)
.setBucket(this.bucket)
.setCreationTime(this.creationTime)
- .setRules(this.rules)
- .setUpdateID(super.getUpdateID())
- .setObjectID(super.getObjectID());
+ .setRules(this.rules);
}
@Override
@@ -160,6 +174,57 @@ public Map<String, String> toAuditMap() {
return auditMap;
}
+ @Override
+ public OmLifecycleConfiguration copyObject() {
+ try {
+ return toBuilder().build();
+ } catch (OMException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public LifecycleConfiguration getProtobuf() {
+ List<LifecycleRule> rulesProtoBuf = rules.stream()
+ .map(OmLCRule::getProtobuf)
+ .collect(Collectors.toList());
+
+ LifecycleConfiguration.Builder b = LifecycleConfiguration.newBuilder()
+ .setVolume(volume)
+ .setBucket(bucket)
+ .setCreationTime(creationTime)
+ .addAllRules(rulesProtoBuf)
+ .setObjectID(getObjectID())
+ .setUpdateID(getUpdateID());
+
+ return b.build();
+ }
+
+ public static OmLifecycleConfiguration getFromProtobuf(
+ LifecycleConfiguration lifecycleConfiguration) throws OMException {
+ List<OmLCRule> rulesList = new ArrayList<>();
+ for (LifecycleRule lifecycleRule : lifecycleConfiguration.getRulesList()) {
+ OmLCRule fromProtobuf = OmLCRule.getFromProtobuf(lifecycleRule);
+ rulesList.add(fromProtobuf);
+ }
+
+ Builder builder = new Builder()
+ .setVolume(lifecycleConfiguration.getVolume())
+ .setBucket(lifecycleConfiguration.getBucket())
+ .setRules(rulesList);
+
+ if (lifecycleConfiguration.hasCreationTime()) {
+ builder.setCreationTime(lifecycleConfiguration.getCreationTime());
+ }
+ if (lifecycleConfiguration.hasObjectID()) {
+ builder.setObjectID(lifecycleConfiguration.getObjectID());
+ }
+ if (lifecycleConfiguration.hasUpdateID()) {
+ builder.setUpdateID(lifecycleConfiguration.getUpdateID());
+ }
+
+ return builder.build();
+ }
+
/**
* Builder of OmLifecycleConfiguration.
*/
@@ -169,6 +234,10 @@ public static class Builder extends WithObjectID.Builder {
private long creationTime;
private List<OmLCRule> rules = new ArrayList<>();
+ private Builder(OmLifecycleConfiguration obj) {
+ super(obj);
+ }
+
public Builder() {
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleRuleAndOperator.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleRuleAndOperator.java
index a8c20e9616..8f74f8bb30 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleRuleAndOperator.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmLifecycleRuleAndOperator.java
@@ -22,8 +22,11 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.stream.Collectors;
import net.jcip.annotations.Immutable;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleFilterTag;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleRuleAndOperator;
/**
* A class that encapsulates lifecycleRule andOperator.
@@ -118,6 +121,39 @@ public OmLifecycleRuleAndOperator build() throws
OMException {
}
}
+ public LifecycleRuleAndOperator getProtobuf() {
+ LifecycleRuleAndOperator.Builder andOpBuilder =
LifecycleRuleAndOperator.newBuilder();
+
+ if (tags != null) {
+ andOpBuilder.addAllTags(
+ tags.entrySet().stream()
+ .map(lcTag ->
+ LifecycleFilterTag.newBuilder()
+ .setKey(lcTag.getKey())
+ .setValue(lcTag.getValue())
+ .build())
+ .collect(Collectors.toList()));
+ }
+ if (prefix != null) {
+ andOpBuilder.setPrefix(prefix);
+ }
+
+ return andOpBuilder.build();
+ }
+
+ public static OmLifecycleRuleAndOperator
getFromProtobuf(LifecycleRuleAndOperator andOperator) throws OMException {
+ OmLifecycleRuleAndOperator.Builder builder = new
OmLifecycleRuleAndOperator.Builder();
+
+ if (andOperator.hasPrefix()) {
+ builder.setPrefix(andOperator.getPrefix());
+ }
+ andOperator.getTagsList().forEach(tag -> {
+ builder.addTag(tag.getKey(), tag.getValue());
+ });
+
+ return builder.build();
+ }
+
@Override
public String toString() {
return "OmLifecycleRuleAndOperator{" +
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCExpiration.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCExpiration.java
index 1a51056d01..a2fe3951cb 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCExpiration.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCExpiration.java
@@ -21,7 +21,11 @@
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.assertOMException;
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.getFutureDateString;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleAction;
import org.junit.jupiter.api.Test;
/**
@@ -164,4 +168,28 @@ public void testDateMustBeAtMidnightUTC() {
.setDate("2099-10-10T00:00:00+01:00");
assertOMException(exp5::build, INVALID_REQUEST, "'Date' must represent
midnight UTC");
}
+
+ @Test
+ public void testProtobufConversion() throws OMException {
+ // Only Days
+ OmLCExpiration expDays = new OmLCExpiration.Builder()
+ .setDays(30)
+ .build();
+ LifecycleAction protoFromDays = expDays.getProtobuf();
+ OmLCExpiration expFromProto = OmLCExpiration.getFromProtobuf(
+ protoFromDays.getExpiration());
+ assertEquals(30, expFromProto.getDays());
+ assertNull(expFromProto.getDate());
+
+ // Only Date
+ String dateStr = "2099-10-10T00:00:00Z";
+ OmLCExpiration expDate = new OmLCExpiration.Builder()
+ .setDate(dateStr)
+ .build();
+ LifecycleAction protoFromDate = expDate.getProtobuf();
+ OmLCExpiration expFromProto2 = OmLCExpiration.getFromProtobuf(
+ protoFromDate.getExpiration());
+ assertNull(expFromProto2.getDays());
+ assertEquals(dateStr, expFromProto2.getDate());
+ }
}
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCFilter.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCFilter.java
index 67974069e5..8f467f0c62 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCFilter.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCFilter.java
@@ -21,12 +21,18 @@
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.VALID_OM_LC_AND_OPERATOR;
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.VALID_OM_LC_FILTER;
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.assertOMException;
+import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCAndOperatorBuilder;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCFilterBuilder;
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCRuleBuilder;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import java.util.Collections;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleFilter;
import org.junit.jupiter.api.Test;
/**
@@ -81,4 +87,42 @@ public void testInValidFilter() {
}
+ @Test
+ public void testProtobufConversion() throws OMException {
+ // Only prefix
+ OmLCFilter filter1 = getOmLCFilterBuilder("prefix", null, null).build();
+ LifecycleFilter proto1 = filter1.getProtobuf();
+ OmLCFilter filterFromProto1 = OmLCFilter.getFromProtobuf(proto1);
+ assertEquals("prefix", filterFromProto1.getPrefix());
+ assertNull(filterFromProto1.getTag());
+ assertNull(filterFromProto1.getAndOperator());
+
+ // Only tag
+ OmLCFilter filter2 = getOmLCFilterBuilder(null, Pair.of("key", "value"),
null).build();
+ LifecycleFilter proto2 = filter2.getProtobuf();
+ OmLCFilter filterFromProto2 = OmLCFilter.getFromProtobuf(proto2);
+ assertNull(filterFromProto2.getPrefix());
+ assertNotNull(filterFromProto2.getTag());
+ assertEquals("key", filterFromProto2.getTag().getKey());
+ assertEquals("value", filterFromProto2.getTag().getValue());
+
+ // Only andOperator
+ OmLifecycleRuleAndOperator andOp = getOmLCAndOperatorBuilder(
+ "prefix", Collections.singletonMap("tag1", "value1")).build();
+ OmLCFilter filter3 = getOmLCFilterBuilder(null, null, andOp).build();
+ LifecycleFilter proto3 = filter3.getProtobuf();
+ OmLCFilter filterFromProto3 = OmLCFilter.getFromProtobuf(proto3);
+ assertNull(filterFromProto3.getPrefix());
+ assertNull(filterFromProto3.getTag());
+ assertNotNull(filterFromProto3.getAndOperator());
+
+ // Only prefix and prefix is ""
+ OmLCFilter filter4 = getOmLCFilterBuilder("", null, null).build();
+ LifecycleFilter proto4 = filter4.getProtobuf();
+ OmLCFilter filterFromProto4 = OmLCFilter.getFromProtobuf(proto4);
+ assertEquals("", filterFromProto4.getPrefix());
+ assertNull(filterFromProto4.getTag());
+ assertNull(filterFromProto4.getAndOperator());
+ }
+
}
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCRule.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCRule.java
index 39e3cab736..287537bb44 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCRule.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLCRule.java
@@ -22,9 +22,12 @@
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.assertOMException;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCAndOperatorBuilder;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCFilterBuilder;
+import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCRuleBuilder;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.common.collect.ImmutableMap;
@@ -34,6 +37,7 @@
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleRule;
import org.junit.jupiter.api.Test;
/**
@@ -168,4 +172,51 @@ public void testDuplicateRuleIDs() throws OMException {
assertOMException(config::build, INVALID_REQUEST, "Duplicate rule IDs
found");
}
+
+ @Test
+ public void testProtobufConversion() throws OMException {
+ // Only Filter
+ // Object to proto
+ OmLCFilter filter1 = getOmLCFilterBuilder("prefix", null, null).build();
+ OmLCRule rule1 = getOmLCRuleBuilder("test-rule", null, true, 1,
filter1).build();
+ LifecycleRule proto = rule1.getProtobuf();
+
+ // Proto to Object
+ OmLCRule ruleFromProto1 = OmLCRule.getFromProtobuf(proto);
+ assertEquals("test-rule", ruleFromProto1.getId());
+ assertNull(ruleFromProto1.getPrefix());
+ assertTrue(ruleFromProto1.isEnabled());
+ assertNotNull(ruleFromProto1.getExpiration());
+ assertEquals(1, ruleFromProto1.getExpiration().getDays());
+ assertNotNull(ruleFromProto1.getFilter());
+ assertEquals("prefix", ruleFromProto1.getFilter().getPrefix());
+
+ // Only Prefix
+ // Object to proto
+ OmLCRule rule2 = getOmLCRuleBuilder("test-rule", "/logs/", false, 30,
null).build();
+ LifecycleRule proto2 = rule2.getProtobuf();
+
+ // Proto to Object
+ OmLCRule ruleFromProto2 = OmLCRule.getFromProtobuf(proto2);
+ assertEquals("test-rule", ruleFromProto2.getId());
+ assertFalse(ruleFromProto2.isEnabled());
+ assertEquals("/logs/", ruleFromProto2.getPrefix());
+ assertNotNull(ruleFromProto2.getExpiration());
+ assertEquals(30, ruleFromProto2.getExpiration().getDays());
+ assertNull(ruleFromProto2.getFilter());
+
+ // Prefix is ""
+ // Object to proto
+ OmLCRule rule3 = getOmLCRuleBuilder("test-rule", "", true, 30,
null).build();
+ LifecycleRule proto3 = rule3.getProtobuf();
+
+ // Proto to Object
+ OmLCRule ruleFromProto3 = OmLCRule.getFromProtobuf(proto3);
+ assertEquals("test-rule", ruleFromProto3.getId());
+ assertTrue(ruleFromProto3.isEnabled());
+ assertEquals("", ruleFromProto3.getPrefix());
+ assertNotNull(ruleFromProto3.getExpiration());
+ assertEquals(30, ruleFromProto3.getExpiration().getDays());
+ assertNull(ruleFromProto3.getFilter());
+ }
}
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifeCycleConfiguration.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifeCycleConfiguration.java
index 8be22c6e82..6918893355 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifeCycleConfiguration.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifeCycleConfiguration.java
@@ -22,10 +22,12 @@
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.getFutureDateString;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCAndOperatorBuilder;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCFilterBuilder;
+import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCRuleBuilder;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLifecycleConfiguration;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
@@ -33,6 +35,7 @@
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleConfiguration;
import org.junit.jupiter.api.Test;
/**
@@ -188,4 +191,33 @@ public void testDisabledRule() throws OMException {
assertDoesNotThrow(rule::valid);
}
+ @Test
+ public void testProtobufConversion() throws OMException {
+ // Object to proto
+ OmLCRule rule = getOmLCRuleBuilder("test-rule", "/logs/", true, 30,
null).build();
+ List<OmLCRule> rules = Collections.singletonList(rule);
+ OmLifecycleConfiguration.Builder builder =
getOmLifecycleConfiguration("test-volume", "test-bucket", rules);
+ OmLifecycleConfiguration config =
builder.setCreationTime(System.currentTimeMillis())
+ .setRules(rules)
+ .setObjectID(123456L)
+ .setUpdateID(78910L)
+ .build();
+ LifecycleConfiguration proto = config.getProtobuf();
+
+ // Proto to Object
+ OmLifecycleConfiguration configFromProto =
+ OmLifecycleConfiguration.getFromProtobuf(proto);
+ assertEquals("test-volume", configFromProto.getVolume());
+ assertEquals("test-bucket", configFromProto.getBucket());
+ assertEquals(config.getCreationTime(), configFromProto.getCreationTime());
+ assertEquals(config.getObjectID(), configFromProto.getObjectID());
+ assertEquals(config.getUpdateID(), configFromProto.getUpdateID());
+ assertNotNull(configFromProto.getRules());
+ assertEquals(1, configFromProto.getRules().size());
+ OmLCRule ruleFromProto = configFromProto.getRules().get(0);
+ assertEquals(config.getRules().get(0).getId(), ruleFromProto.getId());
+ assertEquals(config.getRules().get(0).getPrefix(),
ruleFromProto.getPrefix());
+ assertEquals(30, ruleFromProto.getExpiration().getDays());
+ }
+
}
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifecycleRuleAndOperator.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifecycleRuleAndOperator.java
index ffc47dffdf..55d42dd77b 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifecycleRuleAndOperator.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmLifecycleRuleAndOperator.java
@@ -21,10 +21,15 @@
import static org.apache.hadoop.ozone.om.helpers.OMLCUtils.assertOMException;
import static
org.apache.hadoop.ozone.om.helpers.OMLCUtils.getOmLCAndOperatorBuilder;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
+import java.util.Map;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LifecycleRuleAndOperator;
import org.junit.jupiter.api.Test;
/**
@@ -67,4 +72,36 @@ public void testInValidAndOperator() {
assertOMException(andOperator3::build, INVALID_REQUEST, "Either 'Tags' or
'Prefix' must be specified.");
}
+ @Test
+ public void testProtobufConversion() throws OMException {
+ // Prefix and tags
+ Map<String, String> tags = ImmutableMap.of("tag1", "value1", "tag2", "");
+ OmLifecycleRuleAndOperator andOp = getOmLCAndOperatorBuilder("prefix",
tags).build();
+ LifecycleRuleAndOperator proto = andOp.getProtobuf();
+ OmLifecycleRuleAndOperator andOpFromProto =
+ OmLifecycleRuleAndOperator.getFromProtobuf(proto);
+ assertEquals("prefix", andOpFromProto.getPrefix());
+ assertEquals(2, andOpFromProto.getTags().size());
+ assertTrue(andOpFromProto.getTags().containsKey("tag1"));
+ assertEquals("value1", andOpFromProto.getTags().get("tag1"));
+ assertTrue(andOpFromProto.getTags().containsKey("tag2"));
+ assertEquals("", andOpFromProto.getTags().get("tag2"));
+
+ // Multiple tags
+ OmLifecycleRuleAndOperator andOp2 = getOmLCAndOperatorBuilder(null,
tags).build();
+ LifecycleRuleAndOperator proto2 = andOp2.getProtobuf();
+ OmLifecycleRuleAndOperator andOpFromProto2 =
+ OmLifecycleRuleAndOperator.getFromProtobuf(proto2);
+ assertNull(andOpFromProto2.getPrefix());
+ assertEquals(2, andOpFromProto2.getTags().size());
+
+ // Prefix is ""
+ OmLifecycleRuleAndOperator andOp3 = getOmLCAndOperatorBuilder("",
tags).build();
+ LifecycleRuleAndOperator proto3 = andOp3.getProtobuf();
+ OmLifecycleRuleAndOperator andOpFromProto3 =
+ OmLifecycleRuleAndOperator.getFromProtobuf(proto3);
+ assertEquals("", andOpFromProto3.getPrefix());
+ assertEquals(2, andOpFromProto2.getTags().size());
+ }
+
}
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 7c6afa0407..c52ea1af0c 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -2311,6 +2311,77 @@ message DeleteObjectTaggingRequest {
message DeleteObjectTaggingResponse {
}
+/**
+S3 lifecycles (filter, expiration, rule and configuration).
+ */
+message LifecycleFilterTag {
+ required string key = 1;
+ required string value = 2;
+}
+
+message LifecycleRuleAndOperator {
+ optional string prefix = 1;
+ repeated LifecycleFilterTag tags = 2;
+}
+
+// TODO: proto 2.5 does not support oneof fields, once we start using protoc
3.x, consider to refactor these message using "oneof"
+/*
+message LifecycleFilter {
+ oneof Filter {
+ string prefix = 1;
+ LifecycleFilterTag tag = 2;
+ LifecycleRuleAndOperator andOperator = 3;
+ }
+}
+
+message LifecycleExpiration {
+ oneof Condition {
+ uint32 days = 1;
+ string date = 2;
+ }
+}
+
+message LifecycleRule {
+ //...
+ oneof Condition {
+ optional string prefix = 4;
+ optional LifecycleFilter filter = 5;
+ }
+ //...
+}
+ */
+message LifecycleFilter {
+ optional string prefix = 1;
+ optional LifecycleFilterTag tag = 2;
+ optional LifecycleRuleAndOperator andOperator = 3;
+}
+
+message LifecycleExpiration {
+ optional uint32 days = 1;
+ optional string date = 2;
+}
+
+message LifecycleRule {
+ required string id = 1;
+ required bool enabled = 2;
+ repeated LifecycleAction action = 3;
+ optional string prefix = 4;
+ optional LifecycleFilter filter = 5;
+}
+
+message LifecycleAction {
+ optional LifecycleExpiration expiration = 1;
+}
+
+message LifecycleConfiguration {
+ required string volume = 1;
+ required string bucket = 2;
+ optional uint64 creationTime = 3;
+ repeated LifecycleRule rules = 4;
+ optional uint64 objectID = 5;
+ optional uint64 updateID = 6;
+}
+
/**
The OM service that takes care of Ozone namespace.
*/
diff --git
a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
index 02ef9bf12a..63dc3cc671 100644
---
a/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
+++
b/hadoop-ozone/interface-storage/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java
@@ -44,6 +44,7 @@
import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.OmLifecycleConfiguration;
import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUpload;
import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
@@ -467,6 +468,8 @@ String getMultipartKeyFSO(String volume, String bucket,
String key, String
Table<String, String> getSnapshotRenamedTable();
Table<String, CompactionLogEntry> getCompactionLogTable();
+
+ Table<String, OmLifecycleConfiguration> getLifecycleConfigurationTable();
/**
* Gets the OM Meta table.
* @return meta table reference.
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
index 198a3e4a50..0571290e6b 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
@@ -98,6 +98,7 @@
import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
+import org.apache.hadoop.ozone.om.helpers.OmLifecycleConfiguration;
import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUpload;
import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
@@ -166,6 +167,8 @@ public class OmMetadataManagerImpl implements
OMMetadataManager,
* |----------------------------------------------------------------------|
* | transactionInfoTable| #TRANSACTIONINFO -> OMTransactionInfo |
* |----------------------------------------------------------------------|
+ * | lifecycleConfigurationTable| /volumeName/bucketName -> ... |
+ * |----------------------------------------------------------------------|
* }
* </pre>
* <pre>
@@ -258,6 +261,8 @@ public class OmMetadataManagerImpl implements
OMMetadataManager,
"snapshotRenamedTable";
public static final String COMPACTION_LOG_TABLE =
"compactionLogTable";
+ public static final String LIFECYCLE_CONFIGURATION_TABLE =
+ "lifecycleConfigurationTable";
static final String[] ALL_TABLES = new String[] {
USER_TABLE,
@@ -281,7 +286,8 @@ public class OmMetadataManagerImpl implements
OMMetadataManager,
TENANT_STATE_TABLE,
SNAPSHOT_INFO_TABLE,
SNAPSHOT_RENAMED_TABLE,
- COMPACTION_LOG_TABLE
+ COMPACTION_LOG_TABLE,
+ LIFECYCLE_CONFIGURATION_TABLE
};
private DBStore store;
@@ -314,6 +320,7 @@ public class OmMetadataManagerImpl implements
OMMetadataManager,
private Table compactionLogTable;
private Table deletedDirTable;
+ private Table lifecycleConfigurationTable;
private OzoneManager ozoneManager;
@@ -628,6 +635,7 @@ public static DBStoreBuilder
addOMTablesAndCodecs(DBStoreBuilder builder) {
.addTable(SNAPSHOT_INFO_TABLE)
.addTable(SNAPSHOT_RENAMED_TABLE)
.addTable(COMPACTION_LOG_TABLE)
+ .addTable(LIFECYCLE_CONFIGURATION_TABLE)
.addCodec(OzoneTokenIdentifier.class, TokenIdentifierCodec.get())
.addCodec(OmKeyInfo.class, OmKeyInfo.getCodec(true))
.addCodec(RepeatedOmKeyInfo.class, RepeatedOmKeyInfo.getCodec(true))
@@ -643,7 +651,8 @@ public static DBStoreBuilder
addOMTablesAndCodecs(DBStoreBuilder builder) {
.addCodec(OmDBAccessIdInfo.class, OmDBAccessIdInfo.getCodec())
.addCodec(OmDBUserPrincipalInfo.class,
OmDBUserPrincipalInfo.getCodec())
.addCodec(SnapshotInfo.class, SnapshotInfo.getCodec())
- .addCodec(CompactionLogEntry.class, CompactionLogEntry.getCodec());
+ .addCodec(CompactionLogEntry.class, CompactionLogEntry.getCodec())
+ .addCodec(OmLifecycleConfiguration.class,
OmLifecycleConfiguration.getCodec());
}
/**
@@ -758,6 +767,11 @@ protected void initializeOmTables(CacheType cacheType,
String.class, CompactionLogEntry.class);
checkTableStatus(compactionLogTable, COMPACTION_LOG_TABLE,
addCacheMetrics);
+
+ lifecycleConfigurationTable =
this.store.getTable(LIFECYCLE_CONFIGURATION_TABLE,
+ String.class, OmLifecycleConfiguration.class);
+ checkTableStatus(lifecycleConfigurationTable,
LIFECYCLE_CONFIGURATION_TABLE,
+ addCacheMetrics);
}
/**
@@ -2067,6 +2081,11 @@ public Table<String, CompactionLogEntry>
getCompactionLogTable() {
return compactionLogTable;
}
+ @Override
+ public Table<String, OmLifecycleConfiguration>
getLifecycleConfigurationTable() {
+ return lifecycleConfigurationTable;
+ }
+
/**
* Get Snapshot Chain Manager.
*
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
index a529aa38e4..ed5ddc763f 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
@@ -33,6 +33,7 @@
import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo;
import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.OmLifecycleConfiguration;
import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
@@ -203,6 +204,13 @@ public final class OMDBDefinition extends
DBDefinition.WithMap {
StringCodec.get(),
CompactionLogEntry.getCodec());
+ public static final DBColumnFamilyDefinition<String,
OmLifecycleConfiguration>
+ LIFECYCLE_CONFIGURATION_TABLE =
+ new DBColumnFamilyDefinition<>(
+ OmMetadataManagerImpl.LIFECYCLE_CONFIGURATION_TABLE,
+ StringCodec.get(),
+ OmLifecycleConfiguration.getCodec());
+
/**
* SnapshotRenamedTable that complements the keyTable (or fileTable)
* and dirTable entries of the immediately previous snapshot in the
@@ -245,7 +253,8 @@ public final class OMDBDefinition extends
DBDefinition.WithMap {
TENANT_STATE_TABLE,
TRANSACTION_INFO_TABLE,
USER_TABLE,
- VOLUME_TABLE);
+ VOLUME_TABLE,
+ LIFECYCLE_CONFIGURATION_TABLE);
private static final OMDBDefinition INSTANCE = new OMDBDefinition();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]