/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2008 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $Id$
*/
package org.exist.http;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.io.StringReader;
import java.net.BindException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import junit.framework.TestCase;
import junit.textui.TestRunner;
import org.exist.Namespaces;
import org.exist.StandaloneServer;
import org.exist.memtree.SAXAdapter;
import org.exist.storage.DBBroker;
import org.exist.util.Base64Encoder;
import org.mortbay.util.MultiException;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
/** A test case for accessing a remote server via REST-Style Web API.
* @author wolf
* @author Pierrick Brihaye <pierrick.brihaye@free.fr>
*/
public class RESTServiceTest extends TestCase {
private static StandaloneServer server = null;
private final static String SERVER_URI = "http://localhost:8088";
private final static String COLLECTION_URI = SERVER_URI + DBBroker.ROOT_COLLECTION + "/test";
private final static String RESOURCE_URI = SERVER_URI + DBBroker.ROOT_COLLECTION
+ "/test/test.xml";
private final static String XML_DATA = "<test>"
+ "<para>\u00E4\u00E4\u00FC\u00FC\u00F6\u00F6\u00C4\u00C4\u00D6\u00D6\u00DC\u00DC</para>"
+ "</test>";
private final static String XUPDATE = "<xu:modifications xmlns:xu=\"http://www.xmldb.org/xupdate\" version=\"1.0\">"
+ "<xu:append select=\"/test\" child=\"1\">"
+ "<para>Inserted paragraph.</para>"
+ "</xu:append>" + "</xu:modifications>";
private final static String QUERY_REQUEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<query xmlns=\""+ Namespaces.EXIST_NS + "\">"
+ "<properties>"
+ "<property name=\"indent\" value=\"yes\"/>"
+ "<property name=\"encoding\" value=\"UTF-8\"/>"
+ "</properties>"
+ "<text>"
+ "xquery version \"1.0\";"
+ "(::pragma exist:serialize indent=no ::)"
+ "//para"
+ "</text>" + "</query>";
private final static String QUERY_REQUEST_ERROR = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<query xmlns=\""+ Namespaces.EXIST_NS + "\">"
+ "<properties>"
+ "<property name=\"indent\" value=\"yes\"/>"
+ "<property name=\"encoding\" value=\"UTF-8\"/>"
+ "</properties>"
+ "<text>"
+ "xquery version \"1.0\";"
+ "//undeclared:para"
+ "</text>" + "</query>";
private final static String TEST_MODULE =
"module namespace t=\"http://test.foo\";\n" +
"declare variable $t:VAR { 'World!' };";
private final static String TEST_XQUERY =
"xquery version \"1.0\";\n" +
"declare option exist:serialize \"method=text media-type=text/text\";\n" +
"import module namespace req=\"http://exist-db.org/xquery/request\";\n" +
"import module namespace t=\"http://test.foo\" at \"module.xq\";\n" +
"let $param := req:get-parameter('p', ())\n" +
"return\n" +
" ($param, ' ', $t:VAR)";
private final static String TEST_XQUERY_PARAMETER =
"xquery version \"1.0\";\n" +
"declare namespace request=\"http://exist-db.org/xquery/request\";\n" +
"import module namespace requestparametermod=\"http://exist-db.org/xquery/requestparametermod\" at \"requestparametermod.xqm\";\n" +
"concat(\"xql=\", request:get-parameter(\"doc\",())),\n" +
"concat(\"xqm=\", $requestparametermod:request)";
private final static String TEST_XQUERY_PARAMETER_MODULE =
"module namespace requestparametermod = \"http://exist-db.org/xquery/requestparametermod\";\n" +
"declare namespace request=\"http://exist-db.org/xquery/request\";\n" +
"declare variable $requestparametermod:request { request:get-parameter(\"doc\",())};\n";
private final static String TEST_XQUERY_WITH_PATH_PARAMETER =
"xquery version \"1.0\";\n" +
"declare namespace request=\"http://exist-db.org/xquery/request\";\n" +
"declare option exist:serialize \"method=text media-type=text/text\";\n" +
"(\"pathInfo=\", request:get-path-info(), \"\n\"," +
"\"servletPath=\", request:get-servlet-path(), \"\n\")";
private String credentials;
private String badCredentials;
public RESTServiceTest(String name) {
super(name);
Base64Encoder enc = new Base64Encoder();
enc.translate("admin:".getBytes());
credentials = new String(enc.getCharArray());
enc.reset();
enc.translate("johndoe:this pw should fail".getBytes());
badCredentials = new String(enc.getCharArray());
}
protected void setUp() {
//Don't worry about closing the server : the shutdown hook will do the job
try {
if (server == null) {
server = new StandaloneServer();
if (!server.isStarted()) {
try {
System.out.println("Starting standalone server...");
String[] args = {};
server.run(args);
while (!server.isStarted()) {
Thread.sleep(1000);
}
} catch (MultiException e) {
boolean rethrow = true;
Iterator i = e.getExceptions().iterator();
while (i.hasNext()) {
Exception e0 = (Exception) i.next();
if (e0 instanceof BindException) {
System.out.println("A server is running already !");
rethrow = false;
break;
}
}
if (rethrow)
throw e;
}
}
}
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testGetFailNoSuchDocument() {
try {
System.out.println("--- try to retrieve missing document, should fail ---");
String uri = COLLECTION_URI + "/nosuchdocument.xml";
HttpURLConnection connect = getConnection(uri);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 404, r);
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testXqueryGetWithEmptyPath()
{
try
{
/* store the documents that we need for this test */
System.out.println("--- Storing requestwithpath xquery ---");
doPut(TEST_XQUERY_WITH_PATH_PARAMETER, "requestwithpath.xq");
String path = COLLECTION_URI + "/requestwithpath.xq";
System.out.println("--- retrieving "+path+" --- ");
HttpURLConnection connect = getConnection(path);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String response = readResponse(connect.getInputStream());
System.out.println("--- got response:"+response+"\n -- end response");
String pathInfo = response.substring("pathInfo=".length(), response.indexOf("servletPath=")-2);
String servletPath = response.substring(response.indexOf("servletPath=") + "servletPath=".length(), response.lastIndexOf("\r\n"));
//check the responses
assertEquals("XQuery servletPath is: \"" + servletPath + "\" expected: \"/db/test/requestwithpath.xq\"", "/db/test/requestwithpath.xq", servletPath);
assertEquals("XQuery pathInfo is: \"" + pathInfo + "\" expected: \"\"", "", pathInfo);
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testXqueryPOSTWithEmptyPath()
{
try
{
/* store the documents that we need for this test */
System.out.println("--- Storing requestwithpath xquery ---");
doPut(TEST_XQUERY_WITH_PATH_PARAMETER, "requestwithpath.xq");
String path = COLLECTION_URI + "/requestwithpath.xq";
System.out.println("--- posting to "+path+" --- ");
HttpURLConnection connect = preparePost("boo", path);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String response = readResponse(connect.getInputStream());
System.out.println("--- got response:"+response+"\n -- end response");
String pathInfo = response.substring("pathInfo=".length(), response.indexOf("servletPath=")-2);
String servletPath = response.substring(response.indexOf("servletPath=") + "servletPath=".length(), response.lastIndexOf("\r\n"));
//check the responses
assertEquals("XQuery servletPath is: \"" + servletPath + "\" expected: \"/db/test/requestwithpath.xq\"", "/db/test/requestwithpath.xq", servletPath);
assertEquals("XQuery pathInfo is: \"" + pathInfo + "\" expected: \"\"", "", pathInfo);
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testXqueryGetWithNonEmptyPath()
{
try
{
/* store the documents that we need for this test */
System.out.println("--- Storing requestwithpath xquery ---");
doPut(TEST_XQUERY_WITH_PATH_PARAMETER, "requestwithpath.xq");
String path = COLLECTION_URI + "/requestwithpath.xq/some/path";
System.out.println("--- retrieving "+path+" --- ");
HttpURLConnection connect = getConnection(path);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String response = readResponse(connect.getInputStream());
System.out.println("--- got response:"+response+"\n -- end response");
String pathInfo = response.substring("pathInfo=".length(), response.indexOf("servletPath=")-2);
String servletPath = response.substring(response.indexOf("servletPath=") + "servletPath=".length(), response.lastIndexOf("\r\n"));
//check the responses
assertEquals("XQuery servletPath is: \"" + servletPath + "\" expected: \"/db/test/requestwithpath.xq\"", "/db/test/requestwithpath.xq", servletPath);
assertEquals("XQuery pathInfo is: \"" + pathInfo + "\" expected: \"/some/path\"", "/some/path", pathInfo);
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testXqueryPOSTWithNonEmptyPath()
{
try
{
/* store the documents that we need for this test */
System.out.println("--- Storing requestwithpath xquery ---");
doPut(TEST_XQUERY_WITH_PATH_PARAMETER, "requestwithpath.xq");
String path = COLLECTION_URI + "/requestwithpath.xq/some/path";
System.out.println("--- post to "+path+" --- ");
HttpURLConnection connect = preparePost("boo", path);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String response = readResponse(connect.getInputStream());
System.out.println("--- got response:"+response+"\n -- end response");
String pathInfo = response.substring("pathInfo=".length(), response.indexOf("servletPath=")-2);
String servletPath = response.substring(response.indexOf("servletPath=") + "servletPath=".length(), response.lastIndexOf("\r\n"));
//check the responses
assertEquals("XQuery servletPath is: \"" + servletPath + "\" expected: \"/db/test/requestwithpath.xq\"", "/db/test/requestwithpath.xq", servletPath);
assertEquals("XQuery pathInfo is: \"" + pathInfo + "\" expected: \"/some/path\"", "/some/path", pathInfo);
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testXqueryGetFailWithNonEmptyPath()
{
try
{
/* store the documents that we need for this test */
HttpURLConnection sconnect = getConnection(RESOURCE_URI);
sconnect.setRequestProperty("Authorization", "Basic " + credentials);
sconnect.setRequestMethod("PUT");
sconnect.setDoOutput(true);
sconnect.setRequestProperty("ContentType", "text/xml");
Writer writer = new OutputStreamWriter(sconnect.getOutputStream(), "UTF-8");
writer.write(XML_DATA);
writer.close();
String path = RESOURCE_URI + "/some/path"; // should not be able to get this path
System.out.println("--- retrieving "+path+" should fail --- ");
HttpURLConnection connect = getConnection(path);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 404, r);
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testPut() {
try {
int r = uploadData();
assertEquals("Server returned response code " + r, 201, r);
doGet();
} catch (Exception e) {
fail(e.getMessage());
}
}
private int uploadData() {
try {
System.out.println("--- Storing document ---");
HttpURLConnection connect = getConnection(RESOURCE_URI);
connect.setRequestProperty("Authorization", "Basic " + credentials);
connect.setRequestMethod("PUT");
connect.setDoOutput(true);
connect.setRequestProperty("ContentType", "text/xml");
Writer writer = new OutputStreamWriter(connect.getOutputStream(), "UTF-8");
writer.write(XML_DATA);
writer.close();
connect.connect();
return connect.getResponseCode();
} catch (Exception e) {
fail(e.getMessage());
}
return -1;
}
public void testPutFailAgainstCollection() {
try {
System.out.println("--- Storing document against collection URI - should fail ---");
HttpURLConnection connect = getConnection(COLLECTION_URI);
connect.setRequestProperty("Authorization", "Basic " + credentials);
connect.setRequestMethod("PUT");
connect.setDoOutput(true);
connect.setRequestProperty("ContentType", "text/xml");
Writer writer = new OutputStreamWriter(connect.getOutputStream(), "UTF-8");
writer.write(XML_DATA);
writer.close();
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 400, r);
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testPutWithCharset() {
try {
System.out.println("--- Storing document ---");
HttpURLConnection connect = getConnection(RESOURCE_URI);
connect.setRequestProperty("Authorization", "Basic " + credentials);
connect.setRequestMethod("PUT");
connect.setDoOutput(true);
connect.setRequestProperty("ContentType", "text/xml; charset=UTF-8");
Writer writer = new OutputStreamWriter(connect.getOutputStream(), "UTF-8");
writer.write(XML_DATA);
writer.close();
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 201, r);
doGet();
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testPutFailAndRechallengeAuthorization() {
try {
System.out.println("--- Authenticate with bad credentials ---");
HttpURLConnection connect = getConnection(RESOURCE_URI);
connect.setRequestProperty("Authorization", "Basic " + badCredentials);
connect.setDoOutput(true);
connect.setRequestMethod("PUT");
connect.setAllowUserInteraction(false);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 401, r);
System.out.println("--- Get rechallenged for authentication: basic ---");
String auth = connect.getHeaderField("WWW-Authenticate");
assertEquals("WWW-Authenticate = " + auth, "Basic realm=\"exist\"", auth);
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testXUpdate() {
try {
HttpURLConnection connect = preparePost(XUPDATE, RESOURCE_URI);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
doGet();
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testQueryPost() {
uploadData();
try {
HttpURLConnection connect = preparePost(QUERY_REQUEST, RESOURCE_URI);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String data = readResponse(connect.getInputStream());
System.out.println(data);
int hits = parseResponse(data);
assertEquals(1, hits);
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testQueryPostXQueryError() {
try {
HttpURLConnection connect = preparePost(QUERY_REQUEST_ERROR, RESOURCE_URI);
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 202, r);
System.out.println("--- Get XQuery error code for posted query ---");
System.out.println(readResponse(connect.getInputStream()));
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testQueryGet() {
try {
String uri = COLLECTION_URI
+ "?_query="
+ URLEncoder
.encode(
"doc('"
+ DBBroker.ROOT_COLLECTION
+ "/test/test.xml')//para[. = '\u00E4\u00E4\u00FC\u00FC\u00F6\u00F6\u00C4\u00C4\u00D6\u00D6\u00DC\u00DC']/text()",
"UTF-8");
HttpURLConnection connect = getConnection(uri);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
System.out.println(readResponse(connect.getInputStream()));
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testRequestModule() {
try {
String uri = COLLECTION_URI + "?_query=request:get-uri()&_wrap=no";
HttpURLConnection connect = getConnection(uri);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String response = readResponse(connect.getInputStream()).trim();
assertEquals(response, DBBroker.ROOT_COLLECTION + "/test");
uri = COLLECTION_URI + "?_query=request:get-url()&_wrap=no";
connect = getConnection(uri);
connect.setRequestMethod("GET");
connect.connect();
r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
response = readResponse(connect.getInputStream()).trim();
//TODO : the server name may have been renamed by the Web server
assertEquals(response, SERVER_URI + DBBroker.ROOT_COLLECTION + "/test");
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testRequestGetParameterFromModule()
{
try
{
/* store the documents that we need for this test */
System.out.println("--- Storing xquery and module ---");
doPut(TEST_XQUERY_PARAMETER, "requestparameter.xql");
doPut(TEST_XQUERY_PARAMETER_MODULE, "requestparametermod.xqm");
/* execute the stored xquery a few times */
HttpURLConnection connect;
int iHttpResult;
for(int i=0; i < 5; i++)
{
System.out.println("--- Executing stored xquery, iteration=" + i + " ---");
connect = getConnection(COLLECTION_URI + "/requestparameter.xql?doc=somedoc" + i);
connect.setRequestMethod("GET");
connect.connect();
iHttpResult = connect.getResponseCode();
assertEquals("Server returned response code " + iHttpResult, 200, iHttpResult);
String contentType = connect.getContentType();
int semicolon = contentType.indexOf(';');
if (semicolon > 0) {
contentType = contentType.substring(0, semicolon).trim();
}
assertEquals("Server returned content type " + contentType, "text/xml", contentType);
//get the response of the query
String response = readResponse(connect.getInputStream());
String strXQLRequestParameter = response.substring("xql=".length(), response.indexOf("xqm="));
String strXQMRequestParameter = response.substring(response.indexOf("xqm=") + "xqm=".length(), response.lastIndexOf("\r\n"));
//check the responses
assertEquals("XQuery Request Parameter is: \"" + strXQLRequestParameter + "\" expected: \"somedoc"+i + "\"", "somedoc"+i, strXQLRequestParameter);
assertEquals("XQuery Module Request Parameter is: \"" + strXQMRequestParameter + "\" expected: \"somedoc"+i + "\"", "somedoc"+i, strXQMRequestParameter);
}
}
catch(Exception e)
{
fail(e.getMessage());
}
}
public void testStoredQuery() {
try {
System.out.println("--- Storing query ---");
doPut(TEST_MODULE, "module.xq");
doPut(TEST_XQUERY, "test.xq");
doStoredQuery(false, false);
// cached:
doStoredQuery(true, false);
// cached and wrapped:
doStoredQuery(true, true);
} catch (Exception e) {
fail(e.getMessage());
}
}
protected void doPut(String data, String path) {
try {
HttpURLConnection connect = getConnection(COLLECTION_URI + '/' + path);
connect.setRequestProperty("Authorization", "Basic " + credentials);
connect.setRequestMethod("PUT");
connect.setDoOutput(true);
connect.setRequestProperty("ContentType", "application/xquery");
Writer writer = new OutputStreamWriter(connect.getOutputStream(), "UTF-8");
writer.write(data);
writer.close();
connect.connect();
int r = connect.getResponseCode();
assertEquals("doPut: Server returned response code " + r, 201, r);
} catch (Exception e) {
fail(e.getMessage());
}
}
protected void doStoredQuery(boolean cacheHeader, boolean wrap) {
try {
String uri = COLLECTION_URI + "/test.xq?p=Hello";
if (wrap) {
uri += "&_wrap=yes";
}
System.out.println("--- Calling query: " + uri);
HttpURLConnection connect = getConnection(uri);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
dumpHeaders(connect);
String cached = connect.getHeaderField("X-XQuery-Cached");
System.out.println("X-XQuery-Cached: " + cached);
assertNotNull(cached);
assertEquals(cacheHeader, Boolean.valueOf(cached).booleanValue());
String contentType = connect.getContentType();
int semicolon = contentType.indexOf(';');
if (semicolon > 0) {
contentType = contentType.substring(0, semicolon).trim();
}
if (wrap) {
assertEquals("Server returned content type " + contentType, "text/xml", contentType);
} else {
assertEquals("Server returned content type " + contentType, "text/text", contentType);
}
String response = readResponse(connect.getInputStream());
System.out.println('"' + response + '"');
if (wrap) {
assertTrue ("Server returned response: " + response,
response.startsWith ("<exist:result "));
} else {
assertTrue ("Server returned response: " + response,
response.startsWith ("Hello World!"));
}
} catch (Exception e) {
fail(e.getMessage());
}
}
protected void doGet() {
try {
System.out.println("--- Retrieving document ---");
HttpURLConnection connect = getConnection(RESOURCE_URI);
connect.setRequestMethod("GET");
connect.connect();
int r = connect.getResponseCode();
assertEquals("Server returned response code " + r, 200, r);
String contentType = connect.getContentType();
int semicolon = contentType.indexOf(';');
if (semicolon > 0) {
contentType = contentType.substring(0, semicolon).trim();
}
assertEquals("Server returned content type " + contentType, "text/xml", contentType);
System.out.println(readResponse(connect.getInputStream()));
} catch (Exception e) {
fail(e.getMessage());
}
}
protected HttpURLConnection preparePost(String content, String path) {
try {
HttpURLConnection connect = getConnection(path);
connect.setRequestProperty("Authorization", "Basic " + credentials);
connect.setRequestMethod("POST");
connect.setDoOutput(true);
connect.setRequestProperty("ContentType", "text/xml");
Writer writer = new OutputStreamWriter(connect.getOutputStream(), "UTF-8");
writer.write(content);
writer.close();
return connect;
} catch (Exception e) {
fail(e.getMessage());
}
return null;
}
protected String readResponse(InputStream is) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String line;
StringBuffer out = new StringBuffer();
while ((line = reader.readLine()) != null) {
out.append(line);
out.append("\r\n");
}
return out.toString();
} catch (Exception e) {
fail(e.getMessage());
}
return null;
}
protected int parseResponse(String data) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
InputSource src = new InputSource(new StringReader(data));
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
SAXAdapter adapter = new SAXAdapter();
reader.setContentHandler(adapter);
reader.parse(src);
Document doc = adapter.getDocument();
Element root = doc.getDocumentElement();
String hits = root.getAttributeNS(Namespaces.EXIST_NS, "hits");
return Integer.parseInt(hits);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
return 0;
}
protected HttpURLConnection getConnection(String url) {
try {
URL u = new URL(url);
return (HttpURLConnection) u.openConnection();
} catch (Exception e) {
fail(e.getMessage());
}
return null;
}
protected void dumpHeaders(HttpURLConnection connect) {
Map headers = connect.getHeaderFields();
for (Iterator i = headers.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry) i.next();
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public static void main(String[] args) {
TestRunner.run(RESTServiceTest.class);
//Explicit shutdown for the shutdown hook
System.exit(0);
}
}