package rocks.inspectit.shared.all.serializer.impl; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.slf4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import org.springframework.remoting.support.RemoteInvocation; import org.springframework.remoting.support.RemoteInvocationResult; import org.springframework.stereotype.Component; import com.esotericsoftware.kryo.ClassResolver; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.ReferenceResolver; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.kryo.serializers.CollectionSerializer; import com.esotericsoftware.kryo.serializers.DefaultArraySerializers.LongArraySerializer; import com.esotericsoftware.kryo.serializers.DefaultSerializers.ClassSerializer; import com.esotericsoftware.kryo.serializers.DefaultSerializers.DateSerializer; import com.esotericsoftware.kryo.serializers.DefaultSerializers.EnumSerializer; import com.esotericsoftware.kryo.serializers.FieldSerializer; import com.esotericsoftware.kryo.serializers.MapSerializer; import com.esotericsoftware.kryo.util.DefaultClassResolver; import com.esotericsoftware.kryo.util.MapReferenceResolver; import com.esotericsoftware.kryo.util.ObjectMap; import de.javakaffee.kryoserializers.SynchronizedCollectionsSerializer; import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer; import rocks.inspectit.shared.all.cmr.model.JmxDefinitionDataIdent; import rocks.inspectit.shared.all.cmr.model.JmxSensorTypeIdent; import rocks.inspectit.shared.all.cmr.model.MethodIdent; import rocks.inspectit.shared.all.cmr.model.MethodIdentToSensorType; import rocks.inspectit.shared.all.cmr.model.MethodSensorTypeIdent; import rocks.inspectit.shared.all.cmr.model.PlatformIdent; import rocks.inspectit.shared.all.cmr.model.PlatformSensorTypeIdent; import rocks.inspectit.shared.all.cmr.model.SensorTypeIdent; import rocks.inspectit.shared.all.communication.DefaultData; import rocks.inspectit.shared.all.communication.ExceptionEvent; import rocks.inspectit.shared.all.communication.data.AggregatedExceptionSensorData; import rocks.inspectit.shared.all.communication.data.AggregatedHttpTimerData; import rocks.inspectit.shared.all.communication.data.AggregatedSqlStatementData; import rocks.inspectit.shared.all.communication.data.AggregatedTimerData; import rocks.inspectit.shared.all.communication.data.ClassLoadingInformationData; import rocks.inspectit.shared.all.communication.data.CompilationInformationData; import rocks.inspectit.shared.all.communication.data.CpuInformationData; import rocks.inspectit.shared.all.communication.data.DatabaseAggregatedTimerData; import rocks.inspectit.shared.all.communication.data.ExceptionSensorData; import rocks.inspectit.shared.all.communication.data.HttpInfo; import rocks.inspectit.shared.all.communication.data.HttpTimerData; import rocks.inspectit.shared.all.communication.data.InvocationAwareData.MutableInt; import rocks.inspectit.shared.all.communication.data.InvocationSequenceData; import rocks.inspectit.shared.all.communication.data.JmxSensorValueData; import rocks.inspectit.shared.all.communication.data.LoggingData; import rocks.inspectit.shared.all.communication.data.MemoryInformationData; import rocks.inspectit.shared.all.communication.data.ParameterContentData; import rocks.inspectit.shared.all.communication.data.ParameterContentType; import rocks.inspectit.shared.all.communication.data.RuntimeInformationData; import rocks.inspectit.shared.all.communication.data.SqlStatementData; import rocks.inspectit.shared.all.communication.data.SystemInformationData; import rocks.inspectit.shared.all.communication.data.ThreadInformationData; import rocks.inspectit.shared.all.communication.data.TimerData; import rocks.inspectit.shared.all.communication.data.VmArgumentData; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData.AgentConnection; import rocks.inspectit.shared.all.communication.data.cmr.ApplicationData; import rocks.inspectit.shared.all.communication.data.cmr.BusinessTransactionData; import rocks.inspectit.shared.all.communication.data.cmr.CmrStatusData; import rocks.inspectit.shared.all.exception.BusinessException; import rocks.inspectit.shared.all.exception.RemoteException; import rocks.inspectit.shared.all.exception.TechnicalException; import rocks.inspectit.shared.all.exception.enumeration.AgentManagementErrorCodeEnum; import rocks.inspectit.shared.all.exception.enumeration.AlertErrorCodeEnum; import rocks.inspectit.shared.all.exception.enumeration.BusinessContextErrorCodeEnum; import rocks.inspectit.shared.all.exception.enumeration.ConfigurationInterfaceErrorCodeEnum; import rocks.inspectit.shared.all.exception.enumeration.StorageErrorCodeEnum; import rocks.inspectit.shared.all.instrumentation.classcache.AnnotationType; import rocks.inspectit.shared.all.instrumentation.classcache.ClassType; import rocks.inspectit.shared.all.instrumentation.classcache.InterfaceType; import rocks.inspectit.shared.all.instrumentation.classcache.MethodType; import rocks.inspectit.shared.all.instrumentation.classcache.util.ArraySet; import rocks.inspectit.shared.all.instrumentation.classcache.util.MethodTypeSet; import rocks.inspectit.shared.all.instrumentation.classcache.util.SortedArraySet; import rocks.inspectit.shared.all.instrumentation.classcache.util.TypeSet; import rocks.inspectit.shared.all.instrumentation.classcache.util.TypeWithAnnotationsSet; import rocks.inspectit.shared.all.instrumentation.config.PriorityEnum; import rocks.inspectit.shared.all.instrumentation.config.SpecialInstrumentationType; import rocks.inspectit.shared.all.instrumentation.config.impl.AgentConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.ExceptionSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.InstrumentationDefinition; import rocks.inspectit.shared.all.instrumentation.config.impl.JmxAttributeDescriptor; import rocks.inspectit.shared.all.instrumentation.config.impl.JmxSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodInstrumentationConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.PlatformSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.PropertyPath; import rocks.inspectit.shared.all.instrumentation.config.impl.PropertyPathStart; import rocks.inspectit.shared.all.instrumentation.config.impl.SensorInstrumentationPoint; import rocks.inspectit.shared.all.instrumentation.config.impl.SpecialInstrumentationPoint; import rocks.inspectit.shared.all.instrumentation.config.impl.StrategyConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.SubstitutionDescriptor; import rocks.inspectit.shared.all.pattern.EqualsMatchPattern; import rocks.inspectit.shared.all.pattern.WildcardMatchPattern; import rocks.inspectit.shared.all.serializer.HibernateAwareClassResolver; import rocks.inspectit.shared.all.serializer.IKryoProvider; import rocks.inspectit.shared.all.serializer.ISerializer; import rocks.inspectit.shared.all.serializer.SerializationException; import rocks.inspectit.shared.all.serializer.schema.ClassSchemaManager; import rocks.inspectit.shared.all.spring.logger.Log; import rocks.inspectit.shared.all.tracing.data.ClientSpan; import rocks.inspectit.shared.all.tracing.data.ServerSpan; import rocks.inspectit.shared.all.tracing.data.SpanIdent; import rocks.inspectit.shared.all.util.IHibernateUtil; import rocks.inspectit.shared.all.util.KryoNetNetwork; import rocks.inspectit.shared.all.util.TimeFrame; /** * Implementation of the {@link ISerializer} that uses Kryo library for serializing the objects. * <br> * <br> * <b>This class is not thread safe and should be used with special attention. The class can be used * only by one thread while the serialization/de-serialization process lasts.</b> * * @author Ivan Senic * */ @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Lazy public class SerializationManager implements ISerializer, IKryoProvider, InitializingBean { /** * Logger of this class. */ @Log Logger logger; /** * Main {@link Kryo} instance. */ private Kryo kryo; /** * {@link KryoNetNetwork} for registering needed classes for communication. */ @Autowired private KryoNetNetwork kryoNetNetwork; /** * Schema manager that holds all schemas for the {@link DefaultData} objects to be serialized. */ @Autowired private ClassSchemaManager schemaManager; /** * {@link IHibernateUtil} if needed for Hibernate persistent collections/maps solving. */ @Autowired(required = false) IHibernateUtil hibernateUtil; /** * Initialize {@link Kryo} properties. */ public void initKryo() { // if hibernateUtil is provided, we create special kind of class resolver ClassResolver classResolver; if (null != hibernateUtil) { classResolver = new HibernateAwareClassResolver(hibernateUtil); } else { classResolver = new DefaultClassResolver(); } // we disable references for DefaultData objects because they are not needed // invocations will be handled manually ReferenceResolver referenceResolver = new MapReferenceResolver() { @SuppressWarnings("rawtypes") @Override public boolean useReferences(Class paramClass) { if (DefaultData.class.isAssignableFrom(paramClass)) { return false; } else { return super.useReferences(paramClass); } } }; kryo = new Kryo(classResolver, referenceResolver); kryo.setRegistrationRequired(false); registerClasses(kryo); } /** * Registers all necessary classes to the {@link Kryo} instance; * * ATTENTION! * * Please do not change the order of the registered classes. If new classes need to be * registered, please add this registration at the end. Otherwise the old data will not be able * to be de-serialized. If some class is not need to be register any more, do not remove the * registration. If the class is not available any more, add arbitrary class to its position, so * that the order can be maintained. Do not add unnecessary classes to the registration list. * * NOTE: By default, all primitives (including wrappers) and java.lang.String are registered. * Any other class, including JDK classes like ArrayList and even arrays such as String[] or * int[] must be registered. * * NOTE: If it is known up front what classes need to be serialized, registering the classes is * ideal. However, in some cases the classes to serialize are not known until it is time to * perform the serialization. When setRegistrationOptional is true, registered classes are still * written as an integer. However, unregistered classes are written as a String, using the name * of the class. This is much less efficient, but can't always be avoided. * * @param kryo * Kryo that needs to be prepared. */ private void registerClasses(Kryo kryo) { /** Java native classes */ kryo.register(Class.class, new ClassSerializer()); kryo.register(ArrayList.class, new HibernateAwareCollectionSerializer(hibernateUtil)); // NOPMD kryo.register(CopyOnWriteArrayList.class, new CollectionSerializer()); kryo.register(HashSet.class, new HibernateAwareCollectionSerializer(hibernateUtil)); // NOPMD kryo.register(HashMap.class, new HibernateAwareMapSerializer(hibernateUtil)); // NOPMD kryo.register(ConcurrentHashMap.class, new MapSerializer()); kryo.register(Timestamp.class, new TimestampSerializer()); kryo.register(Date.class, new DateSerializer()); kryo.register(AtomicLong.class, new FieldSerializer<AtomicLong>(kryo, AtomicLong.class)); /** Arrays */ kryo.register(long[].class, new LongArraySerializer()); /** inspectIT model classes */ kryo.register(PlatformIdent.class, new CustomCompatibleFieldSerializer<PlatformIdent>(kryo, PlatformIdent.class, schemaManager)); kryo.register(MethodIdent.class, new CustomCompatibleFieldSerializer<MethodIdent>(kryo, MethodIdent.class, schemaManager)); kryo.register(SensorTypeIdent.class, new CustomCompatibleFieldSerializer<SensorTypeIdent>(kryo, SensorTypeIdent.class, schemaManager)); kryo.register(MethodSensorTypeIdent.class, new CustomCompatibleFieldSerializer<MethodSensorTypeIdent>(kryo, MethodSensorTypeIdent.class, schemaManager)); kryo.register(PlatformSensorTypeIdent.class, new CustomCompatibleFieldSerializer<PlatformSensorTypeIdent>(kryo, PlatformSensorTypeIdent.class, schemaManager, true)); /** Common data classes */ kryo.register(MutableInt.class, new FieldSerializer<MutableInt>(kryo, MutableInt.class)); kryo.register(InvocationSequenceData.class, new InvocationSequenceCustomCompatibleFieldSerializer(kryo, InvocationSequenceData.class, schemaManager)); kryo.register(TimerData.class, new InvocationAwareDataSerializer<TimerData>(kryo, TimerData.class, schemaManager)); kryo.register(HttpTimerData.class, new InvocationAwareDataSerializer<HttpTimerData>(kryo, HttpTimerData.class, schemaManager)); kryo.register(SqlStatementData.class, new InvocationAwareDataSerializer<SqlStatementData>(kryo, SqlStatementData.class, schemaManager)); kryo.register(ExceptionSensorData.class, new InvocationAwareDataSerializer<ExceptionSensorData>(kryo, ExceptionSensorData.class, schemaManager)); kryo.register(ExceptionEvent.class, new EnumSerializer(ExceptionEvent.class)); kryo.register(ParameterContentData.class, new CustomCompatibleFieldSerializer<ParameterContentData>(kryo, ParameterContentData.class, schemaManager)); kryo.register(MemoryInformationData.class, new CustomCompatibleFieldSerializer<MemoryInformationData>(kryo, MemoryInformationData.class, schemaManager)); kryo.register(CpuInformationData.class, new CustomCompatibleFieldSerializer<CpuInformationData>(kryo, CpuInformationData.class, schemaManager)); kryo.register(SystemInformationData.class, new CustomCompatibleFieldSerializer<SystemInformationData>(kryo, SystemInformationData.class, schemaManager)); kryo.register(VmArgumentData.class, new CustomCompatibleFieldSerializer<VmArgumentData>(kryo, VmArgumentData.class, schemaManager)); kryo.register(ThreadInformationData.class, new CustomCompatibleFieldSerializer<ThreadInformationData>(kryo, ThreadInformationData.class, schemaManager)); kryo.register(RuntimeInformationData.class, new CustomCompatibleFieldSerializer<RuntimeInformationData>(kryo, RuntimeInformationData.class, schemaManager)); kryo.register(CompilationInformationData.class, new CustomCompatibleFieldSerializer<CompilationInformationData>(kryo, CompilationInformationData.class, schemaManager)); kryo.register(ClassLoadingInformationData.class, new CustomCompatibleFieldSerializer<ClassLoadingInformationData>(kryo, ClassLoadingInformationData.class, schemaManager)); kryo.register(ParameterContentType.class, new EnumSerializer(ParameterContentType.class)); // aggregation classes kryo.register(AggregatedExceptionSensorData.class, new InvocationAwareDataSerializer<AggregatedExceptionSensorData>(kryo, AggregatedExceptionSensorData.class, schemaManager)); kryo.register(DatabaseAggregatedTimerData.class, new InvocationAwareDataSerializer<DatabaseAggregatedTimerData>(kryo, DatabaseAggregatedTimerData.class, schemaManager, true)); // classes needed for the HTTP calls from the UI kryo.register(RemoteInvocation.class, new FieldSerializer<RemoteInvocation>(kryo, RemoteInvocation.class)); kryo.register(RemoteInvocationResult.class, new FieldSerializer<RemoteInvocationResult>(kryo, RemoteInvocationResult.class) { @Override protected RemoteInvocationResult create(Kryo kryo, Input input, Class<RemoteInvocationResult> type) { return new RemoteInvocationResult(null); } }); // data classes between CMR and UI // this classes can be registered with FieldSerializer since they are not saved to disk kryo.register(CmrStatusData.class, new FieldSerializer<CmrStatusData>(kryo, CmrStatusData.class)); kryo.register(AgentStatusData.class, new FieldSerializer<AgentStatusData>(kryo, AgentStatusData.class)); kryo.register(AgentConnection.class, new EnumSerializer(AgentConnection.class)); // INSPECTIT-849 - Hibernate uses Arrays.asList which does not have no-arg constructor kryo.register(Arrays.asList().getClass(), new CollectionSerializer() { @Override @SuppressWarnings("rawtypes") protected Collection create(Kryo kryo, Input input, Class<Collection> type) { return new ArrayList<Object>(); } }); // INSPECTIT-846 kryo.register(AggregatedHttpTimerData.class, new InvocationAwareDataSerializer<AggregatedHttpTimerData>(kryo, AggregatedHttpTimerData.class, schemaManager)); kryo.register(AggregatedSqlStatementData.class, new InvocationAwareDataSerializer<AggregatedSqlStatementData>(kryo, AggregatedSqlStatementData.class, schemaManager)); kryo.register(AggregatedTimerData.class, new InvocationAwareDataSerializer<AggregatedTimerData>(kryo, AggregatedTimerData.class, schemaManager)); // added with INSPECTIT-853 kryo.register(MethodIdentToSensorType.class, new CustomCompatibleFieldSerializer<MethodIdentToSensorType>(kryo, MethodIdentToSensorType.class, schemaManager)); // added with INSPECTIT-912 UnmodifiableCollectionsSerializer.registerSerializers(kryo); SynchronizedCollectionsSerializer.registerSerializers(kryo); kryo.register(StackTraceElement.class, new StackTraceElementSerializer()); // ATTENTION: registration ID has been increased by 9 as there were 9 classes removed from // registration at this point with ticket INSPECTIT-2276 // there is no other way then using reflection here int nextRegistrationId = kryo.getNextRegistrationId(); nextRegistrationId += 9; // added with INSPECTIT-950 kryo.register(TimeFrame.class, new CustomCompatibleFieldSerializer<TimeFrame>(kryo, TimeFrame.class, schemaManager), nextRegistrationId++); // added with INSPECTIT-480 // needed for KryoNet nextRegistrationId = kryoNetNetwork.register(kryo, nextRegistrationId); // added with INSPECTIT-632 kryo.register(BusinessException.class, new FieldSerializer<BusinessException>(kryo, BusinessException.class), nextRegistrationId++); kryo.register(TechnicalException.class, new FieldSerializer<TechnicalException>(kryo, TechnicalException.class), nextRegistrationId++); kryo.register(RemoteException.class, new FieldSerializer<RemoteException>(kryo, RemoteException.class), nextRegistrationId++); kryo.register(StorageErrorCodeEnum.class, new EnumSerializer(StorageErrorCodeEnum.class), nextRegistrationId++); kryo.register(AgentManagementErrorCodeEnum.class, new EnumSerializer(AgentManagementErrorCodeEnum.class), nextRegistrationId++); kryo.register(InvocationTargetException.class, new FieldSerializer<InvocationTargetException>(kryo, InvocationTargetException.class) { @Override protected InvocationTargetException create(Kryo kryo, Input input, Class<InvocationTargetException> type) { return new InvocationTargetException(null); } }, nextRegistrationId++); // added with INSPECTIT-1924 kryo.register(ConfigurationInterfaceErrorCodeEnum.class, new EnumSerializer(ConfigurationInterfaceErrorCodeEnum.class), nextRegistrationId++); // added with INSPECTIT-1971 kryo.register(LoggingData.class, new InvocationAwareDataSerializer<LoggingData>(kryo, LoggingData.class, schemaManager), nextRegistrationId++); // added with INSPECTIT-1915 kryo.register(JmxSensorTypeIdent.class, new CustomCompatibleFieldSerializer<JmxSensorTypeIdent>(kryo, JmxSensorTypeIdent.class, schemaManager, true), nextRegistrationId++); kryo.register(JmxDefinitionDataIdent.class, new CustomCompatibleFieldSerializer<JmxDefinitionDataIdent>(kryo, JmxDefinitionDataIdent.class, schemaManager), nextRegistrationId++); kryo.register(JmxSensorValueData.class, new CustomCompatibleFieldSerializer<JmxSensorValueData>(kryo, JmxSensorValueData.class, schemaManager), nextRegistrationId++); // added with INSPECTIT-1849 kryo.register(HttpInfo.class, new CustomCompatibleFieldSerializer<HttpInfo>(kryo, HttpInfo.class, schemaManager), nextRegistrationId++); // added with INSPECTIT-1919 kryo.register(AgentConfig.class, new FieldSerializer<AgentConfig>(kryo, AgentConfig.class), nextRegistrationId++); kryo.register(StrategyConfig.class, new FieldSerializer<StrategyConfig>(kryo, StrategyConfig.class), nextRegistrationId++); kryo.register(PlatformSensorTypeConfig.class, new FieldSerializer<PlatformSensorTypeConfig>(kryo, PlatformSensorTypeConfig.class), nextRegistrationId++); kryo.register(MethodSensorTypeConfig.class, new FieldSerializer<MethodSensorTypeConfig>(kryo, MethodSensorTypeConfig.class), nextRegistrationId++); kryo.register(ExceptionSensorTypeConfig.class, new FieldSerializer<ExceptionSensorTypeConfig>(kryo, ExceptionSensorTypeConfig.class), nextRegistrationId++); kryo.register(PropertyPath.class, new FieldSerializer<PropertyPath>(kryo, PropertyPath.class), nextRegistrationId++); kryo.register(PropertyPathStart.class, new FieldSerializer<PropertyPathStart>(kryo, PropertyPathStart.class), nextRegistrationId++); kryo.register(InstrumentationDefinition.class, new FieldSerializer<InstrumentationDefinition>(kryo, InstrumentationDefinition.class), nextRegistrationId++); kryo.register(MethodInstrumentationConfig.class, new FieldSerializer<MethodInstrumentationConfig>(kryo, MethodInstrumentationConfig.class), nextRegistrationId++); kryo.register(SensorInstrumentationPoint.class, new FieldSerializer<SensorInstrumentationPoint>(kryo, SensorInstrumentationPoint.class), nextRegistrationId++); kryo.register(SpecialInstrumentationPoint.class, new FieldSerializer<SpecialInstrumentationPoint>(kryo, SpecialInstrumentationPoint.class), nextRegistrationId++); kryo.register(SpecialInstrumentationType.class, new EnumSerializer(SpecialInstrumentationType.class), nextRegistrationId++); kryo.register(PriorityEnum.class, new EnumSerializer(PriorityEnum.class), nextRegistrationId++); kryo.register(EqualsMatchPattern.class, new FieldSerializer<EqualsMatchPattern>(kryo, EqualsMatchPattern.class), nextRegistrationId++); kryo.register(WildcardMatchPattern.class, new FieldSerializer<WildcardMatchPattern>(kryo, WildcardMatchPattern.class), nextRegistrationId++); // class cache structures kryo.register(ClassType.class, new FieldSerializer<ClassType>(kryo, ClassType.class), nextRegistrationId++); kryo.register(InterfaceType.class, new FieldSerializer<InterfaceType>(kryo, InterfaceType.class), nextRegistrationId++); kryo.register(AnnotationType.class, new FieldSerializer<AnnotationType>(kryo, AnnotationType.class), nextRegistrationId++); kryo.register(MethodType.class, new FieldSerializer<MethodType>(kryo, MethodType.class), nextRegistrationId++); kryo.register(ArraySet.class, new CollectionSerializer(), nextRegistrationId++); kryo.register(SortedArraySet.class, new CollectionSerializer(), nextRegistrationId++); kryo.register(MethodTypeSet.class, new CollectionSerializer(), nextRegistrationId++); kryo.register(TypeSet.class, new CollectionSerializer(), nextRegistrationId++); kryo.register(TypeWithAnnotationsSet.class, new CollectionSerializer(), nextRegistrationId++); // added with INSPECTIT-2071 kryo.register(JmxAttributeDescriptor.class, new FieldSerializer<JmxAttributeDescriptor>(kryo, JmxAttributeDescriptor.class), nextRegistrationId++); kryo.register(JmxSensorTypeConfig.class, new FieldSerializer<JmxSensorTypeConfig>(kryo, JmxSensorTypeConfig.class), nextRegistrationId++); // added with INSPECTIT-1804, INSPECTIT-1807 kryo.register(BusinessContextErrorCodeEnum.class, new EnumSerializer(BusinessContextErrorCodeEnum.class), nextRegistrationId++); kryo.register(ApplicationData.class, new CustomCompatibleFieldSerializer<ApplicationData>(kryo, ApplicationData.class, schemaManager), nextRegistrationId++); kryo.register(BusinessTransactionData.class, new CustomCompatibleFieldSerializer<BusinessTransactionData>(kryo, BusinessTransactionData.class, schemaManager), nextRegistrationId++); // added with INSPECTIT-1953 kryo.register(AlertErrorCodeEnum.class, new EnumSerializer(AlertErrorCodeEnum.class), nextRegistrationId++); // added with INSPECTIT-2226 kryo.register(SubstitutionDescriptor.class, new FieldSerializer<SubstitutionDescriptor>(kryo, SubstitutionDescriptor.class), nextRegistrationId++); // added with INSPECTIT-1921 kryo.register(SpanIdent.class, new CustomCompatibleFieldSerializer<SpanIdent>(kryo, SpanIdent.class, schemaManager), nextRegistrationId++); kryo.register(ClientSpan.class, new CustomCompatibleFieldSerializer<ClientSpan>(kryo, ClientSpan.class, schemaManager, true), nextRegistrationId++); kryo.register(ServerSpan.class, new CustomCompatibleFieldSerializer<ServerSpan>(kryo, ServerSpan.class, schemaManager, true), nextRegistrationId++); } /** * {@inheritDoc} */ @Override public void serialize(Object object, Output output) throws SerializationException { serialize(object, output, Collections.emptyMap()); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public void serialize(Object object, Output output, Map<?, ?> kryoPreferences) throws SerializationException { if (MapUtils.isNotEmpty(kryoPreferences)) { ObjectMap<Object, Object> graphContext = kryo.getGraphContext(); for (Entry<?, ?> entry : kryoPreferences.entrySet()) { graphContext.put(entry.getKey(), entry.getValue()); } } try { kryo.writeClassAndObject(output, object); output.flush(); } catch (Exception exception) { throw new SerializationException("Serialization failed.\n" + exception.getMessage(), exception); } } /** * {@inheritDoc} */ @Override public Object deserialize(Input input) throws SerializationException { Object object = null; try { object = kryo.readClassAndObject(input); } catch (Exception exception) { throw new SerializationException("De-serialization failed.\n" + exception.getMessage(), exception); } return object; } /** * {@inheritDoc} */ @Override public <T> T copy(T object) { return kryo.copy(object); } /** * Gets {@link #schemaManager}. * * @return {@link #schemaManager} */ public ClassSchemaManager getSchemaManager() { return schemaManager; } /** * <i>This setter can be removed when the Spring3.0 on the GUI side is working properly.</i> * * @param schemaManager * the schemaManager to set */ public void setSchemaManager(ClassSchemaManager schemaManager) { this.schemaManager = schemaManager; } /** * Sets {@link #kryoNetNetwork}. * * @param kryoNetNetwork * New value for {@link #kryoNetNetwork} */ public void setKryoNetNetwork(KryoNetNetwork kryoNetNetwork) { this.kryoNetNetwork = kryoNetNetwork; } /** * Gets {@link #kryo}. * * @return {@link #kryo} */ @Override public Kryo getKryo() { return kryo; } /** * {@inheritDoc} */ @Override public void afterPropertiesSet() throws Exception { initKryo(); } /** * {@inheritDoc} */ @Override public String toString() { ToStringBuilder toStringBuilder = new ToStringBuilder(this); toStringBuilder.append("schemaManager", schemaManager); toStringBuilder.append("kryo", ToStringBuilder.reflectionToString(kryo)); return toStringBuilder.toString(); } }