/**
 * 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.storm.serialization;

import com.google.common.collect.Lists;
import org.apache.storm.Config;
import org.apache.storm.testing.TestSerObject;
import org.apache.storm.utils.Utils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SerializationTest {

    private static final Logger LOG = LoggerFactory.getLogger(SerializationTest.class);

    @Test
    public void testJavaSerialization() {
        Object obj = new TestSerObject(1, 2);
        List<Object> vals = Lists.newArrayList(obj);

        Map<String, Object> conf = new HashMap<>();
        conf.put(Config.TOPOLOGY_KRYO_REGISTER, new HashMap<String, String>() {{
            put("org.apache.storm.testing.TestSerObject", null);
        }});
        conf.put(Config.TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION, false);
        try {
            roundtrip(vals, conf);
            Assert.fail("Expected Exception not Thrown for config: " + conf);
        } catch (Exception e) {
        }

        conf.clear();
        conf.put(Config.TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION, true);
        Assert.assertEquals(vals, roundtrip(vals, conf));
    }

    @Test
    public void testKryoDecorator() {
        Object obj = new TestSerObject(1, 2);
        List<Object> vals = Lists.newArrayList(obj);

        Map<String, Object> conf = new HashMap<>();
        conf.put(Config.TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION, false);
        try {
            roundtrip(vals, conf);
            Assert.fail("Expected Exception not Thrown for config: " + conf);
        } catch (Exception e) {
        }

        conf.put(Config.TOPOLOGY_KRYO_DECORATORS, Lists.newArrayList("org.apache.storm.testing.TestKryoDecorator"));
        Assert.assertEquals(vals, roundtrip(vals, conf));
    }

    @Test
    public void testStringSerialization() {
        isRoundtrip(Lists.newArrayList("a", "bb", "cbe"));
        isRoundtrip(Lists.newArrayList(mkString(64 * 1024)));
        isRoundtrip(Lists.newArrayList(mkString(1024 * 1024)));
        isRoundtrip(Lists.newArrayList(mkString(1024 * 1024 * 2)));
    }

    private Map mkConf(Map extra) {
        Map config = Utils.readDefaultConfig();
        config.putAll(extra);
        return config;
    }

    private byte[] serialize(List vals, Map conf) throws IOException {
        KryoValuesSerializer serializer = new KryoValuesSerializer(mkConf(conf));
        return serializer.serialize(vals);
    }

    private List deserialize(byte[] bytes, Map conf) throws IOException {
        KryoValuesDeserializer deserializer = new KryoValuesDeserializer(mkConf(conf));
        return deserializer.deserialize(bytes);
    }

    private List roundtrip(List vals) {
        return roundtrip(vals, new HashMap());
    }

    private List roundtrip(List vals, Map conf) {
        List ret = null;
        try {
            ret = deserialize(serialize(vals, conf), conf);
        } catch (IOException e) {
            LOG.error("Exception when serialize/deserialize ", e);
        }
        return ret;
    }

    private String mkString(int size) {
        StringBuilder sb = new StringBuilder();
        while (size-- > 0) {
            sb.append("a");
        }
        return sb.toString();
    }

    public void isRoundtrip(List vals) {
        Assert.assertEquals(vals, roundtrip(vals));
    }
}
@@ -421,16 +421,21 @@
 se at%0A *
+ %3Cp/%3E
 %0A * http
@@ -475,16 +475,21 @@
 E-2.0%0A *
+ %3Cp/%3E
 %0A * Unle
@@ -1054,65 +1054,8 @@
 est;
-%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aim
@@ -1190,97 +1190,8 @@
  %7B%0A%0A
-    private static final Logger LOG = LoggerFactory.getLogger(SerializationTest.class);%0A%0A
     
@@ -1227,32 +1227,51 @@
 aSerialization()
+ throws IOException
  %7B%0A        Objec
@@ -2017,16 +2017,35 @@
 orator()
+ throws IOException
  %7B%0A     
@@ -2668,16 +2668,35 @@
 zation()
+ throws IOException
  %7B%0A     
@@ -3543,32 +3543,51 @@
 dtrip(List vals)
+ throws IOException
  %7B%0A        retur
@@ -3679,53 +3679,29 @@
 nf) 
-%7B%0A        List ret = null;%0A        try %7B%0A    
+throws IOException %7B%0A
     
@@ -3707,18 +3707,19 @@
      ret
- =
+urn
  deseria
@@ -3757,139 +3757,8 @@
 f);%0A
-        %7D catch (IOException e) %7B%0A            LOG.error(%22Exception when serialize/deserialize %22, e);%0A        %7D%0A        return ret;%0A
     
@@ -3990,16 +3990,35 @@
 st vals)
+ throws IOException
  %7B%0A     

address review comment