Skip to content

Commit 226774b

Browse files
authored
Core: Add policy content and validator for more maintenance policies (#1261)
1 parent c31146c commit 226774b

16 files changed

+605
-298
lines changed

polaris-core/src/main/java/org/apache/polaris/core/policy/PolicyContent.java renamed to polaris-core/src/main/java/org/apache/polaris/core/policy/content/PolicyContent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.polaris.core.policy;
19+
package org.apache.polaris.core.policy.content;
2020

2121
/** A marker interface for policy content */
2222
public interface PolicyContent {}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.polaris.core.policy.validator;
19+
package org.apache.polaris.core.policy.content;
2020

2121
import com.fasterxml.jackson.databind.DeserializationFeature;
2222
import com.fasterxml.jackson.databind.ObjectMapper;
2323

24-
public class PolicyValidatorUtil {
24+
public class PolicyContentUtil {
2525
public static final ObjectMapper MAPPER = configureMapper();
2626

2727
private static ObjectMapper configureMapper() {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.polaris.core.policy.validator;
19+
package org.apache.polaris.core.policy.content;
2020

2121
import com.fasterxml.jackson.core.JsonParser;
2222
import com.fasterxml.jackson.databind.DeserializationContext;
2323
import com.fasterxml.jackson.databind.JsonDeserializer;
2424
import java.io.IOException;
25+
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
2526

2627
public class StrictBooleanDeserializer extends JsonDeserializer<Boolean> {
2728
@Override
Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,27 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.polaris.core.policy.validator.datacompaction;
19+
package org.apache.polaris.core.policy.content.maintenance;
2020

2121
import com.fasterxml.jackson.annotation.JsonCreator;
2222
import com.fasterxml.jackson.annotation.JsonProperty;
2323
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2424
import com.google.common.base.Strings;
2525
import java.util.Map;
2626
import java.util.Set;
27-
import org.apache.polaris.core.policy.PolicyContent;
27+
import org.apache.polaris.core.policy.content.PolicyContent;
28+
import org.apache.polaris.core.policy.content.StrictBooleanDeserializer;
2829
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
29-
import org.apache.polaris.core.policy.validator.PolicyValidatorUtil;
30-
import org.apache.polaris.core.policy.validator.StrictBooleanDeserializer;
31-
32-
public class DataCompactionPolicyContent implements PolicyContent {
33-
private static final String DEFAULT_POLICY_SCHEMA_VERSION = "2025-02-03";
34-
private static final Set<String> POLICY_SCHEMA_VERSIONS = Set.of(DEFAULT_POLICY_SCHEMA_VERSION);
3530

31+
public abstract class BaseMaintenancePolicyContent implements PolicyContent {
3632
@JsonDeserialize(using = StrictBooleanDeserializer.class)
3733
private Boolean enable;
3834

3935
private String version;
4036
private Map<String, String> config;
4137

4238
@JsonCreator
43-
public DataCompactionPolicyContent(
39+
public BaseMaintenancePolicyContent(
4440
@JsonProperty(value = "enable", required = true) boolean enable) {
4541
this.enable = enable;
4642
}
@@ -69,29 +65,21 @@ public void setConfig(Map<String, String> config) {
6965
this.config = config;
7066
}
7167

72-
public static DataCompactionPolicyContent fromString(String content) {
73-
if (Strings.isNullOrEmpty(content)) {
74-
throw new InvalidPolicyException("Policy is empty");
68+
static void validateVersion(
69+
String content,
70+
BaseMaintenancePolicyContent policy,
71+
String defaultVersion,
72+
Set<String> allVersions) {
73+
if (policy == null) {
74+
throw new InvalidPolicyException("Invalid policy: " + content);
7575
}
7676

77-
try {
78-
DataCompactionPolicyContent policy =
79-
PolicyValidatorUtil.MAPPER.readValue(content, DataCompactionPolicyContent.class);
80-
if (policy == null) {
81-
throw new InvalidPolicyException("Invalid policy");
82-
}
83-
84-
if (Strings.isNullOrEmpty(policy.getVersion())) {
85-
policy.setVersion(DEFAULT_POLICY_SCHEMA_VERSION);
86-
}
87-
88-
if (!POLICY_SCHEMA_VERSIONS.contains(policy.getVersion())) {
89-
throw new InvalidPolicyException("Invalid policy version: " + policy.getVersion());
90-
}
77+
if (Strings.isNullOrEmpty(policy.getVersion())) {
78+
policy.setVersion(defaultVersion);
79+
}
9180

92-
return policy;
93-
} catch (Exception e) {
94-
throw new InvalidPolicyException(e);
81+
if (!allVersions.contains(policy.getVersion())) {
82+
throw new InvalidPolicyException("Invalid policy version: " + policy.getVersion());
9583
}
9684
}
9785
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.core.policy.content.maintenance;
20+
21+
import com.fasterxml.jackson.annotation.JsonCreator;
22+
import com.fasterxml.jackson.annotation.JsonProperty;
23+
import com.google.common.base.Strings;
24+
import java.util.Set;
25+
import org.apache.polaris.core.policy.content.PolicyContentUtil;
26+
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
27+
28+
public class DataCompactionPolicyContent extends BaseMaintenancePolicyContent {
29+
private static final String DEFAULT_POLICY_SCHEMA_VERSION = "2025-02-03";
30+
private static final Set<String> POLICY_SCHEMA_VERSIONS = Set.of(DEFAULT_POLICY_SCHEMA_VERSION);
31+
32+
@JsonCreator
33+
public DataCompactionPolicyContent(
34+
@JsonProperty(value = "enable", required = true) boolean enable) {
35+
super(enable);
36+
}
37+
38+
public static DataCompactionPolicyContent fromString(String content) {
39+
if (Strings.isNullOrEmpty(content)) {
40+
throw new InvalidPolicyException("Policy is empty");
41+
}
42+
43+
DataCompactionPolicyContent policy;
44+
try {
45+
policy = PolicyContentUtil.MAPPER.readValue(content, DataCompactionPolicyContent.class);
46+
} catch (Exception e) {
47+
throw new InvalidPolicyException(e);
48+
}
49+
50+
validateVersion(content, policy, DEFAULT_POLICY_SCHEMA_VERSION, POLICY_SCHEMA_VERSIONS);
51+
52+
return policy;
53+
}
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.core.policy.content.maintenance;
20+
21+
import com.fasterxml.jackson.annotation.JsonCreator;
22+
import com.fasterxml.jackson.annotation.JsonProperty;
23+
import com.google.common.base.Strings;
24+
import java.util.Set;
25+
import org.apache.polaris.core.policy.content.PolicyContentUtil;
26+
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
27+
28+
public class MetadataCompactionPolicyContent extends BaseMaintenancePolicyContent {
29+
private static final String DEFAULT_POLICY_SCHEMA_VERSION = "2025-02-03";
30+
private static final Set<String> POLICY_SCHEMA_VERSIONS = Set.of(DEFAULT_POLICY_SCHEMA_VERSION);
31+
32+
@JsonCreator
33+
public MetadataCompactionPolicyContent(
34+
@JsonProperty(value = "enable", required = true) boolean enable) {
35+
super(enable);
36+
}
37+
38+
public static MetadataCompactionPolicyContent fromString(String content) {
39+
if (Strings.isNullOrEmpty(content)) {
40+
throw new InvalidPolicyException("Policy is empty");
41+
}
42+
43+
MetadataCompactionPolicyContent policy;
44+
try {
45+
policy = PolicyContentUtil.MAPPER.readValue(content, MetadataCompactionPolicyContent.class);
46+
} catch (Exception e) {
47+
throw new InvalidPolicyException(e);
48+
}
49+
50+
validateVersion(content, policy, DEFAULT_POLICY_SCHEMA_VERSION, POLICY_SCHEMA_VERSIONS);
51+
52+
return policy;
53+
}
54+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.core.policy.content.maintenance;
20+
21+
import com.fasterxml.jackson.annotation.JsonCreator;
22+
import com.fasterxml.jackson.annotation.JsonProperty;
23+
import com.google.common.base.Strings;
24+
import java.util.List;
25+
import java.util.Set;
26+
import org.apache.polaris.core.policy.content.PolicyContentUtil;
27+
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
28+
29+
public class OrphanFileRemovalPolicyContent extends BaseMaintenancePolicyContent {
30+
private static final String DEFAULT_POLICY_SCHEMA_VERSION = "2025-02-03";
31+
private static final Set<String> POLICY_SCHEMA_VERSIONS = Set.of(DEFAULT_POLICY_SCHEMA_VERSION);
32+
33+
@JsonProperty(value = "max_orphan_file_age_in_days")
34+
private int maxOrphanFileAgeInDays;
35+
36+
private List<String> locations;
37+
38+
@JsonCreator
39+
public OrphanFileRemovalPolicyContent(
40+
@JsonProperty(value = "enable", required = true) boolean enable) {
41+
super(enable);
42+
}
43+
44+
public int getMaxOrphanFileAgeInDays() {
45+
return maxOrphanFileAgeInDays;
46+
}
47+
48+
public void setMaxOrphanFileAgeInDays(int maxOrphanFileAgeInDays) {
49+
this.maxOrphanFileAgeInDays = maxOrphanFileAgeInDays;
50+
}
51+
52+
public List<String> getLocations() {
53+
return locations;
54+
}
55+
56+
public void setLocations(List<String> locations) {
57+
this.locations = locations;
58+
}
59+
60+
public static OrphanFileRemovalPolicyContent fromString(String content) {
61+
if (Strings.isNullOrEmpty(content)) {
62+
throw new InvalidPolicyException("Policy is empty");
63+
}
64+
65+
OrphanFileRemovalPolicyContent policy;
66+
try {
67+
policy = PolicyContentUtil.MAPPER.readValue(content, OrphanFileRemovalPolicyContent.class);
68+
} catch (Exception e) {
69+
throw new InvalidPolicyException(e);
70+
}
71+
72+
validateVersion(content, policy, DEFAULT_POLICY_SCHEMA_VERSION, POLICY_SCHEMA_VERSIONS);
73+
74+
int maxAge = policy.getMaxOrphanFileAgeInDays();
75+
if (maxAge < 0) {
76+
throw new InvalidPolicyException(
77+
"Invalid max_orphan_file_age_in_days: "
78+
+ maxAge
79+
+ ". It must be greater than or equal to 0");
80+
}
81+
82+
return policy;
83+
}
84+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.core.policy.content.maintenance;
20+
21+
import com.fasterxml.jackson.annotation.JsonCreator;
22+
import com.fasterxml.jackson.annotation.JsonProperty;
23+
import com.google.common.base.Strings;
24+
import java.util.Set;
25+
import org.apache.polaris.core.policy.content.PolicyContentUtil;
26+
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
27+
28+
public class SnapshotRetentionPolicyContent extends BaseMaintenancePolicyContent {
29+
private static final String DEFAULT_POLICY_SCHEMA_VERSION = "2025-02-03";
30+
private static final Set<String> POLICY_SCHEMA_VERSIONS = Set.of(DEFAULT_POLICY_SCHEMA_VERSION);
31+
32+
@JsonCreator
33+
public SnapshotRetentionPolicyContent(
34+
@JsonProperty(value = "enable", required = true) boolean enable) {
35+
super(enable);
36+
}
37+
38+
public static SnapshotRetentionPolicyContent fromString(String content) {
39+
if (Strings.isNullOrEmpty(content)) {
40+
throw new InvalidPolicyException("Policy is empty");
41+
}
42+
43+
SnapshotRetentionPolicyContent policy;
44+
try {
45+
policy = PolicyContentUtil.MAPPER.readValue(content, SnapshotRetentionPolicyContent.class);
46+
} catch (Exception e) {
47+
throw new InvalidPolicyException(e);
48+
}
49+
50+
validateVersion(content, policy, DEFAULT_POLICY_SCHEMA_VERSION, POLICY_SCHEMA_VERSIONS);
51+
52+
return policy;
53+
}
54+
}

0 commit comments

Comments
 (0)