1616import java .util .Map ;
1717import java .util .Objects ;
1818import java .util .Optional ;
19- import java .util .regex .Pattern ;
2019import java .util .stream .Collectors ;
2120import javax .annotation .Nonnull ;
2221
@@ -69,7 +68,7 @@ public class ConfigMapHelper {
6968
7069 private static final String SCRIPT_LOCATION = "/scripts" ;
7170 private static final String UPDATEDOMAINRESULT = "UPDATEDOMAINRESULT" ;
72- private static final ConfigMapComparator COMPARATOR = new ConfigMapComparatorImpl ();
71+ private static final ConfigMapComparator COMPARATOR = new ConfigMapComparator ();
7372
7473 private static final FileGroupReader scriptReader = new FileGroupReader (SCRIPT_LOCATION );
7574
@@ -82,12 +81,8 @@ private ConfigMapHelper() {
8281 * @param domainNamespace the domain's namespace
8382 * @return Step for creating config map containing scripts
8483 */
85- public static Step createScriptConfigMapStep (String domainNamespace ) {
86- return new ScriptConfigMapStep (domainNamespace );
87- }
88-
89- static FileGroupReader getScriptReader () {
90- return scriptReader ;
84+ public static Step createScriptConfigMapStep (String domainNamespace , SemanticVersion productVersion ) {
85+ return new ScriptConfigMapStep (domainNamespace , productVersion );
9186 }
9287
9388 static Map <String , String > parseIntrospectorResult (String text , String domainUid ) {
@@ -162,23 +157,25 @@ public static String getIntrospectorConfigMapName(String domainUid) {
162157 return IntrospectorConfigMapConstants .getIntrospectorConfigMapName (domainUid , 0 );
163158 }
164159
165- abstract static class ConfigMapComparator {
166- boolean containsAll (V1ConfigMap actual , V1ConfigMap expected ) {
167- return containsAllData (getData (actual ), getData (expected ));
168- }
160+ static class ConfigMapComparator {
161+ boolean isOutdated (SemanticVersion productVersion , V1ConfigMap actual , V1ConfigMap expected ) {
162+ // Check product version label
163+ if (productVersion != null ) {
164+ SemanticVersion currentVersion = KubernetesUtils .getProductVersionFromMetadata (actual .getMetadata ());
165+ if (currentVersion == null || productVersion .compareTo (currentVersion ) > 0 ) {
166+ return true ;
167+ }
168+ }
169169
170- private Map <String ,String > getData (V1ConfigMap map ) {
171- return Optional .ofNullable (map ).map (V1ConfigMap ::getData ).orElse (Collections .emptyMap ());
170+ return !AnnotationHelper .getHash (expected ).equals (AnnotationHelper .getHash (actual ));
172171 }
173-
174- abstract boolean containsAllData (Map <String , String > actual , Map <String , String > expected );
175172 }
176173
177174 static class ScriptConfigMapStep extends Step {
178175 final ConfigMapContext context ;
179176
180- ScriptConfigMapStep (String domainNamespace ) {
181- context = new ScriptConfigMapContext (this , domainNamespace );
177+ ScriptConfigMapStep (String domainNamespace , SemanticVersion productVersion ) {
178+ context = new ScriptConfigMapContext (this , domainNamespace , productVersion );
182179 }
183180
184181 @ Override
@@ -188,25 +185,23 @@ public NextAction apply(Packet packet) {
188185 }
189186
190187 static class ScriptConfigMapContext extends ConfigMapContext {
191-
192- ScriptConfigMapContext ( Step conflictStep , String domainNamespace ) {
193- super ( conflictStep , SCRIPT_CONFIG_MAP_NAME , domainNamespace , loadScriptsFromClasspath (domainNamespace ), null );
188+ ScriptConfigMapContext ( Step conflictStep , String domainNamespace , SemanticVersion productVersion ) {
189+ super ( conflictStep , SCRIPT_CONFIG_MAP_NAME , domainNamespace ,
190+ loadScriptsFromClasspath (domainNamespace ), null , productVersion );
194191
195192 addLabel (LabelConstants .OPERATORNAME_LABEL , getOperatorNamespace ());
196193 }
197194
198- private static synchronized Map <String , String > loadScriptsFromClasspath (String domainNamespace ) {
199- Map <String , String > scripts = scriptReader .loadFilesFromClasspath ();
200- LOGGER .fine (MessageKeys .SCRIPT_LOADED , domainNamespace );
201- return scripts ;
202- }
203-
204195 @ Override
205196 void recordCurrentMap (Packet packet , V1ConfigMap configMap ) {
206197 packet .put (ProcessingConstants .SCRIPT_CONFIG_MAP , configMap );
207198 }
199+ }
208200
209-
201+ static synchronized Map <String , String > loadScriptsFromClasspath (String domainNamespace ) {
202+ Map <String , String > scripts = scriptReader .loadFilesFromClasspath ();
203+ LOGGER .fine (MessageKeys .SCRIPT_LOADED , domainNamespace );
204+ return scripts ;
210205 }
211206
212207 abstract static class ConfigMapContext extends StepContextBase {
@@ -216,14 +211,21 @@ abstract static class ConfigMapContext extends StepContextBase {
216211 private final String namespace ;
217212 private V1ConfigMap model ;
218213 private final Map <String , String > labels = new HashMap <>();
214+ protected final SemanticVersion productVersion ;
219215
220216 ConfigMapContext (Step conflictStep , String name , String namespace , Map <String , String > contents ,
221217 DomainPresenceInfo info ) {
218+ this (conflictStep , name , namespace , contents , info , null );
219+ }
220+
221+ ConfigMapContext (Step conflictStep , String name , String namespace , Map <String , String > contents ,
222+ DomainPresenceInfo info , SemanticVersion productVersion ) {
222223 super (info );
223224 this .conflictStep = conflictStep ;
224225 this .name = name ;
225226 this .namespace = namespace ;
226227 this .contents = contents ;
228+ this .productVersion = productVersion ;
227229
228230 addLabel (LabelConstants .CREATEDBYOPERATOR_LABEL , "true" );
229231 }
@@ -253,15 +255,22 @@ protected V1ConfigMap getModel() {
253255 }
254256
255257 protected final V1ConfigMap createModel (Map <String , String > data ) {
256- return new V1ConfigMap ().kind ("ConfigMap" ).apiVersion ("v1" ).metadata (createMetadata ()).data (data );
258+ return AnnotationHelper .withSha256Hash (
259+ new V1ConfigMap ().kind ("ConfigMap" ).apiVersion ("v1" ).metadata (createMetadata ()).data (data ), data );
257260 }
258261
259262 private V1ObjectMeta createMetadata () {
260- return updateForOwnerReference (
263+ V1ObjectMeta metadata = updateForOwnerReference (
261264 new V1ObjectMeta ()
262265 .name (name )
263266 .namespace (namespace )
264267 .labels (labels ));
268+
269+ if (productVersion != null ) {
270+ metadata .putLabelsItem (LabelConstants .OPERATOR_VERSION , productVersion .toString ());
271+ }
272+
273+ return metadata ;
265274 }
266275
267276 @ SuppressWarnings ("SameParameterValue" )
@@ -283,8 +292,8 @@ Step verifyConfigMap(Step next) {
283292 return new CallBuilder ().readConfigMapAsync (getName (), namespace , null , new ReadResponseStep (next ));
284293 }
285294
286- boolean isIncompatibleMap (V1ConfigMap existingMap ) {
287- return ! COMPARATOR .containsAll ( existingMap , getModel ());
295+ boolean isOutdated (V1ConfigMap existingMap ) {
296+ return COMPARATOR .isOutdated ( productVersion , existingMap , getModel ());
288297 }
289298
290299 V1ConfigMap withoutTransientData (V1ConfigMap originalMap ) {
@@ -315,8 +324,8 @@ public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callRespons
315324 V1ConfigMap existingMap = withoutTransientData (callResponse .getResult ());
316325 if (existingMap == null ) {
317326 return doNext (createConfigMap (getNext ()), packet );
318- } else if (isIncompatibleMap (existingMap )) {
319- return doNext (updateConfigMap (getNext (), existingMap ), packet );
327+ } else if (isOutdated (existingMap )) {
328+ return doNext (replaceConfigMap (getNext ()), packet );
320329 } else if (mustPatchCurrentMap (existingMap )) {
321330 return doNext (patchCurrentMap (existingMap , getNext ()), packet );
322331 } else {
@@ -335,9 +344,9 @@ private void logConfigMapExists() {
335344 LOGGER .fine (MessageKeys .CM_EXISTS , getName (), namespace );
336345 }
337346
338- private Step updateConfigMap (Step next , V1ConfigMap existingConfigMap ) {
347+ private Step replaceConfigMap (Step next ) {
339348 return new CallBuilder ().replaceConfigMapAsync (name , namespace ,
340- createModel ( getCombinedData ( existingConfigMap )) ,
349+ model ,
341350 createReplaceResponseStep (next ));
342351 }
343352
@@ -370,12 +379,6 @@ private boolean labelsNotDefined(V1ConfigMap currentMap) {
370379 }
371380 }
372381
373- private Map <String , String > getCombinedData (V1ConfigMap existingConfigMap ) {
374- Map <String , String > updated = Objects .requireNonNull (existingConfigMap .getData ());
375- updated .putAll (contents );
376- return updated ;
377- }
378-
379382 private ResponseStep <V1ConfigMap > createCreateResponseStep (Step next ) {
380383 return new CreateResponseStep (next );
381384 }
@@ -440,15 +443,6 @@ public NextAction onSuccess(Packet packet, CallResponse<V1ConfigMap> callRespons
440443
441444 }
442445
443- /** Returns true if the actual map contains all of the entries from the expected map. */
444- static class ConfigMapComparatorImpl extends ConfigMapComparator {
445-
446- @ Override
447- boolean containsAllData (Map <String , String > actual , Map <String , String > expected ) {
448- return actual .entrySet ().containsAll (expected .entrySet ());
449- }
450- }
451-
452446 /**
453447 * Factory for a step that creates or updates the generated domain config map from introspection results.
454448 * Reads the following packet fields:
@@ -596,7 +590,8 @@ private IntrospectorConfigMapContext createIntrospectorConfigMapContext() {
596590 return createIntrospectorConfigMapContext (data , 0 );
597591 }
598592
599- private IntrospectorConfigMapContext createIntrospectorConfigMapContext (Map <String , String > data , int index ) {
593+ private IntrospectorConfigMapContext createIntrospectorConfigMapContext (
594+ Map <String , String > data , int index ) {
600595 return new IntrospectorConfigMapContext (conflictStep , info , data , index );
601596 }
602597
@@ -662,11 +657,10 @@ private String perLine(List<String> errors) {
662657
663658 public static class IntrospectorConfigMapContext extends ConfigMapContext implements SplitterTarget {
664659
665- private static final Pattern ENCODED_ZIP_PATTERN = Pattern .compile ("([A-Za-z_]+)\\ .secure" );
666-
667660 private boolean patchOnly ;
668661
669- IntrospectorConfigMapContext (Step conflictStep , DomainPresenceInfo info , Map <String , String > data , int index ) {
662+ IntrospectorConfigMapContext (Step conflictStep , DomainPresenceInfo info ,
663+ Map <String , String > data , int index ) {
670664 super (conflictStep , getConfigMapName (info , index ), info .getNamespace (), data , info );
671665
672666 addLabel (LabelConstants .DOMAINUID_LABEL , info .getDomainUid ());
@@ -687,8 +681,8 @@ IntrospectorConfigMapContext patchOnly() {
687681 }
688682
689683 @ Override
690- boolean isIncompatibleMap (V1ConfigMap existingMap ) {
691- return !patchOnly && super .isIncompatibleMap (existingMap );
684+ boolean isOutdated (V1ConfigMap existingMap ) {
685+ return !patchOnly && super .isOutdated (existingMap );
692686 }
693687
694688 @ Override
0 commit comments