View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.hadoop.hbase.http.jmx;
19  
20  import java.net.HttpURLConnection;
21  import java.net.URL;
22  import java.net.URLEncoder;
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  import javax.servlet.http.HttpServletResponse;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.testclassification.SmallTests;
31  import org.apache.hadoop.hbase.http.HttpServer;
32  import org.apache.hadoop.hbase.http.HttpServerFunctionalTest;
33  import org.junit.AfterClass;
34  import org.junit.BeforeClass;
35  import org.junit.Test;
36  import org.junit.experimental.categories.Category;
37  
38  @Category(SmallTests.class)
39  public class TestJMXJsonServlet extends HttpServerFunctionalTest {
40    private   static final Log LOG = LogFactory.getLog(TestJMXJsonServlet.class);
41    private static HttpServer server;
42    private static URL baseUrl;
43  
44    @BeforeClass public static void setup() throws Exception {
45      // Eclipse doesn't pick this up correctly from the plugin
46      // configuration in the pom.
47      System.setProperty(HttpServerFunctionalTest.TEST_BUILD_WEBAPPS, "target/test-classes/webapps");
48      server = createTestServer();
49      server.start();
50      baseUrl = getServerURL(server);
51    }
52    
53    @AfterClass public static void cleanup() throws Exception {
54      server.stop();
55    }
56    
57    public static void assertReFind(String re, String value) {
58      Pattern p = Pattern.compile(re);
59      Matcher m = p.matcher(value);
60      assertTrue("'"+p+"' does not match "+value, m.find());
61    }
62    
63    @Test public void testQuery() throws Exception {
64      String result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Runtime"));
65      LOG.info("/jmx?qry=java.lang:type=Runtime RESULT: "+result);
66      assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Runtime\"", result);
67      assertReFind("\"modelerType\"", result);
68      
69      result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Memory"));
70      LOG.info("/jmx?qry=java.lang:type=Memory RESULT: "+result);
71      assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result);
72      assertReFind("\"modelerType\"", result);
73      
74      result = readOutput(new URL(baseUrl, "/jmx"));
75      LOG.info("/jmx RESULT: "+result);
76      assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result);
77      
78      // test to get an attribute of a mbean
79      result = readOutput(new URL(baseUrl, 
80          "/jmx?get=java.lang:type=Memory::HeapMemoryUsage"));
81      LOG.info("/jmx RESULT: "+result);
82      assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result);
83      assertReFind("\"committed\"\\s*:", result);
84      
85      // negative test to get an attribute of a mbean
86      result = readOutput(new URL(baseUrl, 
87          "/jmx?get=java.lang:type=Memory::"));
88      LOG.info("/jmx RESULT: "+result);
89      assertReFind("\"ERROR\"", result);
90  
91      // test to get JSONP result
92      result = readOutput(new URL(baseUrl, "/jmx?qry=java.lang:type=Memory&callback=mycallback1"));
93      LOG.info("/jmx?qry=java.lang:type=Memory&callback=mycallback RESULT: "+result);
94      assertReFind("^mycallback1\\(\\{", result);
95      assertReFind("\\}\\);$", result);
96  
97      // negative test to get an attribute of a mbean as JSONP
98      result = readOutput(new URL(baseUrl,
99          "/jmx?get=java.lang:type=Memory::&callback=mycallback2"));
100     LOG.info("/jmx RESULT: "+result);
101     assertReFind("^mycallback2\\(\\{", result);
102     assertReFind("\"ERROR\"", result);
103     assertReFind("\\}\\);$", result);
104 
105     // test to get an attribute of a mbean as JSONP
106     result = readOutput(new URL(baseUrl,
107         "/jmx?get=java.lang:type=Memory::HeapMemoryUsage&callback=mycallback3"));
108     LOG.info("/jmx RESULT: "+result);
109     assertReFind("^mycallback3\\(\\{", result);
110     assertReFind("\"name\"\\s*:\\s*\"java.lang:type=Memory\"", result);
111     assertReFind("\"committed\"\\s*:", result);
112     assertReFind("\\}\\);$", result);
113 
114   }
115 
116   @Test
117   public void testDisallowedJSONPCallback() throws Exception {
118     String callback = "function(){alert('bigproblems!')};foo";
119     URL url = new URL(
120         baseUrl, "/jmx?qry=java.lang:type=Memory&callback="+URLEncoder.encode(callback, "UTF-8"));
121     HttpURLConnection cnxn = (HttpURLConnection) url.openConnection();
122     assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, cnxn.getResponseCode());
123   }
124 
125   @Test
126   public void testUnderscoresInJSONPCallback() throws Exception {
127     String callback = "my_function";
128     URL url = new URL(
129         baseUrl, "/jmx?qry=java.lang:type=Memory&callback="+URLEncoder.encode(callback, "UTF-8"));
130     HttpURLConnection cnxn = (HttpURLConnection) url.openConnection();
131     assertEquals(HttpServletResponse.SC_OK, cnxn.getResponseCode());
132   }
133 }