package net.openhft.chronicle.engine.queue;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.io.Closeable;
import net.openhft.chronicle.core.pool.ClassAliasPool;
import net.openhft.chronicle.engine.ThreadMonitoringTest;
import net.openhft.chronicle.engine.api.map.MapView;
import net.openhft.chronicle.engine.api.pubsub.TopicPublisher;
import net.openhft.chronicle.engine.api.tree.AssetTree;
import net.openhft.chronicle.engine.server.ServerEndpoint;
import net.openhft.chronicle.engine.tree.ChronicleQueueView;
import net.openhft.chronicle.engine.tree.VanillaAssetTree;
import net.openhft.chronicle.network.TCPRegistry;
import net.openhft.chronicle.network.connection.TcpChannelHub;
import net.openhft.chronicle.wire.WireType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.*;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import static net.openhft.chronicle.engine.Utils.methodName;
/**
* @author Rob Austin.
*/
@RunWith(value = Parameterized.class)
public class QueueAsMapViewTest extends ThreadMonitoringTest {
private static final String DELETE_CHRONICLE_FILE = "?dontPersist=true";
static {
ClassAliasPool.CLASS_ALIASES.addAlias(MyMarshallable.class, "MyMarshallable");
}
@NotNull
@Rule
public TestName name = new TestName();
@NotNull
String methodName = "";
private AssetTree assetTree;
@Nullable
private ServerEndpoint serverEndpoint;
@Nullable
private AssetTree serverAssetTree;
@NotNull
String uri = "/queue/" + System.nanoTime() + "/" + methodName;
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Boolean[][]{
{true}, {false}
});
}
public QueueAsMapViewTest(Boolean isRemote) throws Exception {
if (isRemote) {
serverAssetTree = new VanillaAssetTree().forTesting();
@NotNull String hostPortDescription = "SimpleQueueViewTest-methodName" + methodName;
TCPRegistry.createServerSocketChannelFor(hostPortDescription);
serverEndpoint = new ServerEndpoint(hostPortDescription, serverAssetTree);
@NotNull final VanillaAssetTree client = new VanillaAssetTree();
assetTree = client.forRemoteAccess(hostPortDescription, WireType.BINARY);
} else {
assetTree = (new VanillaAssetTree(1)).forTesting();
serverEndpoint = null;
serverAssetTree = null;
}
}
public static void deleteFiles(@NotNull File element) {
if (element.isDirectory()) {
for (@NotNull File sub : element.listFiles()) {
deleteFiles(sub);
}
}
element.delete();
}
@Before
public void before() throws IOException {
methodName(name.getMethodName());
deleteFiles(new File(uri));
assetTree = (new VanillaAssetTree(1)).forTesting();
serverEndpoint = null;
serverAssetTree = null;
}
@After
public void preAfter() {
threadDump.ignore("ChronicleMapKeyValueStore Closer");
Closeable.closeQuietly(serverAssetTree);
Closeable.closeQuietly(serverEndpoint);
Closeable.closeQuietly(assetTree);
methodName = "";
TcpChannelHub.closeAllHubs();
TCPRegistry.reset();
deleteFiles(new File(uri));
}
@Test
public void testQueueViewAsMapView() throws InterruptedException {
//YamlLogging.setAll(true);
@NotNull String messageType1 = "topic1";
@NotNull String messageType2 = "topic2";
@NotNull TopicPublisher<String, String> publisher = assetTree.acquireTopicPublisher(uri + DELETE_CHRONICLE_FILE, String.class, String.class);
publisher.publish(messageType1, "Message-1");
publisher.publish(messageType2, "Message-2");
Jvm.pause(500);
@NotNull MapView<String, String> map = assetTree.acquireMap(uri, String.class, String.class);
Assert.assertTrue(map instanceof ChronicleQueueView);
int i = 0;
while (map.size() == 0) {
if (i++ == 500)
break;
Thread.sleep(100);
}
Assert.assertEquals(2, map.size());
}
@Test
public void testSimpleMap() throws InterruptedException {
//YamlLogging.setAll(true);
@NotNull MapView<String, String> map = assetTree.acquireMap(uri, String.class, String.class);
map.put("hello", "world");
map.put("hello2", "world");
Assert.assertEquals(2, map.size());
}
@Test
public void testPopulateMapTailQueue() throws InterruptedException {
//YamlLogging.setAll(true);
@NotNull final ArrayBlockingQueue<String> q = new ArrayBlockingQueue<>(100);
assetTree.registerTopicSubscriber(
uri,
String.class,
String.class, (topic, message) -> q.add(topic + ":" + message));
@NotNull MapView<String, String> map = assetTree.acquireMap(uri, String.class, String.class);
Assert.assertTrue(map instanceof ChronicleQueueView);
map.put("hello", "world");
map.put("hello2", "world2");
Assert.assertEquals("hello:world", q.poll(1, TimeUnit.SECONDS));
Assert.assertEquals("hello2:world2", q.poll(1, TimeUnit.SECONDS));
Assert.assertTrue(q.isEmpty());
}
}