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 2015/07/21 23:42:54 UTC
knox git commit: KNOX-549: Test service connections through Knox with
Knox CLI
Repository: knox
Updated Branches:
refs/heads/master 06a61b602 -> fae40583d
KNOX-549: Test service connections through Knox with Knox CLI
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/fae40583
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/fae40583
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/fae40583
Branch: refs/heads/master
Commit: fae40583d026e94a77f3bf6168bb53a917c24b38
Parents: 06a61b6
Author: Kevin Minder <ke...@hortonworks.com>
Authored: Tue Jul 21 17:42:42 2015 -0400
Committer: Kevin Minder <ke...@hortonworks.com>
Committed: Tue Jul 21 17:42:42 2015 -0400
----------------------------------------------------------------------
CHANGES | 1 +
gateway-release/pom.xml | 4 +
.../topology/impl/DefaultTopologyService.java | 21 +
.../org/apache/hadoop/gateway/util/KnoxCLI.java | 190 ++++++++-
.../gateway/util/ServiceDefinitionsLoader.java | 52 ++-
.../service/definition/ServiceDefinition.java | 18 +
.../resources/services/falcon/0.6.0/service.xml | 7 +
.../resources/services/hbase/0.98.0/service.xml | 6 +
.../resources/services/oozie/4.0.0/service.xml | 5 +
.../resources/services/storm/0.9.3/service.xml | 6 +
.../services/webhcat/0.13.0/service.xml | 6 +
.../services/webhdfs/2.4.0/service.xml | 3 +
.../services/yarn-rm/2.5.0/service.xml | 5 +
gateway-service-test/pom.xml | 63 +++
.../service/test/ServiceTestResource.java | 421 +++++++++++++++++++
.../gateway/service/test/ServiceTestURL.java | 89 ++++
.../test/ServiceTestWrapperMarshaller.java | 72 ++++
.../ServiceTestDeploymentContributor.java | 102 +++++
....gateway.deploy.ServiceDeploymentContributor | 19 +
.../hadoop/gateway/service/test/jaxb.properties | 16 +
.../services/topology/TopologyService.java | 7 +-
.../hadoop/gateway/GatewayBasicFuncTest.java | 246 ++++++++++-
.../hadoop/gateway/GatewayFuncTestDriver.java | 30 ++
pom.xml | 6 +
24 files changed, 1368 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 40f2757..ed7bdc7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,7 @@ Release Notes - Apache Knox - Version 0.7.0
* [KNOX-560] - Test LDAP Authentication+Authorization from KnoxCLI
* [KNOX-547] - KnoxCLI adds new validate-topology and list-topologies commands.
* [KNOX-548] - KnoxCLI adds a new system-user-auth-test command to test a topology's system username and password
+ * [KNOX-549] - New Service-Test API can be added to topology. Accessible via Http call or KnoxCLI
** Improvement
* [KNOX-553] - Added topology validation from KnoxCLI to TopologyService deployment.
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index 33472cf..b95865f 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -152,6 +152,10 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-service-as</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-server/src/main/java/org/apache/hadoop/gateway/services/topology/impl/DefaultTopologyService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/topology/impl/DefaultTopologyService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/topology/impl/DefaultTopologyService.java
index d298ba0..ecfbcd9 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/topology/impl/DefaultTopologyService.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/topology/impl/DefaultTopologyService.java
@@ -36,6 +36,7 @@ import org.apache.hadoop.gateway.audit.api.ResourceType;
import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
+import org.apache.hadoop.gateway.service.definition.ServiceDefinition;
import org.apache.hadoop.gateway.services.ServiceLifecycleException;
import org.apache.hadoop.gateway.services.topology.TopologyService;
import org.apache.hadoop.gateway.topology.Topology;
@@ -47,6 +48,7 @@ import org.apache.hadoop.gateway.topology.builder.TopologyBuilder;
import org.apache.hadoop.gateway.topology.validation.TopologyValidator;
import org.apache.hadoop.gateway.topology.xml.AmbariFormatXmlTopologyRules;
import org.apache.hadoop.gateway.topology.xml.KnoxFormatXmlTopologyRules;
+import org.apache.hadoop.gateway.util.ServiceDefinitionsLoader;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.xml.sax.SAXException;
@@ -350,6 +352,25 @@ public class DefaultTopologyService
}
}
+ public Map<String, List<String>> getServiceTestURLs(Topology t, GatewayConfig config) {
+ File tFile = null;
+ Map<String, List<String>> urls = new HashMap<>();
+ for(File f : directory.listFiles()){
+ if(FilenameUtils.removeExtension(f.getName()).equals(t.getName())){
+ tFile = f;
+ }
+ }
+ Set<ServiceDefinition> defs;
+ if(tFile != null) {
+ defs = ServiceDefinitionsLoader.getServiceDefinitions(new File(config.getGatewayServicesDir()));
+
+ for(ServiceDefinition def : defs) {
+ urls.put(def.getRole(), def.getTestURLs());
+ }
+ }
+ return urls;
+ }
+
public Collection<Topology> getTopologies() {
Map<File, Topology> map = topologies;
return Collections.unmodifiableCollection(map.values());
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/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 9022921..497121e 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,6 +17,7 @@
*/
package org.apache.hadoop.gateway.util;
+import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
@@ -38,6 +39,13 @@ import org.apache.hadoop.gateway.topology.Topology;
import org.apache.hadoop.gateway.topology.validation.TopologyValidator;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.PropertyConfigurator;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
@@ -45,13 +53,18 @@ import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
+import org.eclipse.persistence.oxm.MediaType;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.spec.WebArchive;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -81,7 +94,8 @@ public class KnoxCLI extends Configured implements Tool {
" [" + ListTopologiesCommand.USAGE + "]\n" +
" [" + ValidateTopologyCommand.USAGE + "]\n" +
" [" + LDAPAuthCommand.USAGE + "]\n" +
- " [" + LDAPSysBindCommand.USAGE + "]\n";
+ " [" + LDAPSysBindCommand.USAGE + "]\n" +
+ " [" + ServiceTestCommand.USAGE + "]\n";
/** allows stdout to be captured if necessary */
public PrintStream out = System.out;
@@ -95,6 +109,7 @@ public class KnoxCLI extends Configured implements Tool {
private String path = null;
private String generate = "false";
private String hostname = null;
+ private String port = null;
private boolean force = false;
private boolean debug = false;
private String user = null;
@@ -163,6 +178,8 @@ public class KnoxCLI extends Configured implements Tool {
* % knoxcli validate-topology [--cluster clustername] | [--path <path/to/file>]
* % knoxcli user-auth-test [--cluster clustername] [--u username] [--p password]
* % knoxcli system-user-auth-test [--cluster clustername] [--d]
+ * % knoxcli service-test [--u user] [--p password] [--cluster clustername] [--hostname name] [--port port]
+ *
* </pre>
* @param args
* @return
@@ -251,6 +268,13 @@ public class KnoxCLI extends Configured implements Tool {
return -1;
}
this.cluster = args[++i];
+ } else if (args[i].equals("service-test")) {
+ if( i + 1 >= args[i].length()) {
+ printKnoxShellUsage();
+ return -1;
+ } else {
+ command = new ServiceTestCommand();
+ }
} else if (args[i].equals("--generate")) {
if ( command != null && command instanceof MasterCreateCommand ) {
this.master = UUID.randomUUID().toString();
@@ -269,6 +293,12 @@ public class KnoxCLI extends Configured implements Tool {
return -1;
}
this.hostname = args[++i];
+ } else if (args[i].equals("--port")) {
+ if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ printKnoxShellUsage();
+ return -1;
+ }
+ this.port = args[++i];
} else if (args[i].equals("--master")) {
// For testing only
if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
@@ -351,6 +381,9 @@ public class KnoxCLI extends Configured implements Tool {
out.println(LDAPSysBindCommand.USAGE + "\n\n" + LDAPSysBindCommand.DESC);
out.println();
out.println( div );
+ out.println(ServiceTestCommand.USAGE + "\n\n" + ServiceTestCommand.DESC);
+ out.println();
+ out.println( div );
}
}
@@ -1294,6 +1327,161 @@ public class KnoxCLI extends Configured implements Tool {
}
+ public class ServiceTestCommand extends Command {
+ public static final String USAGE = "service-test [--u username] [--p password] [--cluster clustername] [--hostname name] " +
+ "[--port port]";
+ public static final String DESC = "This command requires a running instance of Knox to be present on the same " +
+ "machine. It will execute a test to make sure all services are accessible through the gateway URLs. Errors are " +
+ "reported and suggestions to resolve any problems are returned. JSON formatted.";
+
+ private boolean ssl = true;
+ private int attempts = 0;
+
+ @Override
+ public String getUsage() { return USAGE + ":\n\n" + DESC; };
+
+ @Override
+ public void execute() {
+ attempts++;
+ SSLContext ctx = null;
+ CloseableHttpClient client;
+ String http = "https://";
+ String https = "http://";
+ GatewayConfig conf = getGatewayConfig();
+ String gatewayPort;
+ String host;
+
+
+ if(cluster == null) {
+ printKnoxShellUsage();
+ out.println("A --cluster argument is required.");
+ return;
+ }
+
+ if(hostname != null) {
+ host = hostname;
+ } else {
+ try {
+ host = InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ out.println(e.getMessage());
+ out.println("Defaulting address to localhost. Use --hostname option to specify a different hostname");
+ host = "localhost";
+ }
+ }
+
+ if (port != null) {
+ gatewayPort = port;
+ } else if (conf.getGatewayPort() > -1) {
+ gatewayPort = Integer.toString(conf.getGatewayPort());
+ } else {
+ out.println("Could not get port. Please supply it using the --port option");
+ return;
+ }
+
+
+ String path = "/" + conf.getGatewayPath();
+ String topology = "/" + cluster;
+ String httpServiceTestURL = http + host + ":" + gatewayPort + path + topology + "/service-test";
+ String httpsServiceTestURL = https + host + ":" + gatewayPort + path + topology + "/service-test";
+
+ String authString = "";
+// Create Authorization String
+ if( user != null && pass != null) {
+ authString = "Basic " + Base64.encodeBase64String((user + ":" + pass).getBytes());
+ } else {
+ out.println("Username and/or password not supplied. Expect HTTP 401 Unauthorized responses.");
+ }
+
+// Attempt to build SSL context for HTTP client.
+ try {
+ ctx = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
+ } catch (Exception e) {
+ out.println(e.getMessage());
+ }
+
+// Initialize the HTTP client
+ if(ctx == null) {
+ client = HttpClients.createDefault();
+ } else {
+ client = HttpClients.custom().setSslcontext(ctx).build();
+ }
+
+ HttpGet request = new HttpGet(httpsServiceTestURL);
+ request.setHeader("Authorization", authString);
+ request.setHeader("Accept", MediaType.APPLICATION_JSON.getMediaType());
+ try {
+ CloseableHttpResponse response = client.execute(request);
+
+// Fallback to http in case Http in case https doesn't work.
+ if(response.getStatusLine().getStatusCode() != 200) {
+ request = new HttpGet(httpServiceTestURL);
+ response = client.execute(request);
+ }
+
+ response.close();
+ request.releaseConnection();
+
+ switch (response.getStatusLine().getStatusCode()) {
+
+ case 200:
+ response.getEntity().writeTo(out);
+ break;
+ case 404:
+ out.println("Could not find service-test resource");
+ out.println("Make sure you have configured the SERVICE-TEST service in your topology.");
+ break;
+ case 500:
+ out.println("HTTP 500 Server error");
+ break;
+
+ default:
+ out.println("Unexpected HTTP response code.");
+ out.println(response.getStatusLine().toString());
+ response.getEntity().writeTo(out);
+ break;
+
+
+ }
+
+
+ } catch (ClientProtocolException e) {
+ out.println(e.getMessage());
+ if (debug) {
+ e.printStackTrace(out);
+ }
+ } catch (SSLException e) {
+ out.println(e.getMessage());
+
+ if(attempts < 2) {
+ if(ssl) {
+ ssl = false;
+ out.println("Attempting request without SSL.");
+ } else {
+ ssl = true;
+ out.println("Attempting request with SSL ");
+ }
+ execute();
+ } else {
+ out.println("Unable to successfully make request. Try using the API with cURL.");
+ }
+ } catch (IOException e) {
+ out.println(e.getMessage());
+ if(debug) {
+ e.printStackTrace(out);
+ }
+ } finally {
+ try {
+ client.close();
+ } catch (IOException e) {
+ out.println(e.getMessage());
+ }
+ }
+
+ }
+
+ }
+
private GatewayConfig getGatewayConfig() {
GatewayConfig result;
Configuration conf = getConf();
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-server/src/main/java/org/apache/hadoop/gateway/util/ServiceDefinitionsLoader.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/util/ServiceDefinitionsLoader.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/util/ServiceDefinitionsLoader.java
index 2ff07fd..0f41b2b 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/util/ServiceDefinitionsLoader.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/util/ServiceDefinitionsLoader.java
@@ -55,17 +55,8 @@ public class ServiceDefinitionsLoader {
try {
JAXBContext context = JAXBContext.newInstance(ServiceDefinition.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
- Collection<File> files = FileUtils.listFiles(servicesDir, new IOFileFilter() {
- @Override
- public boolean accept(File file) {
- return file.getName().contains(SERVICE_FILE_NAME);
- }
- @Override
- public boolean accept(File dir, String name) {
- return name.contains(SERVICE_FILE_NAME);
- }
- }, TrueFileFilter.INSTANCE);
- for ( File file : files ) {
+
+ for ( File file : getFileList(servicesDir) ) {
try {
FileInputStream inputStream = new FileInputStream(file);
ServiceDefinition definition = (ServiceDefinition) unmarshaller.unmarshal(inputStream);
@@ -84,6 +75,45 @@ public class ServiceDefinitionsLoader {
return contributors;
}
+ public static Set<ServiceDefinition> getServiceDefinitions(File servicesDir) {
+ Set<ServiceDefinition> definitions = new HashSet<>();
+ try {
+ JAXBContext context = JAXBContext.newInstance(ServiceDefinition.class);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+
+ for (File f : getFileList(servicesDir)){
+ ServiceDefinition definition = (ServiceDefinition) unmarshaller.unmarshal(f);
+ definitions.add( definition );
+ }
+
+ } catch (JAXBException e) {
+ log.failedToLoadServiceDefinition(SERVICE_FILE_NAME, e);
+ }
+
+ return definitions;
+ }
+
+ private static Collection<File> getFileList(File servicesDir) {
+ Collection<File> files;
+ if ( servicesDir.exists() && servicesDir.isDirectory() ) {
+ files = FileUtils.listFiles(servicesDir, new IOFileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return file.getName().contains(SERVICE_FILE_NAME);
+ }
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.contains(SERVICE_FILE_NAME);
+ }
+ }, TrueFileFilter.INSTANCE);
+ } else {
+ return files = new HashSet<File>();
+ }
+
+ return files;
+ }
+
private static UrlRewriteRulesDescriptor loadRewriteRules(File servicesDir) {
File rewriteFile = new File(servicesDir, REWRITE_FILE);
if ( rewriteFile.exists() ) {
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/ServiceDefinition.java
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/ServiceDefinition.java b/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/ServiceDefinition.java
index cbb9309..e85e6f9 100644
--- a/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/ServiceDefinition.java
+++ b/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/ServiceDefinition.java
@@ -21,6 +21,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "service")
@@ -38,6 +39,8 @@ public class ServiceDefinition {
private CustomDispatch dispatch;
+ private List<String> testURLs;
+
@XmlAttribute
public String getName() {
return name;
@@ -90,6 +93,21 @@ public class ServiceDefinition {
return dispatch;
}
+ @XmlElement(name = "testURL")
+ @XmlElementWrapper(name = "testURLs")
+ public List<String> getTestURLs() {
+
+ if(testURLs != null){
+ return testURLs;
+ } else {
+ return new ArrayList<String>();
+ }
+ }
+
+ public void setTestURLs(List<String> testURLs) {
+ this.testURLs = testURLs;
+ }
+
public void setDispatch(CustomDispatch dispatch) {
this.dispatch = dispatch;
}
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/falcon/0.6.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/falcon/0.6.0/service.xml b/gateway-service-definitions/src/main/resources/services/falcon/0.6.0/service.xml
index 716f165..f4d4cf5 100644
--- a/gateway-service-definitions/src/main/resources/services/falcon/0.6.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/falcon/0.6.0/service.xml
@@ -18,4 +18,11 @@
<routes>
<route path="/falcon/api/**"/>
</routes>
+ <testURLs>
+ <testURL>/falcon/api/admin/stack</testURL>
+ <testURL>/falcon/api/admin/version</testURL>
+ <testURL>/falcon/api/metadata/lineage/serialize</testURL>
+ <testURL>/falcon/api/metadata/lineage/vertices/all</testURL>
+ <testURL>/falcon/api/metadata/lineage/edges/all</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml b/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
index 37d49bb..181b536 100644
--- a/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/hbase/0.98.0/service.xml
@@ -30,4 +30,10 @@
</route>
</routes>
<dispatch classname="org.apache.hadoop.gateway.hbase.HBaseDispatch"/>
+ <testURLs>
+ <testURL>/hbase/version</testURL>
+ <testURL>/hbase/version/cluster</testURL>
+ <testURL>/hbase/status/cluster</testURL>
+ <testURL>/hbase</testURL>
+ </testURLs>
</service>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
index 7bc7eb3..455746c 100644
--- a/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/oozie/4.0.0/service.xml
@@ -27,4 +27,9 @@
<rewrite apply="OOZIE/oozie/configuration" to="request.body"/>
</route>
</routes>
+ <testURLs>
+ <testURL>/oozie/v1/admin/build-version</testURL>
+ <testURL>/oozie/v1/admin/status</testURL>
+ <testURL>/oozie/versions</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml b/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
index ffe20a4..c5f388e 100644
--- a/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/storm/0.9.3/service.xml
@@ -25,4 +25,10 @@
</route>
</routes>
<dispatch classname="org.apache.hadoop.gateway.storm.StormDispatch"/>
+ <testURLs>
+ <testURL>/storm/api/v1/cluster/configuration</testURL>
+ <testURL>/storm/api/v1/cluster/summary</testURL>
+ <testURL>/storm/api/v1/supervisor/summary</testURL>
+ <testURL>/storm/api/v1/topology/summary</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml b/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
index c550dc1..d8c92c6 100644
--- a/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/webhcat/0.13.0/service.xml
@@ -20,4 +20,10 @@
<route path="/templeton/v1/?**"/>
<route path="/templeton/v1/**?**"/>
</routes>
+ <testURLs>
+ <testURL>/templeton/v1/status</testURL>
+ <testURL>/templeton/v1/version</testURL>
+ <testURL>/templeton/v1/version/hive</testURL>
+ <testURL>/templeton/v1/version/hadoop</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
index f958b42..9d39a32 100644
--- a/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/webhdfs/2.4.0/service.xml
@@ -37,4 +37,7 @@
</route>
</routes>
<dispatch classname="org.apache.hadoop.gateway.hdfs.dispatch.HdfsHttpClientDispatch" ha-classname="org.apache.hadoop.gateway.hdfs.dispatch.WebHdfsHaDispatch"/>
+ <testURLs>
+ <testURL>/webhdfs/v1/?op=LISTSTATUS</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml b/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
index 73fb771..6b4c6a5 100644
--- a/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/yarn-rm/2.5.0/service.xml
@@ -51,4 +51,9 @@
<rewrite apply="RESOURCEMANAGER/resourcemanager/proxy/taskattempt/outbound" to="response.body"/>
</route>
</routes>
+ <testURLs>
+ <testURL>/resourcemanager/v1/cluster/info</testURL>
+ <testURL>/resourcemanager/v1/cluster/metrics</testURL>
+ <testURL>/resourcemanager/v1/cluster/apps</testURL>
+ </testURLs>
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-test/pom.xml b/gateway-service-test/pom.xml
new file mode 100644
index 0000000..357d23c
--- /dev/null
+++ b/gateway-service-test/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>gateway</artifactId>
+ <groupId>org.apache.knox</groupId>
+ <version>0.7.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>gateway-service-test</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ <name>gateway-service-test</name>
+ <dependencies>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-rewrite</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-jersey</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>eclipselink</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
+ <artifactId>gateway-test-utils</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
new file mode 100644
index 0000000..0d26301
--- /dev/null
+++ b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
@@ -0,0 +1,421 @@
+/**
+ * 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 org.apache.hadoop.gateway.service.test;
+
+import org.apache.hadoop.gateway.config.GatewayConfig;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.topology.TopologyService;
+import org.apache.hadoop.gateway.topology.Service;
+import org.apache.hadoop.gateway.topology.Topology;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.conn.ssl.SSLContexts;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.glassfish.jersey.internal.util.Base64;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static javax.ws.rs.core.Response.ok;
+import static javax.ws.rs.core.Response.status;
+
+@Path( "/service-test" )
+public class ServiceTestResource {
+ @Context
+ private HttpServletRequest request;
+
+
+ @GET
+ @Produces({APPLICATION_XML, APPLICATION_JSON})
+ public ServiceTestWrapper serviceTest(@QueryParam("username") String username,
+ @QueryParam("password") String password) {
+ List<ServiceTest> tests = new ArrayList<>();
+ List<String> messages = new ArrayList<>();
+ String authString;
+ GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+ SSLContext ctx = null;
+ CloseableHttpClient client;
+ String id = getTopologyName();
+
+ Topology topology = getTopology(id);
+
+// Create Authorization String
+ if( username != null && password != null) {
+ authString = "Basic " + Base64.encodeAsString((username + ":" + password).getBytes());
+ } else if (request.getHeader("Authorization") != null) {
+ authString = request.getHeader("Authorization");
+ } else {
+ authString = null;
+ }
+
+// Attempt to build SSL context for HTTP client.
+ try {
+ ctx = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
+ } catch (Exception e) {
+ messages.add(e.getMessage());
+ }
+
+// Initialize the HTTP client
+ if(ctx == null) {
+ client = HttpClients.createDefault();
+ } else {
+ client = HttpClients.custom().setSslcontext(ctx).build();
+ }
+
+ if(topology != null) {
+ for (Service s : topology.getServices()) {
+ List<String> urls = getServiceTestURLs(config, s.getRole(), topology);
+
+// Make sure we handle a case where no URLs are found.
+ if(urls.size() <= 0) {
+ ServiceTest test = new ServiceTest(s);
+ test.setMessage("This service did not contain any test URLs");
+ }
+
+ for (String url : urls) {
+ HttpGet req = new HttpGet();
+ ServiceTest test = new ServiceTest(s, url);
+
+ if(authString != null) {
+ req.setHeader("Authorization", authString);
+ } else {
+ messages.add("No credentials provided. Expect HTTP 401 responses.");
+ }
+
+ try {
+ req.setURI(new URIBuilder(url).build());
+ CloseableHttpResponse res = client.execute(req);
+ String contentLength = "Content-Length:" + res.getEntity().getContentLength();
+ String contentType = (res.getEntity().getContentType() != null) ? res.getEntity().getContentType().toString() : "No-contenttype";
+ test.setResponseContent( contentLength + "," + contentType );
+ test.setHttpCode(res.getStatusLine().getStatusCode());
+ res.close();
+
+ } catch (IOException e) {
+ messages.add("Exception: " + e.getMessage());
+ test.setMessage(e.getMessage());
+ } catch (URISyntaxException e) {
+ test.setMessage(e.getMessage());
+ } catch (Exception e) {
+ messages.add(e.getMessage());
+ test.setMessage(e.getMessage());
+ } finally {
+ req.releaseConnection();
+ tests.add(test);
+ }
+ }
+ }
+ } else {
+ messages.add("Topology " + id + " not found");
+ }
+
+ try {
+ client.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ ServiceTestWrapper stw = new ServiceTestWrapper();
+ stw.setTests(tests);
+ stw.setMessages(messages);
+
+ return stw;
+ }
+
+ private String getTopologyName() {
+ String ctxPath = request.getContextPath();
+ GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+ String path = config.getGatewayPath();
+
+ String topologyName = ctxPath.replace(path, "").replace("/", "");
+ return topologyName;
+ }
+
+ public Topology getTopology(@PathParam("id") String id) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ for (Topology t : ts.getTopologies()) {
+ if(t.getName().equals(id)) {
+ try {
+ t.setUri(new URI( buildURI(t, config, request) ));
+ } catch (URISyntaxException se) {
+ t.setUri(null);
+ }
+ return t;
+ }
+ }
+ return null;
+ }
+
+ private List<String> getServiceTestURLs(GatewayConfig conf, String role, Topology topology) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ List<String> fullURLs = new ArrayList<>();
+ if(services != null) {
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ Map<String, List<String>> urls = ts.getServiceTestURLs(topology, conf);
+ List<String> urlPaths = urls.get(role);
+
+ if(urlPaths != null) {
+ String base = buildURI(topology, conf, request);
+ for (String u : urlPaths) {
+
+ fullURLs.add(base + u);
+ }
+ }
+ }
+ return fullURLs;
+ }
+
+ private String buildXForwardBaseURL(HttpServletRequest req){
+ final String X_Forwarded = "X-Forwarded-";
+ final String X_Forwarded_Context = X_Forwarded + "Context";
+ final String X_Forwarded_Proto = X_Forwarded + "Proto";
+ final String X_Forwarded_Host = X_Forwarded + "Host";
+ final String X_Forwarded_Port = X_Forwarded + "Port";
+ final String X_Forwarded_Server = X_Forwarded + "Server";
+
+ String baseURL = "";
+
+// Get Protocol
+ if(req.getHeader(X_Forwarded_Proto) != null){
+ baseURL += req.getHeader(X_Forwarded_Proto) + "://";
+ } else {
+ baseURL += req.getProtocol() + "://";
+ }
+
+// Handle Server/Host and Port Here
+ if (req.getHeader(X_Forwarded_Host) != null && req.getHeader(X_Forwarded_Port) != null){
+// Double check to see if host has port
+ if(req.getHeader(X_Forwarded_Host).contains(req.getHeader(X_Forwarded_Port))){
+ baseURL += req.getHeader(X_Forwarded_Host);
+ } else {
+// If there's no port, add the host and port together;
+ baseURL += req.getHeader(X_Forwarded_Host) + ":" + req.getHeader(X_Forwarded_Port);
+ }
+ } else if(req.getHeader(X_Forwarded_Server) != null && req.getHeader(X_Forwarded_Port) != null){
+// Tack on the server and port if they're available. Try host if server not available
+ baseURL += req.getHeader(X_Forwarded_Server) + ":" + req.getHeader(X_Forwarded_Port);
+ } else if(req.getHeader(X_Forwarded_Port) != null) {
+// if we at least have a port, we can use it.
+ baseURL += req.getServerName() + ":" + req.getHeader(X_Forwarded_Port);
+ } else {
+// Resort to request members
+ baseURL += req.getServerName() + ":" + req.getLocalPort();
+ }
+
+// Handle Server context
+ if( req.getHeader(X_Forwarded_Context) != null ) {
+ baseURL += req.getHeader( X_Forwarded_Context );
+ } else {
+ baseURL += req.getContextPath();
+ }
+
+ return baseURL;
+ }
+
+ String buildURI(Topology topology, GatewayConfig config, HttpServletRequest req){
+ String uri = buildXForwardBaseURL(req);
+
+// Strip extra context
+ uri = uri.replace(req.getContextPath(), "");
+
+// Add the gateway path
+ String gatewayPath;
+ if(config.getGatewayPath() != null){
+ gatewayPath = config.getGatewayPath();
+ }else{
+ gatewayPath = "gateway";
+ }
+ uri += "/" + gatewayPath;
+
+ uri += "/" + topology.getName();
+ return uri;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ public static class ServiceTest {
+
+ @XmlElement
+ private String serviceName;
+ @XmlElement
+ private String requestURL;
+ @XmlElement
+ private String responseContent;
+ @XmlElement
+ private int httpCode = -1;
+
+ @XmlElement
+ String message;
+
+ public ServiceTest() { }
+
+ public ServiceTest(Service s) {
+ this.serviceName = s.getRole();
+ }
+
+ public ServiceTest(Service s, String requestURL) {
+ this.serviceName = s.getRole();
+ this.requestURL = requestURL;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String n) {
+ serviceName = n;
+ }
+
+ public String getRequestURL() {
+ return requestURL;
+ }
+
+ public void setRequestURL(String requestURL) {
+ this.requestURL = requestURL;
+ }
+
+ public String getResponseContent() {
+ return responseContent;
+ }
+
+ public void setResponseContent(String responseContent) {
+ this.responseContent = responseContent;
+ }
+
+ public int getHttpCode() {
+ return httpCode;
+ }
+
+ public void setHttpCode(int httpCode) {
+ this.httpCode = httpCode;
+ setMessage();
+ }
+
+ public void setMessage() {
+ message = buildMessage(httpCode);
+ }
+
+ public void setMessage(String msg) {
+
+ if(httpCode != -1) {
+ message = buildMessage(httpCode);
+ } else {
+ message = msg;
+ }
+ }
+
+ public String getMessage(){
+ return message;
+ }
+
+ static String buildMessage(int code) {
+
+ String message = "";
+
+ switch (code) {
+
+ case 200:
+ message += "Request sucessful.";
+ break;
+ case 400:
+ message += "Could not properly intepret HTTP request.";
+ break;
+ case 401:
+ message += "User was not authorized. Try using credentials with access to all services. " +
+ "Ensure LDAP server is running.";
+ break;
+ case 403:
+ message += "Access to this resource is forbidden. It seems we might have made a bad request.";
+ break;
+ case 404:
+ message += "The page could not be found. Are the URLs for the topology services correct?";
+ break;
+ case 500:
+ message += "The server encountered an error. Are all of the cluster's services running? \n" +
+ "Can a connection be established without Knox?";
+ break;
+
+ }
+ return message;
+
+ }
+
+
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ @XmlRootElement
+ public static class ServiceTestWrapper{
+
+ @XmlElement(name="ServiceTest")
+ @XmlElementWrapper(name="Tests")
+ private List<ServiceTest> tests = new ArrayList<ServiceTest>();
+
+ @XmlElement(name="message")
+ @XmlElementWrapper(name="messages")
+ private List<String> messages = new ArrayList<>();
+
+ public List<ServiceTest> getTests(){
+ return tests;
+ }
+
+ public void setTests(List<ServiceTest> st){
+ this.tests = st;
+ }
+
+ public List<String> getMessages() {
+ return messages;
+ }
+
+ public void setMessages(List<String> messages){
+ this.messages = messages;
+ }
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestURL.java
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestURL.java b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestURL.java
new file mode 100644
index 0000000..e50451a
--- /dev/null
+++ b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestURL.java
@@ -0,0 +1,89 @@
+/**
+ * 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 org.apache.hadoop.gateway.service.test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ServiceTestURL {
+
+ private static final Map<String, List<String>> urls;
+ static final String WEBHDFS = "WEBHDFS";
+ static final String OOZIE = "OOZIE";
+ static final String YARN = "RESOURCEMANAGER";
+ static final String WEBHCAT = "WEBHCAT";
+ static final String HBASE = "WEBHBASE";
+ static final String HIVE = "HIVE";
+ static final String STORM = "STORM";
+ enum GATEWAY_SERVICES {
+ WEBHDFS, OOZIE, YARN, WEBHCAT, HBASE, HIVE, STORM
+ }
+
+ static {
+ Map<String, List<String>> urlMap = new HashMap<>();
+// WEBHDFS
+ List<String> webhdfs = new ArrayList<>();
+ webhdfs.add("/webhdfs/v1/?op=LISTSTATUS");
+ urlMap.put(WEBHDFS, webhdfs);
+
+// OOZIE
+ List<String> oozie = new ArrayList<>();
+ oozie.add("/oozie/v1/admin/build-version");
+ oozie.add("/oozie/versions");
+ oozie.add("/oozie/v1/admin/status");
+ urlMap.put(OOZIE, oozie);
+
+// RESOURCEMANAGER
+ List<String> resourceManager = new ArrayList<>();
+ resourceManager.add("/resourcemanager/v1/cluster/info");
+ resourceManager.add("/resourcemanager/v1/cluster/metrics");
+ resourceManager.add("/resourcemanager/v1/cluster/apps");
+ urlMap.put(YARN, resourceManager);
+
+// WEBHCAT
+ List<String> templeton = new ArrayList<>();
+ templeton.add("/templeton/v1/status");
+ templeton.add("/templeton/v1/version");
+ templeton.add("/templeton/v1/version/hive");
+ templeton.add("/templeton/v1/version/hadoop");
+ urlMap.put(WEBHCAT, templeton);
+
+// WEBHBASE
+ List<String> hbase = new ArrayList<>();
+ hbase.add("/hbase/version");
+ hbase.add("/hbase/version/cluster");
+ hbase.add("/hbase/status/cluster");
+ hbase.add("/hbase");
+ urlMap.put(HBASE, hbase);
+
+// HIVE
+// Not yet implemented
+// ??????
+
+ urls = urlMap;
+ }
+
+
+ public static List<String> get(String url){
+ return urls.get(url);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestWrapperMarshaller.java
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestWrapperMarshaller.java b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestWrapperMarshaller.java
new file mode 100644
index 0000000..95f053d
--- /dev/null
+++ b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestWrapperMarshaller.java
@@ -0,0 +1,72 @@
+/**
+ * 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 org.apache.hadoop.gateway.service.test;
+
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.Providers;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+@Provider
+@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+public class ServiceTestWrapperMarshaller implements MessageBodyWriter<ServiceTestResource.ServiceTestWrapper> {
+
+ @Context
+ protected Providers providers;
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return (ServiceTestResource.ServiceTestWrapper.class == type);
+ }
+
+ @Override
+ public long getSize(ServiceTestResource.ServiceTestWrapper instance, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return -1;
+ }
+
+ @Override
+ public void writeTo(ServiceTestResource.ServiceTestWrapper instance, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
+ try {
+ Map<String, Object> properties = new HashMap<String, Object>(1);
+ properties.put( JAXBContextProperties.MEDIA_TYPE, mediaType.toString());
+ JAXBContext context = JAXBContext.newInstance(new Class[]{ServiceTestResource.ServiceTestWrapper.class}, properties);
+ Marshaller m = context.createMarshaller();
+ m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ m.marshal(instance, entityStream);
+
+ } catch (JAXBException e) {
+ throw new IOException(e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/deploy/ServiceTestDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/deploy/ServiceTestDeploymentContributor.java b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/deploy/ServiceTestDeploymentContributor.java
new file mode 100644
index 0000000..221c7a7
--- /dev/null
+++ b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/deploy/ServiceTestDeploymentContributor.java
@@ -0,0 +1,102 @@
+/**
+ * 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 org.apache.hadoop.gateway.service.test.deploy;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
+import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase;
+import org.apache.hadoop.gateway.topology.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ServiceTestDeploymentContributor extends JerseyServiceDeploymentContributorBase {
+
+ private static final String PACKAGES_PARAM = "jersey.config.server.provider.packages";
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor#getRole()
+ */
+ @Override
+ public String getRole() {
+ return "SERVICE-TEST";
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor#getName()
+ */
+ @Override
+ public String getName() {
+ return "service-test";
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase#getPackages()
+ */
+ @Override
+ protected String[] getPackages() {
+ return new String[]{ "org.apache.hadoop.gateway.service.test" };
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase#getPatterns()
+ */
+ @Override
+ protected String[] getPatterns() {
+ return new String[]{ "*/**?**", "/*" };
+ }
+
+ @Override
+ public void contributeService( DeploymentContext context, Service service ) throws Exception {
+ String packages = StringUtils.join(getPackages(), ";");
+ for (String pattern : getPatterns()) {
+ ResourceDescriptor resource = context.getGatewayDescriptor().addResource();
+ resource.role(service.getRole());
+ resource.pattern(pattern);
+ addXForwardedFilter(context, service, resource);
+// addAuthenticationFilter(context, service, resource);
+// addIdentityAssertionFilter(context, service, resource);
+// addAuthorizationFilter(context, service, resource);
+// addRewriteFilter( context, service, resource, null );
+ List<FilterParamDescriptor> params = new ArrayList<FilterParamDescriptor>();
+ FilterParamDescriptor param = resource.createFilterParam();
+ param.name(PACKAGES_PARAM);
+ param.value(packages);
+ params.add(param);
+
+ FilterParamDescriptor traceType = resource.createFilterParam();
+ traceType.name( "jersey.config.server.tracing" );
+ traceType.value( "ALL" );
+ params.add( traceType );
+ FilterParamDescriptor traceLevel = resource.createFilterParam();
+ traceLevel.name( "jersey.config.server.tracing.threshold" );
+ traceLevel.value( "VERBOSE" );
+ params.add( traceLevel );
+ context.contributeFilter( service, resource, "pivot", "jersey", params );
+
+
+ context.contributeFilter(service, resource, "pivot", "jersey", params);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor b/gateway-service-test/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
new file mode 100644
index 0000000..cc1a096
--- /dev/null
+++ b/gateway-service-test/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.hadoop.gateway.service.test.deploy.ServiceTestDeploymentContributor
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-service-test/src/main/resources/org/apache/hadoop/gateway/service/test/jaxb.properties
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/resources/org/apache/hadoop/gateway/service/test/jaxb.properties b/gateway-service-test/src/main/resources/org/apache/hadoop/gateway/service/test/jaxb.properties
new file mode 100644
index 0000000..8c7ac2f
--- /dev/null
+++ b/gateway-service-test/src/main/resources/org/apache/hadoop/gateway/service/test/jaxb.properties
@@ -0,0 +1,16 @@
+# 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.
+javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/topology/TopologyService.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/topology/TopologyService.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/topology/TopologyService.java
index 9e787a7..a964f38 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/topology/TopologyService.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/topology/TopologyService.java
@@ -17,11 +17,14 @@
*/
package org.apache.hadoop.gateway.services.topology;
+import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.services.Service;
import org.apache.hadoop.gateway.topology.Topology;
import org.apache.hadoop.gateway.topology.TopologyListener;
import java.util.Collection;
+import java.util.List;
+import java.util.Map;
public interface TopologyService extends Service {
@@ -42,4 +45,6 @@ public interface TopologyService extends Service {
public void deleteTopology(Topology t);
-}
+ public Map<String, List<String>> getServiceTestURLs(Topology t, GatewayConfig config);
+
+ }
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
index 8e2bfe4..51add41 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayBasicFuncTest.java
@@ -19,11 +19,13 @@ package org.apache.hadoop.gateway;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Cookie;
+import com.jayway.restassured.response.Header;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.specification.ResponseSpecification;
import com.mycila.xmltool.XMLDoc;
import com.mycila.xmltool.XMLTag;
import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.hadoop.gateway.util.KnoxCLI;
import org.apache.hadoop.test.TestUtils;
import org.apache.hadoop.test.category.FunctionalTests;
import org.apache.hadoop.test.category.MediumTests;
@@ -49,11 +51,14 @@ import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileNotFoundException;
+import javax.ws.rs.core.MediaType;
+import java.io.PrintStream;
import java.io.IOException;
import java.io.StringWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileFilter;
+import java.io.ByteArrayOutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -66,6 +71,7 @@ import java.util.Map.Entry;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.text.IsEmptyString.isEmptyString;
import static org.xmlmatchers.XmlMatchers.isEquivalentTo;
@@ -230,17 +236,19 @@ public class GatewayBasicFuncTest {
.addTag( "role" ).addText( "WEBHBASE" )
.addTag( "url" ).addText( driver.getRealUrl( "WEBHBASE" ) ).gotoParent()
.addTag("service")
- .addTag( "role" ).addText( "RESOURCEMANAGER" )
- .addTag( "url" ).addText( driver.getRealUrl( "RESOURCEMANAGER" ) ).gotoParent()
- .addTag( "service" )
- .addTag( "role" ).addText( "FALCON" )
- .addTag( "url" ).addText( driver.getRealUrl( "FALCON" ) ).gotoParent()
- .addTag( "service" )
- .addTag( "role" ).addText( "STORM" )
- .addTag( "url" ).addText( driver.getRealUrl( "STORM" ) ).gotoParent()
- .addTag( "service" )
- .addTag( "role" ).addText( "STORM-LOGVIEWER" )
- .addTag( "url" ).addText( driver.getRealUrl( "STORM-LOGVIEWER" ) ).gotoParent()
+ .addTag("role").addText("RESOURCEMANAGER")
+ .addTag("url").addText(driver.getRealUrl("RESOURCEMANAGER")).gotoParent()
+ .addTag("service")
+ .addTag("role").addText("FALCON")
+ .addTag("url").addText(driver.getRealUrl("FALCON")).gotoParent()
+ .addTag("service")
+ .addTag("role").addText("STORM")
+ .addTag("url").addText(driver.getRealUrl("STORM")).gotoParent()
+ .addTag("service")
+ .addTag("role").addText("STORM-LOGVIEWER")
+ .addTag("url").addText(driver.getRealUrl("STORM-LOGVIEWER")).gotoParent()
+ .addTag("service")
+ .addTag("role").addText("SERVICE-TEST")
.gotoRoot();
// System.out.println( "GATEWAY=" + xml.toString() );
return xml;
@@ -3411,4 +3419,214 @@ public class GatewayBasicFuncTest {
MatcherAssert.assertThat(location, not(containsString("host=")));
MatcherAssert.assertThat(location, not(containsString("port=")));
}
+
+ @Test
+ public void testServiceTestAPI() throws Exception {
+
+ String user = "kminder";
+ String password = "kminder-password";
+
+ String queryString = "?username=" + user + "&password=" + password;
+
+ String clusterUrl = driver.getClusterUrl();
+ String testUrl = clusterUrl + "/service-test";
+
+// XML Response
+ setupResources();
+ given()
+ .header(new Header("Accept", MediaType.APPLICATION_XML))
+ .expect()
+ .contentType(MediaType.APPLICATION_XML)
+ .statusCode(HttpStatus.SC_OK)
+ .body(not(containsString("<httpCode>401")))
+ .body(not(containsString("<httpCode>404")))
+ .body(not(containsString("<httpCode>403")))
+ .body(containsString("<httpCode>200"))
+ .when()
+ .get(testUrl + queryString);
+// .prettyPrint();
+ driver.assertComplete();
+
+// JSON Response
+ setupResources();
+ given()
+ .header(new Header("Accept", MediaType.APPLICATION_JSON))
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(not(containsString("\"httpCode\" : 401")))
+ .body(not(containsString("\"httpCode\" : 404")))
+ .body(not(containsString("\"httpCode\" : 403")))
+ .body(containsString("\"httpCode\" : 200"))
+ .when()
+ .get(testUrl + queryString);
+// .prettyPrint();
+ driver.assertComplete();
+
+// Test authorization with a header instead
+ setupResources();
+ given()
+ .header(new Header("Accept", MediaType.APPLICATION_JSON))
+ .auth().preemptive().basic("kminder", "kminder-password")
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(not(containsString("\"httpCode\" : 401")))
+ .body(not(containsString("\"httpCode\" : 404")))
+ .body(not(containsString("\"httpCode\" : 403")))
+ .body(containsString("\"httpCode\" : 200"))
+ .when()
+ .get(testUrl);
+// .prettyPrint();
+ driver.assertComplete();
+
+
+
+// Authorize as a different (invalid) user
+ setupResources();
+ given()
+ .header(new Header("Accept", MediaType.APPLICATION_JSON))
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(not(containsString("\"httpCode\" : 200")))
+ .body(not(containsString("\"httpCode\" : 404")))
+ .body(not(containsString("\"httpCode\" : 403")))
+ .body(containsString("\"httpCode\" : 401"))
+ .when()
+ .get(testUrl + "?username=bad-user&password=bad-password");
+// .prettyPrint();
+ driver.assertNotComplete("WEBHDFS");
+ driver.assertNotComplete("OOZIE");
+ driver.assertNotComplete("RESOURCEMANAGER");
+ driver.assertNotComplete("WEBHCAT");
+ driver.assertNotComplete("STORM");
+ driver.assertNotComplete("WEBHBASE");
+ driver.assertNotComplete("FALCON");
+
+ // Authorize as a different (valid) user
+ setupResources();
+ given()
+ .header(new Header("Accept", MediaType.APPLICATION_JSON))
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(not(containsString("\"httpCode\" : 401")))
+ .body(not(containsString("\"httpCode\" : 404")))
+ .body(not(containsString("\"httpCode\" : 403")))
+ .when()
+ .get(testUrl + "?username=mapred&password=mapred-password");
+// .prettyPrint();
+ driver.assertComplete();
+ }
+
+ @Test
+ public void testCLIServiceTest() throws Exception {
+
+ setupResources();
+ // Now let's make sure we can run this same command from the CLI.
+ PrintStream out = System.out;
+ InetSocketAddress gatewayAddress = driver.gateway.getAddresses()[0];
+ final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outContent));
+
+ String args[] = {"service-test", "--master", "knox", "--cluster", driver.clusterName, "--hostname", gatewayAddress.getHostName(),
+ "--port", Integer.toString(gatewayAddress.getPort()), "--u", "kminder","--p", "kminder-password" };
+ KnoxCLI cli = new KnoxCLI();
+ cli.run(args);
+
+ assertThat(outContent.toString(), not(containsString("\"httpCode\": 401")));
+ assertThat( outContent.toString(), not(containsString("404")));
+ assertThat(outContent.toString(), not(containsString("403")));
+ outContent.reset();
+
+ setupResources();
+
+
+ String args2[] = {"service-test", "--master", "knox", "--cluster", driver.clusterName, "--hostname", gatewayAddress.getHostName(),
+ "--port", Integer.toString(gatewayAddress.getPort()) };
+
+ cli = new KnoxCLI();
+ cli.run(args2);
+ assertThat(outContent.toString(), (containsString("Username and/or password not supplied. Expect HTTP 401 Unauthorized responses.")));
+ outContent.reset();
+
+
+ String args3[] = {"service-test", "--master", "knox", "--cluster", driver.clusterName, "--hostname", "bad-host",
+ "--port", "0" };
+
+ cli = new KnoxCLI();
+ cli.run(args3);
+ assertThat(outContent.toString(), containsString("nodename nor servname provided"));
+ outContent.reset();
+
+ String args4[] = {"service-test", "--master", "knox", "--cluster", driver.clusterName, "--hostname", gatewayAddress.getHostName(),
+ "--port", "543", "--u", "mapred", "--p", "mapred-password" };
+
+ cli = new KnoxCLI();
+ cli.run(args4);
+ assertThat(outContent.toString(), containsString("failed: Connection refused"));
+ outContent.reset();
+
+
+ String args5[] = {"service-test", "--master", "knox", "--hostname", gatewayAddress.getHostName(),
+ "--port", "543", "--u", "mapred", "--p", "mapred-password" };
+
+ cli = new KnoxCLI();
+ cli.run(args5);
+ assertThat(outContent.toString(), containsString("--cluster argument is required"));
+ outContent.reset();
+
+// Reset the out content
+ System.setOut(out);
+ }
+
+
+ void setupResource(String serviceRole, String path){
+ driver.getMock(serviceRole)
+ .expect().method("GET")
+ .pathInfo(path)
+ .respond()
+ .status(HttpStatus.SC_OK)
+ .contentType("application/json")
+ .characterEncoding("utf-8");
+// .content(driver.getResourceBytes(classLoaderResource + "." + type.toString().toLowerCase()))
+// .contentType(type.toString());
+ }
+
+ void setupResources() {
+
+ driver.setResourceBase(GatewayBasicFuncTest.class);
+
+ try {
+ setupResource("WEBHDFS", "/v1/");
+ setupResource("WEBHCAT", "/v1/status");
+ setupResource("WEBHCAT", "/v1/version");
+ setupResource("WEBHCAT", "/v1/version/hive");
+ setupResource("WEBHCAT", "/v1/version/hadoop");
+ setupResource("OOZIE", "/v1/admin/build-version");
+ setupResource("OOZIE", "/v1/admin/status");
+ setupResource("OOZIE", "/versions");
+ setupResource("WEBHBASE", "/version");
+ setupResource("WEBHBASE", "/version/cluster");
+ setupResource("WEBHBASE", "/status/cluster");
+ setupResource("WEBHBASE", "/");
+ setupResource("RESOURCEMANAGER", "/v1/cluster/info/");
+ setupResource("RESOURCEMANAGER", "/v1/cluster/metrics/");
+ setupResource("RESOURCEMANAGER", "/v1/cluster/apps/");
+ setupResource("STORM", "/api/v1/cluster/configuration");
+ setupResource("STORM", "/api/v1/cluster/summary");
+ setupResource("STORM", "/api/v1/supervisor/summary");
+ setupResource("STORM", "/api/v1/topology/summary");
+ setupResource("FALCON", "/api/admin/stack");
+ setupResource("FALCON", "/api/admin/version");
+ setupResource("FALCON", "/api/metadata/lineage/serialize");
+ setupResource("FALCON", "/api/metadata/lineage/vertices/all");
+ setupResource("FALCON", "/api/metadata/lineage/edges/all");
+
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
index 2d6c4be..b4965c8 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
@@ -70,7 +70,9 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isIn;
+import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
/**
* This class was created to reduce much of the duplication and boiler plate that was ending up in the GatewayBasicFuncTest class.
@@ -91,6 +93,7 @@ public class GatewayFuncTestDriver {
public boolean useGateway;
public GatewayServer gateway;
public GatewayConfig config;
+ public String clusterName;
/**
* Sets the class from which relative test resource names should be resolved.
@@ -130,6 +133,7 @@ public class GatewayFuncTestDriver {
public void setupGateway( GatewayTestConfig config, String cluster, XMLTag topology, boolean use ) throws Exception {
this.useGateway = use;
this.config = config;
+ this.clusterName = cluster;
File targetDir = new File( System.getProperty( "user.dir" ), "target" );
File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() );
@@ -233,6 +237,13 @@ public class GatewayFuncTestDriver {
return url;
}
+ public String getClusterUrl() {
+ String url;
+ String localHostName = getLocalHostName();
+ url = "http://" + localHostName + ":" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath() + "/" + clusterName;
+ return url;
+ }
+
public String getRealAddr( String role ) {
String addr;
String localHostName = getLocalHostName();
@@ -314,6 +325,25 @@ public class GatewayFuncTestDriver {
}
}
+
+ public void assertNotComplete(String serviceName) {
+ // Check to make sure that all interaction were satisfied if for mocked services.
+ // Otherwise just clear the mock interaction queue.
+
+ Service service = services.get(serviceName);
+
+ if(service != null) {
+ if(service.mock) {
+ assertThat(
+ "Service " + service.role + " has remaining expected interactions.",
+ service.server.getCount(), not(0));
+ }
+ service.server.reset();
+ } else {
+ fail();
+ }
+ }
+
public void reset() {
for( Service service : services.values() ) {
service.server.reset();
http://git-wip-us.apache.org/repos/asf/knox/blob/fae40583/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4c1f236..cc66fab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,7 @@
<module>gateway-test</module>
<module>hsso-release</module>
<module>gateway-service-vault</module>
+ <module>gateway-service-test</module>
</modules>
<properties>
@@ -498,6 +499,11 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-test</artifactId>
+ <version>${gateway-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-service-as</artifactId>
<version>${gateway-version}</version>
</dependency>