/**
* Copyright 2014 Lockheed Martin Corporation
*
* 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 streamflow.engine.framework;
import backtype.storm.Config;
import backtype.storm.serialization.IKryoFactory;
import backtype.storm.serialization.SerializableSerializer;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import streamflow.model.Topology;
import streamflow.model.TopologyConfig;
import streamflow.model.TopologySerialization;
import streamflow.engine.topology.TopologySubmitter;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FrameworkKryoFactory implements IKryoFactory {
protected static final Logger LOG = LoggerFactory.getLogger(FrameworkKryoFactory.class);
public static final String KRYO_REALM = "kryo-realm";
public static class KryoSerializableDefault extends Kryo {
boolean override = false;
public void overrideDefault(boolean value) {
override = value;
}
@Override
public Serializer getDefaultSerializer(Class type) {
if (override) {
return new SerializableSerializer();
} else {
return super.getDefaultSerializer(type);
}
}
}
@Override
public Kryo getKryo(Map conf) {
KryoSerializableDefault kryo = new KryoSerializableDefault();
kryo.setRegistrationRequired(!((Boolean) conf.get(
Config.TOPOLOGY_FALL_BACK_ON_JAVA_SERIALIZATION)));
kryo.setReferences(false);
// Initialize this topology with the the serialization realms
try {
////////////////////////////////////////////////////////////////////////////////////////
// TODO: NEED TO FIND A WAY TO LOAD THE LIST OF SERIALZATIONS WITHOUT TOPOLOGY.JSON
// AS THIS METHOD WILL ONLY WORK FOR CLUSTER DEPLOYS
////////////////////////////////////////////////////////////////////////////////////////
String topologyJson = IOUtils.toString(
TopologySubmitter.class.getClassLoader().getResourceAsStream(
"STREAMFLOW-INF/topology.json"));
// Retrieve the topology from the inbuilt topology json file
ObjectMapper mapper = new ObjectMapper();
Topology topology = mapper.readValue(topologyJson, Topology.class);
TopologyConfig topologyConfig = topology.getDeployedConfig();
// Iterate over all of the registered serializations and add them to the realm
for (TopologySerialization serialization : topologyConfig.getSerializations()) {
try {
// Retrieve the required serialization class from the Kryo Realm
Class typeClass = FrameworkUtils.getInstance().loadFrameworkClass(
serialization.getFrameworkHash(), serialization.getTypeClass(),
topology.getClassLoaderPolicy());
// Retrieve the optional serializer class
Class<Serializer> serializerClass = null;
if (serialization.getSerializerClass() != null) {
serializerClass = FrameworkUtils.getInstance().loadFrameworkClass(
serialization.getFrameworkHash(), serialization.getSerializerClass(),
topology.getClassLoaderPolicy());
}
if (serializerClass == null) {
// Register the type class using the default Kryo Fields Serializer
kryo.register(typeClass);
LOG.info("Streamflow Registered serialization: Type Class = "
+ serialization.getTypeClass());
} else {
// Register the type class using the custom serializer
kryo.register(typeClass, serializerClass.newInstance());
LOG.info("Streamflow Registered serialization: Type Class = "
+ serialization.getTypeClass() + ", Serializer Class = "
+ serialization.getSerializerClass());
}
} catch (Exception ex) {
LOG.error("Exception while registering serialization: "
+ serialization.getTypeClass() + ": ", ex);
}
}
} catch (Exception ex) {
LOG.error("Exception while initializing the Streamflow Framework Kryo Factory: ", ex);
}
return kryo;
}
@Override
public void preRegister(Kryo kryo, Map map) {
}
@Override
public void postRegister(Kryo kryo, Map map) {
((KryoSerializableDefault) kryo).overrideDefault(true);
}
@Override
public void postDecorate(Kryo kryo, Map map) {
}
}