/*
* Copyright 2011 Red Hat, Inc. and/or its affiliates.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
package org.infinispan.marshall;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.context.Flag;
import org.infinispan.io.ExposedByteArrayOutputStream;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.jgroups.stack.IpAddress;
import org.testng.annotations.Test;
import java.io.ByteArrayInputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collections;
import static org.infinispan.test.TestingUtil.extractCacheMarshaller;
import static org.infinispan.test.TestingUtil.extractGlobalMarshaller;
import static org.testng.AssertJUnit.assertEquals;
/**
* Test to verify whether the same stream can be used with different marshallers.
* The test does work but it requires some special treatment. This could be a
* more efficient way of dealing with global/cache marshaller transition.
*
* @author Galder ZamarreƱo
* @since 5.1
*/
@Test(groups = "functional", testName = "marshall.SharedStreamMultiMarshallerTest", enabled = true)
public class SharedStreamMultiMarshallerTest {
public void testSharingStream() throws Exception {
EmbeddedCacheManager cm = TestCacheManagerFactory.createClusteredCacheManager();
cm.getCache(); // Start cache so that global marshaller is resolved
JGroupsAddress address = new JGroupsAddress(new IpAddress(12345));
PutKeyValueCommand cmd = new PutKeyValueCommand(
"k", "v", false, null, 0, 0, Collections.<Flag>emptySet());
try {
// Write
StreamingMarshaller globalMarshal = extractGlobalMarshaller(cm);
ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(1024);
ObjectOutput globalOO = globalMarshal.startObjectOutput(baos, false, 1024);
try {
globalOO.writeObject(address);
/** BEGIN: Special treatment **/
globalOO.flush(); // IMPORTANT: Flush needed to make sure the address gets written!!
globalOO.writeInt(baos.size()); // Note amount of bytes that have been read so far
globalOO.flush(); // IMPORTANT: Flush again!
/** END: Special treatment **/
// Now try cache marshaller to 'borrow' the output stream
StreamingMarshaller cacheMarshaller = extractCacheMarshaller(cm.getCache());
ObjectOutput cacheOO = cacheMarshaller.startObjectOutput(baos, true, 1024);
try {
cacheOO.writeObject(cmd);
} finally {
cacheMarshaller.finishObjectOutput(cacheOO);
}
} finally {
globalMarshal.finishObjectOutput(globalOO);
}
byte[] bytes = new byte[baos.size()];
System.arraycopy(baos.getRawBuffer(), 0, bytes, 0, bytes.length);
// Read
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInput globalOI = globalMarshal.startObjectInput(bais, false);
try {
assertEquals(address, globalOI.readObject());
/** BEGIN: Special treatment **/
int offset = globalOI.readInt();
// Now try the cache marshaller and borrow the input stream to read
StreamingMarshaller cacheMarshaller = extractCacheMarshaller(cm.getCache());
// Advance 4 bytes to go over the number of bytes written
bais = new ByteArrayInputStream(bytes, offset + 4, bytes.length);
ObjectInput cacheOI = cacheMarshaller.startObjectInput(bais, true);
/** END: Special treatment **/
try {
assertEquals(cmd, cacheOI.readObject());
} finally {
cacheMarshaller.finishObjectInput(cacheOI);
}
} finally {
globalMarshal.finishObjectInput(globalOI);
}
} finally {
cm.stop();
}
}
public void testIndividualStream() throws Exception {
EmbeddedCacheManager cm = TestCacheManagerFactory.createClusteredCacheManager();
cm.getCache(); // Start cache so that global marshaller is resolved
JGroupsAddress address = new JGroupsAddress(new IpAddress(12345));
PutKeyValueCommand cmd = new PutKeyValueCommand(
"k", "v", false, null, 0, 0, Collections.<Flag>emptySet());
try {
// Write
StreamingMarshaller globalMarshal = extractGlobalMarshaller(cm);
ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(1024);
ObjectOutput globalOO = globalMarshal.startObjectOutput(baos, false, 1024);
try {
globalOO.writeObject(address);
} finally {
globalMarshal.finishObjectOutput(globalOO);
}
byte[] bytes = new byte[baos.size()];
System.arraycopy(baos.getRawBuffer(), 0, bytes, 0, bytes.length);
// Read
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInput globalOI = globalMarshal.startObjectInput(bais, false);
try {
assertEquals(address, globalOI.readObject());
} finally {
globalMarshal.finishObjectInput(globalOI);
}
} finally {
cm.stop();
}
}
}