Java Code Examples for org.apache.brooklyn.api.mgmt.Task#blockUntilEnded()

The following examples show how to use org.apache.brooklyn.api.mgmt.Task#blockUntilEnded() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ChildEntityCustomizer.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
@Override
public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) {
    EntitySpec<?> spec = config().get(CHILD_ENTITY_SPEC);
    Boolean create = config().get(CREATE_CHILD_ENTITY);
    Duration timeout = config().get(BrooklynConfigKeys.START_TIMEOUT);
    Entity parent = getCallerContext(machine);

    if (Boolean.TRUE.equals(create) && spec != null) {
        LOG.info("Creating child entity for {} in {}", parent, machine);
        Entity child = getBrooklynManagementContext().getEntityManager().createEntity(spec);
        child.setParent(parent);
        Task<Void> start = Entities.invokeEffectorWithArgs(parent, child, Startable.START, ImmutableList.of(machine));
        if (!start.blockUntilEnded(timeout)) {
            throw new IllegalStateException(String.format("Timed out while starting child entity for %s", parent));
        }
    }
}
 
Example 2
Source File: YamlLauncherAbstract.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
public Application launchAppYaml(Reader input, boolean waitForTasksToComplete) {
    try {
        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);

        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
        Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
        log.info("Launching "+app);

        if (getShutdownAppsOnExit()) BrooklynShutdownHooks.invokeStopOnShutdown(app);

        if (waitForTasksToComplete) {
            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
            log.info("Waiting on "+tasks.size()+" task(s)");
            for (Task<?> t: tasks) {
                t.blockUntilEnded();
            }
        }

        log.info("Application started from YAML: "+app);
        Dumper.dumpInfo(app);
        return (Application)app;
    } catch (Exception e) {
        throw Exceptions.propagate(e);
    }
}
 
Example 3
Source File: JavaWebAppWithDslYamlRebindIntegrationTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
/** as {@link JavaWebAppsIntegrationTest#testWithDbDeploy()} but with rebind */
@Test(groups={"Integration", "WIP", "Broken"})
public void testJavaWebAppDeployAndRebind() throws Exception {
    Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
    AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);

    Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
    final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());

    Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
    for (Task<?> t: tasks) t.blockUntilEnded();
    Dumper.dumpInfo(app);

    Application app2 = rebind(app);
    Assert.assertEquals(app2.getChildren().size(), 2);
}
 
Example 4
Source File: SoftwareEffectorTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
@Test(groups="Integration")
public void testBadExitCodeCaughtAndStdErrAvailable() {
    final ProcessTaskWrapper<?>[] sshTasks = new ProcessTaskWrapper[1];
    
    Task<Void> call = Entities.invokeEffector(app, app, Effectors.effector(Void.class, "badExitCode")
            .impl(new SshEffectorBody<Void>() {
                @Override
                public Void call(ConfigBag parameters) {
                    sshTasks[0] = queue( ssh(COMMAND_THAT_DOES_NOT_EXIST).requiringExitCodeZero() );
                    return null;
                }
            }).build() );
    call.blockUntilEnded();
    Assert.assertTrue(call.isError());
    log.info("stderr gives: "+new String(sshTasks[0].getStderr()));
    Assert.assertTrue(new String(sshTasks[0].getStderr()).indexOf(COMMAND_THAT_DOES_NOT_EXIST) >= 0);
}
 
Example 5
Source File: SoftwareProcessEntityTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
public void doTestReleaseEvenIfErrorDuringStop(final Class<? extends SimulatedDriver> driver) throws Exception {
    MyService entity = app.addChild(EntitySpec.create(MyServiceWithCustomDriver.class)
            .configure(MyServiceWithCustomDriver.DRIVER_CLASS, driver));
    
    entity.start(ImmutableList.of(loc));
    Task<Void> t = entity.invoke(Startable.STOP, ImmutableMap.<String, Object>of());
    t.blockUntilEnded();
    
    assertFalse(t.isError(), "Expected parent to succeed, not fail with " + Tasks.getError(t));
    Iterator<Task<?>> failures;
    failures = Tasks.failed(Tasks.descendants(t, true)).iterator();
    Assert.assertTrue(failures.hasNext(), "Expected error in descendants");
    Optional<Task<?>> stopping = Iterables.tryFind(Tasks.children(t), TaskPredicates.displayNameEqualTo("stopping"));
    Assert.assertTrue(stopping.isPresent(), "Could not find stopping task");
    failures = Tasks.failed(Tasks.children(stopping.get())).iterator();
    Assert.assertTrue(failures.hasNext(), "Expected error in child");
    Throwable e = Tasks.getError(failures.next());
    if (e == null || !e.toString().contains("Simulating stop error")) 
        Assert.fail("Wrong error", e);

    Assert.assertEquals(loc.getAvailable(), ImmutableSet.of(machine), "Expected location to be available again");

    Entities.unmanage(entity);
}
 
Example 6
Source File: DynamicSequentialTask.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
/** waits for this job to complete, or the given time to elapse */
public void join(boolean includePrimary, Duration optionalTimeout) throws InterruptedException {
    CountdownTimer timeLeft = optionalTimeout!=null ? CountdownTimer.newInstanceStarted(optionalTimeout) : null;
    while (true) {
        Task<?> cs;
        Duration remaining;
        synchronized (jobTransitionLock) {
            cs = currentSecondary;
            if (finishedSecondaries) return;
            remaining = timeLeft==null ? Duration.ONE_SECOND : timeLeft.getDurationRemaining();
            if (!remaining.isPositive()) return;
            if (cs==null) {
                if (!includePrimary && secondaryJobsRemaining.isEmpty()) return;
                // parent still running, no children though
                Tasks.setBlockingTask(DynamicSequentialTask.this);
                jobTransitionLock.wait(remaining.toMilliseconds());
                Tasks.resetBlockingDetails();
            }
        }
        if (cs!=null) {
            Tasks.setBlockingTask(cs);
            cs.blockUntilEnded(remaining);
            Tasks.resetBlockingDetails();
        }
    }
}
 
Example 7
Source File: AbstractYamlTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
protected void waitForApplicationTasks(Entity app, @Nullable Duration timeout) {
    Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
    getLogger().info("Waiting on " + tasks.size() + " task(s)");
    for (Task<?> t : tasks) {
        boolean done = t.blockUntilEnded(timeout);
        if (!done) throw new RuntimeException("Timeout waiting for task to complete: " + t);
    }
}
 
Example 8
Source File: JavaWebAppWithDslYamlRebindIntegrationTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
@Test(groups={"Integration", "WIP", "Broken"})
public void testJavaWebWithMemberSpecRebind() throws Exception {
    Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("test-java-web-app-spec-and-db-with-function.yaml"));
    AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);

    Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
    final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());

    Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
    for (Task<?> t: tasks) t.blockUntilEnded();
    Dumper.dumpInfo(app);
    
    Application app2 = rebind(app);
    Assert.assertEquals(app2.getChildren().size(), 2);
}
 
Example 9
Source File: AbstractYamlRebindTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
protected void waitForApplicationTasks(Entity app) {
    Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
    getLogger().info("Waiting on " + tasks.size() + " task(s)");
    for (Task<?> t : tasks) {
        t.blockUntilEnded();
    }
}
 
Example 10
Source File: Tasks.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/** 
 * Workaround for limitation described at {@link Task#cancel(boolean)};
 * internal method used to allow callers to wait for underlying tasks to finished in the case of cancellation.
 * <p> 
 * It is irritating that {@link FutureTask} sync's object clears the runner thread, 
 * so even if {@link BasicTask#getInternalFuture()} is used, there is no means of determining if the underlying object is done.
 * The {@link Task#getEndTimeUtc()} seems the only way.
 *  
 * @return true if tasks ended; false if timed out
 **/ 
@Beta
public static boolean blockUntilInternalTasksEnded(Task<?> t, Duration timeout) {
    CountdownTimer timer = timeout.countdownTimer();
    
    if (t==null)
        return true;
    
    if (t instanceof ScheduledTask) {
        boolean result = ((ScheduledTask)t).blockUntilNextRunFinished(timer.getDurationRemaining());
        if (!result) return false;
    }

    t.blockUntilEnded(timer.getDurationRemaining());
    
    while (true) {
        if (t.getEndTimeUtc()>=0) return true;
        // above should be sufficient; but just in case, trying the below
        Thread tt = t.getThread();
        if (t instanceof ScheduledTask) {
            ((ScheduledTask)t).blockUntilNextRunFinished(timer.getDurationRemaining());
            return true;
        } else {
            if (tt==null || !tt.isAlive()) {
                if (!t.isCancelled()) {
                    // may happen for a cancelled task, interrupted after submit but before start
                    log.warn("Internal task thread is dead or null ("+tt+") but task not ended: "+t.getEndTimeUtc()+" ("+t+")");
                }
                return true;
            }
        }
        if (timer.isExpired())
            return false;
        Time.sleep(Repeater.DEFAULT_REAL_QUICK_PERIOD);
    }
}
 
Example 11
Source File: ApplicationLifecycleStateTest.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/**
 * Tests concurrent modifications to a sensor, asserting that the last notification the subscribers 
 * receives equals the last value that sensor has.
 * 
 * Prior to this being fixed (see https://github.com/apache/brooklyn-server/pull/622), it caused 
 * problems in ComputeServiceIndicatorsFromChildrenAndMembers: it saw a child transition 
 * from "running" to "starting", and thus emitted the on-fire event for the parent entity. As asserted
 * by this test, the enricher should now always receive the events in the correct order (e.g. "starting",
 * "running").
 */
@Test
public void testSettingSensorFromThreads() {
    final TestApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(TestApplication.class));
    final AttributeSensor<String> TEST_SENSOR = Sensors.newStringSensor("test.sensor");

    final AtomicReference<String> lastSeenState = new AtomicReference<>();
    app.subscriptions().subscribe(app, TEST_SENSOR, new SensorEventListener<String>() {
        @Override
        public void onEvent(SensorEvent<String> event) {
            lastSeenState.set(event.getValue());
            log.debug("seen event=" + event);
        }
    });

    Task<?> first = mgmt.getExecutionManager().submit("setting test sensor", () -> {
            app.sensors().set(TEST_SENSOR, "first");
            log.debug("set first");
        });
    Task<?> second = mgmt.getExecutionManager().submit("setting test sensor", () -> {
            app.sensors().set(TEST_SENSOR, "second");
            log.debug("set second");
        });
    first.blockUntilEnded();
    second.blockUntilEnded();

    Asserts.succeedsEventually(new Runnable() {
        @Override
        public void run() {
            EntityAsserts.assertAttributeEquals(app, TEST_SENSOR, lastSeenState.get());
        }
    });
}
 
Example 12
Source File: JcloudsLocation.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
protected void releasePortForwarding(final JcloudsMachineLocation machine) {
    // TODO Implementation needs revisisted. It relies on deprecated PortForwardManager methods.

    boolean usePortForwarding = Boolean.TRUE.equals(machine.getConfig(USE_PORT_FORWARDING));
    final JcloudsPortForwarderExtension portForwarder = machine.getConfig(PORT_FORWARDER);
    final String nodeId = machine.getJcloudsId();
    final Map<String, Runnable> subtasks = Maps.newLinkedHashMap();

    PortForwardManager portForwardManager = machine.getConfig(PORT_FORWARDING_MANAGER);
    if (portForwardManager == null) {
        LOG.debug("No PortForwardManager, using default");
        portForwardManager = (PortForwardManager) getManagementContext().getLocationRegistry().getLocationManaged(PortForwardManagerLocationResolver.PFM_GLOBAL_SPEC);
    }

    if (portForwarder == null) {
        LOG.debug("No port-forwarding to close (because portForwarder null) on release of " + machine);
    } else {
        final Optional<NodeMetadata> node = machine.getOptionalNode();
        // Release the port-forwarding for the login-port, which was explicitly created by JcloudsLocation
        if (usePortForwarding && node.isPresent()) {
            final HostAndPort hostAndPortOverride;
            if (machine instanceof SshMachineLocation) {
                hostAndPortOverride = ((SshMachineLocation)machine).getSshHostAndPort();
            } else if (machine instanceof WinRmMachineLocation) {
                String host = ((WinRmMachineLocation)machine).getAddress().getHostAddress();
                int port = ((WinRmMachineLocation)machine).getPort();
                hostAndPortOverride = HostAndPort.fromParts(host, port);
            } else {
                LOG.warn("Unexpected machine {} of type {}; expected SSH or WinRM", machine, (machine != null ? machine.getClass() : null));
                hostAndPortOverride = null;
            }
            if (hostAndPortOverride != null) {
                final int loginPort = node.get().getLoginPort();
                subtasks.put(
                        "Close port-forward "+hostAndPortOverride+"->"+loginPort,
                        new Runnable() {
                            @Override
                            public void run() {
                                LOG.debug("Closing port-forwarding at {} for machine {}: {}->{}", new Object[] {this, machine, hostAndPortOverride, loginPort});
                                portForwarder.closePortForwarding(node.get(), loginPort, hostAndPortOverride, Protocol.TCP);
                            }
                        });
            }
        }

        // Get all the other port-forwarding mappings for this VM, and release all of those
        Set<PortMapping> mappings = Sets.newLinkedHashSet();
        mappings.addAll(portForwardManager.getLocationPublicIpIds(machine));
        if (nodeId != null) {
            mappings.addAll(portForwardManager.getPortMappingWithPublicIpId(nodeId));
        }

        for (final PortMapping mapping : mappings) {
            final HostAndPort publicEndpoint = mapping.getPublicEndpoint();
            final int targetPort = mapping.getPrivatePort();
            final Protocol protocol = Protocol.TCP;
            if (publicEndpoint != null && node.isPresent()) {
                subtasks.put(
                        "Close port-forward "+publicEndpoint+"->"+targetPort,
                        new Runnable() {
                            @Override
                            public void run() {
                                LOG.debug("Closing port-forwarding at {} for machine {}: {}->{}", new Object[] {this, machine, publicEndpoint, targetPort});
                                portForwarder.closePortForwarding(node.get(), targetPort, publicEndpoint, protocol);
                            }
                        });
            }
        }

        if (subtasks.size() > 0) {
            final TaskBuilder<Void> builder = TaskBuilder.<Void>builder()
                    .parallel(true)
                    .displayName("close port-forwarding at "+machine);
            for (Map.Entry<String, Runnable> entry : subtasks.entrySet()) {
                builder.add(TaskBuilder.builder().displayName(entry.getKey()).body(entry.getValue()).build());
            }
            final Task<Void> task = builder.build();
            final DynamicTasks.TaskQueueingResult<Void> queueResult = DynamicTasks.queueIfPossible(task);
            if(queueResult.isQueuedOrSubmitted()){
                final String origDetails = Tasks.setBlockingDetails("waiting for closing port-forwarding of "+machine);
                try {
                    task.blockUntilEnded();
                } finally {
                    Tasks.setBlockingDetails(origDetails);
                }
            } else {
                LOG.warn("Releasing port-forwarding of "+machine+" not executing in execution-context "
                        + "(e.g. not invoked inside effector); falling back to executing sequentially");
                for (Runnable subtask : subtasks.values()) {
                    subtask.run();
                }
            }
        }
    }

    // Forget all port mappings associated with this VM
    portForwardManager.forgetPortMappings(machine);
    if (nodeId != null) {
        portForwardManager.forgetPortMappings(nodeId);
    }
}
 
Example 13
Source File: AutoScalerPolicy.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
private void resizeNow(String reason) {
    final int currentPoolSize = getCurrentSizeOperator().apply(poolEntity);
    CalculatedDesiredPoolSize calculatedDesiredPoolSize = calculateDesiredPoolSize(currentPoolSize);
    long desiredPoolSize = calculatedDesiredPoolSize.size;
    boolean stable = calculatedDesiredPoolSize.stable;
    
    final int targetPoolSize = applyMinMaxConstraints(desiredPoolSize);
    
    if (!stable) {
        // the desired size fluctuations are not stable; ensure we check again later (due to time-window)
        // even if no additional events have been received
        // (note we continue now with as "good" a resize as we can given the instability)
        if (LOG.isTraceEnabled()) LOG.trace("{} re-scheduling resize check for {}, as desired size not stable (current {}, desired {}); continuing with resize...", 
                new Object[] {this, poolEntity, currentPoolSize, targetPoolSize});
        scheduleResize(reason);
    }
    if (currentPoolSize == targetPoolSize) {
        if (LOG.isTraceEnabled()) LOG.trace("{} not resizing pool {} from {} to {}", 
                new Object[] {this, poolEntity, currentPoolSize, targetPoolSize});
        return;
    }
    
    if (LOG.isDebugEnabled()) LOG.debug("{} requesting resize to {}; current {}, min {}, max {}", 
            new Object[] {this, targetPoolSize, currentPoolSize, getMinPoolSize(), getMaxPoolSize()});
    
    Task<Void> t = Entities.submit(entity, Tasks.<Void>builder().displayName("Auto-scaler")
        .description("Auto-scaler recommending resize from "+currentPoolSize+" to "+targetPoolSize)
        .tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
        .body(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                // TODO Should we use int throughout, rather than casting here?
                try {
                    getResizeOperator().resize(poolEntity, targetPoolSize);
                } catch (Resizable.InsufficientCapacityException e) {
                    // cannot resize beyond this; set the high-water mark
                    int insufficientCapacityHighWaterMark = getCurrentSizeOperator().apply(poolEntity);
                    LOG.warn("{} failed to resize {} due to insufficient capacity; setting high-water mark to {}, "
                            + "and will not attempt to resize above that level again", 
                            new Object[] {AutoScalerPolicy.this, poolEntity, insufficientCapacityHighWaterMark});
                    config().set(INSUFFICIENT_CAPACITY_HIGH_WATER_MARK, insufficientCapacityHighWaterMark);
                }
                return null;
            }
        }).build());
    highlightAction("Resize from "+currentPoolSize+" to "+targetPoolSize+
        (reason!=null ? " because "+reason : ""), t);
    t.blockUntilEnded();
}
 
Example 14
Source File: ActivityRestTest.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
private Task<?> waitForCompletedDescendantWithChildAndSibling(Task<?> tRoot, Task<?> t, CountdownTimer timer, int depthSoFar) {
    while (timer.isLive()) {
        Iterable<Task<?>> children = ((HasTaskChildren)t).getChildren();
        Iterator<Task<?>> ci = children.iterator();
        Task<?> bestFinishedDescendant = null;
        while (ci.hasNext()) {
            Task<?> tc = ci.next();
            Task<?> finishedDescendant = waitForCompletedDescendantWithChildAndSibling(tRoot, tc, timer, depthSoFar+1);
            if (depthOf(finishedDescendant) > depthOf(bestFinishedDescendant)) {
                bestFinishedDescendant = finishedDescendant;
            }
            int finishedDescendantDepth = depthOf(bestFinishedDescendant);
            // log.info("finished "+tc+", depth "+finishedDescendantDepth);
            if (finishedDescendantDepth < 2) {
                if (ci.hasNext()) continue;
                throw new IllegalStateException("not deep enough: "+finishedDescendantDepth);
            }
            if (finishedDescendantDepth == depthSoFar+1) {
                // child completed; now check we complete soon, and assert we have siblings
                if (ci.hasNext()) continue;
                if (!t.blockUntilEnded(timer.getDurationRemaining())) {
                    Dumper.dumpInfo(tRoot);
                    // log.info("Incomplete after "+t+": "+t.getStatusDetail(false));
                    throw Exceptions.propagate( new TimeoutException("parent didn't complete after child depth "+finishedDescendantDepth) );
                }
            }
            if (finishedDescendantDepth == depthSoFar+2) {
                if (Iterables.size(children)<2) {
                    Dumper.dumpInfo(tRoot);
                    throw new IllegalStateException("finished child's parent has no sibling");
                }
            }
            
            return bestFinishedDescendant;
        }
        Thread.yield();
        
        // leaf nodeƄ
        if (t.isDone()) return t;
    }
    throw Exceptions.propagate( new TimeoutException("expired waiting for children") );
}