ch.ralscha.extdirectspring.controller.ControllerUtil.java Source code

Java tutorial

Introduction

Here is the source code for ch.ralscha.extdirectspring.controller.ControllerUtil.java

Source

/**
 * Copyright 2010-2016 Ralph Schaer <ralphschaer@gmail.com>
 *
 * 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 ch.ralscha.extdirectspring.controller;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;

import org.apache.commons.logging.LogFactory;
import org.assertj.core.util.Arrays;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ch.ralscha.extdirectspring.bean.BeanMethod;
import ch.ralscha.extdirectspring.bean.ExtDirectPollResponse;
import ch.ralscha.extdirectspring.bean.ExtDirectRequest;
import ch.ralscha.extdirectspring.bean.ExtDirectResponse;
import ch.ralscha.extdirectspring.util.JsonHandler;

public class ControllerUtil {

    private static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
    }

    public static ExtDirectPollResponse performPollRequest(MockMvc mockMvc, String bean, String method,
            String event, Map<String, String> params, HttpHeaders headers) throws Exception {
        return performPollRequest(mockMvc, bean, method, event, params, headers, null, false);
    }

    public static ExtDirectPollResponse performPollRequest(MockMvc mockMvc, String bean, String method,
            String event, Map<String, String> params, HttpHeaders headers, List<Cookie> cookies) throws Exception {
        return performPollRequest(mockMvc, bean, method, event, params, headers, cookies, false);
    }

    public static ExtDirectPollResponse performPollRequest(MockMvc mockMvc, String bean, String method,
            String event, Map<String, String> params, HttpHeaders headers, List<Cookie> cookies,
            boolean withSession) throws Exception {
        MockHttpServletRequestBuilder request = post("/poll/" + bean + "/" + method + "/" + event)
                .accept(MediaType.ALL).contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8");

        if (cookies != null) {
            request.cookie(cookies.toArray(new Cookie[cookies.size()]));
        }

        if (withSession) {
            request.session(new MockHttpSession());
        }

        if (params != null) {
            for (String paramName : params.keySet()) {
                request.param(paramName, params.get(paramName));
            }
        }

        if (headers != null) {
            request.headers(headers);
        }

        MvcResult result = mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(content().encoding("UTF-8")).andReturn();

        return readDirectPollResponse(result.getResponse().getContentAsByteArray());
    }

    public static MvcResult performRouterRequest(MockMvc mockMvc, String content) throws Exception {
        return performRouterRequest(mockMvc, content, null, null, null, false);
    }

    public static MvcResult performRouterRequest(MockMvc mockMvc, String content, Map<String, String> params,
            HttpHeaders headers, List<Cookie> cookies, boolean withSession) throws Exception {

        MockHttpServletRequestBuilder request = post("/router").accept(MediaType.ALL)
                .contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8");

        if (cookies != null) {
            request.cookie(cookies.toArray(new Cookie[cookies.size()]));
        }

        if (withSession) {
            request.session(new MockHttpSession());
        }

        if (content != null) {
            request.content(content);
        }

        if (params != null) {
            for (String paramName : params.keySet()) {
                request.param(paramName, params.get(paramName));
            }

        }

        if (headers != null) {
            request.headers(headers);
        }

        return mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(content().encoding("UTF-8")).andReturn();

    }

    public static String createEdsRequest(String action, String method, int tid, Object data) {
        return createEdsRequest(action, method, false, tid, data, null);
    }

    public static String createEdsRequest(String action, String method, boolean namedParameter, int tid,
            Object data, Map<String, Object> metadata) {
        ExtDirectRequest dr = new ExtDirectRequest();
        dr.setAction(action);
        dr.setMethod(method);
        dr.setTid(tid);
        dr.setType("rpc");

        if (metadata != null) {
            dr.setMetadata(metadata);
        } else {
            dr.setMetadata(null);
        }

        if (namedParameter && data != null) {
            if (Arrays.isArray(data)) {
                dr.setData(((Object[]) data)[0]);
            } else {
                dr.setData(data);
            }
        } else if (data instanceof Object[] || data == null) {
            dr.setData(data);
        } else {
            dr.setData(new Object[] { data });
        }
        try {
            return mapper.writeValueAsString(dr);
        } catch (JsonProcessingException e) {
            fail("createEdsRequest: " + e.getMessage());
        }
        return null;
    }

    public static String createEdsRequest(List<BeanMethod> methods) {

        List<ExtDirectRequest> edrs = new ArrayList<ExtDirectRequest>();
        for (BeanMethod method : methods) {
            ExtDirectRequest dr = new ExtDirectRequest();
            dr.setAction(method.getBean());
            dr.setMethod(method.getMethod());
            dr.setTid(method.getTid());
            dr.setType("rpc");
            dr.setData(method.getData());
            edrs.add(dr);
        }

        try {
            return mapper.writeValueAsString(edrs);
        } catch (JsonProcessingException e) {
            fail("createEdsRequest: " + e.getMessage());
        }
        return null;
    }

    public static Object sendAndReceive(MockMvc mockMvc, HttpHeaders headers, String bean, String method,
            Object expectedResultOrType, Object... requestData) {
        return sendAndReceive(mockMvc, false, headers, null, null, bean, method, false, expectedResultOrType,
                requestData);
    }

    public static Object sendAndReceive(MockMvc mockMvc, HttpHeaders headers, List<Cookie> cookies, String bean,
            String method, Object expectedResultOrType, Object... requestData) {
        return sendAndReceive(mockMvc, false, headers, cookies, null, bean, method, false, expectedResultOrType,
                requestData);
    }

    public static Object sendAndReceive(MockMvc mockMvc, String bean, String method, Map<String, Object> metadata,
            Object expectedResultOrType, Object... requestData) {
        return sendAndReceive(mockMvc, false, null, null, metadata, bean, method, false, expectedResultOrType,
                requestData);
    }

    public static Object sendAndReceive(MockMvc mockMvc, String bean, String method, Object expectedResultOrType,
            Object... requestData) {
        return sendAndReceive(mockMvc, false, null, null, null, bean, method, false, expectedResultOrType,
                requestData);
    }

    public static Object sendAndReceiveNamed(MockMvc mockMvc, HttpHeaders headers, List<Cookie> cookies,
            String bean, String method, Object expectedResultOrType, Map<String, Object> requestData) {
        return sendAndReceive(mockMvc, false, headers, cookies, null, bean, method, true, expectedResultOrType,
                new Object[] { requestData });
    }

    public static Object sendAndReceiveNamed(MockMvc mockMvc, String bean, String method,
            Object expectedResultOrType, Map<String, Object> requestData) {
        return sendAndReceive(mockMvc, false, null, null, null, bean, method, true, expectedResultOrType,
                new Object[] { requestData });
    }

    public static Object sendAndReceiveWithSession(MockMvc mockMvc, HttpHeaders headers, String bean, String method,
            Object expectedResultOrType, Object... requestData) {
        return sendAndReceive(mockMvc, true, headers, null, null, bean, method, true, expectedResultOrType,
                new Object[] { requestData });
    }

    public static Object sendAndReceiveWithSession(MockMvc mockMvc, HttpHeaders headers, List<Cookie> cookies,
            String bean, String method, Object expectedResultOrType, Object... requestData) {
        return sendAndReceive(mockMvc, true, headers, cookies, null, bean, method, true, expectedResultOrType,
                new Object[] { requestData });
    }

    public static Object sendAndReceive(MockMvc mockMvc, boolean withSession, HttpHeaders headers,
            List<Cookie> cookies, Map<String, Object> metadata, String bean, String method, boolean namedParameters,
            Object expectedResultOrType, Object... requestData) {

        int tid = (int) (Math.random() * 1000);

        MvcResult result = null;
        try {
            result = performRouterRequest(mockMvc,
                    createEdsRequest(bean, method, namedParameters, tid, requestData, metadata), null, headers,
                    cookies, withSession);
        } catch (JsonProcessingException e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        } catch (Exception e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        }

        List<ExtDirectResponse> responses = readDirectResponses(result.getResponse().getContentAsByteArray());
        assertThat(responses).hasSize(1);

        ExtDirectResponse edResponse = responses.get(0);

        assertThat(edResponse.getAction()).isEqualTo(bean);
        assertThat(edResponse.getMethod()).isEqualTo(method);
        assertThat(edResponse.getTid()).isEqualTo(tid);
        assertThat(edResponse.getWhere()).isNull();

        if (expectedResultOrType == null) {
            assertThat(edResponse.getType()).isEqualTo("exception");
            assertThat(edResponse.getResult()).isNull();
            assertThat(edResponse.getMessage()).isEqualTo("Server Error");
        } else {
            assertThat(edResponse.getType()).isEqualTo("rpc");
            assertThat(edResponse.getMessage()).isNull();
            if (expectedResultOrType == Void.TYPE) {
                assertThat(edResponse.getResult()).isNull();
            } else if (expectedResultOrType instanceof Class<?>) {
                return ControllerUtil.convertValue(edResponse.getResult(), (Class<?>) expectedResultOrType);
            } else if (expectedResultOrType instanceof TypeReference) {
                return ControllerUtil.convertValue(edResponse.getResult(), (TypeReference<?>) expectedResultOrType);
            } else {
                assertThat(edResponse.getResult()).isEqualTo(expectedResultOrType);
            }
        }

        return edResponse.getResult();

    }

    public static Object sendAndReceiveObject(MockMvc mockMvc, String bean, String method) {
        int tid = (int) (Math.random() * 1000);

        MvcResult result = null;
        try {
            result = performRouterRequest(mockMvc, createEdsRequest(bean, method, false, tid, null, null), null,
                    null, null, false);
        } catch (JsonProcessingException e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        } catch (Exception e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        }

        List<ExtDirectResponse> responses = readDirectResponses(result.getResponse().getContentAsByteArray());
        assertThat(responses).hasSize(1);

        ExtDirectResponse edResponse = responses.get(0);

        assertThat(edResponse.getAction()).isEqualTo(bean);
        assertThat(edResponse.getMethod()).isEqualTo(method);
        assertThat(edResponse.getTid()).isEqualTo(tid);
        assertThat(edResponse.getWhere()).isNull();

        return edResponse.getResult();
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> sendAndReceiveMap(MockMvc mockMvc, String bean, String method) {
        return (Map<String, Object>) sendAndReceiveObject(mockMvc, bean, method);
    }

    @SuppressWarnings("unchecked")
    public static List<Map<String, Object>> sendAndReceiveMultiple(MockMvc mockMvc, List<BeanMethod> beanMethods) {
        for (BeanMethod beanMethod : beanMethods) {
            beanMethod.setTid((int) (Math.random() * 1000));
        }

        MvcResult result = null;
        try {
            result = performRouterRequest(mockMvc, createEdsRequest(beanMethods));
        } catch (JsonProcessingException e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        } catch (Exception e) {
            fail("perform post to /router" + e.getMessage());
            return null;
        }

        List<ExtDirectResponse> responses = readDirectResponses(result.getResponse().getContentAsByteArray());
        assertThat(responses).hasSize(beanMethods.size());

        List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < beanMethods.size(); i++) {
            ExtDirectResponse edResponse = responses.get(i);
            BeanMethod beanMethod = beanMethods.get(i);
            assertThat(edResponse.getAction()).isEqualTo(beanMethod.getBean());
            assertThat(edResponse.getMethod()).isEqualTo(beanMethod.getMethod());
            assertThat(edResponse.getTid()).isEqualTo(beanMethod.getTid());
            assertThat(edResponse.getWhere()).isNull();

            results.add((Map<String, Object>) edResponse.getResult());
        }

        return results;
    }

    @SuppressWarnings("unchecked")
    public static <T> T readValue(String json, Class<?> clazz) {
        try {
            return (T) mapper.readValue(json, clazz);
        } catch (Exception e) {
            LogFactory.getLog(JsonHandler.class).info("deserialize json to object", e);
            return null;
        }
    }

    public static <T> T convertValue(Object object, Class<T> clazz) {
        return mapper.convertValue(object, clazz);
    }

    public static <T> T convertValue(Object object, TypeReference<T> typeReference) {
        return mapper.convertValue(object, typeReference);
    }

    public static List<ExtDirectResponse> readDirectResponses(byte[] response) {
        try {
            return mapper.readValue(response, new TypeReference<List<ExtDirectResponse>>() {/*
                                                                                            * nothing here
                                                                                            */
            });
        } catch (JsonParseException e) {
            throw new RuntimeException(e);
        } catch (JsonMappingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static ExtDirectResponse readDirectResponse(byte[] response) {
        try {
            return mapper.readValue(response, ExtDirectResponse.class);
        } catch (JsonParseException e) {
            throw new RuntimeException(e);
        } catch (JsonMappingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static ExtDirectPollResponse readDirectPollResponse(byte[] response) {
        try {
            return mapper.readValue(response, ExtDirectPollResponse.class);
        } catch (JsonParseException e) {
            throw new RuntimeException(e);
        } catch (JsonMappingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] writeAsByte(Object obj) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            mapper.getFactory().createGenerator(bos, JsonEncoding.UTF8);
            return mapper.writeValueAsBytes(obj);
        } catch (JsonGenerationException e) {
            throw new RuntimeException(e);
        } catch (JsonMappingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}