You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by km...@apache.org on 2014/03/06 07:17:40 UTC
git commit: KNOX-294: Add version support to knoxcli. KNOX-296: Add
redeploy support to knoxcli.
Repository: knox
Updated Branches:
refs/heads/master 9423ded73 -> a5362cad5
KNOX-294: Add version support to knoxcli.
KNOX-296: Add redeploy support to knoxcli.
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/a5362cad
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/a5362cad
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/a5362cad
Branch: refs/heads/master
Commit: a5362cad587f47a33998561534b160e08216cbd5
Parents: 9423ded
Author: Kevin Minder <ke...@hortonworks.com>
Authored: Thu Mar 6 01:17:30 2014 -0500
Committer: Kevin Minder <ke...@hortonworks.com>
Committed: Thu Mar 6 01:17:30 2014 -0500
----------------------------------------------------------------------
gateway-release/home/bin/gateway.sh | 4 +-
gateway-release/home/bin/knoxcli.sh | 2 +-
.../hadoop/gateway/GatewayCommandLine.java | 11 +-
.../apache/hadoop/gateway/GatewayMessages.java | 10 +
.../apache/hadoop/gateway/GatewayResources.java | 5 +-
.../apache/hadoop/gateway/GatewayServer.java | 68 +++++-
.../topology/file/FileTopologyProvider.java | 4 +-
.../org/apache/hadoop/gateway/util/KnoxCLI.java | 232 ++++++++++++-------
.../hadoop/gateway/topology/Topology.java | 10 +
.../hadoop/gateway/GatewayDeployFuncTest.java | 147 ++++++------
10 files changed, 324 insertions(+), 169 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-release/home/bin/gateway.sh
----------------------------------------------------------------------
diff --git a/gateway-release/home/bin/gateway.sh b/gateway-release/home/bin/gateway.sh
index 4de979b..a449c30 100755
--- a/gateway-release/home/bin/gateway.sh
+++ b/gateway-release/home/bin/gateway.sh
@@ -84,7 +84,7 @@ function main {
stop)
appStop
;;
- status)
+ status)
appStatus
;;
clean)
@@ -94,7 +94,7 @@ function main {
printHelp
;;
*)
- printf "Usage: $0 {start|stop|status|clean|setup}\n"
+ printf "Usage: $0 {start|stop|status|clean}\n"
;;
esac
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-release/home/bin/knoxcli.sh
----------------------------------------------------------------------
diff --git a/gateway-release/home/bin/knoxcli.sh b/gateway-release/home/bin/knoxcli.sh
index 93f55ca..da6e6e2 100755
--- a/gateway-release/home/bin/knoxcli.sh
+++ b/gateway-release/home/bin/knoxcli.sh
@@ -55,7 +55,7 @@ APP_ERR_FILE="$APP_LOG_DIR/$APP_NAME.err"
. $APP_BIN_DIR/knox-env.sh
function main {
- printf "Starting $APP_LABEL \n"
+ #printf "Starting $APP_LABEL \n"
#printf "$@"
exec $JAVA $APP_MEM_OPTS $APP_DBG_OPTS $APP_LOG_OPTS -jar $APP_JAR "$@" || exit 1
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayCommandLine.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayCommandLine.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayCommandLine.java
index 54e03f8..a7e2ebc 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayCommandLine.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayCommandLine.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.gateway;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
@@ -64,13 +65,19 @@ public class GatewayCommandLine {
public static final String PERSIST_SHORT = "pm";
public static final String NOSTART_LONG = "nostart";
- public static final String NOSTART_SHORT = "n";
+ public static final String NOSTART_SHORT = "ns";
+
+ public static final String REDEPLOY_LONG = "redeploy";
+ public static final String REDEPLOY_SHORT = "rd";
private static Options createCommandLine() {
Options options = new Options();
options.addOption( HELP_SHORT, HELP_LONG, false, res.helpMessage() );
options.addOption( VERSION_SHORT, VERSION_LONG, false, res.versionHelpMessage() );
- options.addOption( PERSIST_SHORT, PERSIST_LONG, false, res.persistmasterHelpMessage() );
+ Option redeploy = new Option( REDEPLOY_SHORT, REDEPLOY_LONG, true, res.redeployHelpMessage() );
+ redeploy.setOptionalArg( true );
+ options.addOption( redeploy );
+ options.addOption( PERSIST_SHORT, PERSIST_LONG, false, res.persistMasterHelpMessage() );
options.addOption( NOSTART_SHORT, NOSTART_LONG, false, res.nostartHelpMessage() );
return options;
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index de87aa9..bc25f83 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -90,6 +90,15 @@ public interface GatewayMessages {
@Message( level = MessageLevel.ERROR, text = "Failed to deploy topology {0}: {1}" )
void failedToDeployTopology( String name, @StackTrace(level=MessageLevel.DEBUG) Throwable e );
+ @Message( level = MessageLevel.ERROR, text = "Failed to redeploy topology {0}" )
+ void failedToRedeployTopology( String name );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to redeploy topology {0}: {1}" )
+ void failedToRedeployTopology( String name, @StackTrace(level=MessageLevel.DEBUG) Throwable e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to redeploy topologies: {0}" )
+ void failedToRedeployTopologies( @StackTrace(level=MessageLevel.DEBUG) Throwable e );
+
@Message( level = MessageLevel.ERROR, text = "Failed to undeploy topology {0}: {1}" )
void failedToUndeployTopology( String name, @StackTrace(level=MessageLevel.DEBUG) Exception e );
@@ -303,4 +312,5 @@ public interface GatewayMessages {
@Message( level = MessageLevel.WARN, text = "Value not found for cluster:{0}, alias: {1}" )
void aliasValueNotFound( String cluster, String alias );
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayResources.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayResources.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayResources.java
index ce4b6c7..0f19b2d 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayResources.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayResources.java
@@ -42,7 +42,10 @@ public interface GatewayResources {
String nostartHelpMessage();
@Resource( text="This parameter causes the provider master secret to be persisted. This prevents the server from prompting for a master secret on subsequent starts." )
- String persistmasterHelpMessage();
+ String persistMasterHelpMessage();
+
+ @Resource( text="This parameter causes the existing topologies to be redeployed. A single topology may be specified via an optional parameter. The server will not be started." )
+ String redeployHelpMessage();
@Resource( text="Display server version information." )
String versionHelpMessage();
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
index b49322d..abfce3a 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
@@ -47,9 +47,9 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.webapp.WebAppContext;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.xml.sax.SAXException;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
@@ -90,10 +90,10 @@ public class GatewayServer {
if( cmd.hasOption( GatewayCommandLine.HELP_LONG ) ) {
GatewayCommandLine.printHelp();
} else if( cmd.hasOption( GatewayCommandLine.VERSION_LONG ) ) {
- buildProperties = loadBuildProperties();
- System.out.println( res.gatewayVersionMessage( // I18N not required.
- buildProperties.getProperty( "build.version", "unknown" ),
- buildProperties.getProperty( "build.hash", "unknown" ) ) );
+ printVersion();
+ } else if( cmd.hasOption( GatewayCommandLine.REDEPLOY_LONG ) ) {
+ GatewayConfig config = new GatewayConfigImpl();
+ redeployTopologies( config, cmd.getOptionValue( GatewayCommandLine.REDEPLOY_LONG ) );
} else {
services = instantiateGatewayServices();
if (services == null) {
@@ -110,13 +110,21 @@ public class GatewayServer {
startGateway( config, services );
}
}
- } catch( ParseException e ) {
+ } catch ( ParseException e ) {
log.failedToParseCommandLine( e );
- } catch (ServiceLifecycleException e) {
+ GatewayCommandLine.printHelp();
+ } catch ( ServiceLifecycleException e ) {
log.failedToStartGateway( e );
}
}
+ private static void printVersion() {
+ buildProperties = loadBuildProperties();
+ System.out.println( res.gatewayVersionMessage( // I18N not required.
+ buildProperties.getProperty( "build.version", "unknown" ),
+ buildProperties.getProperty( "build.hash", "unknown" ) ) );
+ }
+
private static GatewayServices instantiateGatewayServices() {
ServiceLoader<GatewayServices> loader = ServiceLoader.load( GatewayServices.class );
Iterator<GatewayServices> services = loader.iterator();
@@ -179,6 +187,52 @@ public class GatewayServer {
input.close();
}
+ private static void redeployTopology( Topology topology ) {
+ File topologyFile = new File( topology.getUri() );
+ long start = System.currentTimeMillis();
+ long limit = 1000L; // One second.
+ long elapsed = 1;
+ while( elapsed <= limit ) {
+ try {
+ long origTimestamp = topologyFile.lastModified();
+ long setTimestamp = Math.max( System.currentTimeMillis(), topologyFile.lastModified() + elapsed );
+ if( topologyFile.setLastModified( setTimestamp ) ) {
+ long newTimstamp = topologyFile.lastModified();
+ if( newTimstamp > origTimestamp ) {
+ break;
+ } else {
+ Thread.sleep( 10 );
+ elapsed = System.currentTimeMillis() - start;
+ continue;
+ }
+ } else {
+ log.failedToRedeployTopology( topology.getName() );
+ break;
+ }
+ } catch( InterruptedException e ) {
+ log.failedToRedeployTopology( topology.getName(), e );
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void redeployTopologies( GatewayConfig config, String topologyName ) {
+ try {
+ File topologiesDir = calculateAbsoluteTopologiesDir( config );
+ FileTopologyProvider provider = new FileTopologyProvider( topologiesDir );
+ provider.reloadTopologies();
+ for( Topology topology : provider.getTopologies() ) {
+ if( topologyName == null || topologyName.equals( topology.getName() ) ) {
+ redeployTopology( topology );
+ }
+ }
+ } catch( SAXException e ) {
+ log.failedToRedeployTopologies( e );
+ } catch( IOException e ) {
+ log.failedToRedeployTopologies( e );
+ }
+ }
+
public static GatewayServer startGateway( GatewayConfig config, GatewayServices svcs ) {
try {
log.startingGateway();
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/file/FileTopologyProvider.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/file/FileTopologyProvider.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/file/FileTopologyProvider.java
index 15bb75e..8e20621 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/file/FileTopologyProvider.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/file/FileTopologyProvider.java
@@ -42,6 +42,7 @@ import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -84,12 +85,13 @@ public class FileTopologyProvider implements TopologyProvider, TopologyMonitor,
this( null, VFS.getManager().toFileObject( directory ) );
}
- private static Topology loadTopology( FileObject file ) throws IOException, SAXException {
+ private static Topology loadTopology( FileObject file ) throws IOException, SAXException, URISyntaxException {
log.loadingTopologyFile( file.getName().getFriendlyURI() );
Digester digester = digesterLoader.newDigester();
FileContent content = file.getContent();
TopologyBuilder topologyBuilder = digester.parse( content.getInputStream() );
Topology topology = topologyBuilder.build();
+ topology.setUri( file.getURL().toURI() );
topology.setName( FilenameUtils.removeExtension( file.getName().getBaseName() ) );
topology.setTimestamp( content.getLastModifiedTime() );
return topology;
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-server/src/main/java/org/apache/hadoop/gateway/util/KnoxCLI.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/util/KnoxCLI.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/util/KnoxCLI.java
index 7694ec6..040dfea 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/util/KnoxCLI.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/util/KnoxCLI.java
@@ -17,15 +17,9 @@
*/
package org.apache.hadoop.gateway.util;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.gateway.GatewayCommandLine;
+import org.apache.hadoop.gateway.GatewayServer;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
import org.apache.hadoop.gateway.services.CLIGatewayServices;
@@ -39,6 +33,16 @@ import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.log4j.PropertyConfigurator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+
/**
*
*/
@@ -47,11 +51,13 @@ public class KnoxCLI extends Configured implements Tool {
private static final String USAGE_PREFIX = "KnoxCLI {cmd} [options]";
final static private String COMMANDS =
" [--help]\n" +
- " [" + CertCreateCommand.USAGE + "]\n" +
+ " [" + VersionCommand.USAGE + "]\n" +
" [" + MasterCreateCommand.USAGE + "]\n" +
+ " [" + CertCreateCommand.USAGE + "]\n" +
" [" + AliasCreateCommand.USAGE + "]\n" +
" [" + AliasDeleteCommand.USAGE + "]\n" +
- " [" + AliasListCommand.USAGE + "]\n";
+ " [" + AliasListCommand.USAGE + "]\n" +
+ " [" + RedeployCommand.USAGE + "]\n";
/** allows stdout to be captured if necessary */
public PrintStream out = System.out;
@@ -109,11 +115,13 @@ public class KnoxCLI extends Configured implements Tool {
/**
* Parse the command line arguments and initialize the data
* <pre>
- * % knox master-create keyName [--size size] [--generate]
- * % knox create-alias alias [--cluster] [--generate] [--value v]
- * % knox list-alias [--cluster]
- * % knox delete=alias alias [--cluster]
- * % knox create-cert alias [--hostname]
+ * % knoxcli version
+ * % knoxcli master-create keyName [--size size] [--generate]
+ * % knoxcli create-alias alias [--cluster c] [--generate] [--value v]
+ * % knoxcli list-alias [--cluster c]
+ * % knoxcli delete=alias alias [--cluster c]
+ * % knoxcli create-cert alias [--hostname h]
+ * % knoxcli redeploy [--cluster c]
* </pre>
* @param args
* @return
@@ -154,8 +162,23 @@ public class KnoxCLI extends Configured implements Tool {
} else if (args[i].equals("list-alias")) {
command = new AliasListCommand();
} else if (args[i].equals("--value")) {
+ if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ printKnoxShellUsage();
+ return -1;
+ }
this.value = args[++i];
- } else if (args[i].equals("--cluster")) {
+ if ( command != null && command instanceof MasterCreateCommand ) {
+ this.master = this.value;
+ }
+ } else if ( args[i].equals("version") ) {
+ command = new VersionCommand();
+ } else if ( args[i].equals("redeploy") ) {
+ command = new RedeployCommand();
+ } else if ( args[i].equals("--cluster") || args[i].equals("--topology") ) {
+ if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ printKnoxShellUsage();
+ return -1;
+ }
this.cluster = args[++i];
} else if (args[i].equals("--generate")) {
if ( command != null && command instanceof MasterCreateCommand ) {
@@ -164,16 +187,24 @@ public class KnoxCLI extends Configured implements Tool {
this.generate = "true";
}
} else if (args[i].equals("--hostname")) {
+ if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ printKnoxShellUsage();
+ return -1;
+ }
this.hostname = args[++i];
} else if (args[i].equals("--master")) {
- // testing only
+ // For testing only
+ if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ printKnoxShellUsage();
+ return -1;
+ }
this.master = args[++i];
} else if (args[i].equals("--help")) {
printKnoxShellUsage();
return -1;
} else {
printKnoxShellUsage();
- ToolRunner.printGenericCommandUsage(System.err);
+ //ToolRunner.printGenericCommandUsage(System.err);
return -1;
}
}
@@ -181,26 +212,34 @@ public class KnoxCLI extends Configured implements Tool {
}
private void printKnoxShellUsage() {
- out.println(USAGE_PREFIX + COMMANDS);
- if (command != null) {
+ out.println( USAGE_PREFIX + "\n" + COMMANDS );
+ if ( command != null ) {
out.println(command.getUsage());
- }
- else {
- out.println("=========================================================" +
- "======");
- out.println(MasterCreateCommand.USAGE + ":\n\n" + MasterCreateCommand.DESC);
- out.println("=========================================================" +
- "======");
- out.println(CertCreateCommand.USAGE + ":\n\n" + CertCreateCommand.DESC);
- out.println("=========================================================" +
- "======");
- out.println(AliasCreateCommand.USAGE + ":\n\n" + AliasCreateCommand.DESC);
- out.println("=========================================================" +
- "======");
- out.println(AliasDeleteCommand.USAGE + ":\n\n" + AliasDeleteCommand.DESC);
- out.println("=========================================================" +
- "======");
- out.println(AliasListCommand.USAGE + ":\n\n" + AliasListCommand.DESC);
+ } else {
+ char[] chars = new char[79];
+ Arrays.fill( chars, '=' );
+ String div = new String( chars );
+
+ out.println( div );
+ out.println( VersionCommand.USAGE + "\n\n" + VersionCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( MasterCreateCommand.USAGE + "\n\n" + MasterCreateCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( CertCreateCommand.USAGE + "\n\n" + CertCreateCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( AliasCreateCommand.USAGE + "\n\n" + AliasCreateCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( AliasDeleteCommand.USAGE + "\n\n" + AliasDeleteCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( AliasListCommand.USAGE + "\n\n" + AliasListCommand.DESC );
+ out.println();
+ out.println( div );
+ out.println( RedeployCommand.USAGE + "\n\n" + RedeployCommand.DESC );
}
}
@@ -222,29 +261,24 @@ public class KnoxCLI extends Configured implements Tool {
public abstract String getUsage();
protected AliasService getAliasService() {
- AliasService as = (AliasService)
- services.getService(GatewayServices.ALIAS_SERVICE);
+ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
return as;
}
protected KeystoreService getKeystoreService() {
- KeystoreService ks = (KeystoreService)
- services.getService(GatewayServices.KEYSTORE_SERVICE);
+ KeystoreService ks = services.getService(GatewayServices.KEYSTORE_SERVICE);
return ks;
}
}
- /**
- *
- */
private class AliasListCommand extends Command {
public static final String USAGE = "list-alias [--cluster c]";
public static final String DESC = "The list-alias command lists all of the aliases\n" +
- "for the given hadoop --cluster. The default\n" +
- "--cluster being the gateway itself.";
+ "for the given hadoop --cluster. The default\n" +
+ "--cluster being the gateway itself.";
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see org.apache.hadoop.gateway.util.KnoxCLI.Command#execute()
*/
@Override
@@ -271,25 +305,18 @@ public class KnoxCLI extends Configured implements Tool {
}
}
- /**
- *
- */
public class CertCreateCommand extends Command {
public static final String USAGE = "create-cert [--hostname h]";
public static final String DESC = "The create-cert command creates and populates\n" +
- "a gateway.jks keystore with a self-signed certificate\n" +
- "to be used as the gateway identity. It also adds an alias\n" +
- "to the __gateway-credentials.jceks credential store for the\n" +
- "key passphrase.";
+ "a gateway.jks keystore with a self-signed certificate\n" +
+ "to be used as the gateway identity. It also adds an alias\n" +
+ "to the __gateway-credentials.jceks credential store for the\n" +
+ "key passphrase.";
private static final String GATEWAY_CREDENTIAL_STORE_NAME = "__gateway";
private static final String GATEWAY_IDENTITY_PASSPHRASE = "gateway-identity-passphrase";
- /**
- *
- */
public CertCreateCommand() {
- // TODO Auto-generated constructor stub
}
/* (non-Javadoc)
@@ -326,14 +353,14 @@ public class KnoxCLI extends Configured implements Tool {
char[] passphrase = as.getPasswordFromAliasForCluster(GATEWAY_CREDENTIAL_STORE_NAME, GATEWAY_IDENTITY_PASSPHRASE);
ks.addSelfSignedCertForGateway("gateway-identity", passphrase, hostname);
// logAndValidateCertificate();
- out.println("gateway-identity has been successfully created.");
+ out.println("Certificate gateway-identity has been successfully created.");
} catch (KeystoreServiceException e) {
throw new ServiceLifecycleException("Keystore was not loaded properly - the provided (or persisted) master secret may not match the password for the keystore.", e);
}
}
}
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see org.apache.hadoop.gateway.util.KnoxCLI.Command#getUsage()
*/
@Override
@@ -343,19 +370,16 @@ public class KnoxCLI extends Configured implements Tool {
}
- /**
- *
- */
public class AliasCreateCommand extends Command {
- public static final String USAGE = "create-alias aliasname [--value value]" +
- " [--cluster c] [--generate]";
+ public static final String USAGE = "create-alias aliasname [--cluster c] " +
+ "[ (--value v) | (--generate) ]";
public static final String DESC = "The create-alias command will create an alias\n" +
- "and secret pair within the credential store for the\n" +
- "indicated --cluster otherwise within the gateway\n" +
- "credential store. The actual secret may be specified via\n" +
- "the --value option or --generate will create a random secret\n" +
- "for you.";
+ "and secret pair within the credential store for the\n" +
+ "indicated --cluster otherwise within the gateway\n" +
+ "credential store. The actual secret may be specified via\n" +
+ "the --value option or --generate will create a random secret\n" +
+ "for you.";
private String name = null;
@@ -407,8 +431,8 @@ public class KnoxCLI extends Configured implements Tool {
public class AliasDeleteCommand extends Command {
public static final String USAGE = "delete-alias aliasname [--cluster c]";
public static final String DESC = "The delete-alias command removes the\n" +
- "indicated alias from the --cluster specific\n" +
- "credential store or the gateway credential store.";
+ "indicated alias from the --cluster specific\n" +
+ "credential store or the gateway credential store.";
private String name = null;
@@ -450,13 +474,10 @@ public class KnoxCLI extends Configured implements Tool {
public class MasterCreateCommand extends Command {
public static final String USAGE = "create-master";
public static final String DESC = "The create-master command persists the\n" +
- "master secret in a file located at:\n" +
- "{GATEWAY_HOME}/data/security/master. It\n" +
- "will prompt the user for the secret to persist.";
+ "master secret in a file located at:\n" +
+ "{GATEWAY_HOME}/data/security/master. It\n" +
+ "will prompt the user for the secret to persist.";
- /**
- * @param keyName
- */
public MasterCreateCommand() {
}
@@ -477,7 +498,62 @@ public class KnoxCLI extends Configured implements Tool {
}
}
- /**
+ private class VersionCommand extends Command {
+
+ public static final String USAGE = "version";
+ public static final String DESC = "Displays Knox version information.";
+
+ @Override
+ public void execute() throws Exception {
+ Properties buildProperties = loadBuildProperties();
+ System.out.println(
+ String.format(
+ "Apache Knox: %s (%s)",
+ buildProperties.getProperty( "build.version", "unknown" ),
+ buildProperties.getProperty( "build.hash", "unknown" ) ) );
+ }
+
+ @Override
+ public String getUsage() {
+ return USAGE + ":\n\n" + DESC;
+ }
+
+ }
+
+ private class RedeployCommand extends Command {
+
+ public static final String USAGE = "redeploy [--cluster c]";
+ public static final String DESC =
+ "Redeploys one or all of the gateway's clusters (a.k.a topologies).";
+
+ @Override
+ public void execute() throws Exception {
+ GatewayConfig config = new GatewayConfigImpl();
+ GatewayServer.redeployTopologies( config, cluster );
+ }
+
+ @Override
+ public String getUsage() {
+ return USAGE + ":\n\n" + DESC;
+ }
+
+ }
+
+ private static Properties loadBuildProperties() {
+ Properties properties = new Properties();
+ InputStream inputStream = KnoxCLI.class.getClassLoader().getResourceAsStream( "build.properties" );
+ if( inputStream != null ) {
+ try {
+ properties.load( inputStream );
+ inputStream.close();
+ } catch( IOException e ) {
+ // Ignore.
+ }
+ }
+ return properties;
+ }
+
+ /**
* @param args
* @throws Exception
*/
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
index 9dd3514..c849ec4 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.gateway.topology;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -25,6 +26,7 @@ import java.util.Map;
public class Topology {
+ private URI uri;
private String name;
private long timestamp;
private List<Provider> providerList = new ArrayList<Provider>();
@@ -32,6 +34,14 @@ public class Topology {
private List<Service> services = new ArrayList<Service>();
private Map<String, Map<String, Service>> serviceMap = new HashMap<String, Map<String, Service>>();
+ public URI getUri() {
+ return uri;
+ }
+
+ public void setUri( URI uri ) {
+ this.uri = uri;
+ }
+
public String getName() {
return name;
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a5362cad/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayDeployFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayDeployFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayDeployFuncTest.java
index 7b71707..6cfac03 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayDeployFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayDeployFuncTest.java
@@ -55,9 +55,8 @@ import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
public class GatewayDeployFuncTest {
@@ -202,13 +201,13 @@ public class GatewayDeployFuncTest {
System.in.read();
}
- @Test
- public void testDeployUndeploy() throws Exception {
- long timeout = 10 * 1000; // Ten seconds.
+ @Test( timeout = 20*1000 )
+ public void testDeployRedeployUndeploy() throws InterruptedException, IOException {
long sleep = 200;
String username = "guest";
String password = "guest-password";
String serviceUrl = clusterUrl + "/test-service-path/test-service-resource";
+ long topoTimestampBefore, topoTimestampAfter;
File topoDir = new File( config.getGatewayTopologyDir() );
File deployDir = new File( config.getGatewayDeploymentDir() );
@@ -218,49 +217,85 @@ public class GatewayDeployFuncTest {
assertThat( topoDir.listFiles().length, is( 0 ) );
assertThat( deployDir.listFiles().length, is( 0 ) );
+ File descriptor = writeTestTopology( "test-cluster", createTopology() );
+
+ warDir = waitForFiles( deployDir, "test-cluster.war\\.[0-9A-Fa-f]+", 1, 0, sleep );
+ for( File webInfDir : warDir.listFiles() ) {
+ waitForFiles( webInfDir, ".*", 4, 0, sleep );
+ }
+ waitForAccess( serviceUrl, username, password, sleep );
+
+ // Redeploy and make sure the timestamp is updated.
+ topoTimestampBefore = descriptor.lastModified();
+ GatewayServer.redeployTopologies( config, null );
+ topoTimestampAfter = descriptor.lastModified();
+ assertThat( topoTimestampAfter, greaterThan( topoTimestampBefore ) );
+
+ // Check to make sure there are two war directories with the same root.
+ warDir = waitForFiles( deployDir, "test-cluster.war\\.[0-9A-Fa-f]+", 2, 1, sleep );
+ for( File webInfDir : warDir.listFiles() ) {
+ waitForFiles( webInfDir, ".*", 4, 0, sleep );
+ }
+ waitForAccess( serviceUrl, username, password, sleep );
+
+ // Redeploy and make sure the timestamp is updated.
+ topoTimestampBefore = descriptor.lastModified();
+ GatewayServer.redeployTopologies( config, "test-cluster" );
+ topoTimestampAfter = descriptor.lastModified();
+ assertThat( topoTimestampAfter, greaterThan( topoTimestampBefore ) );
+
+ // Check to make sure there are two war directories with the same root.
+ warDir = waitForFiles( deployDir, "test-cluster.war\\.[0-9A-Fa-f]+", 3, 2, sleep );
+ for( File webInfDir : warDir.listFiles() ) {
+ waitForFiles( webInfDir, ".*", 4, 0, sleep );
+ }
+ waitForAccess( serviceUrl, username, password, sleep );
+
+ // Delete the test topology.
+ assertThat( "Failed to delete the topology file.", descriptor.delete(), is( true ) );
+
+ waitForFiles( deployDir, ".*", 0, -1, sleep );
+
+ // Wait a bit more to make sure undeployment finished.
+ Thread.sleep( sleep );
+
+ // Make sure the test topology is not accessible.
+ given().auth().preemptive().basic( username, password )
+ .expect().statusCode( HttpStatus.SC_NOT_FOUND )
+ .when().get( serviceUrl );
+
+ // Make sure deployment directory is empty.
+ assertThat( topoDir.listFiles().length, is( 0 ) );
+ assertThat( deployDir.listFiles().length, is( 0 ) );
+ }
+
+ private File writeTestTopology( String name, XMLTag xml ) throws IOException {
// Create the test topology.
- File tempFile = new File( config.getGatewayTopologyDir(), "test-cluster.xml." + UUID.randomUUID() );
+ File tempFile = new File( config.getGatewayTopologyDir(), name + ".xml." + UUID.randomUUID() );
FileOutputStream stream = new FileOutputStream( tempFile );
- createTopology().toStream( stream );
+ xml.toStream( stream );
stream.close();
- File descriptor = new File( config.getGatewayTopologyDir(), "test-cluster.xml" );
+ File descriptor = new File( config.getGatewayTopologyDir(), name + ".xml" );
tempFile.renameTo( descriptor );
+ return descriptor;
+ }
- // Make sure deployment directory has one WAR with the correct name.
- long before = System.currentTimeMillis();
- long elapsed = 0;
+ private File waitForFiles( File dir, String pattern, int count, int index, long sleep ) throws InterruptedException {
+ RegexDirFilter filter = new RegexDirFilter( pattern );
while( true ) {
- elapsed = System.currentTimeMillis() - before;
- assertThat( "Waited too long for topology deployment dir creation.", elapsed, lessThan( timeout ) );
- File[] files = deployDir.listFiles( new RegexDirFilter( "test-cluster.war\\.[0-9A-Fa-f]+" ) );
- if( files.length == 1 ) {
- warDir = files[0];
- break;
- }
- Thread.sleep( sleep );
- }
- while( true ) {
- elapsed = System.currentTimeMillis() - before;
- assertThat( "Waited too long for topology deployment file creation.", elapsed, lessThan( timeout ) );
- File webInfDir = new File( warDir, "WEB-INF" );
- File[] files = webInfDir.listFiles();
- //System.out.println( "DEPLOYMENT FILES: " + files.length );
- //for( File file : files ) {
- // System.out.println( " " + file.getAbsolutePath() );
- //}
- if( files.length >= 4 ) {
- break;
+ File[] files = dir.listFiles( filter );
+ if( files.length == count ) {
+ return ( index < 0 ) ? null : files[ index ];
}
Thread.sleep( sleep );
}
+ }
- // Make sure the test topology is accessible.
+ private void waitForAccess( String url, String username, String password, long sleep ) throws InterruptedException {
while( true ) {
- elapsed = System.currentTimeMillis() - before;
- assertThat( "Waited too long for topology to be accessible.", elapsed, lessThan( timeout ) );
Response response = given()
.auth().preemptive().basic( username, password )
- .when().get( serviceUrl ).andReturn();
+ .when().get( url ).andReturn();
if( response.getStatusCode() == HttpStatus.SC_NOT_FOUND ) {
Thread.sleep( sleep );
continue;
@@ -269,50 +304,8 @@ public class GatewayDeployFuncTest {
assertThat( response.getBody().asString(), is( "test-service-response" ) );
break;
}
-
- // Delete the test topology.
- assertThat( "Failed to delete the topology file.", descriptor.delete(), is( true ) );
-
- // Make sure the deployment directory is empty.
- before = System.currentTimeMillis();
- while( true ) {
- File[] deploymentFiles = deployDir.listFiles( new RegexDirFilter( "test-cluster.war\\.[0-9A-Fa-f]+" ) );
- if( deploymentFiles.length == 0 ) {
- break;
- } else if( ( System.currentTimeMillis() - before ) > timeout ) {
- System.out.println( "TOPOLOGY FILES " + topoDir );
- File[] topologyFiles = topoDir.listFiles( new RegexDirFilter( "test-cluster.*" ) );
- for( File file : topologyFiles ) {
- System.out.println( " " + file.getAbsolutePath() );
- }
- System.out.println( "DEPLOYMENT FILES " + deployDir );
- for( File file : deploymentFiles ) {
- System.out.println( " " + file.getAbsolutePath() );
- }
- fail( "Waited too long for topology undeployment: " + ( System.currentTimeMillis() - before ) + "ms" );
- } else {
- Thread.sleep( sleep );
- }
- }
-
- // Wait a bit more to make sure undeployment finished.
- Thread.sleep( sleep );
-
- // Make sure the test topology is not accessible.
- given()
- //.log().all()
- .auth().preemptive().basic( username, password )
- .expect()
- //.log().all()
- .statusCode( HttpStatus.SC_NOT_FOUND )
- .when().get( serviceUrl );
-
- // Make sure deployment directory is empty.
- assertThat( topoDir.listFiles().length, is( 0 ) );
- assertThat( deployDir.listFiles().length, is( 0 ) );
}
-
private class RegexDirFilter implements FilenameFilter {
Pattern pattern;