/**
* Copyright (C) 2014 Stratio (http://stratio.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 com.stratio.decision.serializer.impl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import com.stratio.decision.commons.avro.Action;
import com.stratio.decision.commons.avro.ColumnType;
import com.stratio.decision.commons.avro.InsertMessage;
import com.stratio.decision.commons.constants.StreamAction;
import com.stratio.decision.commons.messages.ColumnNameTypeValue;
import com.stratio.decision.commons.messages.StratioStreamingMessage;
import com.stratio.decision.serializer.Serializer;
/**
* Created by josepablofernandez on 16/03/16.
*/
public class JavaToAvroSerializer implements Serializer<StratioStreamingMessage, byte[]> {
private static final long serialVersionUID = -3164736956154831507L;
private SpecificDatumReader datumReader = null;
public JavaToAvroSerializer(SpecificDatumReader datumReader) {
this.datumReader = datumReader;
}
@Override
public byte[] serialize(StratioStreamingMessage object) {
List<com.stratio.decision.commons.avro.ColumnType> columns = null;
if (object.getColumns() != null) {
columns = new java.util.ArrayList<>();
ColumnType c = null;
for (ColumnNameTypeValue messageColumn : object.getColumns()) {
if ( messageColumn.getValue() != null){
c = new ColumnType(messageColumn.getColumn(), messageColumn.getValue().toString(),
messageColumn.getValue().getClass().getName());
} else {
c = new ColumnType(messageColumn.getColumn(), null, null);
}
columns.add(c);
}
}
List<Action> actions = new ArrayList<>();
if (object.getActiveActions() != null){
object.getActiveActions().forEach( action -> {
switch (action){
case LISTEN:
actions.add(Action.LISTEN);
break;
case SAVE_TO_CASSANDRA:
actions.add(Action.SAVE_TO_CASSANDRA) ;
break;
case SAVE_TO_ELASTICSEARCH:
actions.add(Action.SAVE_TO_ELASTICSEARCH) ;
break;
case SAVE_TO_MONGO:
actions.add(Action.SAVE_TO_MONGO) ;
break;
case SAVE_TO_SOLR:
actions.add(Action.SAVE_TO_SOLR) ;
break;
default: ;
}
});
}
InsertMessage insertMessage = new InsertMessage(object.getOperation(), object.getStreamName(), object
.getSession_id(), object.getTimestamp(), columns, actions);
return getInsertMessageBytes(insertMessage);
}
private byte[] getInsertMessageBytes(InsertMessage insertMessage){
byte[] result = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);
SpecificDatumWriter writer = new SpecificDatumWriter<InsertMessage>(InsertMessage.getClassSchema());
try {
writer.write(insertMessage, encoder);
encoder.flush();
out.close();
result = out.toByteArray();
}catch (IOException e){
return null;
}
return result;
}
@Override
public StratioStreamingMessage deserialize(byte[] object) {
StratioStreamingMessage result = null;
BinaryDecoder bd = DecoderFactory.get().binaryDecoder(object, null);
if (datumReader == null) {
datumReader = new SpecificDatumReader(InsertMessage.getClassSchema());
}
try {
InsertMessage insertMessage = (InsertMessage) datumReader.read(null, bd);
result = convertMessage(insertMessage);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
private StratioStreamingMessage convertMessage(InsertMessage insertMessage){
StratioStreamingMessage stratioStreamingMessage = new StratioStreamingMessage();
stratioStreamingMessage.setStreamName(insertMessage.getStreamName().toString());
stratioStreamingMessage.setOperation(insertMessage.getOperation()==null?null:insertMessage.getOperation()
.toString());
stratioStreamingMessage.setSession_id(insertMessage.getSessionId()==null?null:insertMessage.getSessionId()
.toString());
stratioStreamingMessage.setTimestamp(insertMessage.getTimestamp());
if (insertMessage.getActions() == null){
stratioStreamingMessage.setActiveActions(null);
} else {
Set<StreamAction> activeActions = new HashSet<>();
insertMessage.getActions().forEach(
action -> {
switch (action) {
case LISTEN:
activeActions.add(StreamAction.LISTEN);
break;
case SAVE_TO_CASSANDRA:
activeActions.add(StreamAction.SAVE_TO_CASSANDRA);
break;
case SAVE_TO_ELASTICSEARCH:
activeActions.add(StreamAction.SAVE_TO_ELASTICSEARCH);
break;
case SAVE_TO_MONGO:
activeActions.add(StreamAction.SAVE_TO_MONGO);
break;
case SAVE_TO_SOLR:
activeActions.add(StreamAction.SAVE_TO_SOLR);
break;
default:
;
}
}
);
stratioStreamingMessage.setActiveActions(activeActions);
}
insertMessage.getData().forEach(
data -> {
ColumnNameTypeValue columnNameTypeValue = new ColumnNameTypeValue();
columnNameTypeValue.setColumn(data.getColumn().toString());
if (data.getValue() == null){
columnNameTypeValue.setValue(null);
columnNameTypeValue.setType(null);
}
else {
switch (data.getType().toString()) {
case "java.lang.Double":
Double doubleData = new Double(data.getValue().toString());
columnNameTypeValue.setValue(doubleData);
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.DOUBLE);
break;
case "java.lang.Float":
Float floatData = new Float(data.getValue().toString());
columnNameTypeValue.setValue(floatData);
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.FLOAT);
break;
case "java.lang.Integer":
Integer integerData = new Integer(data.getValue().toString());
columnNameTypeValue.setValue(integerData);
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.INTEGER);
break;
case "java.lang.Long":
Long longData = new Long(data.getValue().toString());
columnNameTypeValue.setValue(longData);
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.LONG);
break;
case "java.lang.Boolean":
Boolean booleanData = new Boolean(data.getValue().toString());
columnNameTypeValue.setValue(booleanData);
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.BOOLEAN);
break;
default:
columnNameTypeValue.setValue(data.getValue().toString());
columnNameTypeValue.setType(com.stratio.decision.commons.constants.ColumnType.STRING);
}
}
stratioStreamingMessage.addColumn(columnNameTypeValue);
}
);
return stratioStreamingMessage;
}
@Override
public List<byte[]> serialize(List<StratioStreamingMessage> object) {
List<byte[]> result = new ArrayList<>();
if (object != null) {
for (StratioStreamingMessage message : object) {
result.add(serialize(message));
}
}
return result;
}
@Override
public List<StratioStreamingMessage> deserialize(List<byte[]> object) {
List<StratioStreamingMessage> result = new ArrayList<>();
if (object != null) {
for (byte[] event : object) {
result.add(deserialize(event));
}
}
return result;
}
}