Package rename to org.apache.brooklyn: usage-cli
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/74ee6aac Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/74ee6aac Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/74ee6aac Branch: refs/heads/master Commit: 74ee6aaca4cf468ffb820350cb48d3d7f5434035 Parents: 4b80b27 Author: Aled Sage <[email protected]> Authored: Wed Aug 5 14:52:37 2015 +0100 Committer: Aled Sage <[email protected]> Committed: Wed Aug 5 16:51:01 2015 +0100 ---------------------------------------------------------------------- .../com/acme/sample/brooklyn/SampleMain.java | 2 +- .../main/java/brooklyn/cli/AbstractMain.java | 253 ----- .../main/java/brooklyn/cli/CloudExplorer.java | 381 ------- .../src/main/java/brooklyn/cli/ItemLister.java | 272 ----- usage/cli/src/main/java/brooklyn/cli/Main.java | 986 ------------------ .../java/brooklyn/cli/lister/ClassFinder.java | 153 --- .../brooklyn/cli/lister/ItemDescriptors.java | 173 ---- .../org/apache/brooklyn/cli/AbstractMain.java | 254 +++++ .../org/apache/brooklyn/cli/CloudExplorer.java | 381 +++++++ .../org/apache/brooklyn/cli/ItemLister.java | 273 +++++ .../main/java/org/apache/brooklyn/cli/Main.java | 987 +++++++++++++++++++ .../apache/brooklyn/cli/lister/ClassFinder.java | 153 +++ .../brooklyn/cli/lister/ItemDescriptors.java | 173 ++++ .../cli/src/test/java/brooklyn/cli/CliTest.java | 604 ------------ .../brooklyn/cli/CloudExplorerLiveTest.java | 209 ---- .../java/org/apache/brooklyn/cli/CliTest.java | 605 ++++++++++++ .../brooklyn/cli/CloudExplorerLiveTest.java | 209 ++++ .../resources/example-app-app-location.yaml | 2 +- .../resources/example-app-entity-location.yaml | 2 +- .../test/resources/example-app-no-location.yaml | 2 +- 20 files changed, 3039 insertions(+), 3035 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java ---------------------------------------------------------------------- diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java index e029ede..0fa2e1a 100644 --- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java +++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java @@ -9,7 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.brooklyn.catalog.BrooklynCatalog; -import brooklyn.cli.Main; +import org.apache.brooklyn.cli.Main; import com.google.common.base.Objects.ToStringHelper; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/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 deleted file mode 100644 index c05e0b1..0000000 --- a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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 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.InputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -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 org.apache.brooklyn.catalog.BrooklynCatalog; -import brooklyn.cli.Main.LaunchCommand; -import brooklyn.util.exceptions.FatalConfigurationRuntimeException; -import brooklyn.util.exceptions.FatalRuntimeException; -import brooklyn.util.exceptions.UserFacingException; -import brooklyn.util.text.Strings; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; - -/** - * This class is the primary CLI for brooklyn. - * Run with the `help` argument for help. - * <p> - * This class is designed for subclassing, with subclasses typically: - * <li> providing their own static {@link #main(String...)} (of course) which need simply invoke - * {@link #execCli(String[])} with the arguments - * <li> returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()} - * <li> providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired - * <li> providing any other CLI customisations by overriding {@link #cliBuilder()} - * (typically calling the parent and then customizing the builder) - * <li> 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 DEFAULT_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; - - /** - * Field intended for sub-classes (with their own {@code main()}) to customize the banner. - * All accesses to the banner are done through this field, to ensure consistent customization. - * - * Note that a {@code getBanner()} method is not an option for supporting this, because - * it is accessed from static inner-classes (such as {@link InfoCommand}, so non-static - * methods are not an option (and one can't override static methods). - */ - protected static volatile String banner = DEFAULT_BANNER; - - /** 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<Void> { - - @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<String> arguments = new ArrayList<String>(); - - /** @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()); - if (BrooklynVersion.INSTANCE.isSnapshot()) { - System.out.println("Git SHA1: " + BrooklynVersion.INSTANCE.getSha1FromOsgiManifest()); - } - 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-2015 The Apache Software Foundation."); - System.out.println("Licensed under the Apache 2.0 License"); - System.out.println(); - - return null; - } - } - - public static class DefaultInfoCommand extends InfoCommand { - @Override - public Void call() throws Exception { - super.call(); - System.out.println("ERROR: No command specified."); - System.out.println(); - throw new ParseException("No command specified."); - } - } - - /** 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<BrooklynCommand> cliBuilder(); - - protected void execCli(String ...args) { - execCli(cliBuilder().build(), args); - } - - protected void execCli(Cli<BrooklynCommand> 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<BrooklynCommand> parser) { - StringBuilder help = new StringBuilder(); - help.append("\n"); - Help.help(parser.getMetadata(), Collections.<String>emptyList(), help); - return help.toString(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java ---------------------------------------------------------------------- diff --git a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java deleted file mode 100644 index 17db6de..0000000 --- a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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 static com.google.common.base.Preconditions.checkNotNull; -import io.airlift.command.Command; -import io.airlift.command.Option; -import io.airlift.command.ParseException; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jclouds.blobstore.BlobStore; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.compute.ComputeService; -import org.jclouds.compute.domain.ComputeMetadata; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.options.TemplateOptions; - -import brooklyn.location.Location; -import brooklyn.location.LocationDefinition; -import brooklyn.location.basic.LocationConfigKeys; -import brooklyn.location.cloud.CloudLocationConfig; -import brooklyn.location.jclouds.JcloudsLocation; -import brooklyn.location.jclouds.JcloudsUtil; -import brooklyn.management.internal.LocalManagementContext; -import brooklyn.util.exceptions.FatalConfigurationRuntimeException; -import brooklyn.util.stream.Streams; - -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; -import com.google.common.collect.Lists; - -/** - * Convenience for listing Cloud Compute and BlobStore details. - * <p> - * For fuller functionality, consider instead the jclouds CLI or Ruby Fog CLI. - * <p> - * The advantage of this utility is that it piggie-backs off the {@code brooklyn.property} credentials, - * 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 static abstract class JcloudsCommand extends AbstractMain.BrooklynCommandCollectingArgs { - @Option(name = { "--all-locations" }, title = "all locations", - description = "All locations (i.e. all locations in brooklyn.properties for which there are credentials)") - public boolean allLocations; - - @Option(name = { "-l", "--location" }, title = "location spec", - description = "A location spec (e.g. referring to a named location in brooklyn.properties file)") - public String location; - - @Option(name = { "-y", "--yes" }, title = "auto-confirm", - description = "Automatically answer yes to any questions") - public boolean autoconfirm = false; - - protected abstract void doCall(JcloudsLocation loc, String indent) throws Exception; - - @Override - public Void call() throws Exception { - LocalManagementContext mgmt = new LocalManagementContext(); - List<JcloudsLocation> locs = Lists.newArrayList(); - try { - if (location != null && allLocations) { - throw new FatalConfigurationRuntimeException("Must not specify --location and --all-locations"); - } else if (location != null) { - JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(location); - locs.add(loc); - } else if (allLocations) { - // Find all named locations that point at different target clouds - Map<String, LocationDefinition> definedLocations = mgmt.getLocationRegistry().getDefinedLocations(); - for (LocationDefinition locationDef : definedLocations.values()) { - Location loc = mgmt.getLocationRegistry().resolve(locationDef); - if (loc instanceof JcloudsLocation) { - boolean found = false; - for (JcloudsLocation existing : locs) { - if (equalTargets(existing, (JcloudsLocation) loc)) { - found = true; - break; - } - } - if (!found) { - locs.add((JcloudsLocation) loc); - } - } - } - } else { - throw new FatalConfigurationRuntimeException("Must specify one of --location or --all-locations"); - } - - for (JcloudsLocation loc : locs) { - stdout.println("Location {"); - stdout.println("\tprovider: "+loc.getProvider()); - stdout.println("\tdisplayName: "+loc.getDisplayName()); - stdout.println("\tidentity: "+loc.getIdentity()); - if (loc.getEndpoint() != null) stdout.println("\tendpoint: "+loc.getEndpoint()); - if (loc.getRegion() != null) stdout.println("\tregion: "+loc.getRegion()); - - try { - doCall(loc, "\t"); - } finally { - stdout.println("}"); - } - } - } finally { - mgmt.terminate(); - } - return null; - } - - @Override - public ToStringHelper string() { - return super.string() - .add("location", location); - } - - protected boolean equalTargets(JcloudsLocation loc1, JcloudsLocation loc2) { - return Objects.equal(loc1.getProvider(), loc2.getProvider()) - && Objects.equal(loc1.getIdentity(), loc2.getIdentity()) - && Objects.equal(loc1.getEndpoint(), loc2.getEndpoint()) - && Objects.equal(loc1.getRegion(), loc2.getRegion()); - } - - - protected boolean confirm(String msg, String indent) throws Exception { - if (autoconfirm) { - stdout.println(indent+"Auto-confirmed: "+msg); - return true; - } else { - stdout.println(indent+"Enter y/n. Are you sure you want to "+msg); - int in = stdin.read(); - boolean confirmed = (Character.toLowerCase(in) == 'y'); - if (confirmed) { - stdout.println(indent+"Confirmed; will "+msg); - } else { - stdout.println(indent+"Declined; will not "+msg); - } - return confirmed; - } - } - } - - public static abstract class ComputeCommand extends JcloudsCommand { - protected abstract void doCall(ComputeService computeService, String indent) throws Exception; - - @Override - protected void doCall(JcloudsLocation loc, String indent) throws Exception { - ComputeService computeService = loc.getComputeService(); - doCall(computeService, indent); - } - } - - @Command(name = "list-instances", description = "") - public static class ComputeListInstancesCommand extends ComputeCommand { - @Override - protected void doCall(ComputeService computeService, String indent) throws Exception { - failIfArguments(); - Set<? extends ComputeMetadata> instances = computeService.listNodes(); - stdout.println(indent+"Instances {"); - for (ComputeMetadata instance : instances) { - stdout.println(indent+"\t"+instance); - } - stdout.println(indent+"}"); - } - } - - @Command(name = "list-images", description = "") - public static class ComputeListImagesCommand extends ComputeCommand { - @Override - protected void doCall(ComputeService computeService, String indent) throws Exception { - failIfArguments(); - Set<? extends Image> images = computeService.listImages(); - stdout.println(indent+"Images {"); - for (Image image : images) { - stdout.println(indent+"\t"+image); - } - stdout.println(indent+"}"); - } - } - - @Command(name = "list-hardware-profiles", description = "") - public static class ComputeListHardwareProfilesCommand extends ComputeCommand { - @Override - protected void doCall(ComputeService computeService, String indent) throws Exception { - failIfArguments(); - Set<? extends Hardware> hardware = computeService.listHardwareProfiles(); - stdout.println(indent+"Hardware Profiles {"); - for (Hardware image : hardware) { - stdout.println(indent+"\t"+image); - } - stdout.println(indent+"}"); - } - } - - @Command(name = "get-image", description = "") - public static class ComputeGetImageCommand extends ComputeCommand { - @Override - protected void doCall(ComputeService computeService, String indent) throws Exception { - if (arguments.isEmpty()) { - throw new ParseException("Requires at least one image-id arguments"); - } - - for (String imageId : arguments) { - Image image = computeService.getImage(imageId); - stdout.println(indent+"Image "+imageId+" {"); - stdout.println(indent+"\t"+image); - stdout.println(indent+"}"); - } - } - - @Override - public ToStringHelper string() { - return super.string() - .add("imageIds", arguments); - } - } - - @Command(name = "default-template", description = "") - public static class ComputeDefaultTemplateCommand extends JcloudsCommand { - @Override - protected void doCall(JcloudsLocation loc, String indent) throws Exception { - failIfArguments(); - ComputeService computeService = loc.getComputeService(); - - Template template = loc.buildTemplate(computeService, loc.config().getBag()); - Image image = template.getImage(); - Hardware hardware = template.getHardware(); - org.jclouds.domain.Location location = template.getLocation(); - TemplateOptions options = template.getOptions(); - stdout.println(indent+"Default template {"); - stdout.println(indent+"\tImage: "+image); - stdout.println(indent+"\tHardware: "+hardware); - stdout.println(indent+"\tLocation: "+location); - stdout.println(indent+"\tOptions: "+options); - stdout.println(indent+"}"); - } - } - - @Command(name = "terminate-instances", description = "") - public static class ComputeTerminateInstancesCommand extends ComputeCommand { - @Override - protected void doCall(ComputeService computeService, String indent) throws Exception { - if (arguments.isEmpty()) { - throw new ParseException("Requires at least one instance-id arguments"); - } - - for (String instanceId : arguments) { - NodeMetadata instance = computeService.getNodeMetadata(instanceId); - if (instance == null) { - stderr.println(indent+"Cannot terminate instance; could not find "+instanceId); - } else { - boolean confirmed = confirm(indent, "terminate "+instanceId+" ("+instance+")"); - if (confirmed) { - computeService.destroyNode(instanceId); - } - } - } - } - - @Override - public ToStringHelper string() { - return super.string() - .add("instanceIds", arguments); - } - } - - public static abstract class BlobstoreCommand extends JcloudsCommand { - protected abstract void doCall(BlobStore blobstore, String indent) throws Exception; - - @Override - protected void doCall(JcloudsLocation loc, String indent) throws Exception { - String identity = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_IDENTITY), "identity must not be null"); - String credential = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_CREDENTIAL), "credential must not be null"); - String provider = checkNotNull(loc.getConfig(LocationConfigKeys.CLOUD_PROVIDER), "provider must not be null"); - String endpoint = loc.getConfig(CloudLocationConfig.CLOUD_ENDPOINT); - - BlobStoreContext context = JcloudsUtil.newBlobstoreContext(provider, endpoint, identity, credential); - try { - BlobStore blobStore = context.getBlobStore(); - doCall(blobStore, indent); - } finally { - context.close(); - } - } - } - - @Command(name = "list-containers", description = "") - public static class BlobstoreListContainersCommand extends BlobstoreCommand { - @Override - protected void doCall(BlobStore blobstore, String indent) throws Exception { - failIfArguments(); - Set<? extends StorageMetadata> containers = blobstore.list(); - stdout.println(indent+"Containers {"); - for (StorageMetadata container : containers) { - stdout.println(indent+"\t"+container); - } - stdout.println(indent+"}"); - } - } - - @Command(name = "list-container", description = "") - public static class BlobstoreListContainerCommand extends BlobstoreCommand { - @Override - protected void doCall(BlobStore blobStore, String indent) throws Exception { - if (arguments.isEmpty()) { - throw new ParseException("Requires at least one container-name arguments"); - } - - for (String containerName : arguments) { - Set<? extends StorageMetadata> contents = blobStore.list(containerName); - stdout.println(indent+"Container "+containerName+" {"); - for (StorageMetadata content : contents) { - stdout.println(indent+"\t"+content); - } - stdout.println(indent+"}"); - } - } - - @Override - public ToStringHelper string() { - return super.string() - .add("containers", arguments); - } - } - - @Command(name = "blob", description = "") - public static class BlobstoreGetBlobCommand extends BlobstoreCommand { - @Option(name = { "--container" }, title = "list contents of a given container", - description = "") - public String container; - - @Option(name = { "--blob" }, title = "retrieves the blog in the given container", - description = "") - public String blob; - - @Override - protected void doCall(BlobStore blobStore, String indent) throws Exception { - failIfArguments(); - Blob content = blobStore.getBlob(container, blob); - stdout.println(indent+"Blob "+container+" : " +blob +" {"); - stdout.println(indent+"\tHeaders {"); - for (Map.Entry<String, String> entry : content.getAllHeaders().entries()) { - stdout.println(indent+"\t\t"+entry.getKey() + " = " + entry.getValue()); - } - stdout.println(indent+"\t}"); - stdout.println(indent+"\tmetadata : "+content.getMetadata()); - stdout.println(indent+"\tpayload : "+Streams.readFullyString(content.getPayload().openStream())); - stdout.println(indent+"}"); - } - - @Override - public ToStringHelper string() { - return super.string() - .add("container", container) - .add("blob", blob); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/ItemLister.java ---------------------------------------------------------------------- diff --git a/usage/cli/src/main/java/brooklyn/cli/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/ItemLister.java deleted file mode 100644 index 6ed751c..0000000 --- a/usage/cli/src/main/java/brooklyn/cli/ItemLister.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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 io.airlift.command.Command; -import io.airlift.command.Option; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collection; -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 org.apache.brooklyn.catalog.Catalog; -import brooklyn.cli.lister.ClassFinder; -import brooklyn.cli.lister.ItemDescriptors; -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.ResourceUtils; -import brooklyn.util.collections.MutableSet; -import brooklyn.util.net.Urls; -import brooklyn.util.os.Os; -import brooklyn.util.text.Strings; -import brooklyn.util.text.TemplateProcessor; - -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.base.Charsets; -import com.google.common.base.Splitter; -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; - -public class ItemLister { - - private static final Logger LOG = LoggerFactory.getLogger(ItemLister.class); - private static final String BASE = "brooklyn/item-lister"; - private static final String BASE_TEMPLATES = BASE+"/"+"templates"; - private static final String BASE_STATICS = BASE+"/"+"statics"; - - @Command(name = "list-objects", description = "List Brooklyn objects (Entities, Policies, Enrichers and Locations)") - public static class ListAllCommand extends AbstractMain.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<String> jars = Lists.newLinkedList(); - - @Option(name = { "--type-regex" }, title = "Regex for types to list") - public String typeRegex; - - @Option(name = { "--catalog-only" }, title = "Whether to only list items annotated with @Catalog") - public boolean catalogOnly = true; - - @Option(name = { "--ignore-impls" }, title = "Ignore Entity implementations, where there is an Entity interface with @ImplementedBy") - public boolean ignoreImpls = false; - - @Option(name = { "--headings-only" }, title = "Whether to only show name/type, and not config keys etc") - public boolean headingsOnly = false; - - @Option(name = { "--output-folder" }, title = "Folder to save output") - public String outputFolder; - - @SuppressWarnings("unchecked") - @Override - public Void call() throws Exception { - List<URL> urls = getUrls(); - LOG.info("Retrieving objects from "+urls); - - // TODO Remove duplication from separate ListPolicyCommand etc - List<Class<? extends Entity>> entityTypes = getTypes(urls, Entity.class); - List<Class<? extends Policy>> policyTypes = getTypes(urls, Policy.class); - List<Class<? extends Enricher>> enricherTypes = getTypes(urls, Enricher.class); - List<Class<? extends Location>> locationTypes = getTypes(urls, Location.class, Boolean.FALSE); - - Map<String, Object> result = ImmutableMap.<String, Object>builder() - .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); - - if (outputFolder == null) { - System.out.println(json); - } else { - LOG.info("Outputting item list (size "+itemCount+") to " + outputFolder); - 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"); //TODO nothing written here yet... - - mkdir(parentDir, "style"); - mkdir(Os.mergePaths(parentDir, "style"), "js"); - mkdir(Os.mergePaths(parentDir, "style", "js"), "catalog"); - - Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8); - ResourceUtils resourceUtils = ResourceUtils.create(this); - - // root - just loads the above JSON - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "brooklyn-object-list.html", "index.html"); - - // statics - structure mirrors docs (not for any real reason however... the json is usually enough for our docs) - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "common.js"); - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "items.css"); - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.js"); - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.map"); - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/catalog/bloodhound.js"); - - // now make pages for each item - - List<Map<String, Object>> entities = (List<Map<String, Object>>) result.get("entities"); - String entityTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "entity.html")); - for (Map<String, Object> 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<Map<String, Object>> policies = (List<Map<String, Object>>) result.get("policies"); - String policyTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "policy.html")); - for (Map<String, Object> 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<Map<String, Object>> enrichers = (List<Map<String, Object>>) result.get("enrichers"); - String enricherTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "enricher.html")); - for (Map<String, Object> 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<Map<String, Object>> locations = (List<Map<String, Object>>) result.get("locations"); - String locationTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "location.html")); - for (Map<String, Object> 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); - } - LOG.info("Finished outputting item list to " + outputFolder); - } - return null; - } - - private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item) throws IOException { - copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, item, item); - } - private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item, String dest) throws IOException { - String js = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_STATICS, item)); - Files.write(js, new File(Os.mergePaths(outputFolder, dest)), Charsets.UTF_8); - } - - private void mkdir(String rootDir, String dirName) { - (new File(Os.mergePaths(rootDir, dirName))).mkdirs(); - } - - protected List<URL> getUrls() throws MalformedURLException { - List<URL> urls = Lists.newArrayList(); - if (jars.isEmpty()) { - String classpath = System.getenv("INITIAL_CLASSPATH"); - if (Strings.isNonBlank(classpath)) { - List<String> entries = Splitter.on(":").omitEmptyStrings().trimResults().splitToList(classpath); - for (String entry : entries) { - if (entry.endsWith(".jar") || entry.endsWith("/*")) { - urls.addAll(ClassFinder.toJarUrls(entry.replace("/*", ""))); - } - } - } else { - throw new IllegalArgumentException("No Jars to process"); - } - } else { - for (String jar : jars) { - List<URL> expanded = ClassFinder.toJarUrls(jar); - if (expanded.isEmpty()) - LOG.warn("No jars found at: "+jar); - urls.addAll(expanded); - } - } - return urls; - } - - private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type) { - return getTypes(urls, type, null); - } - - int itemCount = 0; - - private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type, Boolean catalogOnlyOverride) { - FluentIterable<Class<? extends T>> 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)); - } - List<Class<? extends T>> filtered = fluent.toList(); - Collection<Class<? extends T>> result; - if (ignoreImpls) { - result = MutableSet.copyOf(filtered); - for (Class<? extends T> clazz : filtered) { - ImplementedBy implementedBy = clazz.getAnnotation(ImplementedBy.class); - if (implementedBy != null) { - result.remove(implementedBy.value()); - } - } - } else { - result = filtered; - } - itemCount += result.size(); - return ImmutableList.copyOf(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); - } - } -}
