Skip to content

Commit 3e09ecb

Browse files
committed
Base for templatized cluster members
1 parent 11bd9e8 commit 3e09ecb

File tree

3 files changed

+106
-3
lines changed

3 files changed

+106
-3
lines changed

operator/src/main/java/oracle/kubernetes/operator/helpers/PodStepContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,8 @@ protected V1PodSpec createSpec(TuningParameters tuningParameters) {
747747
podSpec.addVolumesItem(additionalVolume);
748748
}
749749

750+
doDeepSubstitution(podSpec);
751+
750752
return podSpec;
751753
}
752754

operator/src/main/java/oracle/kubernetes/operator/helpers/StepContextBase.java

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
package oracle.kubernetes.operator.helpers;
66

77
import io.kubernetes.client.models.V1EnvVar;
8-
import java.util.HashMap;
9-
import java.util.List;
10-
import java.util.Map;
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.lang.reflect.Method;
10+
import java.util.*;
11+
import oracle.kubernetes.operator.Pair;
1112
import oracle.kubernetes.operator.TuningParameters;
13+
import oracle.kubernetes.operator.logging.LoggingFacade;
14+
import oracle.kubernetes.operator.logging.LoggingFactory;
15+
import oracle.kubernetes.operator.logging.MessageKeys;
1216

1317
public abstract class StepContextBase implements StepContextConstants {
18+
private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator");
1419

1520
// Map of <token, substitution string> to be used in the translate method
1621
// Subclass should populate this map prior to calling translate().
@@ -53,6 +58,87 @@ protected void doSubstitution(List<V1EnvVar> vars) {
5358
}
5459
}
5560

61+
protected void doDeepSubstitution(Object obj) {
62+
if (obj != null) {
63+
if (obj instanceof List) {
64+
ListIterator<Object> it = ((List) obj).listIterator();
65+
while (it.hasNext()) {
66+
Object member = it.next();
67+
if (member instanceof String) {
68+
String trans = translate((String) member);
69+
if (!member.equals(trans)) {
70+
it.set(trans);
71+
}
72+
} else if (member != null && isModelClass(member.getClass())) {
73+
doDeepSubstitution(member);
74+
}
75+
}
76+
} else {
77+
try {
78+
Class cls = obj.getClass();
79+
if (isModelClass(cls)) {
80+
List<Method> modelOrListBeans = modelOrListBeans(cls);
81+
for (Method item : modelOrListBeans) {
82+
doDeepSubstitution(item.invoke(obj));
83+
}
84+
85+
List<Pair<Method, Method>> stringBeans = stringBeans(cls);
86+
for (Pair<Method, Method> item : stringBeans) {
87+
item.getRight().invoke(obj, translate((String) item.getLeft().invoke(obj)));
88+
}
89+
}
90+
} catch (IllegalAccessException | InvocationTargetException e) {
91+
LOGGER.severe(MessageKeys.EXCEPTION, e);
92+
}
93+
}
94+
}
95+
}
96+
97+
private boolean isModelOrListClass(Class cls) {
98+
return isModelClass(cls) || List.class.isAssignableFrom(cls);
99+
}
100+
101+
private boolean isModelClass(Class cls) {
102+
return cls.getPackageName().startsWith("io.kubernetes.client.models")
103+
|| cls.getPackageName().startsWith("oracle.kubernetes.weblogic.domain.model");
104+
}
105+
106+
private List<Method> modelOrListBeans(Class cls) {
107+
List<Method> results = new ArrayList<>();
108+
Method[] methods = cls.getMethods();
109+
if (methods != null) {
110+
for (Method m : methods) {
111+
if (m.getName().startsWith("get")
112+
&& isModelOrListClass(m.getReturnType())
113+
&& m.getParameterCount() == 0) {
114+
results.add(m);
115+
}
116+
}
117+
}
118+
return results;
119+
}
120+
121+
private List<Pair<Method, Method>> stringBeans(Class cls) {
122+
List<Pair<Method, Method>> results = new ArrayList<>();
123+
Method[] methods = cls.getMethods();
124+
if (methods != null) {
125+
for (Method m : methods) {
126+
if (m.getName().startsWith("get")
127+
&& m.getReturnType().equals(String.class)
128+
&& m.getParameterCount() == 0) {
129+
try {
130+
Method set = cls.getMethod("set" + m.getName().substring(3), String.class);
131+
if (set != null) {
132+
results.add(new Pair<>(m, set));
133+
}
134+
} catch (NoSuchMethodException nsme) {
135+
}
136+
}
137+
}
138+
}
139+
return results;
140+
}
141+
56142
private String translate(String rawValue) {
57143
String result = rawValue;
58144
for (Map.Entry<String, String> entry : substitutionVariables.entrySet()) {

operator/src/test/java/oracle/kubernetes/operator/helpers/ManagedPodHelperTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,21 @@ public void whenPacketHasEnvironmentItemsWithVariables_createManagedPodStartupWi
145145
allOf(hasEnvVar(ITEM1, END_VALUE_1), hasEnvVar(ITEM2, END_VALUE_2)));
146146
}
147147

148+
@Test
149+
public void whenClusterHasAdditionalVolumesWithVariables_createManagedPodWithSubstitutions() {
150+
testSupport.addToPacket(ProcessingConstants.CLUSTER_NAME, CLUSTER_NAME);
151+
getConfigurator()
152+
.configureCluster(CLUSTER_NAME)
153+
.withAdditionalVolume("volume1", "/source-$(SERVER_NAME)")
154+
.withAdditionalVolume("volume2", "/source-$(DOMAIN_NAME)");
155+
156+
assertThat(
157+
getCreatedPod().getSpec().getVolumes(),
158+
allOf(
159+
hasVolume("volume1", "/source-" + SERVER_NAME),
160+
hasVolume("volume2", "/source-domain1")));
161+
}
162+
148163
@Test
149164
public void createManagedPodStartupWithNullAdminUsernamePasswordEnvVarsValues() {
150165
testSupport.addToPacket(ProcessingConstants.ENVVARS, Arrays.asList());

0 commit comments

Comments
 (0)