Source:
<code>public Void call(ConfigBag parameters) { if (!upgradeInProgress.compareAndSet(false, true)) { throw new IllegalStateException("An upgrade is already in progress."); } <START> EntitySpec<?> memberSpec = entity().getConfig(BrooklynCluster.MEMBER_SPEC); <END> Preconditions.checkNotNull(memberSpec, BrooklynCluster.MEMBER_SPEC.getName() + " is required for " + UpgradeClusterEffector.class.getName()); ConfigBag specCfg = ConfigBag.newInstance( memberSpec.getConfig() ); ConfigBag origSpecCfg = ConfigBag.newInstanceCopying(specCfg); log.debug("Upgrading "+entity()+", changing "+BrooklynCluster.MEMBER_SPEC+" from "+memberSpec+" / "+origSpecCfg); try { String newDownloadUrl = parameters.get(DOWNLOAD_URL); specCfg.putIfNotNull(DOWNLOAD_URL, newDownloadUrl); specCfg.put(BrooklynNode.DISTRO_UPLOAD_URL, inferUploadUrl(newDownloadUrl)); specCfg.putAll(ConfigBag.newInstance(parameters.get(EXTRA_CONFIG)).getAllConfigAsConfigKeyMap()); Map<ConfigKey<?>, Object> cfgLive = memberSpec.getConfigLive(); cfgLive.clear(); cfgLive.putAll(specCfg.getAllConfigAsConfigKeyMap()); entity().setConfig(BrooklynCluster.MEMBER_SPEC, memberSpec); log.debug("Upgrading "+entity()+", new "+BrooklynCluster.MEMBER_SPEC+": "+memberSpec+" / "+specCfg); upgrade(parameters); } catch (Exception e) { log.debug("Upgrading "+entity()+" failed, will rethrow after restoring "+BrooklynCluster.MEMBER_SPEC+" to: "+origSpecCfg); Map<ConfigKey<?>, Object> cfgLive = memberSpec.getConfigLive(); cfgLive.clear(); cfgLive.putAll(origSpecCfg.getAllConfigAsConfigKeyMap()); entity().setConfig(BrooklynCluster.MEMBER_SPEC, memberSpec); throw Exceptions.propagate(e); } finally { upgradeInProgress.set(false); } return null; }</code><technical_language>put this in try-block well, guarantee unset upgradeInProgress, if checkNotNull fails</technical_language>

Target:
public Void call(ConfigBag parameters) { if (!upgradeInProgress.compareAndSet(false, true)) { throw new IllegalStateException("An upgrade is already in progress."); } EntitySpec<?> origMemberSpec = entity().getConfig(BrooklynCluster.MEMBER_SPEC); Preconditions.checkNotNull(origMemberSpec, BrooklynCluster.MEMBER_SPEC.getName() + " is required for " + UpgradeClusterEffector.class.getName()); log.debug("Upgrading "+entity()+", changing "+BrooklynCluster.MEMBER_SPEC+" from "+origMemberSpec+" / "+origMemberSpec.getConfig()); boolean success = false; try { String newDownloadUrl = parameters.get(DOWNLOAD_URL); EntitySpec<?> newMemberSpec = EntitySpec.create(origMemberSpec); ConfigBag newConfig = ConfigBag.newInstance(); newConfig.putIfNotNull(DOWNLOAD_URL, newDownloadUrl); newConfig.put(BrooklynNode.DISTRO_UPLOAD_URL, inferUploadUrl(newDownloadUrl)); newConfig.putAll(ConfigBag.newInstance(parameters.get(EXTRA_CONFIG)).getAllConfigAsConfigKeyMap()); newMemberSpec.configure(newConfig.getAllConfigAsConfigKeyMap()); entity().setConfig(BrooklynCluster.MEMBER_SPEC, newMemberSpec); log.debug("Upgrading "+entity()+", new "+BrooklynCluster.MEMBER_SPEC+": "+newMemberSpec+" / "+newMemberSpec.getConfig()+" (adding: "+newConfig+")"); upgrade(parameters); success = true; } finally { if (!success) { log.debug("Upgrading "+entity()+" failed, will rethrow after restoring "+BrooklynCluster.MEMBER_SPEC+" to: "+origMemberSpec); entity().setConfig(BrooklynCluster.MEMBER_SPEC, origMemberSpec); } upgradeInProgress.set(false); } return null; }