/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.module.artifact.serializer; import static java.util.Optional.empty; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mule.runtime.api.message.Message.of; import static org.mule.runtime.core.api.lifecycle.LifecycleUtils.initialiseIfNeeded; import static org.mule.runtime.module.artifact.classloader.ParentFirstLookupStrategy.PARENT_FIRST; import org.mule.runtime.core.api.Event; import org.mule.runtime.core.api.serialization.SerializationException; import org.mule.runtime.core.internal.message.InternalMessage; import org.mule.runtime.module.artifact.classloader.ClassLoaderLookupPolicy; import org.mule.runtime.module.artifact.classloader.ClassLoaderRepository; import org.mule.runtime.module.artifact.classloader.MuleArtifactClassLoader; import org.mule.runtime.module.artifact.descriptor.ArtifactDescriptor; import org.mule.tck.core.internal.serialization.AbstractSerializerProtocolContractTestCase; import org.mule.tck.util.CompilerUtils; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.Optional; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class CustomJavaSerializationProtocolTestCase extends AbstractSerializerProtocolContractTestCase { public static final String INSTANCE_NAME = "serializedInstance"; public static final String SERIALIZABLE_CLASS = "org.foo.SerializableClass"; public static final String ARTIFACT_ID = "testId"; public static final String ARTIFACT_NAME = "test"; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); private ClassLoaderRepository classLoaderRepository; @Override protected void doSetUp() throws Exception { classLoaderRepository = mock(ClassLoaderRepository.class); when(classLoaderRepository.getId(getClass().getClassLoader())).thenReturn(empty()); when(classLoaderRepository.getId(null)).thenReturn(empty()); serializationProtocol = new CustomJavaSerializationProtocol(classLoaderRepository); initialiseIfNeeded(serializationProtocol, muleContext); } @Test(expected = SerializationException.class) public void notSerializable() throws Exception { serializationProtocol.serialize(new Object()); } @Test public final void serializeWithoutDefaultConstructorFromArtifactClassLoader() throws Exception { final File compiledClasses = new File(temporaryFolder.getRoot(), "compiledClasses"); compiledClasses.mkdirs(); final File sourceFile = new File(getClass().getResource("/org/foo/SerializableClass.java").getFile()); CompilerUtils.SingleClassCompiler compiler = new CompilerUtils.SingleClassCompiler(); compiler.compile(sourceFile); final URL[] urls = new URL[] {compiler.getTargetFolder().toURL()}; final ClassLoaderLookupPolicy lookupPolicy = mock(ClassLoaderLookupPolicy.class); when(lookupPolicy.getClassLookupStrategy(any())).thenReturn(PARENT_FIRST); final MuleArtifactClassLoader artifactClassLoader = new MuleArtifactClassLoader(ARTIFACT_ID, new ArtifactDescriptor(ARTIFACT_NAME), urls, getClass().getClassLoader(), lookupPolicy); when(classLoaderRepository.getId(artifactClassLoader)).thenReturn(Optional.of(ARTIFACT_ID)); when(classLoaderRepository.find(ARTIFACT_ID)).thenReturn(Optional.of(artifactClassLoader)); final Class<?> echoTestClass = artifactClassLoader.loadClass(SERIALIZABLE_CLASS); final Object payload = echoTestClass.newInstance(); setObjectName(payload); Event event = eventBuilder().message(of(payload)).build(); byte[] bytes = serializationProtocol.serialize(event.getMessage()); InternalMessage message = serializationProtocol.deserialize(bytes); Object deserialized = message.getPayload().getValue(); assertThat(deserialized.getClass().getName(), equalTo(SERIALIZABLE_CLASS)); assertThat(deserialized.getClass().getClassLoader(), equalTo(artifactClassLoader)); assertThat(deserialized, equalTo(payload)); assertThat(getObjectName(deserialized), equalTo(INSTANCE_NAME)); } private void setObjectName(Object payload) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { final Method setNameMethod = payload.getClass().getMethod("setName", new Class[] {String.class}); setNameMethod.invoke(payload, INSTANCE_NAME); } private String getObjectName(Object payload) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { final Method getNameMethod = payload.getClass().getMethod("getName"); return (String) getNameMethod.invoke(payload); } }