http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java new file mode 100644 index 0000000..4fad031 --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestSpnegoHttpServer.java @@ -0,0 +1,258 @@ +/* + * 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.hbase.http; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.Principal; +import java.security.PrivilegedExceptionAction; +import java.util.Set; + +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosTicket; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.http.TestHttpServer.EchoServlet; +import org.apache.hadoop.hbase.http.resource.JerseyResource; +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.security.authentication.util.KerberosName; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthSchemeProvider; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.KerberosCredentials; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.config.Lookup; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.auth.SPNegoSchemeFactory; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.apache.kerby.kerberos.kerb.KrbException; +import org.apache.kerby.kerberos.kerb.client.JaasKrbUtil; +import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Test class for SPNEGO authentication on the HttpServer. Uses Kerby's MiniKDC and Apache + * HttpComponents to verify that a simple Servlet is reachable via SPNEGO and unreachable w/o. + */ +@Category({MiscTests.class, SmallTests.class}) +public class TestSpnegoHttpServer extends HttpServerFunctionalTest { + private static final Log LOG = LogFactory.getLog(TestSpnegoHttpServer.class); + private static final String KDC_SERVER_HOST = "localhost"; + private static final String CLIENT_PRINCIPAL = "client"; + + private static HttpServer server; + private static URL baseUrl; + private static SimpleKdcServer kdc; + private static File infoServerKeytab; + private static File clientKeytab; + + @BeforeClass + public static void setupServer() throws Exception { + final String serverPrincipal = "HTTP/" + KDC_SERVER_HOST; + final File target = new File(System.getProperty("user.dir"), "target"); + assertTrue(target.exists()); + + kdc = buildMiniKdc(); + kdc.start(); + + File keytabDir = new File(target, TestSpnegoHttpServer.class.getSimpleName() + + "_keytabs"); + if (keytabDir.exists()) { + deleteRecursively(keytabDir); + } + keytabDir.mkdirs(); + + infoServerKeytab = new File(keytabDir, serverPrincipal.replace('/', '_') + ".keytab"); + clientKeytab = new File(keytabDir, CLIENT_PRINCIPAL + ".keytab"); + + setupUser(kdc, clientKeytab, CLIENT_PRINCIPAL); + setupUser(kdc, infoServerKeytab, serverPrincipal); + + Configuration conf = buildSpnegoConfiguration(serverPrincipal, infoServerKeytab); + + server = createTestServerWithSecurity(conf); + server.addServlet("echo", "/echo", EchoServlet.class); + server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), "/jersey/*"); + server.start(); + baseUrl = getServerURL(server); + + LOG.info("HTTP server started: "+ baseUrl); + } + + @AfterClass + public static void stopServer() throws Exception { + try { + if (null != server) { + server.stop(); + } + } catch (Exception e) { + LOG.info("Failed to stop info server", e); + } + try { + if (null != kdc) { + kdc.stop(); + } + } catch (Exception e) { + LOG.info("Failed to stop mini KDC", e); + } + } + + private static void setupUser(SimpleKdcServer kdc, File keytab, String principal) + throws KrbException { + kdc.createPrincipal(principal); + kdc.exportPrincipal(principal, keytab); + } + + private static SimpleKdcServer buildMiniKdc() throws Exception { + SimpleKdcServer kdc = new SimpleKdcServer(); + + final File target = new File(System.getProperty("user.dir"), "target"); + File kdcDir = new File(target, TestSpnegoHttpServer.class.getSimpleName()); + if (kdcDir.exists()) { + deleteRecursively(kdcDir); + } + kdcDir.mkdirs(); + kdc.setWorkDir(kdcDir); + + kdc.setKdcHost(KDC_SERVER_HOST); + int kdcPort = getFreePort(); + kdc.setAllowTcp(true); + kdc.setAllowUdp(false); + kdc.setKdcTcpPort(kdcPort); + + LOG.info("Starting KDC server at " + KDC_SERVER_HOST + ":" + kdcPort); + + kdc.init(); + + return kdc; + } + + private static Configuration buildSpnegoConfiguration(String serverPrincipal, File + serverKeytab) { + Configuration conf = new Configuration(); + KerberosName.setRules("DEFAULT"); + + conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS); + + // Enable Kerberos (pre-req) + conf.set("hbase.security.authentication", "kerberos"); + conf.set(HttpServer.HTTP_UI_AUTHENTICATION, "kerberos"); + conf.set(HttpServer.HTTP_SPNEGO_AUTHENTICATION_PRINCIPAL_KEY, serverPrincipal); + conf.set(HttpServer.HTTP_SPNEGO_AUTHENTICATION_KEYTAB_KEY, serverKeytab.getAbsolutePath()); + + return conf; + } + + @Test + public void testUnauthorizedClientsDisallowed() throws IOException { + URL url = new URL(getServerURL(server), "/echo?a=b"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode()); + } + + @Test + public void testAllowedClient() throws Exception { + // Create the subject for the client + final Subject clientSubject = JaasKrbUtil.loginUsingKeytab(CLIENT_PRINCIPAL, clientKeytab); + final Set<Principal> clientPrincipals = clientSubject.getPrincipals(); + // Make sure the subject has a principal + assertFalse(clientPrincipals.isEmpty()); + + // Get a TGT for the subject (might have many, different encryption types). The first should + // be the default encryption type. + Set<KerberosTicket> privateCredentials = + clientSubject.getPrivateCredentials(KerberosTicket.class); + assertFalse(privateCredentials.isEmpty()); + KerberosTicket tgt = privateCredentials.iterator().next(); + assertNotNull(tgt); + + // The name of the principal + final String principalName = clientPrincipals.iterator().next().getName(); + + // Run this code, logged in as the subject (the client) + HttpResponse resp = Subject.doAs(clientSubject, + new PrivilegedExceptionAction<HttpResponse>() { + @Override + public HttpResponse run() throws Exception { + // Logs in with Kerberos via GSS + GSSManager gssManager = GSSManager.getInstance(); + // jGSS Kerberos login constant + Oid oid = new Oid("1.2.840.113554.1.2.2"); + GSSName gssClient = gssManager.createName(principalName, GSSName.NT_USER_NAME); + GSSCredential credential = gssManager.createCredential(gssClient, + GSSCredential.DEFAULT_LIFETIME, oid, GSSCredential.INITIATE_ONLY); + + HttpClientContext context = HttpClientContext.create(); + Lookup<AuthSchemeProvider> authRegistry = RegistryBuilder.<AuthSchemeProvider>create() + .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true, true)) + .build(); + + HttpClient client = HttpClients.custom().setDefaultAuthSchemeRegistry(authRegistry).build(); + BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new KerberosCredentials(credential)); + + URL url = new URL(getServerURL(server), "/echo?a=b"); + context.setTargetHost(new HttpHost(url.getHost(), url.getPort())); + context.setCredentialsProvider(credentialsProvider); + context.setAuthSchemeRegistry(authRegistry); + + HttpGet get = new HttpGet(url.toURI()); + return client.execute(get, context); + } + }); + + assertNotNull(resp); + assertEquals(HttpURLConnection.HTTP_OK, resp.getStatusLine().getStatusCode()); + assertEquals("a:b", EntityUtils.toString(resp.getEntity()).trim()); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingConfigurationThrowsException() throws Exception { + Configuration conf = new Configuration(); + conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS); + // Enable Kerberos (pre-req) + conf.set("hbase.security.authentication", "kerberos"); + // Intentionally skip keytab and principal + + HttpServer customServer = createTestServerWithSecurity(conf); + customServer.addServlet("echo", "/echo", EchoServlet.class); + customServer.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), "/jersey/*"); + customServer.start(); + } +}
http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java new file mode 100644 index 0000000..8bd1e6d --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/conf/TestConfServlet.java @@ -0,0 +1,116 @@ +/** + * 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.hbase.http.conf; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import junit.framework.TestCase; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.eclipse.jetty.util.ajax.JSON; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * Basic test case that the ConfServlet can write configuration + * to its output in XML and JSON format. + */ +@Category({MiscTests.class, SmallTests.class}) +public class TestConfServlet extends TestCase { + private static final String TEST_KEY = "testconfservlet.key"; + private static final String TEST_VAL = "testval"; + + private Configuration getTestConf() { + Configuration testConf = new Configuration(); + testConf.set(TEST_KEY, TEST_VAL); + return testConf; + } + + @Test + @SuppressWarnings("unchecked") + public void testWriteJson() throws Exception { + StringWriter sw = new StringWriter(); + ConfServlet.writeResponse(getTestConf(), sw, "json"); + String json = sw.toString(); + boolean foundSetting = false; + Object parsed = JSON.parse(json); + Object[] properties = ((Map<String, Object[]>)parsed).get("properties"); + for (Object o : properties) { + Map<String, Object> propertyInfo = (Map<String, Object>)o; + String key = (String)propertyInfo.get("key"); + String val = (String)propertyInfo.get("value"); + String resource = (String)propertyInfo.get("resource"); + System.err.println("k: " + key + " v: " + val + " r: " + resource); + if (TEST_KEY.equals(key) && TEST_VAL.equals(val) + && "programatically".equals(resource)) { + foundSetting = true; + } + } + assertTrue(foundSetting); + } + + @Test + public void testWriteXml() throws Exception { + StringWriter sw = new StringWriter(); + ConfServlet.writeResponse(getTestConf(), sw, "xml"); + String xml = sw.toString(); + + DocumentBuilderFactory docBuilderFactory + = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xml))); + NodeList nameNodes = doc.getElementsByTagName("name"); + boolean foundSetting = false; + for (int i = 0; i < nameNodes.getLength(); i++) { + Node nameNode = nameNodes.item(i); + String key = nameNode.getTextContent(); + System.err.println("xml key: " + key); + if (TEST_KEY.equals(key)) { + foundSetting = true; + Element propertyElem = (Element)nameNode.getParentNode(); + String val = propertyElem.getElementsByTagName("value").item(0).getTextContent(); + assertEquals(TEST_VAL, val); + } + } + assertTrue(foundSetting); + } + + @Test + public void testBadFormat() throws Exception { + StringWriter sw = new StringWriter(); + try { + ConfServlet.writeResponse(getTestConf(), sw, "not a format"); + fail("writeResponse with bad format didn't throw!"); + } catch (ConfServlet.BadFormatException bfe) { + // expected + } + assertEquals("", sw.toString()); + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/jmx/TestJMXJsonServlet.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/jmx/TestJMXJsonServlet.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/jmx/TestJMXJsonServlet.java new file mode 100644 index 0000000..484162a --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/jmx/TestJMXJsonServlet.java @@ -0,0 +1,134 @@ +/* + * 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.hbase.http.jmx; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.http.HttpServer; +import org.apache.hadoop.hbase.http.HttpServerFunctionalTest; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category({MiscTests.class, SmallTests.class}) +public class TestJMXJsonServlet extends HttpServerFunctionalTest { + private static final Log LOG = LogFactory.getLog(TestJMXJsonServlet.class); + private static HttpServer server; + private static URL baseUrl; + + @BeforeClass public static void setup() throws Exception { + // Eclipse doesn't pick this up correctly from the plugin + // configuration in the pom. + System.setProperty(HttpServerFunctionalTest.TEST_BUILD_WEBAPPS, "target/test-classes/webapps"); + server = createTestServer(); + server.start(); + baseUrl = getServerURL(server); + } + + @AfterClass public static void cleanup() throws Exception { + server.stop(); + } + + public static void assertReFind(String re, String value) { + Pattern p = Pattern.compile(re); + Matcher m = p.matcher(value); + assertTrue("'"+p+"' does not match "+value, m.find()); + } + + @Test public void testQuery() throws Exception { + String result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Runtime")); + LOG.info("/jmx?qry=java.lang:type=Runtime RESULT: "+result); + assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Runtime\"", result); + assertReFind("\"modelerType\"", result); + + result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Memory")); + LOG.info("/jmx?qry=java.lang:type=Memory RESULT: "+result); + assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result); + assertReFind("\"modelerType\"", result); + + result = readOutput(new URL(baseUrl, "/jmx")); + LOG.info("/jmx RESULT: "+result); + assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result); + + // test to get an attribute of a mbean + result = readOutput(new URL(baseUrl, + "/jmx?get=java.lang:type=Memory::HeapMemoryUsage")); + LOG.info("/jmx RESULT: "+result); + assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result); + assertReFind("\"committed\"\\s*:", result); + + // negative test to get an attribute of a mbean + result = readOutput(new URL(baseUrl, + "/jmx?get=java.lang:type=Memory::")); + LOG.info("/jmx RESULT: "+result); + assertReFind("\"ERROR\"", result); + + // test to get JSONP result + result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Memory&callback=mycallback1")); + LOG.info("/jmx?qry=java.lang:type=Memory&callback=mycallback RESULT: "+result); + assertReFind("^mycallback1\\(\\{", result); + assertReFind("\\}\\);$", result); + + // negative test to get an attribute of a mbean as JSONP + result = readOutput(new URL(baseUrl, + "/jmx?get=java.lang:type=Memory::&callback=mycallback2")); + LOG.info("/jmx RESULT: "+result); + assertReFind("^mycallback2\\(\\{", result); + assertReFind("\"ERROR\"", result); + assertReFind("\\}\\);$", result); + + // test to get an attribute of a mbean as JSONP + result = readOutput(new URL(baseUrl, + "/jmx?get=java.lang:type=Memory::HeapMemoryUsage&callback=mycallback3")); + LOG.info("/jmx RESULT: "+result); + assertReFind("^mycallback3\\(\\{", result); + assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result); + assertReFind("\"committed\"\\s*:", result); + assertReFind("\\}\\);$", result); + + } + + @Test + public void testDisallowedJSONPCallback() throws Exception { + String callback = "function(){alert('bigproblems!')};foo"; + URL url = new URL( + baseUrl, "/jmx?qry=java.lang:type=Memory&callback="+URLEncoder.encode(callback, "UTF-8")); + HttpURLConnection cnxn = (HttpURLConnection) url.openConnection(); + assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, cnxn.getResponseCode()); + } + + @Test + public void testUnderscoresInJSONPCallback() throws Exception { + String callback = "my_function"; + URL url = new URL( + baseUrl, "/jmx?qry=java.lang:type=Memory&callback="+URLEncoder.encode(callback, "UTF-8")); + HttpURLConnection cnxn = (HttpURLConnection) url.openConnection(); + assertEquals(HttpServletResponse.SC_OK, cnxn.getResponseCode()); + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/lib/TestStaticUserWebFilter.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/lib/TestStaticUserWebFilter.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/lib/TestStaticUserWebFilter.java new file mode 100644 index 0000000..3adca50 --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/lib/TestStaticUserWebFilter.java @@ -0,0 +1,86 @@ +/** + * 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.hbase.http.lib; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeys; +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.http.ServerConfigurationKeys; +import org.apache.hadoop.hbase.http.lib.StaticUserWebFilter.StaticUserFilter; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +@Category({MiscTests.class, SmallTests.class}) +public class TestStaticUserWebFilter { + private FilterConfig mockConfig(String username) { + FilterConfig mock = Mockito.mock(FilterConfig.class); + Mockito.doReturn(username).when(mock).getInitParameter( + ServerConfigurationKeys.HBASE_HTTP_STATIC_USER); + return mock; + } + + @Test + public void testFilter() throws Exception { + FilterConfig config = mockConfig("myuser"); + StaticUserFilter suf = new StaticUserFilter(); + suf.init(config); + + ArgumentCaptor<HttpServletRequestWrapper> wrapperArg = + ArgumentCaptor.forClass(HttpServletRequestWrapper.class); + + FilterChain chain = mock(FilterChain.class); + + suf.doFilter(mock(HttpServletRequest.class), mock(ServletResponse.class), + chain); + + Mockito.verify(chain).doFilter(wrapperArg.capture(), Mockito.<ServletResponse>anyObject()); + + HttpServletRequestWrapper wrapper = wrapperArg.getValue(); + assertEquals("myuser", wrapper.getUserPrincipal().getName()); + assertEquals("myuser", wrapper.getRemoteUser()); + + suf.destroy(); + } + + @Test + public void testOldStyleConfiguration() { + Configuration conf = new Configuration(); + conf.set("dfs.web.ugi", "joe,group1,group2"); + assertEquals("joe", StaticUserWebFilter.getUsernameFromConf(conf)); + } + + @Test + public void testConfiguration() { + Configuration conf = new Configuration(); + conf.set(CommonConfigurationKeys.HADOOP_HTTP_STATIC_USER, "dr.stack"); + assertEquals("dr.stack", StaticUserWebFilter.getUsernameFromConf(conf)); + } + +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java new file mode 100644 index 0000000..e14e3b4 --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java @@ -0,0 +1,92 @@ +/** +* 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.hbase.http.log; + +import static org.junit.Assert.assertTrue; + +import java.io.*; +import java.net.*; + +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.http.HttpServer; +import org.apache.hadoop.net.NetUtils; +import org.apache.commons.logging.*; +import org.apache.commons.logging.impl.*; +import org.apache.log4j.*; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category({MiscTests.class, SmallTests.class}) +public class TestLogLevel { + static final PrintStream out = System.out; + + @Test (timeout=60000) + @SuppressWarnings("deprecation") + public void testDynamicLogLevel() throws Exception { + String logName = TestLogLevel.class.getName(); + Log testlog = LogFactory.getLog(logName); + + //only test Log4JLogger + if (testlog instanceof Log4JLogger) { + Logger log = ((Log4JLogger)testlog).getLogger(); + log.debug("log.debug1"); + log.info("log.info1"); + log.error("log.error1"); + assertTrue(!Level.ERROR.equals(log.getEffectiveLevel())); + + HttpServer server = null; + try { + server = new HttpServer.Builder().setName("..") + .addEndpoint(new URI("http://localhost:0")).setFindPort(true) + .build(); + + server.start(); + String authority = NetUtils.getHostPortString(server + .getConnectorAddress(0)); + + //servlet + URL url = + new URL("http://" + authority + "/logLevel?log=" + logName + "&level=" + Level.ERROR); + out.println("*** Connecting to " + url); + try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) { + for(String line; (line = in.readLine()) != null; out.println(line)); + } + log.debug("log.debug2"); + log.info("log.info2"); + log.error("log.error2"); + assertTrue(Level.ERROR.equals(log.getEffectiveLevel())); + + //command line + String[] args = {"-setlevel", authority, logName, Level.DEBUG.toString()}; + LogLevel.main(args); + log.debug("log.debug3"); + log.info("log.info3"); + log.error("log.error3"); + assertTrue(Level.DEBUG.equals(log.getEffectiveLevel())); + } finally { + if (server != null) { + server.stop(); + } + } + } + else { + out.println(testlog.getClass() + " not tested."); + } + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java new file mode 100644 index 0000000..bf0e609 --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/resource/JerseyResource.java @@ -0,0 +1,64 @@ +/** + * 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.hbase.http.resource; + +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.jetty.util.ajax.JSON; + +/** + * A simple Jersey resource class TestHttpServer. + * The servlet simply puts the path and the op parameter in a map + * and return it in JSON format in the response. + */ +@Path("") +public class JerseyResource { + private static final Log LOG = LogFactory.getLog(JerseyResource.class); + + public static final String PATH = "path"; + public static final String OP = "op"; + + @GET + @Path("{" + PATH + ":.*}") + @Produces({MediaType.APPLICATION_JSON}) + public Response get( + @PathParam(PATH) @DefaultValue("UNKNOWN_" + PATH) final String path, + @QueryParam(OP) @DefaultValue("UNKNOWN_" + OP) final String op + ) throws IOException { + LOG.info("get: " + PATH + "=" + path + ", " + OP + "=" + op); + + final Map<String, Object> m = new TreeMap<>(); + m.put(PATH, path); + m.put(OP, op); + final String js = JSON.toString(m); + return Response.ok(js).type(MediaType.APPLICATION_JSON).build(); + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java new file mode 100644 index 0000000..35d6236 --- /dev/null +++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/ssl/KeyStoreTestUtil.java @@ -0,0 +1,342 @@ +/** + * 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.hbase.http.ssl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.math.BigInteger; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.x500.X500Principal; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory; +import org.apache.hadoop.security.ssl.SSLFactory; +import org.bouncycastle.x509.X509V1CertificateGenerator; + +public class KeyStoreTestUtil { + + public static String getClasspathDir(Class<?> klass) throws Exception { + String file = klass.getName(); + file = file.replace('.', '/') + ".class"; + URL url = Thread.currentThread().getContextClassLoader().getResource(file); + String baseDir = url.toURI().getPath(); + baseDir = baseDir.substring(0, baseDir.length() - file.length() - 1); + return baseDir; + } + + /** + * Create a self-signed X.509 Certificate. + * + * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB" + * @param pair the KeyPair + * @param days how many days from now the Certificate is valid for + * @param algorithm the signing algorithm, eg "SHA1withRSA" + * @return the self-signed certificate + */ + public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm) + throws CertificateEncodingException, InvalidKeyException, IllegalStateException, + NoSuchProviderException, NoSuchAlgorithmException, SignatureException { + Date from = new Date(); + Date to = new Date(from.getTime() + days * 86400000l); + BigInteger sn = new BigInteger(64, new SecureRandom()); + KeyPair keyPair = pair; + X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); + X500Principal dnName = new X500Principal(dn); + + certGen.setSerialNumber(sn); + certGen.setIssuerDN(dnName); + certGen.setNotBefore(from); + certGen.setNotAfter(to); + certGen.setSubjectDN(dnName); + certGen.setPublicKey(keyPair.getPublic()); + certGen.setSignatureAlgorithm(algorithm); + X509Certificate cert = certGen.generate(pair.getPrivate()); + return cert; + } + + public static KeyPair generateKeyPair(String algorithm) + throws NoSuchAlgorithmException { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm); + keyGen.initialize(1024); + return keyGen.genKeyPair(); + } + + private static KeyStore createEmptyKeyStore() + throws GeneralSecurityException, IOException { + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); // initialize + return ks; + } + + private static void saveKeyStore(KeyStore ks, String filename, + String password) + throws GeneralSecurityException, IOException { + FileOutputStream out = new FileOutputStream(filename); + try { + ks.store(out, password.toCharArray()); + } finally { + out.close(); + } + } + + public static void createKeyStore(String filename, + String password, String alias, + Key privateKey, Certificate cert) + throws GeneralSecurityException, IOException { + KeyStore ks = createEmptyKeyStore(); + ks.setKeyEntry(alias, privateKey, password.toCharArray(), + new Certificate[]{cert}); + saveKeyStore(ks, filename, password); + } + + /** + * Creates a keystore with a single key and saves it to a file. + * + * @param filename String file to save + * @param password String store password to set on keystore + * @param keyPassword String key password to set on key + * @param alias String alias to use for the key + * @param privateKey Key to save in keystore + * @param cert Certificate to use as certificate chain associated to key + * @throws GeneralSecurityException for any error with the security APIs + * @throws IOException if there is an I/O error saving the file + */ + public static void createKeyStore(String filename, + String password, String keyPassword, String alias, + Key privateKey, Certificate cert) + throws GeneralSecurityException, IOException { + KeyStore ks = createEmptyKeyStore(); + ks.setKeyEntry(alias, privateKey, keyPassword.toCharArray(), + new Certificate[]{cert}); + saveKeyStore(ks, filename, password); + } + + public static void createTrustStore(String filename, + String password, String alias, + Certificate cert) + throws GeneralSecurityException, IOException { + KeyStore ks = createEmptyKeyStore(); + ks.setCertificateEntry(alias, cert); + saveKeyStore(ks, filename, password); + } + + public static <T extends Certificate> void createTrustStore( + String filename, String password, Map<String, T> certs) + throws GeneralSecurityException, IOException { + KeyStore ks = createEmptyKeyStore(); + for (Map.Entry<String, T> cert : certs.entrySet()) { + ks.setCertificateEntry(cert.getKey(), cert.getValue()); + } + saveKeyStore(ks, filename, password); + } + + public static void cleanupSSLConfig(String keystoresDir, String sslConfDir) + throws Exception { + File f = new File(keystoresDir + "/clientKS.jks"); + f.delete(); + f = new File(keystoresDir + "/serverKS.jks"); + f.delete(); + f = new File(keystoresDir + "/trustKS.jks"); + f.delete(); + f = new File(sslConfDir + "/ssl-client.xml"); + f.delete(); + f = new File(sslConfDir + "/ssl-server.xml"); + f.delete(); + } + + /** + * Performs complete setup of SSL configuration in preparation for testing an + * SSLFactory. This includes keys, certs, keystores, truststores, the server + * SSL configuration file, the client SSL configuration file, and the master + * configuration file read by the SSLFactory. + * + * @param keystoresDir String directory to save keystores + * @param sslConfDir String directory to save SSL configuration files + * @param conf Configuration master configuration to be used by an SSLFactory, + * which will be mutated by this method + * @param useClientCert boolean true to make the client present a cert in the + * SSL handshake + */ + public static void setupSSLConfig(String keystoresDir, String sslConfDir, + Configuration conf, boolean useClientCert) + throws Exception { + String clientKS = keystoresDir + "/clientKS.jks"; + String clientPassword = "clientP"; + String serverKS = keystoresDir + "/serverKS.jks"; + String serverPassword = "serverP"; + String trustKS = keystoresDir + "/trustKS.jks"; + String trustPassword = "trustP"; + + File sslClientConfFile = new File(sslConfDir + "/ssl-client.xml"); + File sslServerConfFile = new File(sslConfDir + "/ssl-server.xml"); + + Map<String, X509Certificate> certs = new HashMap<>(); + + if (useClientCert) { + KeyPair cKP = KeyStoreTestUtil.generateKeyPair("RSA"); + X509Certificate cCert = + KeyStoreTestUtil.generateCertificate("CN=localhost, O=client", cKP, 30, + "SHA1withRSA"); + KeyStoreTestUtil.createKeyStore(clientKS, clientPassword, "client", + cKP.getPrivate(), cCert); + certs.put("client", cCert); + } + + KeyPair sKP = KeyStoreTestUtil.generateKeyPair("RSA"); + X509Certificate sCert = + KeyStoreTestUtil.generateCertificate("CN=localhost, O=server", sKP, 30, + "SHA1withRSA"); + KeyStoreTestUtil.createKeyStore(serverKS, serverPassword, "server", + sKP.getPrivate(), sCert); + certs.put("server", sCert); + + KeyStoreTestUtil.createTrustStore(trustKS, trustPassword, certs); + + Configuration clientSSLConf = createClientSSLConfig(clientKS, clientPassword, + clientPassword, trustKS); + Configuration serverSSLConf = createServerSSLConfig(serverKS, serverPassword, + serverPassword, trustKS); + + saveConfig(sslClientConfFile, clientSSLConf); + saveConfig(sslServerConfFile, serverSSLConf); + + conf.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL"); + conf.set(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfFile.getName()); + conf.set(SSLFactory.SSL_SERVER_CONF_KEY, sslServerConfFile.getName()); + conf.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, useClientCert); + } + + /** + * Creates SSL configuration for a client. + * + * @param clientKS String client keystore file + * @param password String store password, or null to avoid setting store + * password + * @param keyPassword String key password, or null to avoid setting key + * password + * @param trustKS String truststore file + * @return Configuration for client SSL + */ + public static Configuration createClientSSLConfig(String clientKS, + String password, String keyPassword, String trustKS) { + Configuration clientSSLConf = createSSLConfig(SSLFactory.Mode.CLIENT, + clientKS, password, keyPassword, trustKS); + return clientSSLConf; + } + + /** + * Creates SSL configuration for a server. + * + * @param serverKS String server keystore file + * @param password String store password, or null to avoid setting store + * password + * @param keyPassword String key password, or null to avoid setting key + * password + * @param trustKS String truststore file + * @return Configuration for server SSL + */ + public static Configuration createServerSSLConfig(String serverKS, + String password, String keyPassword, String trustKS) throws IOException { + Configuration serverSSLConf = createSSLConfig(SSLFactory.Mode.SERVER, + serverKS, password, keyPassword, trustKS); + return serverSSLConf; + } + + /** + * Creates SSL configuration. + * + * @param mode SSLFactory.Mode mode to configure + * @param keystore String keystore file + * @param password String store password, or null to avoid setting store + * password + * @param keyPassword String key password, or null to avoid setting key + * password + * @param trustKS String truststore file + * @return Configuration for SSL + */ + private static Configuration createSSLConfig(SSLFactory.Mode mode, + String keystore, String password, String keyPassword, String trustKS) { + String trustPassword = "trustP"; + + Configuration sslConf = new Configuration(false); + if (keystore != null) { + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_KEYSTORE_LOCATION_TPL_KEY), keystore); + } + if (password != null) { + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_KEYSTORE_PASSWORD_TPL_KEY), password); + } + if (keyPassword != null) { + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_KEYSTORE_KEYPASSWORD_TPL_KEY), + keyPassword); + } + if (trustKS != null) { + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_TRUSTSTORE_LOCATION_TPL_KEY), trustKS); + } + if (trustPassword != null) { + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_TRUSTSTORE_PASSWORD_TPL_KEY), + trustPassword); + } + sslConf.set(FileBasedKeyStoresFactory.resolvePropertyName(mode, + FileBasedKeyStoresFactory.SSL_TRUSTSTORE_RELOAD_INTERVAL_TPL_KEY), "1000"); + + return sslConf; + } + + /** + * Saves configuration to a file. + * + * @param file File to save + * @param conf Configuration contents to write to file + * @throws IOException if there is an I/O error saving the file + */ + public static void saveConfig(File file, Configuration conf) + throws IOException { + Writer writer = new FileWriter(file); + try { + conf.writeXml(writer); + } finally { + writer.close(); + } + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/resources/log4j.properties b/hbase-http/src/test/resources/log4j.properties new file mode 100644 index 0000000..c322699 --- /dev/null +++ b/hbase-http/src/test/resources/log4j.properties @@ -0,0 +1,68 @@ +# 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. + +# Define some default values that can be overridden by system properties +hbase.root.logger=INFO,console +hbase.log.dir=. +hbase.log.file=hbase.log + +# Define the root logger to the system property "hbase.root.logger". +log4j.rootLogger=${hbase.root.logger} + +# Logging Threshold +log4j.threshold=ALL + +# +# Daily Rolling File Appender +# +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.File=${hbase.log.dir}/${hbase.log.file} + +# Rollver at midnight +log4j.appender.DRFA.DatePattern=.yyyy-MM-dd + +# 30-day backup +#log4j.appender.DRFA.MaxBackupIndex=30 +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +# Debugging Pattern format +log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %C{2}(%L): %m%n + + +# +# console +# Add "console" to rootlogger above if you want to use this +# +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %C{2}(%L): %m%n + +# Custom Logging levels + +#log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG + +log4j.logger.org.apache.hadoop=WARN +log4j.logger.org.apache.zookeeper=ERROR +log4j.logger.org.apache.hadoop.hbase=DEBUG + +#These settings are workarounds against spurious logs from the minicluster. +#See HBASE-4709 +log4j.logger.org.apache.hadoop.metrics2.impl.MetricsConfig=WARN +log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSinkAdapter=WARN +log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSystemImpl=WARN +log4j.logger.org.apache.hadoop.metrics2.util.MBeans=WARN +# Enable this to get detailed connection error/retry logging. +# log4j.logger.org.apache.hadoop.hbase.client.ConnectionImplementation=TRACE http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/resources/webapps/static/test.css ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/resources/webapps/static/test.css b/hbase-http/src/test/resources/webapps/static/test.css new file mode 100644 index 0000000..ae43828 --- /dev/null +++ b/hbase-http/src/test/resources/webapps/static/test.css @@ -0,0 +1,21 @@ +/** + * 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. + */ +/** + * Test CSS file for content type handling - empty, since we just check + * returned content type! + */ http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-http/src/test/resources/webapps/test/testjsp.jsp ---------------------------------------------------------------------- diff --git a/hbase-http/src/test/resources/webapps/test/testjsp.jsp b/hbase-http/src/test/resources/webapps/test/testjsp.jsp new file mode 100644 index 0000000..540adf9 --- /dev/null +++ b/hbase-http/src/test/resources/webapps/test/testjsp.jsp @@ -0,0 +1,21 @@ +<?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. + */ +%> +<%@ page contentType="text/html; charset=UTF-8" %> +Hello world! http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java index e5e5e24..25aecdb 100644 --- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java +++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java @@ -20,10 +20,8 @@ package org.apache.hadoop.hbase.rest; import java.lang.management.ManagementFactory; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.EnumSet; import java.util.concurrent.ArrayBlockingQueue; @@ -46,7 +44,7 @@ import org.apache.hadoop.hbase.rest.filter.GzipFilter; import org.apache.hadoop.hbase.rest.filter.RestCsrfPreventionFilter; import org.apache.hadoop.hbase.security.UserProvider; import org.apache.hadoop.hbase.util.DNS; -import org.apache.hadoop.hbase.util.HttpServerUtil; +import org.apache.hadoop.hbase.http.HttpServerUtil; import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Strings; import org.apache.hadoop.hbase.util.VersionInfo; http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/HBaseRESTTestingUtility.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/HBaseRESTTestingUtility.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/HBaseRESTTestingUtility.java index 0714c7b..4c977fd 100644 --- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/HBaseRESTTestingUtility.java +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/HBaseRESTTestingUtility.java @@ -24,7 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.security.UserProvider; -import org.apache.hadoop.hbase.util.HttpServerUtil; +import org.apache.hadoop.hbase.http.HttpServerUtil; import org.apache.hadoop.util.StringUtils; import org.eclipse.jetty.server.HttpConfiguration; @@ -99,7 +99,7 @@ public class HBaseRESTTestingUtility { // get the port testServletPort = ((ServerConnector)server.getConnectors()[0]).getLocalPort(); - LOG.info("started " + server.getClass().getName() + " on port " + + LOG.info("started " + server.getClass().getName() + " on port " + testServletPort); } http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/pom.xml ---------------------------------------------------------------------- diff --git a/hbase-server/pom.xml b/hbase-server/pom.xml index 23f9cde..e487559 100644 --- a/hbase-server/pom.xml +++ b/hbase-server/pom.xml @@ -360,6 +360,16 @@ <artifactId>hbase-common</artifactId> </dependency> <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-http</artifactId> + </dependency> + <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-http</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> <!--Needed by the visiblity tags and acl CPEP things in here in hbase-server (that should be out in hbase-endpoints or integrated). --> @@ -460,48 +470,13 @@ </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util-ajax</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-jsp</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> </dependency> <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-http</artifactId> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-security</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - <dependency> - <groupId>org.glassfish.jersey.containers</groupId> - <artifactId>jersey-container-servlet-core</artifactId> - </dependency> - <dependency> <!--For JspC used in ant task--> <groupId>org.glassfish.web</groupId> <artifactId>javax.servlet.jsp</artifactId> </dependency> - <!-- Specifically needed for jetty-jsp, included - to bypass version scanning that hits a bad repo - see HBASE-18831 --> - <dependency> - <groupId>org.glassfish</groupId> - <artifactId>javax.el</artifactId> - </dependency> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java deleted file mode 100644 index bd8570e..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/AdminAuthorizedServlet.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.yetus.audience.InterfaceAudience; -import org.apache.yetus.audience.InterfaceStability; -import org.eclipse.jetty.servlet.DefaultServlet; - -/** - * General servlet which is admin-authorized. - */ [email protected] [email protected] -public class AdminAuthorizedServlet extends DefaultServlet { - - private static final long serialVersionUID = 1L; - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - // Do the authorization - if (HttpServer.hasAdministratorAccess(getServletContext(), request, - response)) { - // Authorization is done. Just call super. - super.doGet(request, response); - } - } -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/ClickjackingPreventionFilter.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/ClickjackingPreventionFilter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/ClickjackingPreventionFilter.java deleted file mode 100644 index 9944d29..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/ClickjackingPreventionFilter.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -import org.apache.yetus.audience.InterfaceAudience; -import org.apache.hadoop.hbase.HBaseInterfaceAudience; - [email protected](HBaseInterfaceAudience.CONFIG) -public class ClickjackingPreventionFilter implements Filter { - - private FilterConfig filterConfig; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - } - - @Override - public void doFilter(ServletRequest req, ServletResponse res, - FilterChain chain) - throws IOException, ServletException { - HttpServletResponse httpRes = (HttpServletResponse) res; - httpRes.addHeader("X-Frame-Options", filterConfig.getInitParameter("xframeoptions")); - chain.doFilter(req, res); - } - - @Override - public void destroy() { - } - -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterContainer.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterContainer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterContainer.java deleted file mode 100644 index 7a79acc..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterContainer.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import java.util.Map; - -/** - * A container interface to add javax.servlet.Filter. - */ -public interface FilterContainer { - /** - * Add a filter to the container. - * @param name Filter name - * @param classname Filter class name - * @param parameters a map from parameter names to initial values - */ - void addFilter(String name, String classname, Map<String, String> parameters); - /** - * Add a global filter to the container - This global filter will be - * applied to all available web contexts. - * @param name filter name - * @param classname filter class name - * @param parameters a map from parameter names to initial values - */ - void addGlobalFilter(String name, String classname, Map<String, String> parameters); -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterInitializer.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterInitializer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterInitializer.java deleted file mode 100644 index e033c10..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/FilterInitializer.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import org.apache.hadoop.conf.Configuration; - -/** - * Initialize a javax.servlet.Filter. - */ -public abstract class FilterInitializer { - /** - * Initialize a Filter to a FilterContainer. - * @param container The filter container - * @param conf Configuration for run-time parameters - */ - public abstract void initFilter(FilterContainer container, Configuration conf); -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HtmlQuoting.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HtmlQuoting.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HtmlQuoting.java deleted file mode 100644 index 60a74b7..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HtmlQuoting.java +++ /dev/null @@ -1,215 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * This class is responsible for quoting HTML characters. - */ -public class HtmlQuoting { - private static final byte[] ampBytes = "&".getBytes(); - private static final byte[] aposBytes = "'".getBytes(); - private static final byte[] gtBytes = ">".getBytes(); - private static final byte[] ltBytes = "<".getBytes(); - private static final byte[] quotBytes = """.getBytes(); - - /** - * Does the given string need to be quoted? - * @param data the string to check - * @param off the starting position - * @param len the number of bytes to check - * @return does the string contain any of the active html characters? - */ - public static boolean needsQuoting(byte[] data, int off, int len) { - if (off+len > data.length) { - throw new IllegalStateException("off+len=" + off+len + " should be lower" - + " than data length=" + data.length); - } - for(int i=off; i< off+len; ++i) { - switch(data[i]) { - case '&': - case '<': - case '>': - case '\'': - case '"': - return true; - default: - break; - } - } - return false; - } - - /** - * Does the given string need to be quoted? - * @param str the string to check - * @return does the string contain any of the active html characters? - */ - public static boolean needsQuoting(String str) { - if (str == null) { - return false; - } - byte[] bytes = str.getBytes(); - return needsQuoting(bytes, 0 , bytes.length); - } - - /** - * Quote all of the active HTML characters in the given string as they - * are added to the buffer. - * @param output the stream to write the output to - * @param buffer the byte array to take the characters from - * @param off the index of the first byte to quote - * @param len the number of bytes to quote - */ - public static void quoteHtmlChars(OutputStream output, byte[] buffer, - int off, int len) throws IOException { - for(int i=off; i < off+len; i++) { - switch (buffer[i]) { - case '&': output.write(ampBytes); break; - case '<': output.write(ltBytes); break; - case '>': output.write(gtBytes); break; - case '\'': output.write(aposBytes); break; - case '"': output.write(quotBytes); break; - default: output.write(buffer, i, 1); - } - } - } - - /** - * Quote the given item to make it html-safe. - * @param item the string to quote - * @return the quoted string - */ - public static String quoteHtmlChars(String item) { - if (item == null) { - return null; - } - byte[] bytes = item.getBytes(); - if (needsQuoting(bytes, 0, bytes.length)) { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - try { - quoteHtmlChars(buffer, bytes, 0, bytes.length); - } catch (IOException ioe) { - // Won't happen, since it is a bytearrayoutputstream - } - return buffer.toString(); - } else { - return item; - } - } - - /** - * Return an output stream that quotes all of the output. - * @param out the stream to write the quoted output to - * @return a new stream that the application show write to - * @throws IOException if the underlying output fails - */ - public static OutputStream quoteOutputStream(final OutputStream out - ) throws IOException { - return new OutputStream() { - private byte[] data = new byte[1]; - @Override - public void write(byte[] data, int off, int len) throws IOException { - quoteHtmlChars(out, data, off, len); - } - - @Override - public void write(int b) throws IOException { - data[0] = (byte) b; - quoteHtmlChars(out, data, 0, 1); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - out.close(); - } - }; - } - - /** - * Remove HTML quoting from a string. - * @param item the string to unquote - * @return the unquoted string - */ - public static String unquoteHtmlChars(String item) { - if (item == null) { - return null; - } - int next = item.indexOf('&'); - // nothing was quoted - if (next == -1) { - return item; - } - int len = item.length(); - int posn = 0; - StringBuilder buffer = new StringBuilder(); - while (next != -1) { - buffer.append(item.substring(posn, next)); - if (item.startsWith("&", next)) { - buffer.append('&'); - next += 5; - } else if (item.startsWith("'", next)) { - buffer.append('\''); - next += 6; - } else if (item.startsWith(">", next)) { - buffer.append('>'); - next += 4; - } else if (item.startsWith("<", next)) { - buffer.append('<'); - next += 4; - } else if (item.startsWith(""", next)) { - buffer.append('"'); - next += 6; - } else { - int end = item.indexOf(';', next)+1; - if (end == 0) { - end = len; - } - throw new IllegalArgumentException("Bad HTML quoting for " + - item.substring(next,end)); - } - posn = next; - next = item.indexOf('&', posn); - } - buffer.append(item.substring(posn, len)); - return buffer.toString(); - } - - public static void main(String[] args) throws Exception { - if (args.length == 0) { - throw new IllegalArgumentException("Please provide some arguments"); - } - for(String arg:args) { - System.out.println("Original: " + arg); - String quoted = quoteHtmlChars(arg); - System.out.println("Quoted: "+ quoted); - String unquoted = unquoteHtmlChars(quoted); - System.out.println("Unquoted: " + unquoted); - System.out.println(); - } - } - -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpConfig.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpConfig.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpConfig.java deleted file mode 100644 index b9dde23..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpConfig.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import org.apache.yetus.audience.InterfaceAudience; -import org.apache.yetus.audience.InterfaceStability; -import org.apache.hadoop.conf.Configuration; - -/** - * Statics to get access to Http related configuration. - */ [email protected] [email protected] -public class HttpConfig { - private Policy policy; - public enum Policy { - HTTP_ONLY, - HTTPS_ONLY, - HTTP_AND_HTTPS; - - public Policy fromString(String value) { - if (HTTPS_ONLY.name().equalsIgnoreCase(value)) { - return HTTPS_ONLY; - } else if (HTTP_AND_HTTPS.name().equalsIgnoreCase(value)) { - return HTTP_AND_HTTPS; - } - return HTTP_ONLY; - } - - public boolean isHttpEnabled() { - return this == HTTP_ONLY || this == HTTP_AND_HTTPS; - } - - public boolean isHttpsEnabled() { - return this == HTTPS_ONLY || this == HTTP_AND_HTTPS; - } - } - - public HttpConfig(final Configuration conf) { - boolean sslEnabled = conf.getBoolean( - ServerConfigurationKeys.HBASE_SSL_ENABLED_KEY, - ServerConfigurationKeys.HBASE_SSL_ENABLED_DEFAULT); - policy = sslEnabled ? Policy.HTTPS_ONLY : Policy.HTTP_ONLY; - if (sslEnabled) { - conf.addResource("ssl-server.xml"); - conf.addResource("ssl-client.xml"); - } - } - - public void setPolicy(Policy policy) { - this.policy = policy; - } - - public boolean isSecure() { - return policy == Policy.HTTPS_ONLY; - } - - public String getSchemePrefix() { - return (isSecure()) ? "https://" : "http://"; - } - - public String getScheme(Policy policy) { - return policy == Policy.HTTPS_ONLY ? "https://" : "http://"; - } -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLog.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLog.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLog.java deleted file mode 100644 index cfc0640..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLog.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import java.util.HashMap; - -import org.apache.commons.logging.impl.Log4JLogger; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogConfigurationException; -import org.apache.commons.logging.LogFactory; -import org.apache.log4j.Appender; -import org.apache.log4j.Logger; - -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.NCSARequestLog; - -/** - * RequestLog object for use with Http - */ -public class HttpRequestLog { - - private static final Log LOG = LogFactory.getLog(HttpRequestLog.class); - private static final HashMap<String, String> serverToComponent; - - static { - serverToComponent = new HashMap<>(); - serverToComponent.put("master", "master"); - serverToComponent.put("region", "regionserver"); - } - - public static RequestLog getRequestLog(String name) { - - String lookup = serverToComponent.get(name); - if (lookup != null) { - name = lookup; - } - String loggerName = "http.requests." + name; - String appenderName = name + "requestlog"; - Log logger = LogFactory.getLog(loggerName); - - if (logger instanceof Log4JLogger) { - Log4JLogger httpLog4JLog = (Log4JLogger)logger; - Logger httpLogger = httpLog4JLog.getLogger(); - Appender appender = null; - - try { - appender = httpLogger.getAppender(appenderName); - } catch (LogConfigurationException e) { - LOG.warn("Http request log for " + loggerName - + " could not be created"); - throw e; - } - - if (appender == null) { - LOG.info("Http request log for " + loggerName - + " is not defined"); - return null; - } - - if (appender instanceof HttpRequestLogAppender) { - HttpRequestLogAppender requestLogAppender - = (HttpRequestLogAppender)appender; - NCSARequestLog requestLog = new NCSARequestLog(); - requestLog.setFilename(requestLogAppender.getFilename()); - requestLog.setRetainDays(requestLogAppender.getRetainDays()); - return requestLog; - } else { - LOG.warn("Jetty request log for " + loggerName - + " was of the wrong class"); - return null; - } - } - else { - LOG.warn("Jetty request log can only be enabled using Log4j"); - return null; - } - } -} http://git-wip-us.apache.org/repos/asf/hbase/blob/d6982414/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLogAppender.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLogAppender.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLogAppender.java deleted file mode 100644 index 8039b34..0000000 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/http/HttpRequestLogAppender.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.hbase.http; - -import org.apache.log4j.spi.LoggingEvent; -import org.apache.log4j.AppenderSkeleton; - -/** - * Log4j Appender adapter for HttpRequestLog - */ -public class HttpRequestLogAppender extends AppenderSkeleton { - - private String filename; - private int retainDays; - - public HttpRequestLogAppender() { - } - - public void setRetainDays(int retainDays) { - this.retainDays = retainDays; - } - - public int getRetainDays() { - return retainDays; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public String getFilename() { - return filename; - } - - @Override - public void append(LoggingEvent event) { - } - - @Override - public void close() { - // Do nothing, we don't have close() on AppenderSkeleton. - } - - @Override - public boolean requiresLayout() { - return false; - } -}
