Skip to content

Commit 8671ee6

Browse files
committed
Use schema validation for enum-valued strings
1 parent 99ce448 commit 8671ee6

File tree

13 files changed

+145
-87
lines changed

13 files changed

+145
-87
lines changed

json-schema/src/main/java/oracle/kubernetes/json/Description.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.lang.annotation.RetentionPolicy;
1111
import java.lang.annotation.Target;
1212

13+
/** Supplies a description for a field to be inserted into the generated JSON schema. */
1314
@Retention(RetentionPolicy.RUNTIME)
1415
@Target(FIELD)
1516
public @interface Description {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.json;
6+
7+
import static java.lang.annotation.ElementType.FIELD;
8+
9+
import java.lang.annotation.Retention;
10+
import java.lang.annotation.RetentionPolicy;
11+
import java.lang.annotation.Target;
12+
13+
/** Specifies an enum class whose values match the permitted values for the field. */
14+
@Retention(RetentionPolicy.RUNTIME)
15+
@Target(FIELD)
16+
public @interface EnumClass {
17+
Class<? extends java.lang.Enum> value();
18+
}

json-schema/src/main/java/oracle/kubernetes/json/SchemaGenerator.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,7 @@
1414
import java.lang.reflect.Modifier;
1515
import java.net.MalformedURLException;
1616
import java.net.URL;
17-
import java.util.ArrayList;
18-
import java.util.Arrays;
19-
import java.util.Collection;
20-
import java.util.HashMap;
21-
import java.util.HashSet;
22-
import java.util.Iterator;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.Set;
17+
import java.util.*;
2618
import javax.annotation.Nonnull;
2719

2820
@SuppressWarnings("WeakerAccess")
@@ -205,6 +197,8 @@ private Object getSubSchema(Field field) {
205197
sub.generateTypeIn(result, field.getType());
206198
String description = getDescription(field);
207199
if (description != null) result.put("description", description);
200+
Class<? extends java.lang.Enum> enumClass = getEnumClass(field);
201+
if (enumClass != null) addEnumValues(result, enumClass);
208202

209203
return result;
210204
}
@@ -214,6 +208,16 @@ private String getDescription(Field field) {
214208
return description != null ? description.value() : null;
215209
}
216210

211+
private Class<? extends java.lang.Enum> getEnumClass(Field field) {
212+
EnumClass annotation = field.getAnnotation(EnumClass.class);
213+
return annotation != null ? annotation.value() : null;
214+
}
215+
216+
private void addEnumValues(
217+
Map<String, Object> result, Class<? extends java.lang.Enum> enumClass) {
218+
result.put("enum", getEnumValues(enumClass));
219+
}
220+
217221
private class SubSchemaGenerator {
218222
Field field;
219223

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.json;
6+
7+
@SuppressWarnings("unused")
8+
public enum Directions {
9+
NORTH,
10+
EAST,
11+
SOUTH,
12+
WEST
13+
}

json-schema/src/test/java/oracle/kubernetes/json/SchemaGeneratorTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66

77
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
88
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
9-
import static org.hamcrest.Matchers.arrayContaining;
10-
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
11-
import static org.hamcrest.Matchers.equalTo;
12-
import static org.hamcrest.Matchers.not;
9+
import static org.hamcrest.Matchers.*;
1310
import static org.junit.Assert.assertThat;
1411

1512
import java.io.IOException;
@@ -112,6 +109,21 @@ private enum TrafficLightColors {
112109
@SuppressWarnings("unused")
113110
private TrafficLightColors colors;
114111

112+
@Test
113+
public void generateSchemaForEnumAnnotatedString() throws NoSuchFieldException {
114+
Object schema = generateForField(getClass().getDeclaredField("direction"));
115+
116+
assertThat(schema, hasJsonPath("$.direction.type", equalTo("string")));
117+
assertThat(
118+
schema,
119+
hasJsonPath(
120+
"$.direction.enum", arrayContainingInAnyOrder("NORTH", "SOUTH", "EAST", "WEST")));
121+
}
122+
123+
@SuppressWarnings("unused")
124+
@EnumClass(Directions.class)
125+
private String direction;
126+
115127
@Test
116128
public void generateSchemaForAnnotatedDouble() throws NoSuchFieldException {
117129
Object schema = generateForField(getClass().getDeclaredField("annotatedDouble"));
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator;
6+
7+
public enum ImagePullPolicy {
8+
Always,
9+
Never,
10+
IfNotPresent
11+
}

model/src/main/java/oracle/kubernetes/operator/KubernetesConstants.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
/** Kubernetes constants. */
88
public interface KubernetesConstants {
99
String DEFAULT_IMAGE = "store/oracle/weblogic:12.2.1.3";
10-
String ALWAYS_IMAGEPULLPOLICY = "Always";
11-
String IFNOTPRESENT_IMAGEPULLPOLICY = "IfNotPresent";
12-
String NEVER_IMAGEPULLPOLICY = "Never";
10+
String ALWAYS_IMAGEPULLPOLICY = ImagePullPolicy.Always.name();
11+
String IFNOTPRESENT_IMAGEPULLPOLICY = ImagePullPolicy.IfNotPresent.name();
1312
String LATEST_IMAGE_SUFFIX = ":latest";
1413

1514
String EXTENSIONS_API_VERSION = "extensions/v1beta1";
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator;
6+
7+
public enum ServerStartPolicy {
8+
NEVER,
9+
ALWAYS,
10+
IF_NEEDED,
11+
ADMIN_ONLY;
12+
13+
public static ServerStartPolicy getDefaultPolicy() {
14+
return IF_NEEDED;
15+
}
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator;
6+
7+
public enum ServerStartState {
8+
RUNNING,
9+
ADMIN
10+
}

model/src/main/java/oracle/kubernetes/weblogic/domain/v2/BaseConfiguration.java

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,15 @@
44

55
package oracle.kubernetes.weblogic.domain.v2;
66

7-
import com.google.gson.annotations.Expose;
8-
import com.google.gson.annotations.SerializedName;
9-
import io.kubernetes.client.models.V1EnvVar;
10-
import io.kubernetes.client.models.V1PodSecurityContext;
11-
import io.kubernetes.client.models.V1ResourceRequirements;
12-
import io.kubernetes.client.models.V1SecurityContext;
13-
import io.kubernetes.client.models.V1Volume;
14-
import io.kubernetes.client.models.V1VolumeMount;
7+
import io.kubernetes.client.models.*;
158
import java.util.List;
169
import java.util.Map;
1710
import java.util.Objects;
1811
import javax.annotation.Nullable;
1912
import oracle.kubernetes.json.Description;
13+
import oracle.kubernetes.json.EnumClass;
14+
import oracle.kubernetes.operator.ServerStartPolicy;
15+
import oracle.kubernetes.operator.ServerStartState;
2016
import org.apache.commons.lang3.builder.EqualsBuilder;
2117
import org.apache.commons.lang3.builder.HashCodeBuilder;
2218
import org.apache.commons.lang3.builder.ToStringBuilder;
@@ -33,9 +29,9 @@ public abstract class BaseConfiguration {
3329
private ServerPod serverPod = new ServerPod();
3430

3531
/** Desired startup state. Legal values are RUNNING or ADMIN. */
36-
@SerializedName("serverStartState")
37-
@Expose
38-
@Description("The state in which the server is to be started")
32+
@EnumClass(ServerStartState.class)
33+
@Description(
34+
"The state in which the server is to be started. Use ADMIN if server should start in admin state. Defaults to RUNNING.")
3935
private String serverStartState;
4036

4137
/**
@@ -46,11 +42,10 @@ public abstract class BaseConfiguration {
4642
*
4743
* @since 2.0
4844
*/
49-
@SerializedName("serverStartPolicy")
50-
@Expose
45+
@EnumClass(ServerStartPolicy.class)
5146
@Description(
5247
"The strategy for deciding whether to start a server. "
53-
+ "Legal values are NEVER, ALWAYS, or IF_NEEDED.")
48+
+ "Legal values are ADMIN_ONLY, NEVER, ALWAYS, or IF_NEEDED.")
5449
private String serverStartPolicy;
5550

5651
/**
@@ -72,7 +67,7 @@ private boolean overrideStartPolicyFrom(BaseConfiguration other) {
7267
return serverStartPolicy == null || other.isStartNever();
7368
}
7469

75-
public boolean isStartAdminServerOnly() {
70+
boolean isStartAdminServerOnly() {
7671
return Objects.equals(getServerStartPolicy(), ConfigurationConstants.START_ADMIN_ONLY);
7772
}
7873

@@ -146,47 +141,47 @@ void addLimitRequirement(String resource, String quantity) {
146141
serverPod.addLimitRequirement(resource, quantity);
147142
}
148143

149-
public V1PodSecurityContext getPodSecurityContext() {
144+
V1PodSecurityContext getPodSecurityContext() {
150145
return serverPod.getPodSecurityContext();
151146
}
152147

153-
public V1SecurityContext getContainerSecurityContext() {
148+
V1SecurityContext getContainerSecurityContext() {
154149
return serverPod.getContainerSecurityContext();
155150
}
156151

157-
public void setPodSecurityContext(V1PodSecurityContext podSecurityContext) {
152+
void setPodSecurityContext(V1PodSecurityContext podSecurityContext) {
158153
serverPod.setPodSecurityContext(podSecurityContext);
159154
}
160155

161-
public void setContainerSecurityContext(V1SecurityContext containerSecurityContext) {
156+
void setContainerSecurityContext(V1SecurityContext containerSecurityContext) {
162157
serverPod.setContainerSecurityContext(containerSecurityContext);
163158
}
164159

165-
public List<V1Volume> getAdditionalVolumes() {
160+
List<V1Volume> getAdditionalVolumes() {
166161
return serverPod.getAdditionalVolumes();
167162
}
168163

169164
void addAdditionalVolume(String name, String path) {
170165
serverPod.addAdditionalVolume(name, path);
171166
}
172167

173-
public List<V1VolumeMount> getAdditionalVolumeMounts() {
168+
List<V1VolumeMount> getAdditionalVolumeMounts() {
174169
return serverPod.getAdditionalVolumeMounts();
175170
}
176171

177172
void addAdditionalVolumeMount(String name, String path) {
178173
serverPod.addAdditionalVolumeMount(name, path);
179174
}
180175

181-
public Map<String, String> getPodLabels() {
176+
Map<String, String> getPodLabels() {
182177
return serverPod.getPodLabels();
183178
}
184179

185180
void addPodLabels(String name, String value) {
186181
serverPod.addPodLabel(name, value);
187182
}
188183

189-
public Map<String, String> getPodAnnotations() {
184+
Map<String, String> getPodAnnotations() {
190185
return serverPod.getPodAnnotations();
191186
}
192187

0 commit comments

Comments
 (0)