/** * Copyright 2014 Comcast Cable Communications Management, LLC * * 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.comcast.viper.flume2storm; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Map.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.comcast.viper.flume2storm.event.F2SEvent; import com.comcast.viper.flume2storm.event.F2SEventBuilder; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; /** * Kryo serializer for {@link F2SEvent}.<br /> */ public class F2SEventSerializer extends Serializer<F2SEvent> { protected static final Logger LOG = LoggerFactory.getLogger(F2SEventSerializer.class); /** * @see com.esotericsoftware.kryo.Serializer#read(com.esotericsoftware.kryo.Kryo, * com.esotericsoftware.kryo.io.Input, java.lang.Class) */ @Override public F2SEvent read(Kryo kryo, Input input, Class<F2SEvent> arg2) { return readDirect(kryo, input, arg2); } private F2SEvent readDirect(Kryo kryo, Input input, Class<F2SEvent> arg2) { try { F2SEventBuilder builder = new F2SEventBuilder(); int nbHeaders = input.readInt(); Builder<String, String> headers = new ImmutableMap.Builder<String, String>(); for (int i = 0; i < nbHeaders; i++) { headers.put(input.readString(), input.readString()); } builder.headers(headers.build()); int bodySz = input.readInt(); builder.body(input.readBytes(bodySz)); // builder.body(kryo.readObject(input, byte[].class)); return builder.get(); } catch (Exception e) { LOG.error("Failed to deserialize: " + e.getMessage(), e); return null; } } @SuppressWarnings("unused") private F2SEvent readWithByteBuffer(Kryo kryo, Input input, Class<F2SEvent> arg2) { try { F2SEventBuilder builder = new F2SEventBuilder(); int sz = input.readInt(); byte[] data = input.readBytes(sz); ByteBuffer bb = ByteBuffer.wrap(data); int nbHeaders = bb.getInt(); for (int i = 0; i < nbHeaders; i++) { int keySz = bb.getInt(); byte[] key = new byte[keySz]; bb.get(key); int valueSz = bb.getInt(); byte[] value = new byte[valueSz]; bb.get(value); builder.header(new String(key), new String(value)); } int bodySz = bb.getInt(); byte[] body = new byte[bodySz]; bb.get(body); builder.body(body); return builder.get(); } catch (Exception e) { LOG.error("Failed to deserialize: " + e.getMessage(), e); return null; } } /** * @see com.esotericsoftware.kryo.Serializer#write(com.esotericsoftware.kryo.Kryo, * com.esotericsoftware.kryo.io.Output, java.lang.Object) */ @Override public void write(Kryo kryo, Output output, F2SEvent event) { writeDirect(kryo, output, event); } private void writeDirect(Kryo kryo, Output output, F2SEvent event) { try { output.writeInt(event.getHeaders().size()); for (Entry<String, String> header : event.getHeaders().entrySet()) { output.writeString(header.getKey()); output.writeString(header.getValue()); } output.writeInt(event.getBody().length); output.writeBytes(event.getBody()); } catch (Exception e) { LOG.error("Failed to serialize!", e); } } @SuppressWarnings("unused") private void writeWithByteBuffer(Kryo kryo, Output output, F2SEvent event) { try { // Computing approximate size of the event int sz = 1024 + event.getBody().length; for (Entry<String, String> entry : event.getHeaders().entrySet()) { sz += entry.getKey().getBytes().length + entry.getValue().getBytes().length; } ByteBuffer bb = ByteBuffer.allocate(sz); bb.putInt(event.getHeaders().size()); for (Entry<String, String> entry : event.getHeaders().entrySet()) { byte[] key = entry.getKey().getBytes(); byte[] value = entry.getValue().getBytes(); bb.putInt(key.length); bb.put(key); bb.putInt(value.length); bb.put(value); } bb.putInt(event.getBody().length); bb.put(event.getBody()); bb.flip(); byte[] result = Arrays.copyOf(bb.array(), bb.limit()); output.writeInt(result.length); output.writeBytes(result); } catch (Exception e) { LOG.error("Failed to serialize!", e); } } }