Java Code Examples for org.apache.brooklyn.util.exceptions.Exceptions#collapseText()

The following examples show how to use org.apache.brooklyn.util.exceptions.Exceptions#collapseText() . 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: BrooklynYamlLocationResolver.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
protected LocationSpec<?> resolveLocation(String spec, Map<?,?> flags) {
    LocationDefinition ldef = mgmt.getLocationRegistry().getDefinedLocationByName(spec);
    if (ldef!=null)
        // found it as a named location
        return mgmt.getLocationRegistry().getLocationSpec(ldef, flags).get();
    
    Maybe<LocationSpec<?>> l = mgmt.getLocationRegistry().getLocationSpec(spec, flags);
    if (l.isPresent()) return l.get();
    
    RuntimeException exception = Maybe.getException(l);
    if (exception instanceof NoSuchElementException && 
            exception.getMessage().contains("Unknown location")) {
        // common case
        throw new UserFacingException(exception.getMessage(), exception.getCause());
    }
    throw new UserFacingException("Illegal parameter for 'location' ("+spec+"); not resolvable: "+
        Exceptions.collapseText( exception ), exception);
}
 
Example 2
Source File: BasicLauncher.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
private void startPersistenceWithoutHA() {
    RebindManager rebindManager = managementContext.getRebindManager();
    if (Strings.isNonBlank(persistenceLocation))
        LOG.info("Management node (no HA) rebinding to entities at "+persistenceLocation+" in "+persistenceDir);
    else
        LOG.info("Management node (no HA) rebinding to entities on file system in "+persistenceDir);

    ClassLoader classLoader = managementContext.getCatalogClassLoader();
    try {
        rebindManager.rebind(classLoader, null, ManagementNodeState.MASTER);
    } catch (Exception e) {
        Exceptions.propagateIfFatal(e);
        LOG.debug("Error rebinding to persisted state (rethrowing): "+e, e);
        throw new FatalRuntimeException("Error rebinding to persisted state: "+
            Exceptions.collapseText(e), e);
    }
    rebindManager.startPersistence();
}
 
Example 3
Source File: BrooklynNodeImpl.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
@Override
public Void call(ConfigBag parameters) {
    MutableMap<String, String> formParams = MutableMap.of();
    Lifecycle initialState = entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL);
    ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING);
    for (ConfigKey<?> k: new ConfigKey<?>[] { STOP_APPS_FIRST, FORCE_SHUTDOWN_ON_ERROR, SHUTDOWN_TIMEOUT, REQUEST_TIMEOUT, DELAY_FOR_HTTP_RETURN })
        formParams.addIfNotNull(k.getName(), toNullableString(parameters.get(k)));
    try {
        log.debug("Shutting down "+entity()+" with "+formParams);
        HttpToolResponse resp = ((BrooklynNode)entity()).http()
            .post("/v1/server/shutdown",
                ImmutableMap.of("Brooklyn-Allow-Non-Master-Access", "true"),
                formParams);
        if (resp.getResponseCode() != HttpStatus.SC_NO_CONTENT) {
            throw new IllegalStateException("Response code "+resp.getResponseCode());
        }
    } catch (Exception e) {
        Exceptions.propagateIfFatal(e);
        throw new PropagatedRuntimeException("Error shutting down remote node "+entity()+" (in state "+initialState+"): "+Exceptions.collapseText(e), e);
    }
    ServiceNotUpLogic.updateNotUpIndicator(entity(), SHUTDOWN.getName(), "Shutdown of remote node has completed successfuly");
    return null;
}
 
Example 4
Source File: WebResourceUtils.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
/** @throws WebApplicationException with an ApiError as its body and the given status as its response code.
 * Exception and/or format can be null, and will be filled in / prefixed as appropriate. */
public static WebApplicationException throwWebApplicationException(Response.Status status, Throwable exception, String format, Object... args) {
    String suppliedMsg = format==null ? null : String.format(format, args);
    String fullMsg = suppliedMsg;
    if (exception!=null) {
        if (fullMsg==null) fullMsg = Exceptions.collapseText(exception);
        else fullMsg = suppliedMsg + ": "+Exceptions.collapseText(exception);
    }
    if (log.isDebugEnabled()) {
        log.debug("responding {} {} ({})",
                new Object[]{status.getStatusCode(), status.getReasonPhrase(), fullMsg});
    }
    ApiError apiError = 
        (exception != null ? ApiError.builderFromThrowable(exception).prefixMessage(suppliedMsg) 
            : ApiError.builder().message(fullMsg==null ? "" : fullMsg))
        .errorCode(status).build();
    // including a Throwable is the only way to include a message with the WebApplicationException - ugly!
    throw new WebApplicationException(
        exception==null ? new Throwable(apiError.toString()) :
            suppliedMsg==null ? exception :
            new PropagatedRuntimeException(suppliedMsg, exception), 
        apiError.asJsonResponse());
}
 
Example 5
Source File: EffectorBasicTest.java    From brooklyn-server with Apache License 2.0 6 votes vote down vote up
@Test
public void testInvokeEffectorErrorCollapsedNicely() {
    FailingEntity entity = createFailingEntity();
    Task<Void> task = entity.invoke(Startable.START, MutableMap.of("locations", locs));
    Exception e = assertTaskFails( task );
    // normal collapse should report where we started
    String collapsed = Exceptions.collapseText(e);
    Assert.assertFalse(Strings.containsLiteral(collapsed, "Propagated"), "Error too verbose: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "invoking"), "Error not verbose enough: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "start"), "Error not verbose enough: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "FailingEntity"), "Error not verbose enough: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, entity.getId()), "Error not verbose enough: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "Simulating"), "Error not verbose enough: "+collapsed);
    // in the context of the task we should not report where we started;
    // it instead of
    //    Error invoking start at FailingEntityImpl{id=wv6KwsPh}: Simulating entity stop failure for test
    // show
    //   Simulating entity start failure for test
    collapsed = Exceptions.collapseTextInContext(e, task);
    Assert.assertFalse(Strings.containsLiteral(collapsed, "Propagated"), "Error too verbose: "+collapsed);
    Assert.assertFalse(Strings.containsLiteral(collapsed, "invoking"), "Error too verbose: "+collapsed);
    Assert.assertFalse(Strings.containsLiteral(collapsed, "FailingEntity"), "Error too verbose: "+collapsed);
    Assert.assertFalse(Strings.containsLiteral(collapsed, entity.getId()), "Error too verbose: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "start"), "Error not verbose enough: "+collapsed);
    Assert.assertTrue(Strings.containsLiteral(collapsed, "Simulating"), "Error not verbose enough: "+collapsed);
}
 
Example 6
Source File: BasicLauncher.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
protected void startApps() {
    List<Throwable> appExceptions = Lists.newArrayList();
    for (Application app : apps) {
        if (app instanceof Startable) {

            try {
                LOG.info("Starting brooklyn application {} in location{} {}", new Object[] { app, locations.size()!=1?"s":"", locations });
                ((Startable)app).start(locations);
                Dumper.dumpInfo(app);
                String sensors = "";
                if (app.getAttribute(Attributes.MAIN_URI_MAPPED_PUBLIC)!=null) {
                    sensors = ": "+app.getAttribute(Attributes.MAIN_URI_MAPPED_PUBLIC);
                } else if (app.getAttribute(Attributes.MAIN_URI)!=null) {
                    sensors += ": "+app.getAttribute(Attributes.MAIN_URI);
                }
                LOG.info("Started brooklyn application {} in location{} {}{}", new Object[] { app, locations.size()!=1?"s":"", locations,
                    sensors });
            } catch (Exception e) {
                LOG.error("Error starting "+app+": "+Exceptions.collapseText(e), Exceptions.getFirstInteresting(e));
                appExceptions.add(Exceptions.collapse(e));

                if (Thread.currentThread().isInterrupted()) {
                    LOG.error("Interrupted while starting applications; aborting");
                    break;
                }
            }
        }
    }
    if (!appExceptions.isEmpty()) {
        Throwable t = Exceptions.create(appExceptions);
        throw new FatalRuntimeException("Error starting applications: "+Exceptions.collapseText(t), t);
    }
}
 
Example 7
Source File: Reflections.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/** @deprecated since 0.11.0, use {@link org.apache.brooklyn.util.core.ClassLoaderUtils} in a combination with {@link #invokeConstructorFromArgs(Class, Object...)} instead */
public Object loadInstance(String classname, Object...argValues) throws ReflectionNotFoundException, ReflectionAccessException {
    Class<?> clazz = loadClass(classname);
    Maybe<?> v = null;
    try {
        v = invokeConstructorFromArgs(clazz, argValues);
        if (v.isPresent()) return v.get();
    } catch (Exception e) {
        throw new IllegalStateException("Error invoking constructor for "+clazz+Arrays.toString(argValues) + ": " + Exceptions.collapseText(e));
    }
    throw new IllegalStateException("No suitable constructor for "+clazz+Arrays.toString(argValues));
}
 
Example 8
Source File: Reflections.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/** returns the first method matching the given name */
public Method loadMethod(Class<?> clazz, String methodName) throws ReflectionNotFoundException, ReflectionAccessException {
    try {
        Method[] allmethods = clazz.getMethods();
        for (int i = 0; i < allmethods.length; i++) {
            if (allmethods[i].getName().equals(methodName)) {
                return allmethods[i];
            }
        }
        throw new ReflectionNotFoundException("Cannot find method " + methodName + " on class " + clazz);

    } catch (SecurityException e) {
        throw new ReflectionAccessException("Failed to invoke method '" + methodName + " on class " + clazz + ": " + Exceptions.collapseText(e), e);
    }
}
 
Example 9
Source File: ApiError.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/**
 * @return An {@link ApiError.Builder} whose message is initialised to either the throwable's
 *         message or the throwable's class name if the message is null and whose details are
 *         initialised to the throwable's stack trace.
 */
public static Builder builderFromThrowable(Throwable t) {
    checkNotNull(t, "throwable");
    String message = Exceptions.collapseText(t);
    return builder()
            .message(message)
            .details(Throwables.getStackTraceAsString(t));
}
 
Example 10
Source File: SingleMachineLocationResolver.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
@Override
public LocationSpec<?> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
    ConfigBag config = extractConfig(locationFlags, spec, registry);
    @SuppressWarnings("rawtypes")
    Map globalProperties = registry.getProperties();
    String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
    
    if (registry != null) {
        LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
    }

    if (config.getStringKey("target") == null) {
        throw new IllegalArgumentException("target must be specified in single-machine spec");
    }
    String target = config.getStringKey("target").toString();
    config.remove("target");
    Maybe<LocationSpec<?>> testResolve = managementContext.getLocationRegistry().getLocationSpec(target);
    if (!testResolve.isPresent()) {
        throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+SINGLE+"': "+
            Exceptions.collapseText( Maybe.getException(testResolve) ), Maybe.getException(testResolve));
    }
    
    return LocationSpec.create(SingleMachineProvisioningLocation.class)
            .configure("location", target)
            .configure("locationFlags", config.getAllConfig())
            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
}
 
Example 11
Source File: HostLocationResolver.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
@Override
public LocationSpec<?> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
    // Extract args from spec
    ParsedSpec parsedSpec = specParser.parse(spec);
    Map<String, String> argsMap = parsedSpec.argsMap;
    if (argsMap.isEmpty()) {
        throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
    } else if (argsMap.size() == 1 && Iterables.get(argsMap.values(), 0) == null) {
        // only given ip or hostname
        argsMap = ImmutableMap.of("hosts", Iterables.get(argsMap.keySet(), 0));
    } else if (!(argsMap.containsKey("host") || argsMap.containsKey("hosts"))) {
        throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
    }

    // Find generic applicable properties
    Map globalProperties = registry.getProperties();
    String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
    Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
    ConfigBag flags = ConfigBag.newInstance(locationFlags).putIfAbsent(filteredProperties);
    flags.remove(LocationInternal.NAMED_SPEC_NAME);

    // Generate target spec
    String target = "byon("+KeyValueParser.toLine(argsMap)+")";
    Maybe<LocationSpec<?>> testResolve = managementContext.getLocationRegistry().getLocationSpec(target);
    if (!testResolve.isPresent()) {
        throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+HOST+"': "+
            Exceptions.collapseText( Maybe.getException(testResolve) ), Maybe.getException(testResolve));
    }
    
    return LocationSpec.create(SingleMachineProvisioningLocation.class)
            .configure("location", target)
            .configure("locationFlags", flags.getAllConfig())
            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
}
 
Example 12
Source File: MultiLocation.java    From brooklyn-server with Apache License 2.0 5 votes vote down vote up
/** finds (creates) and returns a {@link MachineLocation}; 
 * this always tries the first sub-location, moving on the second and subsequent if the first throws {@link NoMachinesAvailableException}.
 * (if you want striping across locations, see notes in {@link AvailabilityZoneExtension}.) */
@SuppressWarnings("unchecked")
@Override
public T obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
    List<MachineProvisioningLocation<?>> sublocsList = getSubLocations();
    Iterator<MachineProvisioningLocation<?>> sublocs = sublocsList.iterator();
    List<NoMachinesAvailableException> errors = MutableList.of();
    while (sublocs.hasNext()) {
        try {
            return (T) sublocs.next().obtain(flags);
        } catch (NoMachinesAvailableException e) {
            errors.add(e);
        }
    }
    Exception wrapped;
    String msg;
    if (errors.size()>1) {
        wrapped = new CompoundRuntimeException(errors.size()+" sublocation exceptions, including: "+
            Exceptions.collapseText(errors.get(0)), errors);
        msg = Exceptions.collapseText(wrapped);
    } else if (errors.size()==1) {
        wrapped = errors.get(0);
        msg = wrapped.getMessage();
        if (Strings.isBlank(msg)) msg = wrapped.toString();
    } else {
        msg = "no sub-locations set for this multi-location";
        wrapped = null;
    }
    throw new NoMachinesAvailableException("No machines available in any of the "+sublocsList.size()+" location"+Strings.s(sublocsList.size())+
        " configured here: "+msg, wrapped);
}
 
Example 13
Source File: Asserts.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
/**
 * Convenience method for cases where we need to test until something is true.
 *
 * The Callable will be invoked periodically until it succesfully concludes.
 * <p>
 * The following flags are supported:
 * <ul>
 * <li>abortOnError (boolean, default true)
 * <li>abortOnException - (boolean, default false)
 * <li>timeout - (a Duration or an integer in millis, defaults to {@link Asserts#DEFAULT_LONG_TIMEOUT})
 * <li>period - (a Duration or an integer in millis, for fixed retry time; if not set, defaults to exponentially increasing from 1 to 500ms)
 * <li>minPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the minimum period when exponentially increasing; defaults to 1ms)
 * <li>maxPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the maximum period when exponentially increasing; defaults to 500ms)
 * <li>maxAttempts - (integer, Integer.MAX_VALUE)
 * </ul>
 * 
 * The following flags are deprecated:
 * <ul>
 * <li>useGroovyTruth - (defaults to false; any result code apart from 'false' will be treated as success including null; ignored for Runnables which aren't Callables)
 * </ul>
 * 
 * @param flags, accepts the flags listed above
 * @param c The callable to invoke
 */
public static <T> T succeedsEventually(Map<String,?> flags, Callable<T> c) {
    boolean abortOnException = get(flags, "abortOnException", false);
    boolean abortOnError = get(flags, "abortOnError", false);
    boolean useGroovyTruth = get(flags, "useGroovyTruth", false);
    boolean logException = get(flags, "logException", true);

    // To speed up tests, default is for the period to start small and increase...
    Duration duration = toDuration(flags.get("timeout"), DEFAULT_LONG_TIMEOUT);
    Duration fixedPeriod = toDuration(flags.get("period"), null);
    Duration minPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("minPeriod"), Duration.millis(1));
    Duration maxPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("maxPeriod"), Duration.millis(500));
    int maxAttempts = get(flags, "maxAttempts", Integer.MAX_VALUE);
    int attempt = 0;
    long startTime = System.currentTimeMillis();
    try {
        Throwable lastException = null;
        T result = null;
        long lastAttemptTime = 0;
        long expireTime = startTime+duration.toMilliseconds();
        long sleepTimeBetweenAttempts = minPeriod.toMilliseconds();
        
        while (attempt < maxAttempts && lastAttemptTime < expireTime) {
            try {
                attempt++;
                lastAttemptTime = System.currentTimeMillis();
                result = c.call();
                if (log.isTraceEnabled()) log.trace("Attempt {} after {} ms: {}", new Object[] {attempt, System.currentTimeMillis() - startTime, result});
                if (useGroovyTruth) {
                    if (groovyTruth(result)) return result;
                } else if (Boolean.FALSE.equals(result)) {
                    if (result instanceof BooleanWithMessage) 
                        log.warn("Test returned an instance of BooleanWithMessage but useGroovyTruth is not set! " +
                                 "The result of this probably isn't what you intended.");
                    // FIXME surprising behaviour, "false" result here is acceptable
                    return result;
                } else {
                    return result;
                }
                lastException = null;
            } catch(Throwable e) {
                Exceptions.propagateIfInterrupt(e);
                lastException = e;
                if (log.isTraceEnabled()) log.trace("Attempt {} after {} ms: {}", new Object[] {attempt, System.currentTimeMillis() - startTime, e.getMessage()});
                if (abortOnException) throw e;
                if (abortOnError && e instanceof Error) throw e;
            }
            long sleepTime = Math.min(sleepTimeBetweenAttempts, expireTime-System.currentTimeMillis());
            if (sleepTime > 0) Thread.sleep(sleepTime);
            sleepTimeBetweenAttempts = Math.min(
                // grow by 1.5x; doubling causes longer extra waits than we like in tests
                sleepTimeBetweenAttempts + Math.max(1, sleepTimeBetweenAttempts/2), 
                maxPeriod.toMilliseconds());
        }
        
        log.info("succeedsEventually exceeded max attempts or timeout - {} attempts lasting {} ms, for {}", new Object[] {attempt, System.currentTimeMillis()-startTime, c});
        if (lastException != null)
            throw lastException;
        throw fail("invalid results; last was: "+result);
    } catch (Throwable t) {
        Exceptions.propagateIfInterrupt(t);
        if (logException) log.info("failed succeeds-eventually, "+attempt+" attempts, "+
                (System.currentTimeMillis()-startTime)+"ms elapsed "+
                "(rethrowing): "+t);
        throw new AssertionError("failed succeeds-eventually, "+attempt+" attempts, "+
            (System.currentTimeMillis()-startTime)+"ms elapsed: "+Exceptions.collapseText(t), t);
    }
}
 
Example 14
Source File: WebAppContextProvider.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
/**
 * Serve given WAR at the given pathSpec; if not yet started, it is simply remembered until start;
 * if server already running, the context for this WAR is started.
 * @return the context created and added as a handler (and possibly already started if server is
 * started, so be careful with any changes you make to it!)
 */
public WebAppContext get(ManagementContext managementContext, Map<String, Object> attributes, boolean ignoreFailures) {
    checkNotNull(managementContext, "managementContext");
    checkNotNull(attributes, "attributes");
    boolean isRoot = pathSpec.isEmpty();

    final WebAppContext context = new WebAppContext();
    // use a unique session ID to prevent interference with other web apps on same server (esp for localhost);
    // note however this is only run for the legacy launcher
    // TODO would be nice if the various karaf startups rename the session cookie property (from JSESSIONID)
    // as the default is likely to conflict with other java-based servers (esp on localhost);
    // this can be done e.g. on ServletContext.getSessionCookieConfig(), but will be needed for REST and for JS (static) bundles
    // low priority however, if you /etc/hosts a localhost-brooklyn and use that it will stop conflicting
    context.setInitParameter(SessionHandler.__SessionCookieProperty, SessionHandler.__DefaultSessionCookie + "_" + "BROOKLYN" + Identifiers.makeRandomId(6));
    context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
    context.setAttribute(BrooklynServiceAttributes.BROOKLYN_MANAGEMENT_CONTEXT, managementContext);
    for (Map.Entry<String, Object> attributeEntry : attributes.entrySet()) {
        context.setAttribute(attributeEntry.getKey(), attributeEntry.getValue());
    }

    try {
        final CustomResourceLocator locator = new CustomResourceLocator(managementContext.getConfig(), ResourceUtils.create(this));
        final InputStream resource = locator.getResourceFromUrl(warUrl);
        final String warName = isRoot ? "ROOT" : ("embedded-" + pathSpec);
        File tmpWarFile = Os.writeToTempFile(resource, warName, ".war");
        context.setWar(tmpWarFile.getAbsolutePath());
    } catch (Exception e) {
        LOG.warn("Failed to deploy webapp " + pathSpec + " from " + warUrl
                + (ignoreFailures ? "; launching run without WAR" : " (rethrowing)")
                + ": " + Exceptions.collapseText(e));
        if (!ignoreFailures) {
            throw new IllegalStateException("Failed to deploy webapp " + pathSpec + " from " + warUrl + ": " + Exceptions.collapseText(e), e);
        }
        LOG.debug("Detail on failure to deploy webapp: " + e, e);
        context.setWar("/dev/null");
    }

    context.setContextPath("/" + pathSpec);
    context.setParentLoaderPriority(true);

    return context;
}
 
Example 15
Source File: DynamicClusterImpl.java    From brooklyn-server with Apache License 2.0 4 votes vote down vote up
protected void doStart() {
    if (isQuarantineEnabled()) {
        QuarantineGroup quarantineGroup = getAttribute(QUARANTINE_GROUP);
        if (quarantineGroup==null || !Entities.isManaged(quarantineGroup)) {
            quarantineGroup = addChild(EntitySpec.create(QuarantineGroup.class).displayName("quarantine"));
            sensors().set(QUARANTINE_GROUP, quarantineGroup);
        }
    }

    int initialSize = getConfig(INITIAL_SIZE).intValue();
    int initialQuorumSize = getInitialQuorumSize();
    Exception internalError = null;

    try {
        resize(initialSize);
    } catch (Exception e) {
        Exceptions.propagateIfFatal(e);
        // Apart from logging, ignore problems here; we extract them below.
        // But if it was this thread that threw the exception (rather than a sub-task), then need
        // to record that failure here.
        LOG.debug("Error resizing "+this+" to size "+initialSize+" (collecting and handling): "+e, e);
        internalError = e;
    }

    Iterable<Task<?>> failed = Tasks.failed(Tasks.children(Tasks.current()));
    boolean noFailed = Iterables.isEmpty(failed);
    boolean severalFailed = Iterables.size(failed) > 1;

    int currentSize = getCurrentSize().intValue();
    if (currentSize < initialQuorumSize) {
        String message;
        if (currentSize == 0 && !noFailed) {
            if (severalFailed)
                message = "All nodes in cluster "+this+" failed";
            else
                message = "Node in cluster "+this+" failed";
        } else {
            message = "On start of cluster " + this + ", failed to get to initial size of " + initialSize
                + "; size is " + getCurrentSize()
                + (initialQuorumSize != initialSize ? " (initial quorum size is " + initialQuorumSize + ")" : "");
        }
        Throwable firstError = Tasks.getError(Maybe.next(failed.iterator()).orNull());
        if (firstError==null && internalError!=null) {
            // only use the internal error if there were no nested task failures
            // (otherwise the internal error should be a wrapper around the nested failures)
            firstError = internalError;
        }
        if (firstError!=null) {
            if (severalFailed) {
                message += "; first failure is: "+Exceptions.collapseText(firstError);
            } else {
                message += ": "+Exceptions.collapseText(firstError);
            }
        }
        throw new IllegalStateException(message, firstError);
        
    } else if (currentSize < initialSize) {
        LOG.warn(
                "On start of cluster {}, size {} reached initial minimum quorum size of {} but did not reach desired size {}; continuing",
                new Object[] { this, currentSize, initialQuorumSize, initialSize });
    }

    for (Policy it : policies()) {
        it.resume();
    }
}