From 0ad704d24fa415703e54ef27e62e039cb6e38080 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 13:59:56 +0100 Subject: [PATCH 01/13] Fix BrooklynTypes.loadDefinedBrooklynType --- core/src/main/java/brooklyn/basic/BrooklynTypes.java | 11 +++++++++++ .../brooklyn/enricher/basic/EnricherDynamicType.java | 4 ++++ .../java/brooklyn/policy/basic/PolicyDynamicType.java | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java index c2052c7fc5..246e519bae 100644 --- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java +++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java @@ -21,9 +21,14 @@ import java.util.Map; import brooklyn.config.ConfigKey; +import brooklyn.enricher.basic.EnricherDynamicType; import brooklyn.entity.Entity; import brooklyn.entity.basic.EntityDynamicType; import brooklyn.event.Sensor; +import brooklyn.location.Location; +import brooklyn.policy.Enricher; +import brooklyn.policy.Policy; +import brooklyn.policy.basic.PolicyDynamicType; import brooklyn.util.exceptions.Exceptions; import com.google.common.collect.Maps; @@ -84,6 +89,12 @@ private static synchronized BrooklynDynamicType loadDefinedBrooklynType(Cla if (Entity.class.isAssignableFrom(brooklynClass)) { type = new ImmutableEntityType((Class)brooklynClass); + } else if (Location.class.isAssignableFrom(brooklynClass)) { + type = new ImmutableEntityType((Class)brooklynClass); + } else if (Policy.class.isAssignableFrom(brooklynClass)) { + type = new PolicyDynamicType((Class)brooklynClass); // TODO immutable? + } else if (Enricher.class.isAssignableFrom(brooklynClass)) { + type = new EnricherDynamicType((Class)brooklynClass); // TODO immutable? } else { throw new IllegalStateException("Invalid brooklyn type "+brooklynClass); } diff --git a/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java index 9217c3d1a2..d2c26f62a1 100644 --- a/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java +++ b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java @@ -24,6 +24,10 @@ public class EnricherDynamicType extends BrooklynDynamicType { + public EnricherDynamicType(Class type) { + super(type); + } + public EnricherDynamicType(AbstractEnricher enricher) { super(enricher); } diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java index 6c99240fe3..6beeda6948 100644 --- a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java +++ b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java @@ -24,6 +24,10 @@ public class PolicyDynamicType extends BrooklynDynamicType { + public PolicyDynamicType(Class type) { + super(type); + } + public PolicyDynamicType(AbstractPolicy policy) { super(policy); } From e862b50127a2cb751bcb6d3de9dde905ed906eca Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 20:52:01 +0100 Subject: [PATCH 02/13] Adds MutableSet.copyOf(iterator) --- .../java/brooklyn/util/collections/MutableSet.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/utils/common/src/main/java/brooklyn/util/collections/MutableSet.java b/utils/common/src/main/java/brooklyn/util/collections/MutableSet.java index e79515800f..071d0d9c4c 100644 --- a/utils/common/src/main/java/brooklyn/util/collections/MutableSet.java +++ b/utils/common/src/main/java/brooklyn/util/collections/MutableSet.java @@ -69,6 +69,13 @@ public static MutableSet copyOf(@Nullable Iterable orig) { return orig==null ? new MutableSet() : new MutableSet(orig); } + public static MutableSet copyOf(@Nullable Iterator elements) { + if (elements == null || !elements.hasNext()) { + return of(); + } + return new MutableSet.Builder().addAll(elements).build(); + } + public MutableSet() { } @@ -146,6 +153,13 @@ public Builder addAll(Iterable iterable) { return this; } + public Builder addAll(Iterator iter) { + while (iter.hasNext()) { + add(iter.next()); + } + return this; + } + public Builder removeAll(Iterable iterable) { if (iterable instanceof Collection) { result.removeAll((Collection) iterable); From e67819cf583cda920430cfb3a6d2677eaeb8e0e8 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 20:51:26 +0100 Subject: [PATCH 03/13] Extract AbstractMain to remove duplication - CLI tools (Main and CloudExplorer) extend AbstractMain --- .../main/java/brooklyn/cli/AbstractMain.java | 263 ++++++++++++++++++ .../main/java/brooklyn/cli/CloudExplorer.java | 58 +--- .../cli/src/main/java/brooklyn/cli/Main.java | 165 +---------- .../src/test/java/brooklyn/cli/CliTest.java | 4 +- .../brooklyn/cli/CloudExplorerLiveTest.java | 2 +- 5 files changed, 269 insertions(+), 223 deletions(-) create mode 100644 usage/cli/src/main/java/brooklyn/cli/AbstractMain.java diff --git a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java b/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java new file mode 100644 index 0000000000..d27dee771e --- /dev/null +++ b/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java @@ -0,0 +1,263 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package brooklyn.cli; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyShell; +import io.airlift.command.Arguments; +import io.airlift.command.Cli; +import io.airlift.command.Cli.CliBuilder; +import io.airlift.command.Command; +import io.airlift.command.Help; +import io.airlift.command.Option; +import io.airlift.command.OptionType; +import io.airlift.command.ParseException; + +import java.io.Console; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Callable; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.BrooklynVersion; +import brooklyn.catalog.BrooklynCatalog; +import brooklyn.entity.Application; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.AbstractApplication; +import brooklyn.entity.basic.AbstractEntity; +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.basic.StartableApplication; +import brooklyn.entity.proxying.EntitySpec; +import brooklyn.entity.rebind.persister.PersistMode; +import brooklyn.entity.trait.Startable; +import brooklyn.launcher.BrooklynLauncher; +import brooklyn.launcher.BrooklynServerDetails; +import brooklyn.launcher.config.StopWhichAppsOnShutdown; +import brooklyn.management.ManagementContext; +import brooklyn.management.ha.HighAvailabilityMode; +import brooklyn.rest.security.PasswordHasher; +import brooklyn.util.ResourceUtils; +import brooklyn.util.exceptions.Exceptions; +import brooklyn.util.exceptions.FatalConfigurationRuntimeException; +import brooklyn.util.exceptions.FatalRuntimeException; +import brooklyn.util.exceptions.UserFacingException; +import brooklyn.util.guava.Maybe; +import brooklyn.util.javalang.Enums; +import brooklyn.util.net.Networking; +import brooklyn.util.text.Identifiers; +import brooklyn.util.text.StringEscapes.JavaStringEscapes; +import brooklyn.util.text.Strings; + +import com.google.common.annotations.Beta; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; +import com.google.common.collect.ImmutableList; + +/** + * This class is the primary CLI for brooklyn. + * Run with the `help` argument for help. + *

+ * This class is designed for subclassing, with subclasses typically: + *

  • providing their own static {@link #main(String...)} (of course) which need simply invoke + * {@link #execCli(String[])} with the arguments + *
  • returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()} + *
  • providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired + *
  • providing any other CLI customisations by overriding {@link #cliBuilder()} + * (typically calling the parent and then customizing the builder) + *
  • populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)} + */ +public abstract class AbstractMain { + + private static final Logger log = LoggerFactory.getLogger(AbstractMain.class); + + // Launch banner + public static final String BANNER = + " _ _ _ \n" + + "| |__ _ __ ___ ___ | | _| |_ _ _ __ (R)\n" + + "| '_ \\| '__/ _ \\ / _ \\| |/ / | | | | '_ \\ \n" + + "| |_) | | | (_) | (_) | <| | |_| | | | |\n" + + "|_.__/|_| \\___/ \\___/|_|\\_\\_|\\__, |_| |_|\n" + + " |___/ "+BrooklynVersion.get()+"\n"; + + // Error codes + public static final int SUCCESS = 0; + public static final int PARSE_ERROR = 1; + public static final int EXECUTION_ERROR = 2; + public static final int CONFIGURATION_ERROR = 3; + + /** abstract superclass for commands defining global options, but not arguments, + * as that prevents Help from being injectable in the {@link HelpCommand} subclass */ + public static abstract class BrooklynCommand implements Callable { + + @Option(type = OptionType.GLOBAL, name = { "-v", "--verbose" }, description = "Verbose mode") + public boolean verbose = false; + + @Option(type = OptionType.GLOBAL, name = { "-q", "--quiet" }, description = "Quiet mode") + public boolean quiet = false; + + @VisibleForTesting + protected PrintStream stdout = System.out; + + @VisibleForTesting + protected PrintStream stderr = System.err; + + @VisibleForTesting + protected InputStream stdin = System.in; + + public ToStringHelper string() { + return Objects.toStringHelper(getClass()) + .add("verbose", verbose) + .add("quiet", quiet); + } + + @Override + public String toString() { + return string().toString(); + } + } + + /** common superclass for commands, defining global options (in our super) and extracting the arguments */ + public static abstract class BrooklynCommandCollectingArgs extends BrooklynCommand { + + /** extra arguments */ + @Arguments + public List arguments = new ArrayList(); + + /** @return true iff there are arguments; it also sys.errs a warning in that case */ + protected boolean warnIfArguments() { + if (arguments.isEmpty()) return false; + stderr.println("Invalid subcommand arguments: "+Strings.join(arguments, " ")); + return true; + } + + /** throw {@link ParseException} iff there are arguments */ + protected void failIfArguments() { + if (arguments.isEmpty()) return ; + throw new ParseException("Invalid subcommand arguments '"+Strings.join(arguments, " ")+"'"); + } + + @Override + public ToStringHelper string() { + return super.string() + .add("arguments", arguments); + } + } + + @Command(name = "help", description = "Display help for available commands") + public static class HelpCommand extends BrooklynCommand { + + @Inject + public Help help; + + @Override + public Void call() throws Exception { + if (log.isDebugEnabled()) log.debug("Invoked help command: {}", this); + return help.call(); + } + } + + @Command(name = "info", description = "Display information about brooklyn") + public static class InfoCommand extends BrooklynCommandCollectingArgs { + + @Override + public Void call() throws Exception { + if (log.isDebugEnabled()) log.debug("Invoked info command: {}", this); + warnIfArguments(); + + System.out.println(BANNER); + System.out.println("Version: " + BrooklynVersion.get()); + System.out.println("Website: http://brooklyn.incubator.apache.org"); + System.out.println("Source: https://github.com/apache/incubator-brooklyn"); + System.out.println(); + System.out.println("Copyright 2011-2014 The Apache Software Foundation."); + System.out.println("Licensed under the Apache 2.0 License"); + System.out.println(); + + return null; + } + } + + + /** method intended for overriding when the script filename is different + * @return the name of the script the user has invoked */ + protected String cliScriptName() { + return "brooklyn"; + } + + /** + * Build the commands. + */ + protected abstract CliBuilder cliBuilder(); + + protected void execCli(String ...args) { + execCli(cliBuilder().build(), args); + } + + protected void execCli(Cli parser, String ...args) { + try { + log.debug("Parsing command line arguments: {}", Arrays.asList(args)); + BrooklynCommand command = parser.parse(args); + log.debug("Executing command: {}", command); + command.call(); + System.exit(SUCCESS); + } catch (ParseException pe) { // looks like the user typed it wrong + System.err.println("Parse error: " + pe.getMessage()); // display + // error + System.err.println(getUsageInfo(parser)); // display cli help + System.exit(PARSE_ERROR); + } catch (FatalConfigurationRuntimeException e) { + log.error("Configuration error: "+e.getMessage(), e.getCause()); + System.err.println("Configuration error: " + e.getMessage()); + System.exit(CONFIGURATION_ERROR); + } catch (FatalRuntimeException e) { // anticipated non-configuration error + log.error("Startup error: "+e.getMessage(), e.getCause()); + System.err.println("Startup error: "+e.getMessage()); + System.exit(EXECUTION_ERROR); + } catch (Exception e) { // unexpected error during command execution + log.error("Execution error: " + e.getMessage(), e); + System.err.println("Execution error: " + e.getMessage()); + if (!(e instanceof UserFacingException)) + e.printStackTrace(); + System.exit(EXECUTION_ERROR); + } + } + + protected String getUsageInfo(Cli parser) { + StringBuilder help = new StringBuilder(); + help.append("\n"); + Help.help(parser.getMetadata(), Collections.emptyList(), help); + return help.toString(); + } + +} diff --git a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java index 379f362130..d2936c8e8a 100644 --- a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java +++ b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java @@ -22,12 +22,9 @@ import io.airlift.command.Cli; import io.airlift.command.Cli.CliBuilder; import io.airlift.command.Command; -import io.airlift.command.Help; import io.airlift.command.Option; import io.airlift.command.ParseException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -46,10 +43,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.cli.Main.BrooklynCommand; -import brooklyn.cli.Main.BrooklynCommandCollectingArgs; -import brooklyn.cli.Main.HelpCommand; -import brooklyn.cli.Main.InfoCommand; import brooklyn.location.Location; import brooklyn.location.LocationDefinition; import brooklyn.location.basic.LocationConfigKeys; @@ -58,8 +51,6 @@ import brooklyn.location.jclouds.JcloudsUtil; import brooklyn.management.internal.LocalManagementContext; import brooklyn.util.exceptions.FatalConfigurationRuntimeException; -import brooklyn.util.exceptions.FatalRuntimeException; -import brooklyn.util.exceptions.UserFacingException; import brooklyn.util.stream.Streams; import com.google.common.base.Objects; @@ -76,16 +67,10 @@ * so requires less additional credential configuration. It also gives brooklyn-specific information, * such as which image will be used by default in a given cloud. */ -public class CloudExplorer { +public class CloudExplorer extends AbstractMain { private static final Logger log = LoggerFactory.getLogger(Main.class); - // Error codes - public static final int SUCCESS = 0; - public static final int PARSE_ERROR = 1; - public static final int EXECUTION_ERROR = 2; - public static final int CONFIGURATION_ERROR = 3; - public static void main(String... args) { new CloudExplorer().execCli(args); } @@ -442,45 +427,4 @@ protected CliBuilder cliBuilder() { return builder; } - - protected void execCli(String ...args) { - execCli(cliBuilder().build(), args); - } - - protected void execCli(Cli parser, String ...args) { - try { - log.debug("Parsing command line arguments: {}", Arrays.asList(args)); - BrooklynCommand command = parser.parse(args); - log.debug("Executing command: {}", command); - command.call(); - System.exit(SUCCESS); - } catch (ParseException pe) { // looks like the user typed it wrong - System.err.println("Parse error: " + pe.getMessage()); // display - // error - System.err.println(getUsageInfo(parser)); // display cli help - System.exit(PARSE_ERROR); - } catch (FatalConfigurationRuntimeException e) { - log.error("Configuration error: "+e.getMessage(), e.getCause()); - System.err.println("Configuration error: " + e.getMessage()); - System.exit(CONFIGURATION_ERROR); - } catch (FatalRuntimeException e) { // anticipated non-configuration error - log.error("Startup error: "+e.getMessage(), e.getCause()); - System.err.println("Startup error: "+e.getMessage()); - System.exit(EXECUTION_ERROR); - } catch (Exception e) { // unexpected error during command execution - log.error("Execution error: " + e.getMessage(), e); - System.err.println("Execution error: " + e.getMessage()); - if (!(e instanceof UserFacingException)) - e.printStackTrace(); - System.exit(EXECUTION_ERROR); - } - } - - protected String getUsageInfo(Cli parser) { - StringBuilder help = new StringBuilder(); - help.append("\n"); - Help.help(parser.getMetadata(), Collections.emptyList(), help); - return help.toString(); - } - } diff --git a/usage/cli/src/main/java/brooklyn/cli/Main.java b/usage/cli/src/main/java/brooklyn/cli/Main.java index 6bd6ca8850..5a8c7d4c32 100644 --- a/usage/cli/src/main/java/brooklyn/cli/Main.java +++ b/usage/cli/src/main/java/brooklyn/cli/Main.java @@ -20,36 +20,23 @@ import groovy.lang.GroovyClassLoader; import groovy.lang.GroovyShell; -import io.airlift.command.Arguments; import io.airlift.command.Cli; import io.airlift.command.Cli.CliBuilder; import io.airlift.command.Command; -import io.airlift.command.Help; import io.airlift.command.Option; -import io.airlift.command.OptionType; -import io.airlift.command.ParseException; import java.io.Console; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Callable; - -import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.BrooklynVersion; import brooklyn.catalog.BrooklynCatalog; import brooklyn.entity.Application; import brooklyn.entity.Entity; @@ -83,7 +70,6 @@ import com.google.common.annotations.Beta; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.collect.ImmutableList; @@ -100,22 +86,7 @@ * (typically calling the parent and then customizing the builder) *
  • populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)} */ -public class Main { - - // Launch banner - public static final String BANNER = - " _ _ _ \n" + - "| |__ _ __ ___ ___ | | _| |_ _ _ __ (R)\n" + - "| '_ \\| '__/ _ \\ / _ \\| |/ / | | | | '_ \\ \n" + - "| |_) | | | (_) | (_) | <| | |_| | | | |\n" + - "|_.__/|_| \\___/ \\___/|_|\\_\\_|\\__, |_| |_|\n" + - " |___/ "+BrooklynVersion.get()+"\n"; - - // Error codes - public static final int SUCCESS = 0; - public static final int PARSE_ERROR = 1; - public static final int EXECUTION_ERROR = 2; - public static final int CONFIGURATION_ERROR = 3; +public class Main extends AbstractMain { /** @deprecated since 0.7.0 will become private static, subclasses should define their own logger */ @Deprecated @@ -125,98 +96,6 @@ public static void main(String... args) { new Main().execCli(args); } - /** abstract superclass for commands defining global options, but not arguments, - * as that prevents Help from being injectable in the {@link HelpCommand} subclass */ - public static abstract class BrooklynCommand implements Callable { - - @Option(type = OptionType.GLOBAL, name = { "-v", "--verbose" }, description = "Verbose mode") - public boolean verbose = false; - - @Option(type = OptionType.GLOBAL, name = { "-q", "--quiet" }, description = "Quiet mode") - public boolean quiet = false; - - @VisibleForTesting - protected PrintStream stdout = System.out; - - @VisibleForTesting - protected PrintStream stderr = System.err; - - @VisibleForTesting - protected InputStream stdin = System.in; - - public ToStringHelper string() { - return Objects.toStringHelper(getClass()) - .add("verbose", verbose) - .add("quiet", quiet); - } - - @Override - public String toString() { - return string().toString(); - } - } - - /** common superclass for commands, defining global options (in our super) and extracting the arguments */ - public static abstract class BrooklynCommandCollectingArgs extends BrooklynCommand { - - /** extra arguments */ - @Arguments - public List arguments = new ArrayList(); - - /** @return true iff there are arguments; it also sys.errs a warning in that case */ - protected boolean warnIfArguments() { - if (arguments.isEmpty()) return false; - stderr.println("Invalid subcommand arguments: "+Strings.join(arguments, " ")); - return true; - } - - /** throw {@link ParseException} iff there are arguments */ - protected void failIfArguments() { - if (arguments.isEmpty()) return ; - throw new ParseException("Invalid subcommand arguments '"+Strings.join(arguments, " ")+"'"); - } - - @Override - public ToStringHelper string() { - return super.string() - .add("arguments", arguments); - } - } - - @Command(name = "help", description = "Display help for available commands") - public static class HelpCommand extends BrooklynCommand { - - @Inject - public Help help; - - @Override - public Void call() throws Exception { - if (log.isDebugEnabled()) log.debug("Invoked help command: {}", this); - return help.call(); - } - } - - @Command(name = "info", description = "Display information about brooklyn") - public static class InfoCommand extends BrooklynCommandCollectingArgs { - - @Override - public Void call() throws Exception { - if (log.isDebugEnabled()) log.debug("Invoked info command: {}", this); - warnIfArguments(); - - System.out.println(BANNER); - System.out.println("Version: " + BrooklynVersion.get()); - System.out.println("Website: http://brooklyn.incubator.apache.org"); - System.out.println("Source: https://github.com/apache/incubator-brooklyn"); - System.out.println(); - System.out.println("Copyright 2011-2014 The Apache Software Foundation."); - System.out.println("Licensed under the Apache 2.0 License"); - System.out.println(); - - return null; - } - } - @Command(name = "generate-password", description = "Generates a hashed web-console password") public static class GeneratePasswordCommand extends BrooklynCommandCollectingArgs { @@ -886,6 +765,7 @@ protected String cliScriptName() { /** method intended for overriding when a different {@link Cli} is desired, * or when the subclass wishes to change any of the arguments */ + @Override protected CliBuilder cliBuilder() { @SuppressWarnings({ "unchecked" }) CliBuilder builder = Cli.builder(cliScriptName()) @@ -905,45 +785,4 @@ protected CliBuilder cliBuilder() { protected Class cliLaunchCommand() { return LaunchCommand.class; } - - protected void execCli(String ...args) { - execCli(cliBuilder().build(), args); - } - - protected void execCli(Cli parser, String ...args) { - try { - log.debug("Parsing command line arguments: {}", Arrays.asList(args)); - BrooklynCommand command = parser.parse(args); - log.debug("Executing command: {}", command); - command.call(); - System.exit(SUCCESS); - } catch (ParseException pe) { // looks like the user typed it wrong - System.err.println("Parse error: " + pe.getMessage()); // display - // error - System.err.println(getUsageInfo(parser)); // display cli help - System.exit(PARSE_ERROR); - } catch (FatalConfigurationRuntimeException e) { - log.error("Configuration error: "+e.getMessage(), e.getCause()); - System.err.println("Configuration error: " + e.getMessage()); - System.exit(CONFIGURATION_ERROR); - } catch (FatalRuntimeException e) { // anticipated non-configuration error - log.error("Startup error: "+e.getMessage(), e.getCause()); - System.err.println("Startup error: "+e.getMessage()); - System.exit(EXECUTION_ERROR); - } catch (Exception e) { // unexpected error during command execution - log.error("Execution error: " + e.getMessage(), e); - System.err.println("Execution error: " + e.getMessage()); - if (!(e instanceof UserFacingException)) - e.printStackTrace(); - System.exit(EXECUTION_ERROR); - } - } - - protected String getUsageInfo(Cli parser) { - StringBuilder help = new StringBuilder(); - help.append("\n"); - Help.help(parser.getMetadata(), Collections.emptyList(), help); - return help.toString(); - } - } diff --git a/usage/cli/src/test/java/brooklyn/cli/CliTest.java b/usage/cli/src/test/java/brooklyn/cli/CliTest.java index 7b934f92a8..058641ab67 100644 --- a/usage/cli/src/test/java/brooklyn/cli/CliTest.java +++ b/usage/cli/src/test/java/brooklyn/cli/CliTest.java @@ -47,9 +47,9 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import brooklyn.cli.Main.BrooklynCommand; +import brooklyn.cli.AbstractMain.BrooklynCommand; +import brooklyn.cli.AbstractMain.HelpCommand; import brooklyn.cli.Main.GeneratePasswordCommand; -import brooklyn.cli.Main.HelpCommand; import brooklyn.cli.Main.LaunchCommand; import brooklyn.entity.Entity; import brooklyn.entity.basic.AbstractApplication; diff --git a/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java b/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java index 2a314bb910..a79ad78368 100644 --- a/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java +++ b/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java @@ -33,7 +33,7 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; -import brooklyn.cli.Main.BrooklynCommand; +import brooklyn.cli.AbstractMain.BrooklynCommand; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; From bffa5dfce8a8e02d179253e8fc7874faeaca8315 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 20:54:12 +0100 Subject: [PATCH 04/13] Add @Catalog annotation --- .../java/brooklyn/enricher/basic/Aggregator.java | 2 ++ .../main/java/brooklyn/enricher/basic/Combiner.java | 2 ++ .../java/brooklyn/enricher/basic/Propagator.java | 2 ++ .../java/brooklyn/enricher/basic/Transformer.java | 2 ++ .../main/java/brooklyn/enricher/DeltaEnricher.java | 3 +++ .../java/brooklyn/enricher/HttpLatencyDetector.java | 2 ++ .../java/brooklyn/enricher/RollingMeanEnricher.java | 3 +++ .../enricher/RollingTimeWindowMeanEnricher.java | 3 +++ .../enricher/TimeFractionDeltaEnricher.java | 3 +++ .../enricher/TimeWeightedDeltaEnricher.java | 4 ++++ .../policy/autoscaling/AutoScalerPolicy.java | 13 +++++++++---- .../policy/followthesun/FollowTheSunPolicy.java | 3 ++- .../policy/ha/ConnectionFailureDetector.java | 3 +++ .../brooklyn/policy/ha/ServiceFailureDetector.java | 12 ++++++++++++ .../java/brooklyn/policy/ha/ServiceReplacer.java | 2 ++ .../java/brooklyn/policy/ha/ServiceRestarter.java | 3 +++ .../policy/loadbalancing/LoadBalancingPolicy.java | 5 ++++- .../entity/basic/VanillaSoftwareProcess.java | 2 ++ .../entity/brooklynnode/BrooklynEntityMirror.java | 3 +++ .../brooklyn/entity/brooklynnode/BrooklynNode.java | 2 ++ .../java/brooklyn/entity/machine/MachineEntity.java | 2 ++ .../main/java/brooklyn/entity/pool/ServerPool.java | 4 +++- .../java/brooklyn/entity/messaging/storm/Storm.java | 2 ++ .../entity/messaging/storm/StormDeployment.java | 2 ++ .../entity/zookeeper/ZooKeeperEnsemble.java | 2 ++ .../brooklyn/entity/zookeeper/ZooKeeperNode.java | 2 ++ .../entity/nosql/cassandra/CassandraNode.java | 4 ++++ .../entity/nosql/couchbase/CouchbaseCluster.java | 2 ++ .../entity/nosql/couchbase/CouchbaseNode.java | 2 ++ .../nosql/elasticsearch/ElasticSearchCluster.java | 2 ++ .../nosql/elasticsearch/ElasticSearchNode.java | 2 ++ .../nosql/mongodb/sharding/MongoDBRouter.java | 4 ++++ .../mongodb/sharding/MongoDBShardedDeployment.java | 4 ++++ .../brooklyn/entity/nosql/riak/RiakCluster.java | 6 ++++-- .../java/brooklyn/entity/nosql/riak/RiakNode.java | 2 ++ .../webapp/ControlledDynamicWebAppCluster.java | 2 ++ .../entity/webapp/DynamicWebAppCluster.java | 2 ++ 37 files changed, 111 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/brooklyn/enricher/basic/Aggregator.java b/core/src/main/java/brooklyn/enricher/basic/Aggregator.java index e865799f07..a4df35648c 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Aggregator.java +++ b/core/src/main/java/brooklyn/enricher/basic/Aggregator.java @@ -27,6 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -44,6 +45,7 @@ /** Building on {@link AbstractAggregator} for a single source sensor (on multiple children and/or members) */ @SuppressWarnings("serial") +@Catalog(name="Aggregator", description="Aggregates attributes from multiple entities into a single attribute value; see Enrichers.builder().aggregating(...)") public class Aggregator extends AbstractAggregator implements SensorEventListener { private static final Logger LOG = LoggerFactory.getLogger(Aggregator.class); diff --git a/core/src/main/java/brooklyn/enricher/basic/Combiner.java b/core/src/main/java/brooklyn/enricher/basic/Combiner.java index 6876be23c8..5a78048702 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Combiner.java +++ b/core/src/main/java/brooklyn/enricher/basic/Combiner.java @@ -30,6 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -49,6 +50,7 @@ import com.google.common.reflect.TypeToken; @SuppressWarnings("serial") +@Catalog(name="Combiner", description="Combines attributes; see Enrichers.builder().combining(...)") public class Combiner extends AbstractEnricher implements SensorEventListener { private static final Logger LOG = LoggerFactory.getLogger(Combiner.class); diff --git a/core/src/main/java/brooklyn/enricher/basic/Propagator.java b/core/src/main/java/brooklyn/enricher/basic/Propagator.java index 7aca9ca8e8..f9924433f3 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Propagator.java +++ b/core/src/main/java/brooklyn/enricher/basic/Propagator.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.Attributes; @@ -46,6 +47,7 @@ import com.google.common.reflect.TypeToken; @SuppressWarnings("serial") +@Catalog(name="Propagator", description="Propagates attributes from one entity to another; see Enrichers.builder().propagating(...)") public class Propagator extends AbstractEnricher implements SensorEventListener { private static final Logger LOG = LoggerFactory.getLogger(Propagator.class); diff --git a/core/src/main/java/brooklyn/enricher/basic/Transformer.java b/core/src/main/java/brooklyn/enricher/basic/Transformer.java index 81ee346160..7c04d1038a 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Transformer.java +++ b/core/src/main/java/brooklyn/enricher/basic/Transformer.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -36,6 +37,7 @@ import com.google.common.base.Function; import com.google.common.reflect.TypeToken; +@Catalog(name="Transformer", description="Transformers attributes of an entity; see Enrichers.builder().transforming(...)") @SuppressWarnings("serial") public class Transformer extends AbstractEnricher implements SensorEventListener { diff --git a/policy/src/main/java/brooklyn/enricher/DeltaEnricher.java b/policy/src/main/java/brooklyn/enricher/DeltaEnricher.java index d3e3edc528..064a750469 100644 --- a/policy/src/main/java/brooklyn/enricher/DeltaEnricher.java +++ b/policy/src/main/java/brooklyn/enricher/DeltaEnricher.java @@ -19,6 +19,7 @@ package brooklyn.enricher; import static brooklyn.util.JavaGroovyEquivalents.elvis; +import brooklyn.catalog.Catalog; import brooklyn.enricher.basic.AbstractTransformingEnricher; import brooklyn.entity.Entity; import brooklyn.event.AttributeSensor; @@ -29,6 +30,8 @@ /** * Converts an absolute sensor into a delta sensor (i.e. the diff between the current and previous value) */ +@Catalog(name="Delta", description="Converts an absolute sensor into a delta sensor " + + "(i.e. the diff between the current and previous value)") public class DeltaEnricher extends AbstractTransformingEnricher { Number last = 0; diff --git a/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java b/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java index 70502e95db..a1b8f3e93f 100644 --- a/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java +++ b/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.enricher.basic.AbstractEnricher; import brooklyn.entity.Entity; @@ -64,6 +65,7 @@ * optionally returned from sensors. It does not currently support POST * and has limited support for https. */ +@Catalog(name="HTTP Latency Detector", description="An Enricher which computes latency in accessing a URL, normally by periodically polling that URL") public class HttpLatencyDetector extends AbstractEnricher { private static final Logger log = LoggerFactory.getLogger(HttpLatencyDetector.class); diff --git a/policy/src/main/java/brooklyn/enricher/RollingMeanEnricher.java b/policy/src/main/java/brooklyn/enricher/RollingMeanEnricher.java index 49e12414ba..50f0878b82 100644 --- a/policy/src/main/java/brooklyn/enricher/RollingMeanEnricher.java +++ b/policy/src/main/java/brooklyn/enricher/RollingMeanEnricher.java @@ -20,6 +20,7 @@ import java.util.LinkedList; +import brooklyn.catalog.Catalog; import brooklyn.enricher.basic.AbstractTypeTransformingEnricher; import brooklyn.entity.Entity; import brooklyn.event.AttributeSensor; @@ -32,6 +33,8 @@ * Transforms a sensor into a rolling average based on a fixed window size. This is useful for smoothing sample type metrics, * such as latency or CPU time */ +@Catalog(name="Rolling Mean", description="Transforms a sensor into a rolling average based on a fixed " + + "window size. This is useful for smoothing sample type metrics, such as latency or CPU time") public class RollingMeanEnricher extends AbstractTypeTransformingEnricher { private LinkedList values = new LinkedList(); diff --git a/policy/src/main/java/brooklyn/enricher/RollingTimeWindowMeanEnricher.java b/policy/src/main/java/brooklyn/enricher/RollingTimeWindowMeanEnricher.java index b196efa1ce..2ac3b976a7 100644 --- a/policy/src/main/java/brooklyn/enricher/RollingTimeWindowMeanEnricher.java +++ b/policy/src/main/java/brooklyn/enricher/RollingTimeWindowMeanEnricher.java @@ -23,6 +23,7 @@ import com.google.common.base.Preconditions; +import brooklyn.catalog.Catalog; import brooklyn.enricher.basic.AbstractTypeTransformingEnricher; import brooklyn.entity.Entity; import brooklyn.event.AttributeSensor; @@ -55,6 +56,8 @@ *

    * The default average when no data has been received is 0, with a confidence of 0 */ +@Catalog(name="Rolling Mean in Time Window", description="Transforms a sensor's data into a rolling average " + + "based on a time window.") public class RollingTimeWindowMeanEnricher extends AbstractTypeTransformingEnricher { public static class ConfidenceQualifiedNumber { final Double value; diff --git a/policy/src/main/java/brooklyn/enricher/TimeFractionDeltaEnricher.java b/policy/src/main/java/brooklyn/enricher/TimeFractionDeltaEnricher.java index 253cdc63a0..035bb6f10d 100644 --- a/policy/src/main/java/brooklyn/enricher/TimeFractionDeltaEnricher.java +++ b/policy/src/main/java/brooklyn/enricher/TimeFractionDeltaEnricher.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.enricher.basic.AbstractTypeTransformingEnricher; import brooklyn.entity.Entity; import brooklyn.event.AttributeSensor; @@ -41,6 +42,8 @@ * * It also configured with the time units for the values. */ +@Catalog(name="Time-fraction Delta", description="Converts an absolute measure of time into a fraction of time, " + + "based on the delta between consecutive values and the elapsed time between those values.") public class TimeFractionDeltaEnricher extends AbstractTypeTransformingEnricher { private static final Logger LOG = LoggerFactory.getLogger(TimeFractionDeltaEnricher.class); diff --git a/policy/src/main/java/brooklyn/enricher/TimeWeightedDeltaEnricher.java b/policy/src/main/java/brooklyn/enricher/TimeWeightedDeltaEnricher.java index d344dd42ac..ed857304ac 100644 --- a/policy/src/main/java/brooklyn/enricher/TimeWeightedDeltaEnricher.java +++ b/policy/src/main/java/brooklyn/enricher/TimeWeightedDeltaEnricher.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.enricher.basic.AbstractTypeTransformingEnricher; import brooklyn.entity.Entity; import brooklyn.event.AttributeSensor; @@ -42,6 +43,9 @@ *

    * NB for time (e.g. "total milliseconds consumed") use {@link TimeFractionDeltaEnricher} */ +@Catalog(name="Time-weighted Delta", description="Converts an absolute sensor into a delta sensor " + + "(i.e. the diff between the current and previous value), presented as a units/timeUnit " + + "based on the event timing.") public class TimeWeightedDeltaEnricher extends AbstractTypeTransformingEnricher { private static final Logger LOG = LoggerFactory.getLogger(TimeWeightedDeltaEnricher.class); diff --git a/policy/src/main/java/brooklyn/policy/autoscaling/AutoScalerPolicy.java b/policy/src/main/java/brooklyn/policy/autoscaling/AutoScalerPolicy.java index 5399654f84..40f93ed1f2 100644 --- a/policy/src/main/java/brooklyn/policy/autoscaling/AutoScalerPolicy.java +++ b/policy/src/main/java/brooklyn/policy/autoscaling/AutoScalerPolicy.java @@ -62,12 +62,17 @@ /** * Policy that is attached to a {@link Resizable} entity and dynamically adjusts its size in response to - * emitted {@code POOL_COLD} and {@code POOL_HOT} events. (This policy does not itself determine whether - * the pool is hot or cold, but instead relies on these events being emitted by the monitored entity itself, or - * by another policy that is attached to it; see, for example, {@link LoadBalancingPolicy}.) + * emitted {@code POOL_COLD} and {@code POOL_HOT} events. Alternatively, the policy can be configured to + * keep a given metric within a required range. + *

    + * TThis policy does not itself determine whether the pool is hot or cold, but instead relies on these + * events being emitted by the monitored entity itself, or by another policy that is attached to it; see, + * for example, {@link LoadBalancingPolicy}.) */ @SuppressWarnings({"rawtypes", "unchecked"}) -@Catalog +@Catalog(name="Auto-scaler", description="Policy that is attached to a Resizable entity and dynamically " + + "adjusts its size in response to either keep a metric within a given range, or in response to " + + "POOL_COLD and POOL_HOT events") public class AutoScalerPolicy extends AbstractPolicy { private static final Logger LOG = LoggerFactory.getLogger(AutoScalerPolicy.class); diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java index bfd5ce1ab3..87881bf8c0 100644 --- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java +++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java @@ -53,7 +53,8 @@ import com.google.common.collect.Iterables; import com.google.common.util.concurrent.ThreadFactoryBuilder; -@Catalog +@Catalog(name="Follow the Sun", description="Policy for moving \"work\" around to follow the demand; " + + "the work can be any \"Movable\" entity") public class FollowTheSunPolicy extends AbstractPolicy { private static final Logger LOG = LoggerFactory.getLogger(FollowTheSunPolicy.class); diff --git a/policy/src/main/java/brooklyn/policy/ha/ConnectionFailureDetector.java b/policy/src/main/java/brooklyn/policy/ha/ConnectionFailureDetector.java index 816bc58813..acd371dd74 100644 --- a/policy/src/main/java/brooklyn/policy/ha/ConnectionFailureDetector.java +++ b/policy/src/main/java/brooklyn/policy/ha/ConnectionFailureDetector.java @@ -28,6 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.BrooklynTaskTags; import brooklyn.entity.basic.ConfigKeys; @@ -53,6 +54,8 @@ * Monitors a given {@link HostAndPort}, to emit HASensors.CONNECTION_FAILED and HASensors.CONNECTION_RECOVERED * if the connection is lost/restored. */ +@Catalog(name="Connection Failure Detector", description="HA policy for monitoring a host:port, " + + "emitting an event if the connection is lost/restored") public class ConnectionFailureDetector extends AbstractPolicy { // TODO Remove duplication from ServiceFailureDetector, particularly for the stabilisation delays. diff --git a/policy/src/main/java/brooklyn/policy/ha/ServiceFailureDetector.java b/policy/src/main/java/brooklyn/policy/ha/ServiceFailureDetector.java index c523aba5ac..d74ff28de8 100644 --- a/policy/src/main/java/brooklyn/policy/ha/ServiceFailureDetector.java +++ b/policy/src/main/java/brooklyn/policy/ha/ServiceFailureDetector.java @@ -26,6 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.Attributes; import brooklyn.entity.basic.ConfigKeys; @@ -54,8 +55,19 @@ * (or until another process manually sets {@link Attributes#SERVICE_STATE_ACTUAL} to {@value Lifecycle#ON_FIRE}, * which this enricher will not clear until all problems have gone away) */ +@Catalog(name="Service Failure Detector", description="HA policy for deteting failure of a service") public class ServiceFailureDetector extends ServiceStateLogic.ComputeServiceState { + // TODO Remove duplication between this and MemberFailureDetectionPolicy. + // The latter could be re-written to use this. Or could even be deprecated + // in favour of this. + + public enum LastPublished { + NONE, + FAILED, + RECOVERED; + } + private static final Logger LOG = LoggerFactory.getLogger(ServiceFailureDetector.class); private static final long MIN_PERIOD_BETWEEN_EXECS_MILLIS = 100; diff --git a/policy/src/main/java/brooklyn/policy/ha/ServiceReplacer.java b/policy/src/main/java/brooklyn/policy/ha/ServiceReplacer.java index 9142c786d0..30c5de4e54 100644 --- a/policy/src/main/java/brooklyn/policy/ha/ServiceReplacer.java +++ b/policy/src/main/java/brooklyn/policy/ha/ServiceReplacer.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.Group; @@ -56,6 +57,7 @@ /** attaches to a DynamicCluster and replaces a failed member in response to HASensors.ENTITY_FAILED or other sensor; * if this fails, it sets the Cluster state to on-fire */ +@Catalog(name="Service Replacer", description="HA policy for replacing a failed member of a group") public class ServiceReplacer extends AbstractPolicy { private static final Logger LOG = LoggerFactory.getLogger(ServiceReplacer.class); diff --git a/policy/src/main/java/brooklyn/policy/ha/ServiceRestarter.java b/policy/src/main/java/brooklyn/policy/ha/ServiceRestarter.java index 06e6c771d3..3a0b6d4f87 100644 --- a/policy/src/main/java/brooklyn/policy/ha/ServiceRestarter.java +++ b/policy/src/main/java/brooklyn/policy/ha/ServiceRestarter.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.Attributes; import brooklyn.entity.basic.ConfigKeys; @@ -52,6 +53,8 @@ * if there is a subsequent failure within a configurable time interval, or if the restart fails, * this gives up and emits {@link #ENTITY_RESTART_FAILED} */ +@Catalog(name="Service Restarter", description="HA policy for restarting a service automatically, " + + "and for emitting an events if the service repeatedly fails") public class ServiceRestarter extends AbstractPolicy { private static final Logger LOG = LoggerFactory.getLogger(ServiceRestarter.class); diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/LoadBalancingPolicy.java b/policy/src/main/java/brooklyn/policy/loadbalancing/LoadBalancingPolicy.java index 7cef21d243..0e36928faf 100644 --- a/policy/src/main/java/brooklyn/policy/loadbalancing/LoadBalancingPolicy.java +++ b/policy/src/main/java/brooklyn/policy/loadbalancing/LoadBalancingPolicy.java @@ -67,7 +67,10 @@ * of container resource in the pool respectively. These events may be consumed by a separate policy that is capable * of resizing the container pool. */ -@Catalog +@Catalog(name="Load Balancer", description="Policy that is attached to a pool of \"containers\", each of which " + + "can host one or more migratable \"items\". The policy monitors the workrates of the items and effects " + + "migrations in an attempt to ensure that the containers are all sufficiently utilized without any of " + + "them being overloaded.") public class LoadBalancingPolicy extends AbstractPolicy { private static final Logger LOG = LoggerFactory.getLogger(LoadBalancingPolicy.class); diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java index 9e9e17107e..f6d6ec1216 100644 --- a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java +++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcess.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.basic; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.proxying.ImplementedBy; import brooklyn.event.basic.AttributeSensorAndConfigKey; @@ -51,6 +52,7 @@ *

  • A different {@link SoftwareProcess#PID_FILE} to use *
  • */ +@Catalog(name="Vanilla Software Process", description="A software process configured with scripts, e.g. for launch, check-running and stop") @ImplementedBy(VanillaSoftwareProcessImpl.class) public interface VanillaSoftwareProcess extends SoftwareProcess { diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java index dd013940fe..296287b0d6 100644 --- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java +++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.brooklynnode; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -32,6 +33,8 @@ *

    * Note tests for this depend on a REST server so are in other projects; search for *Mirror*Test, * as well as *BrooklynNode*Test. */ +@Catalog(name="Brooklyn Entity Mirror", description="Provides an entity which can sit in one brooklyn " + + "domain and reflect the status of an entity via the REST API of another domain.") @ImplementedBy(BrooklynEntityMirrorImpl.class) public interface BrooklynEntityMirror extends Entity { diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java index 75523e3d13..88f34ef4f6 100644 --- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java +++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java @@ -23,6 +23,7 @@ import java.util.Map; import brooklyn.BrooklynVersion; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Effector; import brooklyn.entity.basic.BrooklynConfigKeys; @@ -48,6 +49,7 @@ import com.google.common.collect.Lists; import com.google.common.reflect.TypeToken; +@Catalog(name="Brooklyn Node", description="Deploys a Brooklyn management server") @ImplementedBy(BrooklynNodeImpl.class) public interface BrooklynNode extends SoftwareProcess, UsesJava { diff --git a/software/base/src/main/java/brooklyn/entity/machine/MachineEntity.java b/software/base/src/main/java/brooklyn/entity/machine/MachineEntity.java index c353e80393..cf550c5e0a 100644 --- a/software/base/src/main/java/brooklyn/entity/machine/MachineEntity.java +++ b/software/base/src/main/java/brooklyn/entity/machine/MachineEntity.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.machine; +import brooklyn.catalog.Catalog; import brooklyn.entity.annotation.Effector; import brooklyn.entity.annotation.EffectorParam; import brooklyn.entity.basic.EmptySoftwareProcess; @@ -26,6 +27,7 @@ import brooklyn.event.AttributeSensor; import brooklyn.util.time.Duration; +@Catalog(name="Machine Entity", description="Represents a machine, providing metrics (normally optained of ssh) about it") @ImplementedBy(MachineEntityImpl.class) public interface MachineEntity extends EmptySoftwareProcess { diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java index 4212aab8d8..efbd94645d 100644 --- a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java +++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java @@ -21,14 +21,15 @@ import java.util.Collection; import java.util.Map; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.annotation.Effector; import brooklyn.entity.annotation.EffectorParam; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.MethodEffector; -import brooklyn.entity.machine.MachineEntity; import brooklyn.entity.group.DynamicCluster; +import brooklyn.entity.machine.MachineEntity; import brooklyn.entity.proxying.EntitySpec; import brooklyn.entity.proxying.ImplementedBy; import brooklyn.event.AttributeSensor; @@ -62,6 +63,7 @@ *

  • * */ +@Catalog(name="Server Pool", description="Creates a pre-allocated server pool, which other applications can deploy to") @ImplementedBy(ServerPoolImpl.class) public interface ServerPool extends DynamicCluster, LocationOwner { diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java index 5544507751..d7ec47b47d 100644 --- a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java +++ b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.messaging.storm; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.config.render.RendererHints; import brooklyn.entity.Entity; @@ -35,6 +36,7 @@ /** * An {@link brooklyn.entity.Entity} that represents a Storm node (UI, Nimbus or Supervisor). */ +@Catalog(name="Storm Node", description="Storm is...") @ImplementedBy(StormImpl.class) public interface Storm extends SoftwareProcess, UsesJmx { diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java index 4ab4d11fc4..14832815bb 100644 --- a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java +++ b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.messaging.storm; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -25,6 +26,7 @@ import brooklyn.entity.trait.Startable; import brooklyn.util.flags.SetFromFlag; +@Catalog(name="Storm Deployment", description="Storm is...") @ImplementedBy(StormDeploymentImpl.class) public interface StormDeployment extends Entity, Startable { diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java index 08149d9769..f33ee90ee7 100644 --- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java +++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java @@ -20,6 +20,7 @@ import java.util.List; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.group.DynamicCluster; @@ -31,6 +32,7 @@ import com.google.common.reflect.TypeToken; +@Catalog(name="ZooKeeper ensemble", description="ZooKeeper is...") @ImplementedBy(ZooKeeperEnsembleImpl.class) public interface ZooKeeperEnsemble extends DynamicCluster { diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java index 8ca44bebba..40b7b3ebce 100644 --- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java +++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.zookeeper; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.SoftwareProcess; @@ -31,6 +32,7 @@ /** * An {@link brooklyn.entity.Entity} that represents a single Apache ZooKeeper instance. */ +@Catalog(name="ZooKeeper Node", description="ZooKeeper is...") @ImplementedBy(ZooKeeperNodeImpl.class) public interface ZooKeeperNode extends SoftwareProcess { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/cassandra/CassandraNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/cassandra/CassandraNode.java index 996f8ff8d9..91d04fecd5 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/cassandra/CassandraNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/cassandra/CassandraNode.java @@ -21,6 +21,7 @@ import java.math.BigInteger; import java.util.Set; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Effector; import brooklyn.entity.Entity; @@ -45,6 +46,9 @@ /** * An {@link brooklyn.entity.Entity} that represents a Cassandra node in a {@link CassandraDatacenter}. */ +@Catalog(name="Apache Cassandra Node", description="Cassandra is a highly scalable, eventually " + + "consistent, distributed, structured key-value store which provides a ColumnFamily-based data model " + + "richer than typical key/value systems", iconUrl="classpath:///cassandra-logo.jpeg") @ImplementedBy(CassandraNodeImpl.class) public interface CassandraNode extends DatastoreMixins.DatastoreCommon, SoftwareProcess, UsesJmx, UsesJavaMXBeans, DatastoreMixins.HasDatastoreUrl, DatastoreMixins.CanExecuteScript { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java index 25a2b8de56..1bdc124a1a 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -34,6 +35,7 @@ import com.google.common.reflect.TypeToken; +@Catalog(name="CouchBase Cluster", description="CouchBase is...") @ImplementedBy(CouchbaseClusterImpl.class) public interface CouchbaseCluster extends DynamicCluster { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java index dd46eba88c..9fa23b52ff 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.nosql.couchbase; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.config.render.RendererHints; import brooklyn.entity.annotation.Effector; @@ -35,6 +36,7 @@ import brooklyn.util.flags.SetFromFlag; import brooklyn.util.text.ByteSizeStrings; +@Catalog(name="CouchBase Node", description="CouchBase is...") @ImplementedBy(CouchbaseNodeImpl.class) public interface CouchbaseNode extends SoftwareProcess { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java index f0190f59ce..738661bd17 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.nosql.elasticsearch; +import brooklyn.catalog.Catalog; import brooklyn.entity.group.DynamicCluster; import brooklyn.entity.proxying.ImplementedBy; import brooklyn.event.basic.BasicAttributeSensorAndConfigKey; @@ -26,6 +27,7 @@ /** * A cluster of {@link ElasticSearchNode}s based on {@link DynamicCluster} which can be resized by a policy if required. */ +@Catalog(name="Elastic Search Cluster", description="Elastic Search is...") @ImplementedBy(ElasticSearchClusterImpl.class) public interface ElasticSearchCluster extends DynamicCluster { @SetFromFlag("clusterName") diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java index 76c20c8336..d679f3fe6c 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.nosql.elasticsearch; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.basic.SoftwareProcess; @@ -35,6 +36,7 @@ /** * An {@link brooklyn.entity.Entity} that represents an ElasticSearch node */ +@Catalog(name="Elastic Search Node", description="Elastic Search is...") @ImplementedBy(ElasticSearchNodeImpl.class) public interface ElasticSearchNode extends SoftwareProcess, DatastoreMixins.HasDatastoreUrl { @SetFromFlag("version") diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java b/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java index 4a6bbb75a4..3d8b28163b 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.nosql.mongodb.sharding; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.basic.ConfigKeys; import brooklyn.entity.nosql.mongodb.AbstractMongoDBServer; @@ -28,6 +29,9 @@ import com.google.common.reflect.TypeToken; +@Catalog(name="MongoDB Router", + description="MongoDB (from \"humongous\") is a scalable, high-performance, open source NoSQL database", + iconUrl="classpath:///mongodb-logo.png") @ImplementedBy(MongoDBRouterImpl.class) public interface MongoDBRouter extends AbstractMongoDBServer { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java b/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java index a300f364d3..ffda9b188c 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.nosql.mongodb.sharding; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.Group; @@ -29,6 +30,9 @@ import brooklyn.util.flags.SetFromFlag; import brooklyn.util.time.Duration; +@Catalog(name="MongoDB Sharded Deployment", + description="MongoDB (from \"humongous\") is a scalable, high-performance, open source NoSQL database", + iconUrl="classpath:///mongodb-logo.png") @ImplementedBy(MongoDBShardedDeploymentImpl.class) public interface MongoDBShardedDeployment extends Entity, Startable { @SetFromFlag("configClusterSize") diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java index c4fabedda6..798ebe9e09 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java @@ -20,8 +20,7 @@ import java.util.Map; -import com.google.common.reflect.TypeToken; - +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; @@ -32,6 +31,9 @@ import brooklyn.util.flags.SetFromFlag; import brooklyn.util.time.Duration; +import com.google.common.reflect.TypeToken; + +@Catalog(name="Riak Node", description="Riak is...") @ImplementedBy(RiakClusterImpl.class) public interface RiakCluster extends DynamicCluster { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java index 0f5a47a82c..0acc7b11e8 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java @@ -22,6 +22,7 @@ import com.google.common.reflect.TypeToken; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.annotation.Effector; import brooklyn.entity.annotation.EffectorParam; @@ -34,6 +35,7 @@ import brooklyn.event.basic.Sensors; import brooklyn.util.flags.SetFromFlag; +@Catalog(name="Riak Node", description="Riak is...") @ImplementedBy(RiakNodeImpl.class) public interface RiakNode extends SoftwareProcess { diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java index 72b2bb66d0..e2ceb32807 100644 --- a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java +++ b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.webapp; +import brooklyn.catalog.Catalog; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.Group; @@ -56,6 +57,7 @@ * than with the child {@link brooklyn.entity.group.DynamicCluster}. However, note that changing this entity's * members has no effect on the members of the underlying DynamicCluster - treat this as a read-only view. */ +@Catalog(name="Controlled Dynamic Web-app Cluster", description="A cluster of load-balanced web-apps, which can be dynamically re-sized") @ImplementedBy(ControlledDynamicWebAppClusterImpl.class) public interface ControlledDynamicWebAppCluster extends DynamicGroup, Entity, Startable, Resizable, MemberReplaceable, Group, ElasticJavaWebAppService, JavaWebAppService.CanDeployAndUndeploy, JavaWebAppService.CanRedeployAll { diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/DynamicWebAppCluster.java b/software/webapp/src/main/java/brooklyn/entity/webapp/DynamicWebAppCluster.java index 04ec69e1e7..38d35083b1 100644 --- a/software/webapp/src/main/java/brooklyn/entity/webapp/DynamicWebAppCluster.java +++ b/software/webapp/src/main/java/brooklyn/entity/webapp/DynamicWebAppCluster.java @@ -18,6 +18,7 @@ */ package brooklyn.entity.webapp; +import brooklyn.catalog.Catalog; import brooklyn.config.render.RendererHints; import brooklyn.entity.group.DynamicCluster; import brooklyn.entity.proxying.ImplementedBy; @@ -34,6 +35,7 @@ *
  • Entity processing time
  • * */ +@Catalog(name="Dynamic Web-app Cluster", description="A cluster of web-apps, which can be dynamically re-sized; this does not include a load-balancer") @ImplementedBy(DynamicWebAppClusterImpl.class) public interface DynamicWebAppCluster extends DynamicCluster, WebAppService, JavaWebAppService, JavaWebAppService.CanDeployAndUndeploy, JavaWebAppService.CanRedeployAll { From c92b175a4de6077663604f62938d4f2d62dfcbc9 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 20:55:02 +0100 Subject: [PATCH 05/13] Deprecate unused GeneralPurposePolicy --- .../main/java/brooklyn/policy/basic/GeneralPurposePolicy.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java b/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java index bcc3fd8f91..06000062b6 100644 --- a/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java +++ b/core/src/main/java/brooklyn/policy/basic/GeneralPurposePolicy.java @@ -21,6 +21,10 @@ import java.util.Collections; import java.util.Map; +/** + * @deprecated since 0.7.0; will be either deleted or moved to tests + */ +@Deprecated public class GeneralPurposePolicy extends AbstractPolicy { public GeneralPurposePolicy() { this(Collections.emptyMap()); From af85653292522a6b5cff59939a28dbdfdc8b7ef8 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Wed, 13 Aug 2014 14:00:16 +0100 Subject: [PATCH 06/13] Adds ItemLister for getting entities etc --- .../java/brooklyn/basic/BrooklynTypes.java | 2 +- .../brooklyn/cli/itemlister/ClassFinder.java | 130 +++++++++++++++ .../cli/itemlister/ItemDescriptors.java | 104 ++++++++++++ .../brooklyn/cli/itemlister/ItemLister.java | 156 ++++++++++++++++++ .../rest/transform/EntityTransformer.java | 2 +- 5 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java create mode 100644 usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java create mode 100644 usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java index 246e519bae..1a0049c63d 100644 --- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java +++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java @@ -76,7 +76,7 @@ public static EntityDynamicType getDefinedEntityType(Class ent return (EntityDynamicType) BrooklynTypes.getDefinedBrooklynType(entityClass); } - private static BrooklynDynamicType getDefinedBrooklynType(Class brooklynClass) { + public static BrooklynDynamicType getDefinedBrooklynType(Class brooklynClass) { BrooklynDynamicType t = cache.get(brooklynClass); if (t!=null) return t; return loadDefinedBrooklynType(brooklynClass); diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java new file mode 100644 index 0000000000..18888ac058 --- /dev/null +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java @@ -0,0 +1,130 @@ +package brooklyn.cli.itemlister; + +import java.io.File; +import java.lang.annotation.Annotation; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.reflections.Reflections; +import org.reflections.scanners.FieldAnnotationsScanner; +import org.reflections.scanners.SubTypesScanner; +import org.reflections.scanners.TypeAnnotationsScanner; +import org.reflections.util.ConfigurationBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import brooklyn.basic.BrooklynObject; +import brooklyn.enricher.basic.AbstractEnricher; +import brooklyn.entity.Application; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.AbstractApplication; +import brooklyn.entity.basic.AbstractEntity; +import brooklyn.entity.basic.SoftwareProcessImpl; +import brooklyn.policy.Enricher; +import brooklyn.policy.Policy; +import brooklyn.policy.basic.AbstractPolicy; +import brooklyn.util.ResourceUtils; +import brooklyn.util.javalang.UrlClassLoader; +import brooklyn.util.net.Urls; +import brooklyn.util.os.Os; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +public class ClassFinder { + + private static final Logger log = LoggerFactory.getLogger(ClassFinder.class); + + private static final Collection> BORING = ImmutableList.>of( + Entity.class, + AbstractEntity.class, + SoftwareProcessImpl.class, + Application.class, + AbstractApplication.class, + Policy.class, + Enricher.class, + AbstractPolicy.class, + AbstractEnricher.class); + + public static Predicate> notBoring() { + return new Predicate>() { + public boolean apply(Class input) { + return (input != null && !BORING.contains(input)); + } + }; + } + + public static Predicate> withAnnotation(final Class annotation) { + return new Predicate>() { + public boolean apply(Class input) { + return (input != null && input.getAnnotation(annotation) != null); + } + }; + } + + public static Predicate> withClassNameMatching(final String typeRegex) { + return new Predicate>() { + public boolean apply(Class input) { + return (input != null && input.getName() != null && input.getName().matches(typeRegex)); + } + }; + } + + public static List toJarUrls(String url) throws MalformedURLException { + if (url==null) throw new NullPointerException("Cannot read from null"); + if (url=="") throw new NullPointerException("Cannot read from empty string"); + + List result = Lists.newArrayList(); + + String protocol = Urls.getProtocol(url); + if (protocol!=null) { + // it's a URL - easy + if ("file".equals(protocol)) { + url = ResourceUtils.tidyFileUrl(url); + } + result.add(new URL(url)); + } else { + // treat as file + String tidiedPath = Os.tidyPath(url); + File tidiedFile = new File(tidiedPath); + if (tidiedFile.isDirectory()) { + List toscan = Lists.newLinkedList(); + toscan.add(tidiedFile); + while (toscan.size() > 0) { + File file = toscan.remove(0); + if (file.isFile()) { + if (file.getName().toLowerCase().endsWith(".jar")) { + result.add(new URL("file://"+file.getAbsolutePath())); + } + } else if (file.isDirectory()) { + for (File subfile : file.listFiles()) { + toscan.add(subfile); + } + } else { + log.info("Cannot read "+file+"; not a file or directory"); + } + } + } + } + + return result; + } + + public static Set> findClasses(Collection urls, Class clazz) { + ClassLoader classLoader = new UrlClassLoader(urls.toArray(new URL[urls.size()])); + + Reflections reflections = new ConfigurationBuilder() + .addClassLoader(classLoader) + .addScanners(new SubTypesScanner(), new TypeAnnotationsScanner(), new FieldAnnotationsScanner()) + .addUrls(urls) + .build(); + + Set> types = reflections.getSubTypesOf(clazz); + + return types; + } +} diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java new file mode 100644 index 0000000000..a3929eed4a --- /dev/null +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java @@ -0,0 +1,104 @@ +package brooklyn.cli.itemlister; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import brooklyn.basic.BrooklynDynamicType; +import brooklyn.basic.BrooklynObject; +import brooklyn.basic.BrooklynType; +import brooklyn.basic.BrooklynTypes; +import brooklyn.catalog.Catalog; +import brooklyn.config.ConfigKey; +import brooklyn.entity.Effector; +import brooklyn.entity.EntityType; +import brooklyn.entity.basic.BrooklynConfigKeys; +import brooklyn.event.Sensor; +import brooklyn.location.LocationResolver; +import brooklyn.rest.domain.EffectorSummary; +import brooklyn.rest.domain.EntityConfigSummary; +import brooklyn.rest.domain.SensorSummary; +import brooklyn.rest.domain.SummaryComparators; +import brooklyn.rest.transform.EffectorTransformer; +import brooklyn.rest.transform.EntityTransformer; +import brooklyn.rest.transform.SensorTransformer; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class ItemDescriptors { + + public static List> toItemDescriptors(Iterable> types, boolean headingsOnly) { + List> itemDescriptors = Lists.newArrayList(); + + for (Class type : types) { + Map itemDescriptor = toItemDescriptor(type, headingsOnly); + itemDescriptors.add(itemDescriptor); + } + + return itemDescriptors; + } + + public static Map toItemDescriptor(Class clazz, boolean headingsOnly) { + BrooklynDynamicType dynamicType = BrooklynTypes.getDefinedBrooklynType(clazz); + BrooklynType type = dynamicType.getSnapshot(); + ConfigKey version = dynamicType.getConfigKey(BrooklynConfigKeys.SUGGESTED_VERSION.getName()); + + Map result = Maps.newLinkedHashMap(); + + result.put("type", clazz.getName()); + if (version != null) { + result.put("defaultVersion", version.getDefaultValue()); + } + + Catalog catalogAnnotation = clazz.getAnnotation(Catalog.class); + if (catalogAnnotation != null) { + result.put("name", catalogAnnotation.name()); + result.put("description", catalogAnnotation.description()); + result.put("iconUrl", catalogAnnotation.iconUrl()); + } + + Deprecated deprecatedAnnotation = clazz.getAnnotation(Deprecated.class); + if (deprecatedAnnotation != null) { + result.put("deprecated", true); + } + + if (!headingsOnly) { + Set config = Sets.newTreeSet(SummaryComparators.nameComparator()); + Set sensors = Sets.newTreeSet(SummaryComparators.nameComparator()); + Set effectors = Sets.newTreeSet(SummaryComparators.nameComparator()); + + for (ConfigKey x: type.getConfigKeys()) { + config.add(EntityTransformer.entityConfigSummary(x, dynamicType.getConfigKeyField(x.getName()))); + } + result.put("config", config); + + if (type instanceof EntityType) { + for (Sensor x: ((EntityType)type).getSensors()) + sensors.add(SensorTransformer.sensorSummaryForCatalog(x)); + result.put("sensors", sensors); + + for (Effector x: ((EntityType)type).getEffectors()) + effectors.add(EffectorTransformer.effectorSummaryForCatalog(x)); + result.put("effectors", effectors); + } + } + + return result; + } + + public static Object toItemDescriptors(List resolvers) { + List result = Lists.newArrayList(); + for (LocationResolver resolver : resolvers) { + result.add(toItemDescriptor(resolver)); + } + return result; + } + + public static Object toItemDescriptor(LocationResolver resolver) { + // TODO Get javadoc of LocationResolver? Could use docklet? But that would give dependency here + // on com.sun.javadoc.* + return resolver.getPrefix(); + } +} diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java new file mode 100644 index 0000000000..bc3782d5a1 --- /dev/null +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java @@ -0,0 +1,156 @@ +package brooklyn.cli.itemlister; + +import io.airlift.command.Cli; +import io.airlift.command.Cli.CliBuilder; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +import brooklyn.basic.BrooklynObject; +import brooklyn.catalog.Catalog; +import brooklyn.cli.AbstractMain; +import brooklyn.entity.Entity; +import brooklyn.entity.proxying.ImplementedBy; +import brooklyn.location.Location; +import brooklyn.location.LocationResolver; +import brooklyn.policy.Enricher; +import brooklyn.policy.Policy; +import brooklyn.util.collections.MutableSet; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; + +public class ItemLister extends AbstractMain { + + public static void main(String... args) { + new ItemLister().execCli(args); + } + + @Command(name = "all", description = "Lists everything") + public static class ListAllCommand extends BrooklynCommandCollectingArgs { + + @Option(name = { "--jars" }, title = "Jars", description = "jars to scan. If a file (not a url) pointing at a directory, will include all files in that directory") + public List jars; + + @Option(name = { "--type-regex" }, title = "Regex for types to list") + public String typeRegex = null; + + @Option(name = { "--catalog-only" }, title = "Whether to only list items annotated with @Catalog") + public boolean catalogOnly; + + @Option(name = { "--ignore-impls" }, title = "Ignore Entity implementations, where there is an Entity interface with @ImplementedBy") + public boolean ignoreImpls; + + @Option(name = { "--headings-only" }, title = "Whether to only show name/type, and not config keys etc") + public boolean headingsOnly; + + @Override + public Void call() throws Exception { + List urls = getUrls(); + + // TODO Remove duplication from separate ListPolicyCommand etc + List> entityTypes = getTypes(urls, Entity.class); + List> policyTypes = getTypes(urls, Policy.class); + List> enricherTypes = getTypes(urls, Enricher.class); + List> locationTypes = getTypes(urls, Location.class, Boolean.FALSE); + + Map result = ImmutableMap.builder() + .put("entities", ItemDescriptors.toItemDescriptors(entityTypes, headingsOnly)) + .put("policies", ItemDescriptors.toItemDescriptors(policyTypes, headingsOnly)) + .put("enrichers", ItemDescriptors.toItemDescriptors(enricherTypes, headingsOnly)) + .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly)) + .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)))) + .build(); + + System.out.println(toJson(result)); + return null; + } + + protected List getUrls() throws MalformedURLException { + List urls = Lists.newArrayList(); + for (String jar : jars) { + urls.addAll(ClassFinder.toJarUrls(jar)); + } + return urls; + } + + private List> getTypes(List urls, Class type) { + return getTypes(urls, type, null); + } + + private List> getTypes(List urls, Class type, Boolean catalogOnlyOverride) { + FluentIterable> fluent = FluentIterable.from(ClassFinder.findClasses(urls, type)); + if (typeRegex != null) { + fluent = fluent.filter(ClassFinder.withClassNameMatching(typeRegex)); + } + if (catalogOnlyOverride == null ? catalogOnly : catalogOnlyOverride) { + fluent = fluent.filter(ClassFinder.withAnnotation(Catalog.class)); + } + ImmutableList> result = fluent.toList(); + if (ignoreImpls) { + MutableSet> mutableResult = MutableSet.copyOf(result); + for (Class clazz : result) { + ImplementedBy implementedBy = clazz.getAnnotation(ImplementedBy.class); + if (implementedBy != null) { + mutableResult.remove(implementedBy.value()); + } + } + return ImmutableList.copyOf(mutableResult); + } else { + return result; + } + } + + private String toJson(Object obj) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper() + .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS) + .enable(SerializationFeature.INDENT_OUTPUT) + .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) + .setSerializationInclusion(JsonInclude.Include.ALWAYS) + + // Only serialise annotated fields + .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE) + .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + + return objectMapper.writeValueAsString(obj); + } + } + + /** method intended for overriding when the script filename is different + * @return the name of the script the user has invoked */ + protected String cliScriptName() { + return "item-lister"; + } + + /** method intended for overriding when a different {@link Cli} is desired, + * or when the subclass wishes to change any of the arguments */ + protected CliBuilder cliBuilder() { + @SuppressWarnings({ "unchecked" }) + CliBuilder builder = Cli.builder(cliScriptName()) + .withDescription("Brooklyn Management Service") + .withDefaultCommand(ListAllCommand.class) + .withCommands( + HelpCommand.class, + InfoCommand.class, + ListAllCommand.class + ); + + return builder; + } +} diff --git a/usage/rest-server/src/main/java/brooklyn/rest/transform/EntityTransformer.java b/usage/rest-server/src/main/java/brooklyn/rest/transform/EntityTransformer.java index cebdf860ae..23107c5d67 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/transform/EntityTransformer.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/transform/EntityTransformer.java @@ -127,7 +127,7 @@ public static String entityUri(Entity entity) { return applicationUri(entity.getApplication()) + "/entities/" + entity.getId(); } - protected static EntityConfigSummary entityConfigSummary(ConfigKey config, Field configKeyField) { + public static EntityConfigSummary entityConfigSummary(ConfigKey config, Field configKeyField) { CatalogConfig catalogConfig = configKeyField!=null ? configKeyField.getAnnotation(CatalogConfig.class) : null; String label = catalogConfig==null ? null : catalogConfig.label(); Double priority = catalogConfig==null ? null : catalogConfig.priority(); From 37ec238f9e67d25fdca9e20e1176e97efa76d17c Mon Sep 17 00:00:00 2001 From: Martin Harris Date: Fri, 22 Aug 2014 11:54:33 +0100 Subject: [PATCH 07/13] Creates first-pass at outputting entities, policies, locations and locationResolvers --- .../brooklyn/cli/itemlister/ItemLister.java | 88 +++++++++++++++---- .../main/resources/brooklyn-object-list.html | 70 +++++++++++++++ usage/cli/src/main/resources/enricher.html | 34 +++++++ usage/cli/src/main/resources/entity.html | 59 +++++++++++++ usage/cli/src/main/resources/location.html | 34 +++++++ usage/cli/src/main/resources/policy.html | 34 +++++++ 6 files changed, 304 insertions(+), 15 deletions(-) create mode 100644 usage/cli/src/main/resources/brooklyn-object-list.html create mode 100644 usage/cli/src/main/resources/enricher.html create mode 100644 usage/cli/src/main/resources/entity.html create mode 100644 usage/cli/src/main/resources/location.html create mode 100644 usage/cli/src/main/resources/policy.html diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java index bc3782d5a1..4375c38d73 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java @@ -1,16 +1,5 @@ package brooklyn.cli.itemlister; -import io.airlift.command.Cli; -import io.airlift.command.Cli.CliBuilder; -import io.airlift.command.Command; -import io.airlift.command.Option; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; - import brooklyn.basic.BrooklynObject; import brooklyn.catalog.Catalog; import brooklyn.cli.AbstractMain; @@ -20,8 +9,10 @@ import brooklyn.location.LocationResolver; import brooklyn.policy.Enricher; import brooklyn.policy.Policy; +import brooklyn.util.ResourceUtils; import brooklyn.util.collections.MutableSet; - +import brooklyn.util.os.Os; +import brooklyn.util.text.TemplateProcessor; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -29,10 +20,23 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.base.Charsets; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import com.google.common.io.Files; +import io.airlift.command.Cli; +import io.airlift.command.Cli.CliBuilder; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; public class ItemLister extends AbstractMain { @@ -50,13 +54,16 @@ public static class ListAllCommand extends BrooklynCommandCollectingArgs { public String typeRegex = null; @Option(name = { "--catalog-only" }, title = "Whether to only list items annotated with @Catalog") - public boolean catalogOnly; + public boolean catalogOnly = true; @Option(name = { "--ignore-impls" }, title = "Ignore Entity implementations, where there is an Entity interface with @ImplementedBy") public boolean ignoreImpls; @Option(name = { "--headings-only" }, title = "Whether to only show name/type, and not config keys etc") public boolean headingsOnly; + + @Option(name = { "--output-folder" }, title = "Whether to only show name/type, and not config keys etc") + public String outputFolder; @Override public Void call() throws Exception { @@ -75,11 +82,62 @@ public Void call() throws Exception { .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly)) .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)))) .build(); - - System.out.println(toJson(result)); + + String json = toJson(result); + + if (outputFolder == null) { + System.out.println(json); + } else { + String outputPath = Os.mergePaths(outputFolder, "index.html"); + String parentDir = (new File(outputPath).getParentFile()).getAbsolutePath(); + mkdir(parentDir, "entities"); + mkdir(parentDir, "policies"); + mkdir(parentDir, "enrichers"); + mkdir(parentDir, "locations"); + mkdir(parentDir, "locationResolvers"); + Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8); + ResourceUtils resourceUtils = ResourceUtils.create(this); + String mainHtml = resourceUtils.getResourceAsString("brooklyn-object-list.html"); + Files.write(mainHtml, new File(Os.mergePaths(outputFolder, "index.html")), Charsets.UTF_8); + List> entities = (List>) result.get("entities"); + String entityTemplateHtml = resourceUtils.getResourceAsString("entity.html"); + for (Map entity : entities) { + String type = (String) entity.get("type"); + String name = (String) entity.get("name"); + String entityHtml = TemplateProcessor.processTemplateContents(entityTemplateHtml, ImmutableMap.of("type", type, "name", name)); + Files.write(entityHtml, new File(Os.mergePaths(outputFolder, "entities", type + ".html")), Charsets.UTF_8); + } + List> policies = (List>) result.get("policies"); + String policyTemplateHtml = resourceUtils.getResourceAsString("policy.html"); + for (Map policy : policies) { + String type = (String) policy.get("type"); + String name = (String) policy.get("name"); + String policyHtml = TemplateProcessor.processTemplateContents(policyTemplateHtml, ImmutableMap.of("type", type, "name", name)); + Files.write(policyHtml, new File(Os.mergePaths(outputFolder, "policies", type + ".html")), Charsets.UTF_8); + } + List> enrichers = (List>) result.get("enrichers"); + String enricherTemplateHtml = resourceUtils.getResourceAsString("enricher.html"); + for (Map enricher : enrichers) { + String type = (String) enricher.get("type"); + String name = (String) enricher.get("name"); + String enricherHtml = TemplateProcessor.processTemplateContents(enricherTemplateHtml, ImmutableMap.of("type", type, "name", name)); + Files.write(enricherHtml, new File(Os.mergePaths(outputFolder, "enrichers", type + ".html")), Charsets.UTF_8); + } + List> locations = (List>) result.get("locations"); + String locationTemplateHtml = resourceUtils.getResourceAsString("location.html"); + for (Map location : locations) { + String type = (String) location.get("type"); + String locationHtml = TemplateProcessor.processTemplateContents(locationTemplateHtml, ImmutableMap.of("type", type)); + Files.write(locationHtml, new File(Os.mergePaths(outputFolder, "locations", type + ".html")), Charsets.UTF_8); + } + } return null; } + private void mkdir(String rootDir, String dirName) { + (new File(Os.mergePaths(rootDir, dirName))).mkdirs(); + } + protected List getUrls() throws MalformedURLException { List urls = Lists.newArrayList(); for (String jar : jars) { diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html new file mode 100644 index 0000000000..338da2b30c --- /dev/null +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -0,0 +1,70 @@ + + + + Brooklyn Object List + + +

    Entities

    + + + + + + +
    NameTypeDescription
    +
    +

    Policies

    + + + + + + +
    NameTypeDescription
    +

    Enrichers

    + + + + + + +
    NameTypeDescription
    +
    +

    Locations

    + + + + +
    Type
    +
    +

    Location Resolvers

    + + + + +
    Name
    +
    +
    + + + + + \ No newline at end of file diff --git a/usage/cli/src/main/resources/enricher.html b/usage/cli/src/main/resources/enricher.html new file mode 100644 index 0000000000..783af00939 --- /dev/null +++ b/usage/cli/src/main/resources/enricher.html @@ -0,0 +1,34 @@ + + + + Brooklyn Enricher - ${name} + + +

    ${name}

    +Type: +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    + + + + + + \ No newline at end of file diff --git a/usage/cli/src/main/resources/entity.html b/usage/cli/src/main/resources/entity.html new file mode 100644 index 0000000000..2255e7878d --- /dev/null +++ b/usage/cli/src/main/resources/entity.html @@ -0,0 +1,59 @@ + + + + Brooklyn - ${name} + + +

    ${name}

    +Type: +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    +

    Sensors

    + + + + + + +
    NameTypeDescription
    +
    +

    Effectors

    + + + + + + +
    NameTypeDescription
    +
    + + + + + \ No newline at end of file diff --git a/usage/cli/src/main/resources/location.html b/usage/cli/src/main/resources/location.html new file mode 100644 index 0000000000..6c9aad538e --- /dev/null +++ b/usage/cli/src/main/resources/location.html @@ -0,0 +1,34 @@ + + + + Brooklyn Location - ${type} + + +

    ${type}

    +Type: +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    + + + + + + \ No newline at end of file diff --git a/usage/cli/src/main/resources/policy.html b/usage/cli/src/main/resources/policy.html new file mode 100644 index 0000000000..c2f3ea8cce --- /dev/null +++ b/usage/cli/src/main/resources/policy.html @@ -0,0 +1,34 @@ + + + + Brooklyn Policy - ${name} + + +

    ${name}

    +Type: +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    + + + + + + \ No newline at end of file From 2157c98fcf218057b68c456ea1b116d0e882ec52 Mon Sep 17 00:00:00 2001 From: Martin Harris Date: Tue, 2 Sep 2014 17:23:42 +0100 Subject: [PATCH 08/13] Styles HTML output --- .../main/java/brooklyn/cli/AbstractMain.java | 34 +-- .../main/java/brooklyn/cli/CloudExplorer.java | 4 - .../brooklyn/cli/itemlister/ClassFinder.java | 18 ++ .../cli/itemlister/ItemDescriptors.java | 18 ++ .../brooklyn/cli/itemlister/ItemLister.java | 31 +++ .../main/resources/brooklyn-object-list.html | 188 ++++++++++----- usage/cli/src/main/resources/enricher.html | 65 ++++-- usage/cli/src/main/resources/entity.html | 110 +++++---- usage/cli/src/main/resources/items.css | 217 ++++++++++++++++++ usage/cli/src/main/resources/location.html | 64 ++++-- usage/cli/src/main/resources/policy.html | 65 ++++-- 11 files changed, 622 insertions(+), 192 deletions(-) create mode 100644 usage/cli/src/main/resources/items.css diff --git a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java b/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java index d27dee771e..d2b9169d84 100644 --- a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java +++ b/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java @@ -18,8 +18,6 @@ */ package brooklyn.cli; -import groovy.lang.GroovyClassLoader; -import groovy.lang.GroovyShell; import io.airlift.command.Arguments; import io.airlift.command.Cli; import io.airlift.command.Cli.CliBuilder; @@ -29,16 +27,10 @@ import io.airlift.command.OptionType; import io.airlift.command.ParseException; -import java.io.Console; -import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; @@ -50,39 +42,15 @@ import brooklyn.BrooklynVersion; import brooklyn.catalog.BrooklynCatalog; -import brooklyn.entity.Application; -import brooklyn.entity.Entity; -import brooklyn.entity.basic.AbstractApplication; -import brooklyn.entity.basic.AbstractEntity; -import brooklyn.entity.basic.ApplicationBuilder; -import brooklyn.entity.basic.Entities; -import brooklyn.entity.basic.StartableApplication; -import brooklyn.entity.proxying.EntitySpec; -import brooklyn.entity.rebind.persister.PersistMode; -import brooklyn.entity.trait.Startable; -import brooklyn.launcher.BrooklynLauncher; -import brooklyn.launcher.BrooklynServerDetails; -import brooklyn.launcher.config.StopWhichAppsOnShutdown; -import brooklyn.management.ManagementContext; -import brooklyn.management.ha.HighAvailabilityMode; -import brooklyn.rest.security.PasswordHasher; -import brooklyn.util.ResourceUtils; -import brooklyn.util.exceptions.Exceptions; +import brooklyn.cli.Main.LaunchCommand; import brooklyn.util.exceptions.FatalConfigurationRuntimeException; import brooklyn.util.exceptions.FatalRuntimeException; import brooklyn.util.exceptions.UserFacingException; -import brooklyn.util.guava.Maybe; -import brooklyn.util.javalang.Enums; -import brooklyn.util.net.Networking; -import brooklyn.util.text.Identifiers; -import brooklyn.util.text.StringEscapes.JavaStringEscapes; import brooklyn.util.text.Strings; -import com.google.common.annotations.Beta; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; -import com.google.common.collect.ImmutableList; /** * This class is the primary CLI for brooklyn. diff --git a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java index d2936c8e8a..a5f4948fdd 100644 --- a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java +++ b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java @@ -40,8 +40,6 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.options.TemplateOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import brooklyn.location.Location; import brooklyn.location.LocationDefinition; @@ -69,8 +67,6 @@ */ public class CloudExplorer extends AbstractMain { - private static final Logger log = LoggerFactory.getLogger(Main.class); - public static void main(String... args) { new CloudExplorer().execCli(args); } diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java index 18888ac058..92cf1cadc5 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ClassFinder.java @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package brooklyn.cli.itemlister; import java.io.File; diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java index a3929eed4a..ecb226479e 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package brooklyn.cli.itemlister; import java.util.List; diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java index 4375c38d73..8ee267fe84 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package brooklyn.cli.itemlister; import brooklyn.basic.BrooklynObject; @@ -13,6 +31,7 @@ import brooklyn.util.collections.MutableSet; import brooklyn.util.os.Os; import brooklyn.util.text.TemplateProcessor; + import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -26,6 +45,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.io.Files; + import io.airlift.command.Cli; import io.airlift.command.Cli.CliBuilder; import io.airlift.command.Command; @@ -38,7 +58,12 @@ import java.util.Map; import java.util.ServiceLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class ItemLister extends AbstractMain { + + private static final Logger LOG = LoggerFactory.getLogger(ItemLister.class); public static void main(String... args) { new ItemLister().execCli(args); @@ -65,8 +90,10 @@ public static class ListAllCommand extends BrooklynCommandCollectingArgs { @Option(name = { "--output-folder" }, title = "Whether to only show name/type, and not config keys etc") public String outputFolder; + @SuppressWarnings("unchecked") @Override public Void call() throws Exception { + LOG.info("Retrieving objects"); List urls = getUrls(); // TODO Remove duplication from separate ListPolicyCommand etc @@ -88,6 +115,7 @@ public Void call() throws Exception { if (outputFolder == null) { System.out.println(json); } else { + LOG.info("Outputting item list to " + outputFolder); String outputPath = Os.mergePaths(outputFolder, "index.html"); String parentDir = (new File(outputPath).getParentFile()).getAbsolutePath(); mkdir(parentDir, "entities"); @@ -97,6 +125,8 @@ public Void call() throws Exception { mkdir(parentDir, "locationResolvers"); Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8); ResourceUtils resourceUtils = ResourceUtils.create(this); + String css = resourceUtils.getResourceAsString("items.css"); + Files.write(css, new File(Os.mergePaths(outputFolder, "items.css")), Charsets.UTF_8); String mainHtml = resourceUtils.getResourceAsString("brooklyn-object-list.html"); Files.write(mainHtml, new File(Os.mergePaths(outputFolder, "index.html")), Charsets.UTF_8); List> entities = (List>) result.get("entities"); @@ -130,6 +160,7 @@ public Void call() throws Exception { String locationHtml = TemplateProcessor.processTemplateContents(locationTemplateHtml, ImmutableMap.of("type", type)); Files.write(locationHtml, new File(Os.mergePaths(outputFolder, "locations", type + ".html")), Charsets.UTF_8); } + LOG.info("Finished outputting item list to " + outputFolder); } return null; } diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html index 338da2b30c..8a5863c1ad 100644 --- a/usage/cli/src/main/resources/brooklyn-object-list.html +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -1,70 +1,132 @@ - - - - Brooklyn Object List - - -

    Entities

    - - - - - - -
    NameTypeDescription
    + + + + + Brooklyn Object List + + + + +
    + +
    + +
    +
    +

    Entities

    + + + + + + +
    NameTypeDescription
    +

    -

    Policies

    - - - - - - -
    NameTypeDescription
    -

    Enrichers

    - - - - - - -
    NameTypeDescription
    + +
    +

    Policies

    + + + + + + +
    NameTypeDescription
    +

    -

    Locations

    - - - - -
    Type
    + +
    +

    Enrichers

    + + + + + + +
    NameTypeDescription
    +

    -

    Location Resolvers

    - - - - -
    Name
    + +
    +

    Locations

    + + + + +
    Type
    +

    + +
    +

    Location Resolvers

    + + + + +
    Name
    +

    - - - + + - + } + + $(document).ready(function () { + items.entities.forEach(function (element) { + $("#entityTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + }); + items.policies.forEach(function (element) { + $("#policyTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + }); + items.enrichers.forEach(function (element) { + $("#enricherTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + }); + items.locations.forEach(function (element) { + $("#locationTable").find("tr:last").after("" + element.type + "") + }); + items.locationResolvers.forEach(function (element) { + $("#locationResolverTable").find("tr:last").after("" + element + "") + }); + }); + +
    + \ No newline at end of file diff --git a/usage/cli/src/main/resources/enricher.html b/usage/cli/src/main/resources/enricher.html index 783af00939..dc018fac91 100644 --- a/usage/cli/src/main/resources/enricher.html +++ b/usage/cli/src/main/resources/enricher.html @@ -1,31 +1,62 @@ - + + - Brooklyn Enricher - ${name} + + -

    ${name}

    -Type: -

    Config Keys

    - - - - - - - -
    NameTypeDefault ValueDescription
    -
    +
    + +
    +
    +

    ${name}

    +

    Type:

    + +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    +
    +
    + diff --git a/usage/cli/src/main/resources/policy.html b/usage/cli/src/main/resources/policy.html index c2f3ea8cce..4fc1f59cb2 100644 --- a/usage/cli/src/main/resources/policy.html +++ b/usage/cli/src/main/resources/policy.html @@ -1,32 +1,61 @@ - + + - Brooklyn Policy - ${name} + + -

    ${name}

    -Type: -

    Config Keys

    - - - - - - - -
    NameTypeDefault ValueDescription
    -
    +
    + +
    +

    ${name}

    +

    Type:

    + +

    Config Keys

    + + + + + + + +
    NameTypeDefault ValueDescription
    +
    +
    +
    From f14a64b61d771b9b5eb8ffb9fdfb7f208ac32e8c Mon Sep 17 00:00:00 2001 From: Martin Harris Date: Tue, 2 Sep 2014 18:13:47 +0100 Subject: [PATCH 09/13] Sorts output --- .../cli/itemlister/ItemDescriptors.java | 36 +++++++++++++++++ .../brooklyn/cli/itemlister/ItemLister.java | 40 +++++++++---------- .../main/resources/brooklyn-object-list.html | 6 +-- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java index ecb226479e..f909524274 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemDescriptors.java @@ -18,6 +18,8 @@ */ package brooklyn.cli.itemlister; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,6 +43,7 @@ import brooklyn.rest.transform.EntityTransformer; import brooklyn.rest.transform.SensorTransformer; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -48,6 +51,10 @@ public class ItemDescriptors { public static List> toItemDescriptors(Iterable> types, boolean headingsOnly) { + return toItemDescriptors(types, headingsOnly, null); + } + + public static List> toItemDescriptors(Iterable> types, boolean headingsOnly, final String sortField) { List> itemDescriptors = Lists.newArrayList(); for (Class type : types) { @@ -55,6 +62,22 @@ public static List> toItemDescriptors(Iterable>() { + @Override public int compare(Map id1, Map id2) { + Object o1 = id1.get(sortField); + Object o2 = id2.get(sortField); + if (o1 == null) { + return o2 == null ? 0 : 1; + } + if (o2 == null) { + return -1; + } + return o1.toString().compareTo(o2.toString()); + } + }); + } + return itemDescriptors; } @@ -107,10 +130,23 @@ public static Map toItemDescriptor(Class resolvers) { + return toItemDescriptors(resolvers, false); + } + + public static Object toItemDescriptors(List resolvers, Boolean sort) { List result = Lists.newArrayList(); for (LocationResolver resolver : resolvers) { result.add(toItemDescriptor(resolver)); } + if (sort) { + Collections.sort(result, new Comparator() { + @Override public int compare(Object o1, Object o2) { + String s1 = o1 == null ? "" : o1.toString(); + String s2 = o2 == null ? "" : o2.toString(); + return s1.compareTo(s2); + } + }); + } return result; } diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java index 8ee267fe84..0dfec167fb 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java @@ -18,6 +18,21 @@ */ package brooklyn.cli.itemlister; +import io.airlift.command.Cli; +import io.airlift.command.Cli.CliBuilder; +import io.airlift.command.Command; +import io.airlift.command.Option; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import brooklyn.basic.BrooklynObject; import brooklyn.catalog.Catalog; import brooklyn.cli.AbstractMain; @@ -46,21 +61,6 @@ import com.google.common.collect.Lists; import com.google.common.io.Files; -import io.airlift.command.Cli; -import io.airlift.command.Cli.CliBuilder; -import io.airlift.command.Command; -import io.airlift.command.Option; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - public class ItemLister extends AbstractMain { private static final Logger LOG = LoggerFactory.getLogger(ItemLister.class); @@ -103,11 +103,11 @@ public Void call() throws Exception { List> locationTypes = getTypes(urls, Location.class, Boolean.FALSE); Map result = ImmutableMap.builder() - .put("entities", ItemDescriptors.toItemDescriptors(entityTypes, headingsOnly)) - .put("policies", ItemDescriptors.toItemDescriptors(policyTypes, headingsOnly)) - .put("enrichers", ItemDescriptors.toItemDescriptors(enricherTypes, headingsOnly)) - .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly)) - .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)))) + .put("entities", ItemDescriptors.toItemDescriptors(entityTypes, headingsOnly, "name")) + .put("policies", ItemDescriptors.toItemDescriptors(policyTypes, headingsOnly, "name")) + .put("enrichers", ItemDescriptors.toItemDescriptors(enricherTypes, headingsOnly, "name")) + .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly, "type")) + .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)), true)) .build(); String json = toJson(result); diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html index 8a5863c1ad..8ec86fbed3 100644 --- a/usage/cli/src/main/resources/brooklyn-object-list.html +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -111,13 +111,13 @@

    Location Resolvers

    $(document).ready(function () { items.entities.forEach(function (element) { - $("#entityTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + $("#entityTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") }); items.policies.forEach(function (element) { - $("#policyTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + $("#policyTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") }); items.enrichers.forEach(function (element) { - $("#enricherTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") + $("#enricherTable").find("tr:last").after("" + element.name + "" + element.type + "" + element.description + "") }); items.locations.forEach(function (element) { $("#locationTable").find("tr:last").after("" + element.type + "") From 3853681f05c8297929cb1bb55f383048118df12f Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 5 Sep 2014 13:41:28 +0100 Subject: [PATCH 10/13] Improve @Catalog descriptions --- .../main/java/brooklyn/demo/NodeJsTodoApplication.java | 2 +- .../main/java/brooklyn/entity/messaging/storm/Storm.java | 4 +++- .../brooklyn/entity/messaging/storm/StormDeployment.java | 4 +++- .../java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java | 3 ++- .../java/brooklyn/entity/zookeeper/ZooKeeperNode.java | 3 ++- .../brooklyn/entity/nosql/couchbase/CouchbaseCluster.java | 3 ++- .../brooklyn/entity/nosql/couchbase/CouchbaseNode.java | 3 ++- .../entity/nosql/elasticsearch/ElasticSearchCluster.java | 4 +++- .../entity/nosql/elasticsearch/ElasticSearchNode.java | 4 +++- .../main/java/brooklyn/entity/nosql/riak/RiakCluster.java | 8 +++++--- .../main/java/brooklyn/entity/nosql/riak/RiakNode.java | 3 ++- .../entity/webapp/nodejs/NodeJsWebAppService.java | 2 +- 12 files changed, 29 insertions(+), 14 deletions(-) diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java index 483986afe5..50d5f74b7d 100644 --- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java +++ b/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java @@ -37,7 +37,7 @@ * Node.JS Todo Application */ @Catalog(name="NodeJS Todo", - description="Node.JS Todo Application.", + description="Node.js is a cross-platform runtime environment for server-side and networking applications. Node.js applications are written in JavaScript", iconUrl="classpath://nodejs-logo.png") public class NodeJsTodoApplication extends AbstractApplication implements StartableApplication { diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java index d7ec47b47d..455747a692 100644 --- a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java +++ b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/Storm.java @@ -36,7 +36,9 @@ /** * An {@link brooklyn.entity.Entity} that represents a Storm node (UI, Nimbus or Supervisor). */ -@Catalog(name="Storm Node", description="Storm is...") +@Catalog(name="Storm Node", description="Apache Storm is a distributed realtime computation system. " + + "Storm makes it easy to reliably process unbounded streams of data, doing for realtime processing " + + "what Hadoop did for batch processing") @ImplementedBy(StormImpl.class) public interface Storm extends SoftwareProcess, UsesJmx { diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java index 14832815bb..f5e3373ecb 100644 --- a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java +++ b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormDeployment.java @@ -26,7 +26,9 @@ import brooklyn.entity.trait.Startable; import brooklyn.util.flags.SetFromFlag; -@Catalog(name="Storm Deployment", description="Storm is...") +@Catalog(name="Storm Deployment", description="A Storm cluster. Apache Storm is a distributed realtime computation system. " + + "Storm makes it easy to reliably process unbounded streams of data, doing for realtime processing " + + "what Hadoop did for batch processing") @ImplementedBy(StormDeploymentImpl.class) public interface StormDeployment extends Entity, Startable { diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java index f33ee90ee7..a15eeef1dd 100644 --- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java +++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java @@ -32,7 +32,8 @@ import com.google.common.reflect.TypeToken; -@Catalog(name="ZooKeeper ensemble", description="ZooKeeper is...") +@Catalog(name="ZooKeeper ensemble", description="A cluster of ZooKeeper servers. " + + "Apache ZooKeeper enables highly reliable distributed coordination.") @ImplementedBy(ZooKeeperEnsembleImpl.class) public interface ZooKeeperEnsemble extends DynamicCluster { diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java index 40b7b3ebce..a4a6d2d6b1 100644 --- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java +++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperNode.java @@ -32,7 +32,8 @@ /** * An {@link brooklyn.entity.Entity} that represents a single Apache ZooKeeper instance. */ -@Catalog(name="ZooKeeper Node", description="ZooKeeper is...") +@Catalog(name="ZooKeeper Node", description="Apache ZooKeeper is a server which enables " + + "highly reliable distributed coordination.") @ImplementedBy(ZooKeeperNodeImpl.class) public interface ZooKeeperNode extends SoftwareProcess { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java index 1bdc124a1a..9a5de95003 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java @@ -35,7 +35,8 @@ import com.google.common.reflect.TypeToken; -@Catalog(name="CouchBase Cluster", description="CouchBase is...") +@Catalog(name="CouchBase Cluster", description="Couchbase is an open source, distributed (shared-nothing architecture) " + + "NoSQL document-oriented database that is optimized for interactive applications.") @ImplementedBy(CouchbaseClusterImpl.class) public interface CouchbaseCluster extends DynamicCluster { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java index 9fa23b52ff..4a843dd67a 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchbase/CouchbaseNode.java @@ -36,7 +36,8 @@ import brooklyn.util.flags.SetFromFlag; import brooklyn.util.text.ByteSizeStrings; -@Catalog(name="CouchBase Node", description="CouchBase is...") +@Catalog(name="CouchBase Node", description="Couchbase Server is an open source, distributed (shared-nothing architecture) " + + "NoSQL document-oriented database that is optimized for interactive applications.") @ImplementedBy(CouchbaseNodeImpl.class) public interface CouchbaseNode extends SoftwareProcess { diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java index 738661bd17..155b79feba 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java @@ -27,7 +27,9 @@ /** * A cluster of {@link ElasticSearchNode}s based on {@link DynamicCluster} which can be resized by a policy if required. */ -@Catalog(name="Elastic Search Cluster", description="Elastic Search is...") +@Catalog(name="Elastic Search Cluster", description="Elasticsearch is an open-source search server based on Lucene. " + + "It provides a distributed, multitenant-capable full-text search engine with a RESTful web interface and " + + "schema-free JSON documents.") @ImplementedBy(ElasticSearchClusterImpl.class) public interface ElasticSearchCluster extends DynamicCluster { @SetFromFlag("clusterName") diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java index d679f3fe6c..ddd7b36b99 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java @@ -36,7 +36,9 @@ /** * An {@link brooklyn.entity.Entity} that represents an ElasticSearch node */ -@Catalog(name="Elastic Search Node", description="Elastic Search is...") +@Catalog(name="Elastic Search Node", description="Elasticsearch is an open-source search server based on Lucene. " + + "It provides a distributed, multitenant-capable full-text search engine with a RESTful web interface and " + + "schema-free JSON documents.") @ImplementedBy(ElasticSearchNodeImpl.class) public interface ElasticSearchNode extends SoftwareProcess, DatastoreMixins.HasDatastoreUrl { @SetFromFlag("version") diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java index 798ebe9e09..32e8de7178 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakCluster.java @@ -33,13 +33,15 @@ import com.google.common.reflect.TypeToken; -@Catalog(name="Riak Node", description="Riak is...") +@Catalog(name="Riak Cluster", description="Riak is a distributed NoSQL key-value data store that offers " + + "extremely high availability, fault tolerance, operational simplicity and scalability.") @ImplementedBy(RiakClusterImpl.class) public interface RiakCluster extends DynamicCluster { @SuppressWarnings("serial") - AttributeSensor> RIAK_CLUSTER_NODES = Sensors.newSensor(new TypeToken>() { - }, "riak.cluster.nodes", "Names of all active Riak nodes in the cluster "); + AttributeSensor> RIAK_CLUSTER_NODES = Sensors.newSensor( + new TypeToken>() {}, + "riak.cluster.nodes", "Names of all active Riak nodes in the cluster "); @SetFromFlag("delayBeforeAdvertisingCluster") ConfigKey DELAY_BEFORE_ADVERTISING_CLUSTER = ConfigKeys.newConfigKey(Duration.class, "riak.cluster.delayBeforeAdvertisingCluster", "Delay after cluster is started before checking and advertising its availability", Duration.seconds(2 * 60)); diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java index 0acc7b11e8..8eb583f740 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/riak/RiakNode.java @@ -35,7 +35,8 @@ import brooklyn.event.basic.Sensors; import brooklyn.util.flags.SetFromFlag; -@Catalog(name="Riak Node", description="Riak is...") +@Catalog(name="Riak Node", description="Riak is a distributed NoSQL key-value data store that offers " + + "extremely high availability, fault tolerance, operational simplicity and scalability.") @ImplementedBy(RiakNodeImpl.class) public interface RiakNode extends SoftwareProcess { diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java b/software/webapp/src/main/java/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java index 1711563ce6..dd1534b317 100644 --- a/software/webapp/src/main/java/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java +++ b/software/webapp/src/main/java/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java @@ -35,7 +35,7 @@ import com.google.common.reflect.TypeToken; @Catalog(name="Node.JS Application", - description="Node.JS Web Application", + description="Node.js is a cross-platform runtime environment for server-side and networking applications. Node.js applications are written in JavaScriptq", iconUrl="classpath:///nodejs-logo.png") @ImplementedBy(NodeJsWebAppServiceImpl.class) public interface NodeJsWebAppService extends SoftwareProcess, WebAppService { From 286323eae112093c601ff21045f1cf1f91ac814a Mon Sep 17 00:00:00 2001 From: Alasdair Hodge Date: Fri, 5 Sep 2014 16:09:03 +0100 Subject: [PATCH 11/13] =?UTF-8?q?Tidy=20up=20main=20items=20page:=20=20*?= =?UTF-8?q?=20use=20=E2=80=98cards=E2=80=99=20instead=20of=20tables,=20wit?= =?UTF-8?q?h=20underscore=20templates=20=20*=20replace=20brooklyn-esque=20?= =?UTF-8?q?navbar=20with=20bootstrap=20tabs=20for=20categories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/brooklyn-object-list.html | 132 +++---- usage/cli/src/main/resources/items.css | 344 ++++++++++++------ 2 files changed, 281 insertions(+), 195 deletions(-) diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html index 8ec86fbed3..dbd629ed78 100644 --- a/usage/cli/src/main/resources/brooklyn-object-list.html +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -19,9 +19,13 @@ - Brooklyn Object List + Brooklyn Objects + + + +
    @@ -29,6 +33,7 @@ +
    -
    - -
    -
    -

    Entities

    - - - - - - -
    NameTypeDescription
    -
    -
    - -
    -

    Policies

    - - - - - - -
    NameTypeDescription
    -
    -
    -
    -

    Enrichers

    - - - - - - -
    NameTypeDescription
    -
    -
    - -
    -

    Locations

    - - - - -
    Type
    -
    -
    + -
    -

    Location Resolvers

    - - - - -
    Name
    -
    -
    +
    +
    +
    +
    +
    +
    -
    - +
    diff --git a/usage/cli/src/main/resources/items.css b/usage/cli/src/main/resources/items.css index e6e87d1f96..a92920bb65 100644 --- a/usage/cli/src/main/resources/items.css +++ b/usage/cli/src/main/resources/items.css @@ -18,200 +18,316 @@ */ /* landing page */ body { - margin: 0px; - padding: 10px 0px 20px 0px; - font-family: arial, helvetica, sans-serif; - background-color: #ffffff; - color: #393939; - font-size: 15px; + margin: 0px; + padding: 10px 0px 20px 0px; + font-family: arial, helvetica, sans-serif; + background-color: #ffffff; + color: #393939; + font-size: 15px; } h1 { - margin: 0 0 20px 0; - padding: 0; - font-size: 32px; - font-weight: normal; - color: #4d9d3a; - border-bottom: 1px solid #e9e9e9; + margin: 0 0 20px 0; + padding: 0; + font-size: 32px; + font-weight: normal; + color: #4d9d3a; + border-bottom: 1px solid #e9e9e9; +} + +.nav-tabs { + clear: both; + font-size: 16pt; + font-weight: bold; +} +.nav-tabs a { + color: #4d9d3a; +} +.nav-tabs a:hover { + color: #4d9d3a; +} + +.cardList { + padding: 20px; + padding-bottom: 10px; + border: 1px solid #ddd; + border-top: none; +} +.card { + position: relative; + padding: 12px; + margin-bottom: 10px; + background-color: #f8f8f8; + color: #333; + border: 1px solid #E1E1E8; + border-radius: 6px; + font-size: 11pt; +} +.card:hover { + background-color: #f4f4f4; + top: -2px; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2); +} +.card .detailsLink { + display: block; + position: absolute; + right: 0; + top: 0; + padding: 8px; + font-size: 20pt; + color: #8a8 !important; + text-decoration: none; +} +.detailsLink:hover { + color: #686 !important; +} +.name { + font-size: 12pt; + font-weight: bold; +} +.type { + font-family: monospace; + color: #888; + margin-top: 2px; +} +.description { + margin: 10px 40px 0 20px; } th { - margin: 1.25em 0 20px 0; - font-size: 20px; - font-weight: normal; - color: #4f8243 + margin: 1.25em 0 20px 0; + font-size: 20px; + font-weight: normal; + color: #4f8243 } .typeLabel { - display: inline; - padding-right: 10px; + display: inline; + padding-right: 10px; } table { - border: 1px solid #f0f0f0; - border-radius: 5px; - background-color: #fcfcfc; - border-collapse: collapse; + border: 1px solid #f0f0f0; + border-radius: 5px; + background-color: #fcfcfc; + border-collapse: collapse; padding: 6px; } td { - border-bottom: 1px solid #f0f0f0; - padding: 6px; - max-width: 350px; - white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - white-space: pre-wrap; /* css-3 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - word-break: break-all; - white-space: normal; + border-bottom: 1px solid #f0f0f0; + padding: 6px; + max-width: 350px; + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* css-3 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + word-break: break-all; + white-space: normal; } .wordWrap { - word-break: normal !important; + word-break: normal !important; } +.nav-tabs { + font-size: 16pt; + font-weight: bold; +} +.nav-tabs a { + color: #4d9d3a; +} +.nav-tabs a:hover { + color: #4d9d3a; +} + +.cardList { + padding: 20px; + padding-bottom: 10px; + border: 1px solid #ddd; + border-top: none; +} +.card { + position: relative; + padding: 12px; + margin-bottom: 10px; + background-color: #f8f8f8; + color: #333; + border: 1px solid #E1E1E8; + border-radius: 6px; + font-size: 11pt; +} +.card:hover { + background-color: #f4f4f4; + top: -2px; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2); +} +.card .detailsLink { + display: block; + position: absolute; + right: 0; + top: 0; + padding: 8px; + font-size: 20pt; + color: #8a8 !important; + text-decoration: none; +} +.detailsLink:hover { + color: #686 !important; +} +.name { + font-size: 12pt; + font-weight: bold; +} +.type { + font-family: monospace; + color: #888; + margin-top: 2px; +} +.description { + margin: 10px 40px 0 20px; +} .location { - word-break: keep-all; - max-width: 100%; + word-break: keep-all; + max-width: 100%; } .objectContent { - display: block; - clear: both; + display: block; + clear: both; } #container { - width: 980px; - padding: 0; - margin: 0 auto; + width: 980px; + padding: 0; + margin: 0 auto; } #identity { - float: left; - margin: 0; - padding: 30px 0 15px 10px; + float: left; + margin: 0; + padding: 30px 0 15px 10px; } #identity a { - text-decoration: none; - display: block; - margin: 0; - color: #4d9d3a; - font-size: 2.5em; - padding: 0; - background: transparent url(images/brooklyn.gif) no-repeat 0 0; - width: 206px; - height: 44px; - text-indent: -1000px; - overflow: hidden; + text-decoration: none; + display: block; + margin: 0; + color: #4d9d3a; + font-size: 2.5em; + padding: 0; + background: transparent url(images/brooklyn.gif) no-repeat 0 0; + width: 206px; + height: 44px; + text-indent: -1000px; + overflow: hidden; } #menubar { - clear: both; - width: 978px; - height: 34px; - background-color: #e8eded; - border: 1px solid #d5dade; - -moz-border-radius: 8px; - border-radius: 8px; + clear: both; + width: 978px; + height: 34px; + background-color: #e8eded; + border: 1px solid #d5dade; + -moz-border-radius: 8px; + border-radius: 8px; } #mainmenu { - list-style: none; - margin: 0; - padding: 4px 0 0 2px; - width: 765px; - display: block; - float: left; - font-size: 15px; + list-style: none; + margin: 0; + padding: 4px 0 0 2px; + width: 765px; + display: block; + float: left; + font-size: 15px; } #mainmenu li { - float: left; - position: relative; - margin: 0; - padding: 0; + float: left; + position: relative; + margin: 0; + padding: 0; } #mainmenu>li { - border: 1px solid transparent; - border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-bottom: 0; + border: 1px solid transparent; + border-top-left-radius: 5px; + -moz-border-radius-topleft: 5px; + border-top-right-radius: 5px; + -moz-border-radius-topright: 5px; + border-bottom: 0; } #mainmenu a { - display: block; - text-decoration: none; - color: #508243; + display: block; + text-decoration: none; + color: #508243; } #mainmenu>li>a { - padding: 0 8px 5px 8px; - line-height: 25px; + padding: 0 8px 5px 8px; + line-height: 25px; } #mainmenu>li:hover { - background-color: #ffffff; - border: 1px solid #dbe0e4; - border-bottom: 0; + background-color: #ffffff; + border: 1px solid #dbe0e4; + border-bottom: 0; } #mainmenu .current a { - color: #838a8b; + color: #838a8b; } #mainmenu ul { - display: none; - position: absolute; - top: 30px; - left: -1px; - float: left; - background-color: #f5f5f5; - border: 1px solid #dbe0e4; - border-top: 0; - list-style: none; - margin: 0; - padding: 5px; - width: 185px; + display: none; + position: absolute; + top: 30px; + left: -1px; + float: left; + background-color: #f5f5f5; + border: 1px solid #dbe0e4; + border-top: 0; + list-style: none; + margin: 0; + padding: 5px; + width: 185px; } #mainmenu ul ul { - left: 100%; - margin-left: 6px; - top: -1px; - border-top: 1px solid #dbe0e4; + left: 100%; + margin-left: 6px; + top: -1px; + border-top: 1px solid #dbe0e4; } #mainmenu ul li { - width: 183px; - padding: 0; - border: 1px solid transparent; + width: 183px; + padding: 0; + border: 1px solid transparent; } #mainmenu ul li:hover { - border: 1px solid #dbe0e4; - background-color: #ffffff; + border: 1px solid #dbe0e4; + background-color: #ffffff; } #mainmenu ul a { - font-size: 14px; - padding: 7px; + font-size: 14px; + padding: 7px; } #mainmenu li:hover>ul,#mainmenu li.sfHover>ul { - display: block; + display: block; } #content { - overflow: scroll; - height: 1000px; + overflow: scroll; + height: 1000px; } #content a { - color: #4f8243; + color: #4f8243; } \ No newline at end of file From 91d7bc7585fdcb63ec82630017aad79ce84c6075 Mon Sep 17 00:00:00 2001 From: Alasdair Hodge Date: Fri, 5 Sep 2014 22:17:21 +0100 Subject: [PATCH 12/13] Remove redundant stuff. --- .../main/resources/brooklyn-object-list.html | 21 ++----- usage/cli/src/main/resources/items.css | 62 +------------------ 2 files changed, 8 insertions(+), 75 deletions(-) diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html index dbd629ed78..5c8852956c 100644 --- a/usage/cli/src/main/resources/brooklyn-object-list.html +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -33,17 +33,6 @@ -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    diff --git a/usage/cli/src/main/resources/items.css b/usage/cli/src/main/resources/items.css index a92920bb65..d36774893d 100644 --- a/usage/cli/src/main/resources/items.css +++ b/usage/cli/src/main/resources/items.css @@ -37,8 +37,8 @@ h1 { .nav-tabs { clear: both; - font-size: 16pt; font-weight: bold; + font-size: 12pt; } .nav-tabs a { color: #4d9d3a; @@ -47,12 +47,13 @@ h1 { color: #4d9d3a; } -.cardList { +.tab-content { padding: 20px; padding-bottom: 10px; border: 1px solid #ddd; border-top: none; } + .card { position: relative; padding: 12px; @@ -131,63 +132,6 @@ td { word-break: normal !important; } -.nav-tabs { - font-size: 16pt; - font-weight: bold; -} -.nav-tabs a { - color: #4d9d3a; -} -.nav-tabs a:hover { - color: #4d9d3a; -} - -.cardList { - padding: 20px; - padding-bottom: 10px; - border: 1px solid #ddd; - border-top: none; -} -.card { - position: relative; - padding: 12px; - margin-bottom: 10px; - background-color: #f8f8f8; - color: #333; - border: 1px solid #E1E1E8; - border-radius: 6px; - font-size: 11pt; -} -.card:hover { - background-color: #f4f4f4; - top: -2px; - box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2); -} -.card .detailsLink { - display: block; - position: absolute; - right: 0; - top: 0; - padding: 8px; - font-size: 20pt; - color: #8a8 !important; - text-decoration: none; -} -.detailsLink:hover { - color: #686 !important; -} -.name { - font-size: 12pt; - font-weight: bold; -} -.type { - font-family: monospace; - color: #888; - margin-top: 2px; -} -.description { - margin: 10px 40px 0 20px; -} .location { word-break: keep-all; max-width: 100%; From a14adf02031f18acf0d3543352f57f5935a116aa Mon Sep 17 00:00:00 2001 From: Alasdair Hodge Date: Sat, 6 Sep 2014 17:46:16 +0100 Subject: [PATCH 13/13] Move common javascript to separate file. Clean up child pages. --- .../brooklyn/cli/itemlister/ItemLister.java | 2 + .../main/resources/brooklyn-object-list.html | 69 ++---- usage/cli/src/main/resources/common.js | 94 ++++++++ usage/cli/src/main/resources/enricher.html | 68 +++--- usage/cli/src/main/resources/entity.html | 99 ++++----- usage/cli/src/main/resources/items.css | 207 ++++-------------- usage/cli/src/main/resources/policy.html | 66 +++--- 7 files changed, 257 insertions(+), 348 deletions(-) create mode 100644 usage/cli/src/main/resources/common.js diff --git a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java index 0dfec167fb..f12d31d949 100644 --- a/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java +++ b/usage/cli/src/main/java/brooklyn/cli/itemlister/ItemLister.java @@ -125,6 +125,8 @@ public Void call() throws Exception { mkdir(parentDir, "locationResolvers"); Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8); ResourceUtils resourceUtils = ResourceUtils.create(this); + String js = resourceUtils.getResourceAsString("common.js"); + Files.write(js, new File(Os.mergePaths(outputFolder, "common.js")), Charsets.UTF_8); String css = resourceUtils.getResourceAsString("items.css"); Files.write(css, new File(Os.mergePaths(outputFolder, "items.css")), Charsets.UTF_8); String mainHtml = resourceUtils.getResourceAsString("brooklyn-object-list.html"); diff --git a/usage/cli/src/main/resources/brooklyn-object-list.html b/usage/cli/src/main/resources/brooklyn-object-list.html index 5c8852956c..b1a576a3c9 100644 --- a/usage/cli/src/main/resources/brooklyn-object-list.html +++ b/usage/cli/src/main/resources/brooklyn-object-list.html @@ -18,74 +18,49 @@ --> - + Brooklyn Objects - - - - - -
    - - - \ No newline at end of file + + diff --git a/usage/cli/src/main/resources/common.js b/usage/cli/src/main/resources/common.js new file mode 100644 index 0000000000..877052a7cb --- /dev/null +++ b/usage/cli/src/main/resources/common.js @@ -0,0 +1,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var brooklyn = (function ($, _) { + + return { + findItemOfType: function(items, type) { + return _.findWhere(items, { type: type }); + }, + + entityCard: _.template( + "" + + "
    " + + "" + + "
    <%=name%>
    " + + "
    <%=type%>
    " + + "
    <%=description%>
    " + + "
    " + + "
    " + ), + policyCard: _.template( + "" + + "
    " + + "" + + "
    <%=name%>
    " + + "
    <%=type%>
    " + + "
    <%=description%>
    " + + "
    " + + "
    " + ), + enricherCard: _.template( + "" + + "
    " + + "" + + "
    <%=name%>
    " + + "
    <%=type%>
    " + + "
    <%=description%>
    " + + "
    " + + "
    " + ), + + typeSummary: _.template( + "
    <%=name%>
    " + + "
    <%=type%>
    " + + "
    <%=description%>
    " + ), + + configKeyCard: _.template( + "
    " + + "
    <%=name%>
    " + + "
    " + + "
    description
    <%=(description||' ')%>
    " + + "
    value type
    <%=(type||' ')%>
    " + + "
    default value
    <%=(defaultValue||' ')%>
    " + + "
    " + + "
    " + ), + sensorCard: _.template( + "
    " + + "
    <%=name%>
    " + + "
    " + + "
    description
    <%=(description||' ')%>
    " + + "
    value type
    <%=(type||' ')%>
    " + + "
    " + + "
    " + ), + effectorCard: _.template( + "
    " + + "
    <%=name%>
    " + + "
    " + + "
    description
    <%=(description||' ')%>
    " + + "
    return type
    <%=(returnType||' ')%>
    " + + "
    " + + "
    " + ), + }; + +}(jQuery, _)); diff --git a/usage/cli/src/main/resources/enricher.html b/usage/cli/src/main/resources/enricher.html index dc018fac91..b484de2f49 100644 --- a/usage/cli/src/main/resources/enricher.html +++ b/usage/cli/src/main/resources/enricher.html @@ -17,49 +17,43 @@ under the License. --> - + Brooklyn Enricher - ${name} + - - -
    - +
    + + +
    +
    +
    + +
    - - - + + + + + - - \ No newline at end of file + + + diff --git a/usage/cli/src/main/resources/entity.html b/usage/cli/src/main/resources/entity.html index d4d2fe7b22..b1602f7225 100644 --- a/usage/cli/src/main/resources/entity.html +++ b/usage/cli/src/main/resources/entity.html @@ -17,75 +17,50 @@ under the License. --> - - Brooklyn - ${name} + + Brooklyn Entity - ${name} + - - -
    - - - - + + + + + - - \ No newline at end of file + + + diff --git a/usage/cli/src/main/resources/items.css b/usage/cli/src/main/resources/items.css index d36774893d..0e9ff73056 100644 --- a/usage/cli/src/main/resources/items.css +++ b/usage/cli/src/main/resources/items.css @@ -26,15 +26,6 @@ body { font-size: 15px; } -h1 { - margin: 0 0 20px 0; - padding: 0; - font-size: 32px; - font-weight: normal; - color: #4d9d3a; - border-bottom: 1px solid #e9e9e9; -} - .nav-tabs { clear: both; font-weight: bold; @@ -54,6 +45,11 @@ h1 { border-top: none; } +a:hover > .card { + top: -2px; + background-color: #f4f4f4; + box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2); +} .card { position: relative; padding: 12px; @@ -64,23 +60,20 @@ h1 { border-radius: 6px; font-size: 11pt; } -.card:hover { - background-color: #f4f4f4; - top: -2px; - box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2); -} -.card .detailsLink { +a .glyphicon { display: block; position: absolute; right: 0; top: 0; padding: 8px; - font-size: 20pt; - color: #8a8 !important; - text-decoration: none; + font-size: 16pt; + color: #aaa; } -.detailsLink:hover { - color: #686 !important; +a:hover .glyphicon { + color: #888; +} +a.plain { + text-decoration: none !important; } .name { font-size: 12pt; @@ -91,55 +84,43 @@ h1 { color: #888; margin-top: 2px; } -.description { - margin: 10px 40px 0 20px; +#summary .description { + margin: 15px 0 25px 0; } - -th { - margin: 1.25em 0 20px 0; - font-size: 20px; - font-weight: normal; - color: #4f8243 +.card .description { + margin: 10px 40px 0 20px; } -.typeLabel { - display: inline; - padding-right: 10px; +#summary { + clear: both; + margin: 10px 0 20px 0; } - -table { - border: 1px solid #f0f0f0; - border-radius: 5px; - background-color: #fcfcfc; - border-collapse: collapse; - padding: 6px; +.summaryLabel { + font-size: 20px; + font-weight: bold; } - -td { - border-bottom: 1px solid #f0f0f0; - padding: 6px; - max-width: 350px; - white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - white-space: pre-wrap; /* css-3 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - word-break: break-all; - white-space: normal; +.summaryType { + font-family: monospace; + font-size: 12pt; + color: #888; } - -.wordWrap { - word-break: normal !important; +.java { + font-family: monospace; } -.location { - word-break: keep-all; - max-width: 100%; +.card dl { + margin-bottom: 0; + margin-top: 5px; } - -.objectContent { - display: block; +dt { clear: both; + float: left; + width: 8em; + text-align: right; + font-weight: normal; +} +dd { + margin-left: 9em; } #container { @@ -167,111 +148,3 @@ td { text-indent: -1000px; overflow: hidden; } - -#menubar { - clear: both; - width: 978px; - height: 34px; - background-color: #e8eded; - border: 1px solid #d5dade; - -moz-border-radius: 8px; - border-radius: 8px; -} - -#mainmenu { - list-style: none; - margin: 0; - padding: 4px 0 0 2px; - width: 765px; - display: block; - float: left; - font-size: 15px; -} - -#mainmenu li { - float: left; - position: relative; - margin: 0; - padding: 0; -} - -#mainmenu>li { - border: 1px solid transparent; - border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-bottom: 0; -} - -#mainmenu a { - display: block; - text-decoration: none; - color: #508243; -} - -#mainmenu>li>a { - padding: 0 8px 5px 8px; - line-height: 25px; -} - -#mainmenu>li:hover { - background-color: #ffffff; - border: 1px solid #dbe0e4; - border-bottom: 0; -} - -#mainmenu .current a { - color: #838a8b; -} - -#mainmenu ul { - display: none; - position: absolute; - top: 30px; - left: -1px; - float: left; - background-color: #f5f5f5; - border: 1px solid #dbe0e4; - border-top: 0; - list-style: none; - margin: 0; - padding: 5px; - width: 185px; -} - -#mainmenu ul ul { - left: 100%; - margin-left: 6px; - top: -1px; - border-top: 1px solid #dbe0e4; -} - -#mainmenu ul li { - width: 183px; - padding: 0; - border: 1px solid transparent; -} - -#mainmenu ul li:hover { - border: 1px solid #dbe0e4; - background-color: #ffffff; -} - -#mainmenu ul a { - font-size: 14px; - padding: 7px; -} - -#mainmenu li:hover>ul,#mainmenu li.sfHover>ul { - display: block; -} - -#content { - overflow: scroll; - height: 1000px; -} - -#content a { - color: #4f8243; -} \ No newline at end of file diff --git a/usage/cli/src/main/resources/policy.html b/usage/cli/src/main/resources/policy.html index 4fc1f59cb2..ef4b7cbbe5 100644 --- a/usage/cli/src/main/resources/policy.html +++ b/usage/cli/src/main/resources/policy.html @@ -17,47 +17,43 @@ under the License. --> - + Brooklyn Policy - ${name} + - - -
    - - - - + + + + + - - \ No newline at end of file + + +