Package com.alibaba.citrus.webx.servlet

Source Code of com.alibaba.citrus.webx.servlet.Holder

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed 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 com.alibaba.citrus.webx.servlet;

import static com.alibaba.citrus.springext.util.SpringExtUtil.*;
import static com.alibaba.citrus.test.TestUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletException;

import com.alibaba.citrus.service.pipeline.PipelineContext;
import com.alibaba.citrus.service.requestcontext.RequestContext;
import com.alibaba.citrus.service.requestcontext.rundata.RunData;
import com.alibaba.citrus.service.requestcontext.support.AbstractRequestContextFactory;
import com.alibaba.citrus.webx.AbstractWebxTests;
import com.alibaba.citrus.webx.BadRequestException;
import com.alibaba.citrus.webx.ResourceNotFoundException;
import com.alibaba.citrus.webx.handler.RequestHandler;
import com.alibaba.citrus.webx.handler.RequestHandlerContext;
import com.alibaba.citrus.webx.handler.RequestHandlerMapping;
import com.alibaba.citrus.webx.impl.WebxRootControllerImpl;
import com.alibaba.citrus.webx.pipeline.TestValve;
import com.alibaba.citrus.webx.pipeline.ValveRunner;
import com.alibaba.citrus.webx.util.ErrorHandlerHelper;
import com.meterware.httpunit.HeadMethodWebRequest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.web.context.WebApplicationContext;

public class WebxRootControllerTests extends AbstractWebxTests {
    private WebxFrameworkFilter    filter;
    private WebxRootControllerImpl controller;

    @Before
    public void init() throws Exception {
        // 特别测试当有/contextPath存在时,passthru参数正确工作
        prepareWebClient(null, "/myapps");

        filter = (WebxFrameworkFilter) client.newInvocation("http://www.taobao.com/myapps/app1").getFilter();
        controller = (WebxRootControllerImpl) filter.getWebxComponents().getWebxRootController();

        setErrorHandler(controller, new TestErrorHandler());
    }

    @Test
    public void passthru() throws Exception {
        // passthru
        invokeServlet("/myapps/app1/plaintext.txt");

        assertEquals(200, clientResponseCode);
        assertEquals("hello, app1", clientResponseContent); // text from plain text file

        // 普通request
        invokeServlet("/myapps/app1/plaintext2.txt");

        assertEquals(200, clientResponseCode);
        assertEquals("hello!", clientResponseContent.trim()); // text from valve
    }

    @Test
    public void requestContextFailed() throws Exception {
        requestContextFactoryHolder.set(new AbstractRequestContextFactory() {
            @Override
            public RequestContext getRequestContextWrapper(RequestContext wrappedContext) {
                throw new IllegalArgumentException("ouch!");
            }

            public String[] getFeatures() {
                return null;
            }

            public FeatureOrder[] featureOrders() {
                return null;
            }
        });

        invokeServlet("/myapps/app1/test.htm");

        assertEquals(500, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertThat(clientResponseContent,
                   containsAll("<pre>", "</pre>", IllegalArgumentException.class.getName(), "ouch!"));
    }

    @Test
    public void internalRequest_illegal() throws Exception {
        // internal
        invokeServlet("/myapps/internal/notexist");

        // 由main handler接手,然后抛出异常
        assertEquals(404, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertThat(
                clientResponseContent,
                containsAll("<pre>", "</pre>", ResourceNotFoundException.class.getName(),
                            "Resource Not Found: notexist"));
    }

    @Test
    public void internalRequest_error() throws Exception {
        invokeServlet("/myapps/internal/error");

        assertEquals(200, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertEquals(null, trimToNull(clientResponseContent));
    }

    @Test
    public void nonInternalRequest() throws Exception {
        invokeServlet("/myapps/app1/internal.htm");

        assertEquals(200, clientResponseCode);
        assertThat(clientResponseContent, containsAll("hello!"));
    }

    @Test
    public void internalRequestMapping() throws Exception {
        WebApplicationContext context = controller.getComponents().getParentApplicationContext();

        class Holder {
            @Autowired
            private RequestHandlerMapping mapping;
        }

        Holder holder = autowireAndInitialize(new Holder(), context, AbstractBeanDefinition.AUTOWIRE_AUTODETECT,
                                              "holder");

        assertArrayEquals(new String[] { "Webx/Info/Environment+Variables", "Webx/Info/System+Properties",
                                         "Webx/Info/Request+Info", "Webx/Info/System+Info", "Webx/Schema" },
                          holder.mapping.getRequestHandlerNames());
    }

    @Test
    public void valve_breakToTop() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                pipelineContext.breakPipeline(0);
            }
        });

        invokeServlet("/myapps/app1/plaintext.txt");

        assertEquals(200, clientResponseCode);
        assertEquals("text/plain", clientResponse.getContentType());
        assertThat(clientResponseContent, containsAll("hello, app1"));
    }

    @Test
    public void valve_exception() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                throw new IllegalStateException("wrong!");
            }
        });

        invokeServlet("/myapps/app1/test.htm");

        assertEquals(500, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertThat(clientResponseContent,
                   containsAll("<pre>", "</pre>", IllegalStateException.class.getName(), "wrong!"));
    }

    @Test
    public void valve_not_found_exception() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                throw new ResourceNotFoundException("not found!");
            }
        });

        invokeServlet("/myapps/app1/test.htm");

        assertEquals(404, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertThat(clientResponseContent,
                   containsAll("<pre>", "</pre>", ResourceNotFoundException.class.getName(), "not found!"));
    }

    @Test
    public void valve_bad_request_exception() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                throw new BadRequestException("bad request!");
            }
        });

        invokeServlet("/myapps/app1/test.htm");

        assertEquals(400, clientResponseCode);
        assertEquals("text/html", clientResponse.getContentType());
        assertThat(clientResponseContent,
                   containsAll("<pre>", "</pre>", BadRequestException.class.getName(), "bad request!"));
    }

    @Test
    public void valve_exception_exception() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                throw new IllegalStateException("wrong!");
            }
        });

        setErrorHandler(controller, new RequestHandler() {
            public void handleRequest(RequestHandlerContext ctx) throws Exception {
                throw new IllegalArgumentException("wrong again!");
            }
        });

        try {
            invokeServlet("/myapps/app1/test.htm");
            fail();
        } catch (ServletException e) {
            // 真正的servlet engine在这里会显示web.xml中的错误页面,而测试时只会接收异常。
            assertThat(e, exception(IllegalStateException.class)); // 所抛出的是第一个应用产生的异常
            assertThat(e, not(exception(IllegalArgumentException.class))); // 而不是第二个errorHandler产生的异常
        }
    }

    @Test
    public void valve_exception_exception_2() throws Exception {
        TestValve.runnerHolder.set(new ValveRunner() {
            public void run(RunData rundata, PipelineContext pipelineContext) throws Exception {
                throw new IllegalStateException("wrong!");
            }
        });

        setErrorHandler(controller, new RequestHandler() {
            public void handleRequest(RequestHandlerContext ctx) throws Exception {
                throw new ServletException(ErrorHandlerHelper.getInstance(ctx.getRequest()).getException());
            }
        });

        try {
            invokeServlet("/myapps/app1/test.htm");
            fail();
        } catch (ServletException e) {
            // 真正的servlet engine在这里会显示web.xml中的错误页面,而测试时只会接收异常。
            assertThat(e, exception(IllegalStateException.class));
        }
    }

    @Test
    public void head() throws Exception {
        clientResponse = client.getResponse(new HeadMethodWebRequest("http://localhost/myapps/app1/internal.htm"));
        clientResponseCode = clientResponse.getResponseCode();
        clientResponseContent = clientResponse.getText();

        assertEquals(200, clientResponseCode);
        assertEquals(null, trimToNull(clientResponseContent));
    }

    @Test
    public void loadInternalRequestHandlers() throws Exception {
        Map<String, RequestHandler> handlers;

        // names are normalized and sorted
        // skipped empty name/class
        // skipped reserved name: error
        // skipped abstract and wrong type
        handlers = loadInternalHandlers("internal-request-handlers-test-1");
        assertArrayEquals(new String[] { "aa/bb/cc", "aa/cc" }, handlers.keySet().toArray(new String[0]));
    }

    @SuppressWarnings("unchecked")
    private Map<String, RequestHandler> loadInternalHandlers(String location) throws Exception {
        location = "META-INF/" + location;

        Object internalHandlerMapping = getFieldValue(controller, "internalHandlerMapping", null); // of inner type InternalHandlerMapping
        Method loadInternalHandlers = getAccessibleMethod(internalHandlerMapping.getClass(), "loadInternalHandlers",
                                                          new Class<?>[] { String.class });

        return (Map<String, RequestHandler>) loadInternalHandlers.invoke(internalHandlerMapping, location);
    }
}
TOP

Related Classes of com.alibaba.citrus.webx.servlet.Holder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.