| /* |
| * 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.chukwa.datacollection.agent.rest; |
| |
| import junit.framework.Assert; |
| import junit.framework.TestCase; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.hadoop.chukwa.datacollection.agent.ChukwaAgent; |
| import org.springframework.mock.web.MockHttpServletRequest; |
| import org.springframework.mock.web.MockHttpServletResponse; |
| import org.json.simple.JSONObject; |
| import org.json.simple.JSONValue; |
| import org.mortbay.jetty.servlet.ServletHolder; |
| import org.mortbay.jetty.servlet.Context; |
| import org.mortbay.jetty.servlet.ServletHandler; |
| import org.mortbay.jetty.Server; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.Servlet; |
| import javax.ws.rs.core.MediaType; |
| |
| import java.io.File; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.io.UnsupportedEncodingException; |
| |
| import com.sun.jersey.spi.container.servlet.ServletContainer; |
| |
| /** |
| * Tests the basic functionality of the AdaptorController. |
| */ |
| public class TestAdaptorController extends TestCase { |
| protected Log log = LogFactory.getLog(getClass()); |
| |
| Server jettyServer; |
| ChukwaAgent agent; |
| Servlet servlet; |
| MockHttpServletRequest request; |
| MockHttpServletResponse response; |
| StringBuilder sb; |
| String adaptor; |
| |
| protected void setUp() throws Exception { |
| String path = System.getenv("CHUKWA_LOG_DIR"); |
| String[] checkpointNames = new File(path).list(new FilenameFilter() { |
| public boolean accept(File dir, String name) { |
| String checkPointBaseName = "chukwa_agent_checkpoint"; |
| return name.startsWith(checkPointBaseName); |
| } |
| }); |
| for(String cpn : checkpointNames) { |
| File checkpoint = new File(path+"/"+cpn); |
| if(!checkpoint.delete()) { |
| Assert.fail("Fail to clean up existing check point file: "+ cpn); |
| } |
| } |
| agent = ChukwaAgent.getAgent(); |
| agent.start(); |
| |
| ServletHolder servletHolder = new ServletHolder(ServletContainer.class); |
| servletHolder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", |
| "com.sun.jersey.api.core.PackagesResourceConfig"); |
| servletHolder.setInitParameter("com.sun.jersey.config.property.packages", |
| "org.apache.hadoop.chukwa.datacollection.agent.rest"); |
| servletHolder.setServletHandler(new ServletHandler()); |
| |
| jettyServer = new Server(); |
| |
| Context root = new Context(jettyServer, "/foo/bar", Context.SESSIONS); |
| root.setAttribute("ChukwaAgent", agent); |
| root.addServlet(servletHolder, "/*"); |
| |
| jettyServer.start(); |
| jettyServer.setStopAtShutdown(true); |
| |
| servlet = servletHolder.getServlet(); |
| request = new MockHttpServletRequest(); |
| request.setContextPath("/foo/bar"); |
| |
| response = new MockHttpServletResponse(); |
| adaptor = agent.processAddCommandE("add org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor SomeDataType 0"); |
| sb = new StringBuilder(); |
| } |
| |
| protected void tearDown() throws Exception { |
| agent.getAdaptor(adaptor); |
| agent.shutdown(); |
| jettyServer.stop(); |
| } |
| |
| public void testGetJSON() throws IOException, ServletException { |
| request.setServletPath("/adaptor"); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| request.addHeader("Accept", "application/json"); |
| request.setMethod("GET"); |
| |
| servlet.service(request, response); |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount()); |
| } |
| |
| private void assertOccurs(String message, int occurances, String text, String match) { |
| |
| int index = -1; |
| for(int i = 0; i < occurances; i++) { |
| index = text.indexOf(match, index + 1); |
| assertTrue(message + ": " + text, index != -1); |
| } |
| } |
| |
| public void testGetXml() throws IOException, ServletException { |
| request.setServletPath("/adaptor"); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| request.addHeader("Accept", "application/xml"); |
| request.setMethod("GET"); |
| |
| servlet.service(request, response); |
| |
| // assert response |
| assertXmlResponse(response, 1); |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount()); |
| } |
| |
| public void testGetInvalidViewType() throws IOException, ServletException { |
| request.setServletPath("/adaptor"); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| request.addHeader("Accept", "unsupportedViewType"); |
| request.setMethod("GET"); |
| |
| servlet.service(request, response); |
| |
| // assert response |
| assertEquals("Unexpected response status", 406, response.getStatus()); |
| } |
| |
| public void testDeleteAdaptor() throws IOException, ServletException { |
| String adaptorId = agent.getAdaptorList().keySet().iterator().next(); |
| |
| request.setServletPath("/adaptor/" + adaptorId); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount()); |
| request.setMethod("DELETE"); |
| |
| servlet.service(request, response); |
| |
| // assert response |
| assertEquals("Unexpected response status", 200, response.getStatus()); |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 0, agent.adaptorCount()); |
| } |
| |
| public void testAddAdaptor() throws IOException, ServletException { |
| request.setServletPath("/adaptor"); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| request.addHeader("Content-Type", MediaType.APPLICATION_JSON); |
| request.addHeader("Accept", MediaType.APPLICATION_JSON); |
| request.setMethod("POST"); |
| request.setContent("{ \"dataType\" : \"SomeDataType\", \"adaptorClass\" : \"org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor\", \"adaptorParams\" : \"1000\", \"offset\" : 5555 }".getBytes()); |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount()); |
| String initialAdaptorId = agent.getAdaptorList().keySet().iterator().next(); |
| |
| servlet.service(request, response); |
| |
| // assert response |
| String responseContent = assertJSONResponse(response, 1); |
| String newAdaptorId = null; |
| for (String id : agent.getAdaptorList().keySet()) { |
| if (id != initialAdaptorId) { |
| newAdaptorId = id; |
| break; |
| } |
| } |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 2, agent.adaptorCount()); |
| |
| assertOccurs("Response did not contain adaptorId", 1, responseContent, newAdaptorId); |
| |
| //assert agent |
| assertEquals("Incorrect total number of adaptors", 2, agent.adaptorCount()); |
| |
| // fire a doGet to assert that the servlet shows 2 adaptors |
| request = new MockHttpServletRequest(); |
| response = new MockHttpServletResponse(); |
| request.setServletPath("/adaptor"); |
| request.setRequestURI(request.getContextPath() + request.getServletPath()); |
| request.addHeader("Accept", MediaType.APPLICATION_XML); |
| request.addHeader("Content-Type", MediaType.APPLICATION_XML); |
| request.setMethod("GET"); |
| |
| servlet.service(request, response); |
| |
| // assert response |
| assertXmlResponse(response, 2); |
| } |
| |
| private String assertJSONResponse(MockHttpServletResponse response, |
| int adaptorCount) |
| throws UnsupportedEncodingException { |
| String responseContent = response.getContentAsString(); |
| assertEquals("Unexpected response status", 200, response.getStatus()); |
| |
| JSONObject json = (JSONObject) JSONValue.parse(responseContent); |
| String adaptorClass = (String) json.get("adaptorClass"); |
| String dataType = (String) json.get("dataType"); |
| assertEquals("Response text doesn't include adaptor class", |
| "org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor", adaptorClass); |
| assertEquals("Response text doesn't include data type", |
| "SomeDataType", dataType); |
| |
| return responseContent; |
| } |
| |
| private String assertXmlResponse(MockHttpServletResponse response, |
| int adaptorCount) |
| throws UnsupportedEncodingException { |
| String responseContent = response.getContentAsString(); |
| |
| // assert response |
| assertEquals("Unexpected response status", 200, response.getStatus()); |
| |
| //Content it correct when executed via an HTTP client, but it doesn't seem |
| //to get set by the servlet |
| assertOccurs("Response XML doesn't include correct adaptor_count", adaptorCount, |
| responseContent, "adaptorCount>"); |
| assertOccurs("Response XML doesn't include adaptorClass", adaptorCount, responseContent, |
| "<adaptorClass>org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor</adaptorClass>"); |
| assertOccurs("Response XML doesn't include dataType", adaptorCount, responseContent, |
| "<dataType>SomeDataType</dataType>"); |
| |
| return responseContent; |
| } |
| |
| } |