Skip to content

Commit 1f81c23

Browse files
committed
refactor ConfigMapHelper
1 parent c3049b6 commit 1f81c23

File tree

3 files changed

+155
-242
lines changed

3 files changed

+155
-242
lines changed

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

Lines changed: 144 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44

55
package oracle.kubernetes.operator.helpers;
66

7-
import io.kubernetes.client.ApiException;
7+
import static oracle.kubernetes.operator.VersionConstants.DOMAIN_V1;
8+
89
import io.kubernetes.client.models.V1ConfigMap;
910
import io.kubernetes.client.models.V1ObjectMeta;
10-
import java.util.HashMap;
11-
import java.util.List;
1211
import java.util.Map;
1312
import oracle.kubernetes.operator.KubernetesConstants;
1413
import oracle.kubernetes.operator.LabelConstants;
1514
import oracle.kubernetes.operator.ProcessingConstants;
16-
import oracle.kubernetes.operator.VersionConstants;
15+
import oracle.kubernetes.operator.calls.CallResponse;
1716
import oracle.kubernetes.operator.logging.LoggingFacade;
1817
import oracle.kubernetes.operator.logging.LoggingFactory;
1918
import oracle.kubernetes.operator.logging.MessageKeys;
19+
import oracle.kubernetes.operator.steps.DefaultResponseStep;
2020
import oracle.kubernetes.operator.work.NextAction;
2121
import oracle.kubernetes.operator.work.Packet;
2222
import oracle.kubernetes.operator.work.Step;
@@ -39,164 +39,161 @@ private ConfigMapHelper() {}
3939
* @return Step for creating config map containing scripts
4040
*/
4141
public static Step createScriptConfigMapStep(String operatorNamespace, String domainNamespace) {
42-
return new ScriptConfigMapStep(operatorNamespace, domainNamespace, null);
42+
return new ScriptConfigMapStep(operatorNamespace, domainNamespace);
43+
}
44+
45+
static class ScriptConfigMapStep extends Step {
46+
ConfigMapContext context;
47+
48+
ScriptConfigMapStep(String operatorNamespace, String domainNamespace) {
49+
context = new ConfigMapContext(this, operatorNamespace, domainNamespace);
50+
}
51+
52+
@Override
53+
public NextAction apply(Packet packet) {
54+
return doNext(context.verifyConfigMap(getNext()), packet);
55+
}
4356
}
4457

45-
// Make this public so that it can be unit tested
46-
public static class ScriptConfigMapStep extends Step {
58+
static class ConfigMapContext {
59+
private final Step conflictStep;
4760
private final String operatorNamespace;
4861
private final String domainNamespace;
62+
private final V1ConfigMap model;
63+
private final Map<String, String> classpathScripts = loadScriptsFromClasspath();
4964

50-
ScriptConfigMapStep(String operatorNamespace, String domainNamespace, Step next) {
65+
ConfigMapContext(Step conflictStep, String operatorNamespace, String domainNamespace) {
66+
this.conflictStep = conflictStep;
5167
this.operatorNamespace = operatorNamespace;
5268
this.domainNamespace = domainNamespace;
69+
this.model = createModel(classpathScripts);
5370
}
5471

55-
@Override
56-
public NextAction apply(Packet packet) {
57-
V1ConfigMap cm = computeDomainConfigMap();
58-
CallBuilderFactory factory = new CallBuilderFactory();
59-
Step read =
60-
factory
61-
.create()
62-
.readConfigMapAsync(
63-
cm.getMetadata().getName(),
64-
domainNamespace,
65-
new ResponseStep<V1ConfigMap>(getNext()) {
66-
@Override
67-
public NextAction onFailure(
68-
Packet packet,
69-
ApiException e,
70-
int statusCode,
71-
Map<String, List<String>> responseHeaders) {
72-
if (statusCode == CallBuilder.NOT_FOUND) {
73-
return onSuccess(packet, null, statusCode, responseHeaders);
74-
}
75-
return super.onFailure(packet, e, statusCode, responseHeaders);
76-
}
77-
78-
@Override
79-
public NextAction onSuccess(
80-
Packet packet,
81-
V1ConfigMap result,
82-
int statusCode,
83-
Map<String, List<String>> responseHeaders) {
84-
if (result == null) {
85-
Step create =
86-
factory
87-
.create()
88-
.createConfigMapAsync(
89-
domainNamespace,
90-
cm,
91-
new ResponseStep<V1ConfigMap>(getNext()) {
92-
@Override
93-
public NextAction onFailure(
94-
Packet packet,
95-
ApiException e,
96-
int statusCode,
97-
Map<String, List<String>> responseHeaders) {
98-
return super.onFailure(
99-
ScriptConfigMapStep.this,
100-
packet,
101-
e,
102-
statusCode,
103-
responseHeaders);
104-
}
105-
106-
@Override
107-
public NextAction onSuccess(
108-
Packet packet,
109-
V1ConfigMap result,
110-
int statusCode,
111-
Map<String, List<String>> responseHeaders) {
112-
113-
LOGGER.info(MessageKeys.CM_CREATED, domainNamespace);
114-
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, result);
115-
return doNext(packet);
116-
}
117-
});
118-
return doNext(create, packet);
119-
} else if (VersionHelper.matchesResourceVersion(
120-
result.getMetadata(), VersionConstants.DOMAIN_V1)
121-
&& COMPARATOR.containsAll(result, cm)) {
122-
// existing config map has correct data
123-
LOGGER.fine(MessageKeys.CM_EXISTS, domainNamespace);
124-
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, result);
125-
return doNext(packet);
126-
} else {
127-
// we need to update the config map
128-
Map<String, String> updated = result.getData();
129-
updated.putAll(cm.getData());
130-
cm.setData(updated);
131-
Step replace =
132-
factory
133-
.create()
134-
.replaceConfigMapAsync(
135-
cm.getMetadata().getName(),
136-
domainNamespace,
137-
cm,
138-
new ResponseStep<V1ConfigMap>(getNext()) {
139-
@Override
140-
public NextAction onFailure(
141-
Packet packet,
142-
ApiException e,
143-
int statusCode,
144-
Map<String, List<String>> responseHeaders) {
145-
return super.onFailure(
146-
ScriptConfigMapStep.this,
147-
packet,
148-
e,
149-
statusCode,
150-
responseHeaders);
151-
}
152-
153-
@Override
154-
public NextAction onSuccess(
155-
Packet packet,
156-
V1ConfigMap result,
157-
int statusCode,
158-
Map<String, List<String>> responseHeaders) {
159-
LOGGER.info(MessageKeys.CM_REPLACED, domainNamespace);
160-
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, result);
161-
return doNext(packet);
162-
}
163-
});
164-
return doNext(replace, packet);
165-
}
166-
}
167-
});
168-
169-
return doNext(read, packet);
170-
}
171-
172-
// Make this protected so that it can be unit tested
173-
protected V1ConfigMap computeDomainConfigMap() {
174-
String name = KubernetesConstants.DOMAIN_CONFIG_MAP_NAME;
175-
V1ConfigMap cm = new V1ConfigMap();
176-
cm.setApiVersion("v1");
177-
cm.setKind("ConfigMap");
178-
179-
V1ObjectMeta metadata = new V1ObjectMeta();
180-
metadata.setName(name);
181-
metadata.setNamespace(domainNamespace);
182-
183-
Map<String, String> labels = new HashMap<>();
184-
labels.put(LabelConstants.RESOURCE_VERSION_LABEL, VersionConstants.DOMAIN_V1);
185-
labels.put(LabelConstants.OPERATORNAME_LABEL, operatorNamespace);
186-
labels.put(LabelConstants.CREATEDBYOPERATOR_LABEL, "true");
187-
metadata.setLabels(labels);
188-
189-
cm.setMetadata(metadata);
190-
cm.setData(loadScriptsFromClasspath());
191-
192-
return cm;
72+
private V1ConfigMap createModel(Map<String, String> data) {
73+
return new V1ConfigMap()
74+
.apiVersion("v1")
75+
.kind("ConfigMap")
76+
.metadata(createMetadata())
77+
.data(data);
78+
}
79+
80+
private V1ObjectMeta createMetadata() {
81+
return new V1ObjectMeta()
82+
.name(KubernetesConstants.DOMAIN_CONFIG_MAP_NAME)
83+
.namespace(this.domainNamespace)
84+
.putLabelsItem(LabelConstants.RESOURCE_VERSION_LABEL, DOMAIN_V1)
85+
.putLabelsItem(LabelConstants.OPERATORNAME_LABEL, operatorNamespace)
86+
.putLabelsItem(LabelConstants.CREATEDBYOPERATOR_LABEL, "true");
19387
}
19488

19589
private synchronized Map<String, String> loadScriptsFromClasspath() {
19690
Map<String, String> scripts = scriptReader.loadFilesFromClasspath();
197-
LOGGER.info(MessageKeys.SCRIPT_LOADED, domainNamespace);
91+
LOGGER.info(MessageKeys.SCRIPT_LOADED, this.domainNamespace);
19892
return scripts;
19993
}
94+
95+
Step verifyConfigMap(Step next) {
96+
return new CallBuilder()
97+
.readConfigMapAsync(
98+
model.getMetadata().getName(), domainNamespace, createReadResponseStep(next));
99+
}
100+
101+
ResponseStep<V1ConfigMap> createReadResponseStep(Step next) {
102+
return new ReadResponseStep(next);
103+
}
104+
105+
class ReadResponseStep extends DefaultResponseStep<V1ConfigMap> {
106+
ReadResponseStep(Step next) {
107+
super(next);
108+
}
109+
110+
@Override
111+
public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callResponse) {
112+
V1ConfigMap existingMap = callResponse.getResult();
113+
if (existingMap == null) {
114+
return doNext(createConfigMap(getNext()), packet);
115+
} else if (isCompatibleMap(existingMap)) {
116+
logConfigMapExists();
117+
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, existingMap);
118+
return doNext(packet);
119+
} else {
120+
return doNext(updateConfigMap(getNext(), existingMap), packet);
121+
}
122+
}
123+
}
124+
125+
Step createConfigMap(Step next) {
126+
return new CallBuilder()
127+
.createConfigMapAsync(domainNamespace, model, createCreateResponseStep(next));
128+
}
129+
130+
ResponseStep<V1ConfigMap> createCreateResponseStep(Step next) {
131+
return new CreateResponseStep(next);
132+
}
133+
134+
private class CreateResponseStep extends ResponseStep<V1ConfigMap> {
135+
CreateResponseStep(Step next) {
136+
super(next);
137+
}
138+
139+
@Override
140+
public NextAction onFailure(Packet packet, CallResponse<V1ConfigMap> callResponse) {
141+
return super.onFailure(conflictStep, packet, callResponse);
142+
}
143+
144+
@Override
145+
public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callResponse) {
146+
LOGGER.info(MessageKeys.CM_CREATED, domainNamespace);
147+
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, callResponse.getResult());
148+
return doNext(packet);
149+
}
150+
}
151+
152+
private boolean isCompatibleMap(V1ConfigMap existingMap) {
153+
return VersionHelper.matchesResourceVersion(existingMap.getMetadata(), DOMAIN_V1)
154+
&& COMPARATOR.containsAll(existingMap, this.model);
155+
}
156+
157+
void logConfigMapExists() {
158+
LOGGER.fine(MessageKeys.CM_EXISTS, domainNamespace);
159+
}
160+
161+
Step updateConfigMap(Step next, V1ConfigMap existingConfigMap) {
162+
return new CallBuilder()
163+
.replaceConfigMapAsync(
164+
model.getMetadata().getName(),
165+
domainNamespace,
166+
createModel(getCombinedData(existingConfigMap)),
167+
createReplaceResponseStep(next));
168+
}
169+
170+
Map<String, String> getCombinedData(V1ConfigMap existingConfigMap) {
171+
Map<String, String> updated = existingConfigMap.getData();
172+
updated.putAll(this.classpathScripts);
173+
return updated;
174+
}
175+
176+
ResponseStep<V1ConfigMap> createReplaceResponseStep(Step next) {
177+
return new ReplaceResponseStep(next);
178+
}
179+
180+
private class ReplaceResponseStep extends ResponseStep<V1ConfigMap> {
181+
ReplaceResponseStep(Step next) {
182+
super(next);
183+
}
184+
185+
@Override
186+
public NextAction onFailure(Packet packet, CallResponse<V1ConfigMap> callResponse) {
187+
return super.onFailure(conflictStep, packet, callResponse);
188+
}
189+
190+
@Override
191+
public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callResponse) {
192+
LOGGER.info(MessageKeys.CM_REPLACED, domainNamespace);
193+
packet.put(ProcessingConstants.SCRIPT_CONFIG_MAP, callResponse.getResult());
194+
return doNext(packet);
195+
}
196+
}
200197
}
201198

202199
static FileGroupReader getScriptReader() {

0 commit comments

Comments
 (0)