com.netflix.suro.routing.TestRoutingMap.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.suro.routing.TestRoutingMap.java

Source

/*
 * Copyright 2013 Netflix, Inc.
 *
 *    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.netflix.suro.routing;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.collect.*;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.netflix.suro.SuroPlugin;
import com.netflix.suro.jackson.DefaultObjectMapper;
import com.netflix.suro.message.MessageContainer;
import com.netflix.suro.routing.RoutingMap.Route;
import com.netflix.suro.routing.RoutingMap.RoutingInfo;
import com.netflix.suro.sink.TestSinkManager.TestSink;
import org.junit.Test;
import org.mockito.Mockito;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.*;

public class TestRoutingMap {

    private static Injector injector = Guice.createInjector(new SuroPlugin() {
        @Override
        protected void configure() {
            this.addSinkType("TestSink", TestSink.class);
        }
    }, new AbstractModule() {
        @Override
        protected void configure() {
            bind(ObjectMapper.class).to(DefaultObjectMapper.class);
        }
    }, new RoutingPlugin());

    private Map<String, RoutingInfo> getRoutingMap(String desc) throws Exception {
        return injector.getInstance(ObjectMapper.class).<Map<String, RoutingInfo>>readValue(desc,
                new TypeReference<Map<String, RoutingInfo>>() {
                });
    }

    @Test
    public void generateRoutingInfo() throws Exception {
        RoutingInfo route1 = new RoutingInfo(
                ImmutableList.<Route>of(
                        new Route("sink2",
                                new XPathFilter("xpath(\"//customerInfo/country\") =~ \"(?i)^US\"",
                                        new JsonMapConverter()),
                                null),

                        new Route("sink3",
                                new XPathFilter("xpath(\"//responseInfo/status\") >= 400", new JsonMapConverter()),
                                null)),
                null);

        System.out.println(new DefaultObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(route1));
    }

    @Test
    public void testRoutingMapWithXPathFilter() throws Exception {
        String mapDesc = "{\n" + "  \"request_trace\" : {\n" + "    \"where\" : [ {\n"
                + "      \"sink\" : \"sink1\",\n" + "      \"filter\" : {\n" + "        \"type\" : \"xpath\",\n"
                + "        \"filter\" : \"xpath(\\\"//foo/bar\\\") =~ \\\"(?i)test\\\"\",\n"
                + "        \"converter\" : {\n" + "          \"type\" : \"jsonmap\"\n" + "        }\n" + "      }\n"
                + "    } ],\n" + "    \"filter\" : {\n" + "      \"type\" : \"regex\",\n"
                + "      \"regex\" : \"[a-b]+\"\n" + "    }\n" + "  }\n" + "}";

        Map<String, RoutingInfo> map = getRoutingMap(mapDesc);

        String routingKey = "request_trace";
        assertEquals("There should be one and only one key", 1, map.size());
        assertTrue("The only key is " + routingKey, map.containsKey(routingKey));

        RoutingInfo info = map.get(routingKey);
        List<Route> routes = info.getWhere();
        assertEquals("There should be only one sink", 1, routes.size());

        Route route = routes.get(0);
        assertEquals("sink1", route.getSink());

        Map<String, Map<String, String>> obj = Maps.newHashMap();
        obj.put("foo", ImmutableMap.of("bar", "tESt"));

        MessageContainer container = Mockito.mock(MessageContainer.class);
        Mockito.when(container.getEntity(Map.class)).thenReturn(obj);
        assertEquals(true, route.getFilter().doFilter(container));
    }

    @Test
    public void test() throws Exception {
        String mapDesc = "{\n" + "    \"request_trace\": {\n" + "        \"where\": [\n"
                + "            {\"sink\":\"sink1\"},\n" + "            {\"sink\":\"sink2\"},\n"
                + "            {\"sink\":\"sink3\"}\n" + "        ]\n" + "    },\n" + "    \"nf_errors_log\": {\n"
                + "        \"where\": [\n" + "            {\"sink\":\"sink3\"},\n"
                + "            {\"sink\":\"sink4\"}\n" + "        ]\n" + "    }\n" + "}";

        RoutingMap routingMap = new RoutingMap();
        routingMap.set(getRoutingMap(mapDesc));
        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("request_trace").getWhere()),
                new String[] { "sink1", "sink2", "sink3" }));

        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("nf_errors_log").getWhere()),
                new String[] { "sink3", "sink4" }));
        assertNull(routingMap.getRoutingInfo("streaming"));

        // test error
        // map description changed with json syntax error
        // nothing should be changed
        mapDesc = "{\n" + "    \"request_trace\": {\n" + "        \"where\": [\n"
                + "            {\"sink\":\"sink1\"},\n" + "            {\"sink\":\"sink2\"},\n"
                + "            {\"sink\":\"sink3\"}\n" + "        ]\n" + "    },\n" + "    \"nf_errors_log\": {\n"
                + "        \"where\": [\n" + "            {\"sink\":\"sink3\"},\n"
                + "            {\"sink\":\"sink4\"}\n" + "        ]\n" + "    }\n" + "}";
        routingMap.set(getRoutingMap(mapDesc));
        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("request_trace").getWhere()),
                new String[] { "sink1", "sink2", "sink3" }));

        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("nf_errors_log").getWhere()),
                new String[] { "sink3", "sink4" }));
        assertNull(routingMap.getRoutingInfo("streaming"));

        // description changed
        mapDesc = "{\n" + "    \"request_trace\": {\n" + "        \"where\": [\n"
                + "            {\"sink\":\"sink1\"},\n" + "            {\"sink\":\"sink2\"},\n"
                + "            {\"sink\":\"sink3\"}\n" + "        ]\n" + "    }\n" + "}";
        routingMap.set(getRoutingMap(mapDesc));
        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("request_trace").getWhere()),
                new String[] { "sink1", "sink2", "sink3" }));

        assertNull(routingMap.getRoutingInfo("nf_errors_log"));
        assertNull(routingMap.getRoutingInfo("streaming"));
    }

    private Object[] getSinkNames(List<Route> routes) {
        return Lists.newArrayList(Collections2.transform(routes, new Function<Route, String>() {
            @Override
            @Nullable
            public String apply(@Nullable Route input) {
                return input.getSink();
            }
        })).toArray();
    }

    @Test
    public void testDefaultRoutingIsOptional() throws Exception {
        // description changed
        String mapDesc = "{\n" + "    \"request_trace\": {\n" + "        \"where\": [\n"
                + "            {\"sink\":\"sink1\"},\n" + "            {\"sink\":\"sink2\"},\n"
                + "            {\"sink\":\"sink3\"}\n" + "        ]\n" + "    }\n" + "}";

        RoutingMap routingMap = new RoutingMap();
        routingMap.set(getRoutingMap(mapDesc));
        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("request_trace").getWhere()),
                new String[] { "sink1", "sink2", "sink3" }));

        // Verify that
        assertNull(routingMap.getRoutingInfo("nf_errors_log"));
        assertNull(routingMap.getRoutingInfo("streaming"));
    }

    @Test
    public void testDefaultRouting() throws Exception {
        String mapDesc = "{\n" + "    \"__default__\": {\n" + "       \"where\": [\n"
                + "         {\"sink\": \"sinkD1\"},\n" + "         {\"sink\": \"sinkD2\"}\n" + "       ]\n"
                + "    },\n" + "    \"request_trace\": {\n" + "        \"where\": [\n"
                + "            {\"sink\":\"sink1\"},\n" + "            {\"sink\":\"sink2\"},\n"
                + "            {\"sink\":\"sink3\"}\n" + "        ]\n" + "    },\n" + "    \"nf_errors_log\": {\n"
                + "        \"where\": [\n" + "            {\"sink\":\"sink3\"},\n"
                + "            {\"sink\":\"sink4\"}\n" + "        ]\n" + "    }\n" + "}";

        RoutingMap routingMap = new RoutingMap();
        routingMap.set(getRoutingMap(mapDesc));

        // Verify that default routes are in place
        assertArrayEquals(getSinkNames(routingMap.getRoutingInfo("some non existing key").getWhere()),
                new String[] { "sinkD1", "sinkD2" });

        // Ensure that overrides still work
        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("request_trace").getWhere()),
                new String[] { "sink1", "sink2", "sink3" }));

        assertTrue(Arrays.equals(getSinkNames(routingMap.getRoutingInfo("nf_errors_log").getWhere()),
                new String[] { "sink3", "sink4" }));

    }
}