View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18   
19  package org.apache.hadoop.hbase.http;
20  
21  import org.apache.hadoop.net.NetUtils;
22  import org.apache.hadoop.security.authorize.AccessControlList;
23  import org.junit.Assert;
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.http.HttpServer.Builder;
26  
27  import java.io.File;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.net.URI;
31  import java.net.URL;
32  import java.net.MalformedURLException;
33  
34  /**
35   * This is a base class for functional tests of the {@link HttpServer}.
36   * The methods are static for other classes to import statically.
37   */
38  public class HttpServerFunctionalTest extends Assert {
39    /** JVM property for the webapp test dir : {@value} */
40    public static final String TEST_BUILD_WEBAPPS = "test.build.webapps";
41    /** expected location of the test.build.webapps dir: {@value} */
42    private static final String BUILD_WEBAPPS_DIR = "build/test/webapps";
43    
44    /** name of the test webapp: {@value} */
45    private static final String TEST = "test";
46  
47    /**
48     * Create but do not start the test webapp server. The test webapp dir is
49     * prepared/checked in advance.
50     *
51     * @return the server instance
52     *
53     * @throws IOException if a problem occurs
54     * @throws AssertionError if a condition was not met
55     */
56    public static HttpServer createTestServer() throws IOException {
57      prepareTestWebapp();
58      return createServer(TEST);
59    }
60  
61    /**
62     * Create but do not start the test webapp server. The test webapp dir is
63     * prepared/checked in advance.
64     * @param conf the server configuration to use
65     * @return the server instance
66     *
67     * @throws IOException if a problem occurs
68     * @throws AssertionError if a condition was not met
69     */
70    public static HttpServer createTestServer(Configuration conf)
71        throws IOException {
72      prepareTestWebapp();
73      return createServer(TEST, conf);
74    }
75  
76    public static HttpServer createTestServer(Configuration conf, AccessControlList adminsAcl)
77        throws IOException {
78      prepareTestWebapp();
79      return createServer(TEST, conf, adminsAcl);
80    }
81  
82    /**
83     * Create but do not start the test webapp server. The test webapp dir is
84     * prepared/checked in advance.
85     * @param conf the server configuration to use
86     * @return the server instance
87     *
88     * @throws IOException if a problem occurs
89     * @throws AssertionError if a condition was not met
90     */
91    public static HttpServer createTestServer(Configuration conf, 
92        String[] pathSpecs) throws IOException {
93      prepareTestWebapp();
94      return createServer(TEST, conf, pathSpecs);
95    }
96  
97    /**
98     * Prepare the test webapp by creating the directory from the test properties
99     * fail if the directory cannot be created.
100    * @throws AssertionError if a condition was not met
101    */
102   protected static void prepareTestWebapp() {
103     String webapps = System.getProperty(TEST_BUILD_WEBAPPS, BUILD_WEBAPPS_DIR);
104     File testWebappDir = new File(webapps +
105         File.separatorChar + TEST);
106     try {
107     if (!testWebappDir.exists()) {
108       fail("Test webapp dir " + testWebappDir.getCanonicalPath() + " missing");
109     }
110     }
111     catch (IOException e) {
112     }
113   }
114 
115   /**
116    * Create an HttpServer instance on the given address for the given webapp
117    * @param host to bind
118    * @param port to bind
119    * @return the server
120    * @throws IOException if it could not be created
121    */
122   public static HttpServer createServer(String host, int port)
123       throws IOException {
124     prepareTestWebapp();
125     return new HttpServer.Builder().setName(TEST)
126         .addEndpoint(URI.create("http://" + host + ":" + port))
127         .setFindPort(true).build();
128   }
129 
130   /**
131    * Create an HttpServer instance for the given webapp
132    * @param webapp the webapp to work with
133    * @return the server
134    * @throws IOException if it could not be created
135    */
136   public static HttpServer createServer(String webapp) throws IOException {
137     return localServerBuilder(webapp).setFindPort(true).build();
138   }
139   /**
140    * Create an HttpServer instance for the given webapp
141    * @param webapp the webapp to work with
142    * @param conf the configuration to use for the server
143    * @return the server
144    * @throws IOException if it could not be created
145    */
146   public static HttpServer createServer(String webapp, Configuration conf)
147       throws IOException {
148     return localServerBuilder(webapp).setFindPort(true).setConf(conf).build();
149   }
150 
151   public static HttpServer createServer(String webapp, Configuration conf, AccessControlList adminsAcl)
152       throws IOException {
153     return localServerBuilder(webapp).setFindPort(true).setConf(conf).setACL(adminsAcl).build();
154   }
155 
156   private static Builder localServerBuilder(String webapp) {
157     return new HttpServer.Builder().setName(webapp).addEndpoint(
158         URI.create("http://localhost:0"));
159   }
160   
161   /**
162    * Create an HttpServer instance for the given webapp
163    * @param webapp the webapp to work with
164    * @param conf the configuration to use for the server
165    * @param pathSpecs the paths specifications the server will service
166    * @return the server
167    * @throws IOException if it could not be created
168    */
169   public static HttpServer createServer(String webapp, Configuration conf,
170       String[] pathSpecs) throws IOException {
171     return localServerBuilder(webapp).setFindPort(true).setConf(conf).setPathSpec(pathSpecs).build();
172   }
173 
174   /**
175    * Create and start a server with the test webapp
176    *
177    * @return the newly started server
178    *
179    * @throws IOException on any failure
180    * @throws AssertionError if a condition was not met
181    */
182   public static HttpServer createAndStartTestServer() throws IOException {
183     HttpServer server = createTestServer();
184     server.start();
185     return server;
186   }
187 
188   /**
189    * If the server is non null, stop it
190    * @param server to stop
191    * @throws Exception on any failure
192    */
193   public static void stop(HttpServer server) throws Exception {
194     if (server != null) {
195       server.stop();
196     }
197   }
198 
199   /**
200    * Pass in a server, return a URL bound to localhost and its port
201    * @param server server
202    * @return a URL bonded to the base of the server
203    * @throws MalformedURLException if the URL cannot be created.
204    */
205   public static URL getServerURL(HttpServer server)
206       throws MalformedURLException {
207     assertNotNull("No server", server);
208     return new URL("http://"
209         + NetUtils.getHostPortString(server.getConnectorAddress(0)));
210   }
211 
212   /**
213    * Read in the content from a URL
214    * @param url URL To read
215    * @return the text from the output
216    * @throws IOException if something went wrong
217    */
218   protected static String readOutput(URL url) throws IOException {
219     StringBuilder out = new StringBuilder();
220     InputStream in = url.openConnection().getInputStream();
221     byte[] buffer = new byte[64 * 1024];
222     int len = in.read(buffer);
223     while (len > 0) {
224       out.append(new String(buffer, 0, len));
225       len = in.read(buffer);
226     }
227     return out.toString();
228   }
229 }