Source:
<code>public Action<?, ?> upgradeCluster() { return new AbstractClusterUpgradeAction<>(ClusterManagerUpgradeSuccess.class) { @Override protected ClusterUpgradeContext createFlowContext(FlowParameters flowParameters, StateContext<FlowState, FlowEvent> stateContext, ClusterManagerUpgradeSuccess payload) { return ClusterUpgradeContext.from(flowParameters, payload); } @Override protected void doExecute(ClusterUpgradeContext context, ClusterManagerUpgradeSuccess payload, Map<Object, Object> variables) { Image currentImage = getImage(variables, CURRENT_IMAGE); Image targetImage = getImage(variables, TARGET_IMAGE); boolean clusterRuntimeUpgradeNeeded = clusterUpgradeService.upgradeCluster(context.getStackId(), currentImage, targetImage); Selectable event; if (clusterRuntimeUpgradeNeeded) { event = new ClusterUpgradeRequest(context.getStackId(), isPatchUpgrade(currentImage, targetImage)); } else { event = new ClusterUpgradeSuccess(context.getStackId()); } sendEvent(context, event.selector(), event); } private boolean isPatchUpgrade(Image currentImage, Image targetImage) { <START> return currentImage.getStackDetails().getVersion().equals(targetImage.getStackDetails().getVersion()); <END> } private Image getImage(Map<Object, Object> variables, String key) { return ((StatedImage) variables.get(key)).getImage(); } @Override protected Object getFailurePayload(ClusterManagerUpgradeSuccess payload, Optional<ClusterUpgradeContext> flowContext, Exception ex) { return ClusterUpgradeFailedEvent.from(payload, ex, DetailedStackStatus.CLUSTER_UPGRADE_FAILED); } }; }</code><technical_language>pls this NPE safe in case of base images</technical_language>

Target:
public Action<?, ?> upgradeCluster() { return new AbstractClusterUpgradeAction<>(ClusterManagerUpgradeSuccess.class) { @Override protected ClusterUpgradeContext createFlowContext(FlowParameters flowParameters, StateContext<FlowState, FlowEvent> stateContext, ClusterManagerUpgradeSuccess payload) { return ClusterUpgradeContext.from(flowParameters, payload); } @Override protected void doExecute(ClusterUpgradeContext context, ClusterManagerUpgradeSuccess payload, Map<Object, Object> variables) { Image currentImage = getImage(variables, CURRENT_IMAGE); Image targetImage = getImage(variables, TARGET_IMAGE); boolean clusterRuntimeUpgradeNeeded = clusterUpgradeService.upgradeCluster(context.getStackId(), currentImage, targetImage); Selectable event; if (clusterRuntimeUpgradeNeeded) { event = new ClusterUpgradeRequest(context.getStackId(), isPatchUpgrade(currentImage, targetImage)); } else { event = new ClusterUpgradeSuccess(context.getStackId()); } sendEvent(context, event.selector(), event); } private boolean isPatchUpgrade(Image currentImage, Image targetImage) { StackDetails currentImageStackDetails = currentImage.getStackDetails(); StackDetails targetImageStackDetails = targetImage.getStackDetails(); return currentImageStackDetails != null && targetImageStackDetails != null && currentImageStackDetails.getVersion().equals(targetImageStackDetails.getVersion()); } private Image getImage(Map<Object, Object> variables, String key) { return ((StatedImage) variables.get(key)).getImage(); } @Override protected Object getFailurePayload(ClusterManagerUpgradeSuccess payload, Optional<ClusterUpgradeContext> flowContext, Exception ex) { return ClusterUpgradeFailedEvent.from(payload, ex, DetailedStackStatus.CLUSTER_UPGRADE_FAILED); } }; }