ch.ralscha.extdirectspring_itest.SimpleServiceTest.java Source code

Java tutorial

Introduction

Here is the source code for ch.ralscha.extdirectspring_itest.SimpleServiceTest.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_itest;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.databene.contiperf.PerfTest;
import org.databene.contiperf.junit.ContiPerfRule;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.junit.Rule;
import org.junit.Test;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ch.ralscha.extdirectspring.bean.api.Action;
import ch.ralscha.extdirectspring.bean.api.PollingProvider;
import ch.ralscha.extdirectspring.bean.api.RemotingApi;
import ch.ralscha.extdirectspring.controller.ApiControllerTest;
import ch.ralscha.extdirectspring.controller.ApiRequestParams;

public class SimpleServiceTest extends JettyTest2 {

    @Rule
    public ContiPerfRule i = new ContiPerfRule();

    private final static AtomicInteger id = new AtomicInteger();

    private final static ObjectMapper mapper = new ObjectMapper();

    private static RemotingApi api() {
        RemotingApi remotingApi = new RemotingApi("remoting", "/controller/router", null);
        remotingApi.addAction("simpleService", Action.create("toUpperCase", 1));
        remotingApi.addAction("simpleService",
                Action.createNamed("echo", Arrays.asList("userId", "logLevel"), null, null));

        PollingProvider pollingProvider = new PollingProvider("simpleService", "poll", "poll");
        remotingApi.addPollingProvider(pollingProvider);

        return remotingApi;
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleApiDebug() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            HttpGet get = new HttpGet("http://localhost:9998/controller/api-debug.js?group=itest_simple");
            handleApi(client, get, false);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleApi() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            HttpGet get = new HttpGet("http://localhost:9998/controller/api.js?group=itest_simple");
            handleApi(client, get, false);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleApiFingerprinted() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            HttpGet get = new HttpGet("http://localhost:9998/controller/api-1.0.0.js?group=itest_simple");
            handleApi(client, get, true);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    private static void handleApi(HttpClient client, HttpGet get, boolean fingerprinted)
            throws IOException, JsonParseException, JsonMappingException {
        HttpResponse response = client.execute(get);
        HttpEntity entity = response.getEntity();
        assertThat(entity).isNotNull();
        String responseString = EntityUtils.toString(entity);

        String contentType = response.getFirstHeader("Content-Type").getValue();
        ApiControllerTest.compare(responseString, contentType, api(), ApiRequestParams.builder().build());

        assertCacheHeaders(response, fingerprinted);
    }

    public static void assertCacheHeaders(HttpResponse response, boolean fingerprinted) {
        if (fingerprinted) {
            assertThat(response.getFirstHeader("Content-Type").getValue())
                    .isEqualTo("application/javascript;charset=UTF-8");
            assertThat(response.getFirstHeader("Content-Length")).isNotNull();

            String expiresString = response.getFirstHeader("Expires").getValue();
            DateTimeFormatter fmt = DateTimeFormat.forPattern("E, dd MMM yyyy HH:mm:ss ZZZ")
                    .withLocale(Locale.ENGLISH);

            DateTime expires = DateTime.parse(expiresString, fmt);
            DateTime inSixMonths = DateTime.now(DateTimeZone.UTC).plusSeconds(6 * 30 * 24 * 60 * 60);
            assertThat(expires.getYear()).isEqualTo(inSixMonths.getYear());
            assertThat(expires.getMonthOfYear()).isEqualTo(inSixMonths.getMonthOfYear());
            assertThat(expires.getDayOfMonth()).isEqualTo(inSixMonths.getDayOfMonth());
            assertThat(expires.getHourOfDay()).isEqualTo(inSixMonths.getHourOfDay());
            assertThat(expires.getMinuteOfDay()).isEqualTo(inSixMonths.getMinuteOfDay());

            assertThat(response.getFirstHeader("ETag").getValue()).isNotNull();
            assertThat(response.getFirstHeader("Cache-Control").getValue()).isEqualTo("public, max-age=15552000");

        } else {
            assertThat(response.getFirstHeader("Content-Type").getValue())
                    .isEqualTo("application/javascript;charset=UTF-8");
            assertThat(response.getFirstHeader("Content-Length")).isNotNull();
            assertThat(response.getFirstHeader("Expires")).isNull();
            assertThat(response.getFirstHeader("ETag")).isNull();
            assertThat(response.getFirstHeader("Cache-Control")).isNull();
        }
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleCall() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            postToUpperCase("ralph", client);
            postToUpperCase("renee", client);
            postToUpperCase("andrea", client);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testPoll() throws IOException {
        String _id = String.valueOf(id.incrementAndGet());
        CloseableHttpClient client = HttpClientBuilder.create().build();
        CloseableHttpResponse response = null;
        try {

            HttpGet get = new HttpGet("http://localhost:9998/controller/poll/simpleService/poll/poll?id=" + _id);
            response = client.execute(get);

            assertThat(response.getFirstHeader("Content-Type").getValue())
                    .isEqualTo("application/json;charset=UTF-8");

            String responseString = EntityUtils.toString(response.getEntity());
            Map<String, Object> rootAsMap = mapper.readValue(responseString, Map.class);
            assertThat(rootAsMap).hasSize(3);
            assertThat(rootAsMap.get("type")).isEqualTo("event");
            assertThat(rootAsMap.get("name")).isEqualTo("poll");
            assertThat(rootAsMap.get("data")).isEqualTo(_id);
        } finally {
            IOUtils.closeQuietly(response);
            IOUtils.closeQuietly(client);
        }
    }

    private static void postToUpperCase(String text, HttpClient client)
            throws IOException, JsonParseException, JsonMappingException {
        HttpPost post = new HttpPost("http://localhost:9998/controller/router");

        StringEntity postEntity = new StringEntity(
                "{\"action\":\"simpleService\",\"method\":\"toUpperCase\",\"data\":[\"" + text
                        + "\"],\"type\":\"rpc\",\"tid\":1}",
                "UTF-8");
        post.setEntity(postEntity);
        post.setHeader("Content-Type", "application/json; charset=UTF-8");

        HttpResponse response = client.execute(post);

        HttpEntity entity = response.getEntity();
        assertThat(entity).isNotNull();
        String responseString = EntityUtils.toString(entity);
        assertThat(response.getFirstHeader("Content-Length").getValue()).isEqualTo("" + responseString.length());

        assertThat(responseString).isNotNull();
        assertThat(responseString).startsWith("[").endsWith("]");

        Map<String, Object> rootAsMap = mapper.readValue(responseString.substring(1, responseString.length() - 1),
                Map.class);
        assertThat(rootAsMap).hasSize(5);
        assertThat(rootAsMap.get("result")).isEqualTo(text.toUpperCase());
        assertThat(rootAsMap.get("method")).isEqualTo("toUpperCase");
        assertThat(rootAsMap.get("type")).isEqualTo("rpc");
        assertThat(rootAsMap.get("action")).isEqualTo("simpleService");
        assertThat(rootAsMap.get("tid")).isEqualTo(1);
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleNamedCall() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            postToEcho(Collections.singletonList("\"userId\":\"ralph\", \"logLevel\": 100"),
                    Collections.singletonList("UserId: ralph LogLevel: 100"), client);
            postToEcho(Collections.singletonList("\"userId\":\"tom\""),
                    Collections.singletonList("UserId: tom LogLevel: 10"), client);
            postToEcho(Collections.singletonList("\"userId\":\"renee\", \"logLevel\": 1"),
                    Collections.singletonList("UserId: renee LogLevel: 1"), client);
            postToEcho(Collections.singletonList("\"userId\":\"andrea\""),
                    Collections.singletonList("UserId: andrea LogLevel: 10"), client);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    @Test
    @PerfTest(invocations = 150, threads = 5)
    public void testSimpleNamedCallBatched() throws IllegalStateException, IOException {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        try {
            postToEcho(
                    Arrays.asList("\"userId\":\"Ralph\", \"logLevel\": 100", "\"userId\":\"Tom\"",
                            "\"userId\":\"Renee\", \"logLevel\": 1", "\"userId\":\"Andrea\""),
                    Arrays.asList("UserId: Ralph LogLevel: 100", "UserId: Tom LogLevel: 10",
                            "UserId: Renee LogLevel: 1", "UserId: Andrea LogLevel: 10"),
                    client);
        } finally {
            IOUtils.closeQuietly(client);
        }
    }

    private static void postToEcho(List<String> datas, List<String> expectedResult, HttpClient client)
            throws IOException, JsonParseException, JsonMappingException {

        HttpPost post = new HttpPost("http://localhost:9998/controller/router");

        StringBuilder postData = new StringBuilder();

        if (datas.size() > 1) {
            postData.append("[");
        }

        for (int i = 0; i < datas.size(); i++) {
            postData.append("{\"action\":\"simpleService\",\"method\":\"echo\",\"data\":{");
            postData.append(datas.get(i));
            postData.append("},\"type\":\"rpc\",\"tid\":");
            postData.append(i + 1);
            postData.append("}");
            if (i < datas.size() - 1) {
                postData.append(",");
            }
        }

        if (datas.size() > 1) {
            postData.append("]");
        }

        StringEntity postEntity = new StringEntity(postData.toString(), "UTF-8");

        post.setEntity(postEntity);
        post.setHeader("Content-Type", "application/json; charset=UTF-8");

        HttpResponse response = client.execute(post);
        HttpEntity entity = response.getEntity();
        assertThat(entity).isNotNull();
        String responseString = EntityUtils.toString(entity);

        assertThat(response.getFirstHeader("Content-Length")).isNull();

        assertThat(responseString).isNotNull();

        assertThat(responseString).startsWith("[").endsWith("]");

        List<Map<String, Object>> results = mapper.readValue(responseString, List.class);
        assertThat(results).hasSize(expectedResult.size());
        int tid = 1;
        for (Map<String, Object> map : results) {
            assertThat(map).hasSize(5);
            assertThat(map.get("result")).isEqualTo(expectedResult.get(tid - 1));
            assertThat(map.get("method")).isEqualTo("echo");
            assertThat(map.get("type")).isEqualTo("rpc");
            assertThat(map.get("action")).isEqualTo("simpleService");
            assertThat(map.get("tid")).isEqualTo(tid++);
        }

    }

}