44
55package oracle .kubernetes .operator .helpers ;
66
7- import io .kubernetes .client .ApiException ;
7+ import static oracle .kubernetes .operator .VersionConstants .DOMAIN_V1 ;
8+
89import io .kubernetes .client .models .V1ConfigMap ;
910import io .kubernetes .client .models .V1ObjectMeta ;
10- import java .util .HashMap ;
11- import java .util .List ;
1211import java .util .Map ;
1312import oracle .kubernetes .operator .KubernetesConstants ;
1413import oracle .kubernetes .operator .LabelConstants ;
1514import oracle .kubernetes .operator .ProcessingConstants ;
16- import oracle .kubernetes .operator .VersionConstants ;
15+ import oracle .kubernetes .operator .calls . CallResponse ;
1716import oracle .kubernetes .operator .logging .LoggingFacade ;
1817import oracle .kubernetes .operator .logging .LoggingFactory ;
1918import oracle .kubernetes .operator .logging .MessageKeys ;
19+ import oracle .kubernetes .operator .steps .DefaultResponseStep ;
2020import oracle .kubernetes .operator .work .NextAction ;
2121import oracle .kubernetes .operator .work .Packet ;
2222import 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