@Override public void undeploy(String targetName) { checkNotNull(targetName, "targetName"); targetName = FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName); // set it up so future nodes get the right wars if (!removeFromWarsByContext(this, targetName)) { DynamicTasks.submit( Tasks.warning( "Context " + targetName + " not known at " + this + "; attempting to undeploy regardless", null), this); } log.debug( "Undeploying " + targetName + " across cluster " + this + "; WARs now " + getConfig(WARS_BY_CONTEXT)); Iterable<CanDeployAndUndeploy> targets = Iterables.filter(getChildren(), CanDeployAndUndeploy.class); TaskBuilder<Void> tb = Tasks.<Void>builder() .parallel(true) .name( "Undeploy " + targetName + " across cluster (size " + Iterables.size(targets) + ")"); for (Entity target : targets) { tb.add( whenServiceUp( target, Effectors.invocation(target, UNDEPLOY, MutableMap.of("targetName", targetName)), "Undeploy " + targetName + " at " + target + " when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); // Update attribute Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS)); deployedWars.remove( FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName)); setAttribute(DEPLOYED_WARS, deployedWars); }