/** @see #queueIfPossible(TaskAdaptable) */ public static <T> TaskQueueingResult<T> queueIfPossible(TaskFactory<? extends TaskAdaptable<T>> task) { return queueIfPossible(task.newTask()); }
/** queues the task if possible, otherwise submits it asynchronously; returns the task for callers to * {@link Task#getUnchecked()} or {@link Task#blockUntilEnded()} */ public static <T> Task<T> submit(TaskAdaptable<T> task, Entity entity) { return queueIfPossible(task).orSubmitAsync(entity).asTask(); }
/** Common implementation for stop in parent nodes; just invokes stop on all children of the entity */ public static void stop(Entity e) { log.debug("Stopping entity "+e); DynamicTasks.queueIfPossible(stoppingChildren(e)).orSubmitAsync(e).getTask().getUnchecked(); if (log.isDebugEnabled()) log.debug("Stopped entity "+e); }
/** Common implementation for restart in parent nodes; just invokes restart on all children of the entity */ public static void restart(Entity e) { log.debug("Restarting entity "+e); DynamicTasks.queueIfPossible(restartingChildren(e)).orSubmitAsync(e).getTask().getUnchecked(); if (log.isDebugEnabled()) log.debug("Restarted entity "+e); }
/** queues the task for execution if we are in a {@link TaskQueueingContext} (e.g. EffectorTaskFactory); * or if we aren't in a queueing context, it will submit the task (assuming there is an {@link ExecutionContext} * _and_ block until completion, throwing on error */ @Beta public Task<Integer> queue() { return DynamicTasks.queueIfPossible(newTask()).orSubmitAndBlock().getTask(); }
/** queues the task for execution if we are in a {@link TaskQueueingContext} (e.g. EffectorTaskFactory); * or if we aren't in a queueing context, it will submit the task (assuming there is an {@link ExecutionContext} * _and_ block until completion, throwing on error */ @Beta public Task<Integer> queue() { return DynamicTasks.queueIfPossible(newTask()).orSubmitAndBlock().getTask(); }
@Override public Entity addExistingMachine(MachineLocation machine) { LOG.info("Adding additional machine to {}: {}", this, machine); Entity added = addNode(machine, MutableMap.of(REMOVABLE, false)); Map<String, ?> args = ImmutableMap.of("locations", ImmutableList.of(machine)); Task<Void> task = Effectors.invocation(added, Startable.START, args).asTask(); DynamicTasks.queueIfPossible(task).orSubmitAsync(this); return added; }
/** Common implementation for start in parent nodes; just invokes start on all children of the entity */ public static void start(Entity e, Collection<? extends Location> locations) { log.debug("Starting entity "+e+" at "+locations); DynamicTasks.queueIfPossible(startingChildren(e, locations)).orSubmitAsync(e).getTask().getUnchecked(); }
/** * Creates a MachineDetails for the given location by SSHing to the machine and * running a Bash script to gather data. Should only be called from within a * task context. If this might not be the case then use {@link * #taskForSshMachineLocation(SshMachineLocation)} instead. */ @Beta public static BasicMachineDetails forSshMachineLocationLive(SshMachineLocation location) { return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location)) .orSubmitAsync() .asTask()) .getUnchecked(); }
protected void stopAndRemoveNode(Entity member) { removeMember(member); try { if (member instanceof Startable) { Task<?> task = newThrottledEffectorTask(member, Startable.STOP, Collections.<String, Object>emptyMap()); DynamicTasks.queueIfPossible(task).orSubmitAsync(); task.getUnchecked(); } } finally { Entities.unmanage(member); } }
@Override protected String startProcessesAtMachine(Supplier<MachineLocation> machineS) { DynamicTasks.queueIfPossible(StartableMethods.startingChildren(entity(), machineS.get())) .orSubmitAsync(entity()) .getTask() .getUnchecked(); DynamicTasks.waitForLast(); return "children started"; }
@Override public void redeployAll() { Map<String, String> wars = MutableMap.copyOf(getConfig(WARS_BY_CONTEXT)); String redeployPrefix = "Redeploy all WARs (count "+wars.size()+")"; log.debug("Redeplying all WARs across cluster "+this+": "+getConfig(WARS_BY_CONTEXT)); Iterable<CanDeployAndUndeploy> targetEntities = Iterables.filter(getChildren(), CanDeployAndUndeploy.class); TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).displayName(redeployPrefix+" across cluster (size "+Iterables.size(targetEntities)+")"); for (Entity targetEntity: targetEntities) { TaskBuilder<Void> redeployAllToTarget = Tasks.<Void>builder().displayName(redeployPrefix+" at "+targetEntity+" (after ready check)"); for (String warContextPath: wars.keySet()) { redeployAllToTarget.add(Effectors.invocation(targetEntity, DEPLOY, MutableMap.of("url", wars.get(warContextPath), "targetName", warContextPath))); } tb.add(whenServiceUp(targetEntity, redeployAllToTarget.build(), redeployPrefix+" at "+targetEntity+" when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); }
protected void connectSensorsAsync() { Callable<Void> asyncTask = new Callable<Void>() { @Override public Void call() throws Exception { //blocks until available (could be a task) String mirroredEntityUrl = getConfig(MIRRORED_ENTITY_URL); Preconditions.checkNotNull(mirroredEntityUrl, "Required config: "+MIRRORED_ENTITY_URL); connectSensors(mirroredEntityUrl); return null; } }; DynamicTasks.queueIfPossible( Tasks.<Void>builder() .displayName("Start entity mirror feed") .body(asyncTask) .build()) .orSubmitAsync(this); }
@Override public Boolean call() throws Exception { Task<Entity> first = DependentConfiguration.attributeWhenReady(cluster, DynamicCluster.FIRST); DynamicTasks.queueIfPossible(first).orSubmitAsync(); final Entity source = first.get(); final Task<Boolean> booleanTask = DependentConfiguration.attributeWhenReady(source, Attributes.SERVICE_UP); DynamicTasks.queueIfPossible(booleanTask).orSubmitAsync(); return booleanTask.get(); } })
@Override public void deploy(String url, String targetName) { checkNotNull(url, "url"); checkNotNull(targetName, "targetName"); targetName = FILENAME_TO_WEB_CONTEXT_MAPPER.convertDeploymentTargetNameToContext(targetName); // set it up so future nodes get the right wars addToWarsByContext(this, url, targetName); log.debug("Deploying "+targetName+"->"+url+" 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).displayName("Deploy "+targetName+" to cluster (size "+Iterables.size(targets)+")"); for (Entity target: targets) { tb.add(whenServiceUp(target, Effectors.invocation(target, DEPLOY, MutableMap.of("url", url, "targetName", targetName)), "Deploy "+targetName+" to "+target+" when ready")); } DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked(); // Update attribute // TODO support for atomic sensor update (should be part of standard tooling; NB there is some work towards this, according to @aledsage) Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS)); deployedWars.add(targetName); sensors().set(DEPLOYED_WARS, deployedWars); }
public void apply(final Entity source, final Object valueIgnored) { T val = (T) attribute.getValue(); if (!readiness.apply(val)) { log.warn("Skipping {} for {} because attribute {} not ready", new Object[]{description, attribute.getEntity(), attribute.getAttribute()}); return; } final Task<Void> task = TaskBuilder.<Void>builder().displayName(description).body(runnable).build(); DynamicTasks.queueIfPossible(task).orSubmitAsync(source).asTask(); if (blockUntilEnded) { final String originalBlock = Tasks.setBlockingDetails(description); try { task.blockUntilEnded(); } finally { Tasks.setBlockingDetails(originalBlock); } } } }
public static void addExtraPublicKeys(Entity entity, SshMachineLocation location) { String extraPublicKey = location.config().get(JcloudsLocationConfig.EXTRA_PUBLIC_KEY_DATA_TO_AUTH); if (extraPublicKey == null) { // Custom location config doesn't get passed through because locations are cached for performance reasons. // As a fallback check the entity config. extraPublicKey = entity.config().get(JcloudsLocationConfig.EXTRA_PUBLIC_KEY_DATA_TO_AUTH); } if (extraPublicKey != null) { LOG.info(location + ": Adding public key " + extraPublicKey); String cmd = "mkdir -p ~/.ssh && cat <<EOF >> ~/.ssh/authorized_keys\n" + extraPublicKey + "\nEOF\n"; ProcessTaskWrapper<Integer> task = SshTasks.newSshExecTaskFactory(location, cmd) .summary("Add public key") .requiringExitCodeZero().newTask(); BrooklynTaskTags.markInessential(task); DynamicTasks.queueIfPossible(task).orSubmitAsync(entity); } } }
private boolean installFile(InputStream contents, String destName) { String uid = Identifiers.makeRandomId(8); // TODO currently put in /tmp for staging, since run dir may not be accessible to ssh user getMachine().copyTo(contents, "/tmp/"+destName+"_"+uid); DynamicTasks.queueIfPossible(SshEffectorTasks.ssh( "cd "+getRunDir(), "mv /tmp/"+destName+"_"+uid+" "+destName, "chown postgres:postgres "+destName, "chmod 644 "+destName) .runAsRoot().requiringExitCodeZero()) .orSubmitAndBlock(getEntity()).andWaitForSuccess(); return true; } private boolean copyDatabaseCreationScript() {
@Override public Boolean execute(final boolean shouldThrow) { Task<Boolean> t = Tasks.<Boolean>builder() .body(new Callable<Boolean>() { @Override public Boolean call() { if (shouldThrow) { throw new IllegalArgumentException("exception in feed task"); } return true; } }) .build(); return DynamicTasks.queueIfPossible(t).orSubmitAsync().asTask().getUnchecked(); } }
@Override public void rebind() { super.rebind(); Task<String> task = new BasicTask<String>(new Callable<String>() { @Override public String call() { return "abc"; }}); String val = DynamicTasks.queueIfPossible(task) .orSubmitAsync() .asTask() .getUnchecked(); sensors().set(TestEntity.NAME, val); } }