/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* 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 net.openhft.chronicle.engine.map;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.engine.ThreadMonitoringTest;
import net.openhft.chronicle.engine.api.pubsub.Subscriber;
import net.openhft.chronicle.engine.api.tree.AssetTree;
import net.openhft.chronicle.engine.server.ServerEndpoint;
import net.openhft.chronicle.engine.tree.*;
import net.openhft.chronicle.network.TCPRegistry;
import net.openhft.chronicle.network.connection.TcpChannelHub;
import net.openhft.chronicle.wire.WireType;
import net.openhft.chronicle.wire.YamlLogging;
import org.jetbrains.annotations.NotNull;
import org.junit.*;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static java.util.concurrent.TimeUnit.SECONDS;
import static net.openhft.chronicle.engine.Utils.methodName;
import static net.openhft.chronicle.engine.Utils.yamlLoggger;
/**
* test using the listener both remotely or locally via the engine
*
* @author Rob Austin.
*/
@RunWith(value = Parameterized.class)
public class TopologicalSubscriptionEventTest extends ThreadMonitoringTest {
private static final String NAME = "test";
private final boolean isRemote;
private final WireType wireType;
@NotNull
@Rule
public TestName name = new TestName();
private AssetTree clientAssetTree = new VanillaAssetTree().forTesting();
private VanillaAssetTree serverAssetTree;
private ServerEndpoint serverEndpoint;
public TopologicalSubscriptionEventTest(boolean isRemote, WireType wireType) {
this.isRemote = isRemote;
this.wireType = wireType;
}
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[]{false, null}
, new Object[]{true, WireType.TEXT}
, new Object[]{true, WireType.BINARY}
);
}
@Before
public void before() throws IOException {
serverAssetTree = new VanillaAssetTree().forTesting();
if (isRemote) {
methodName(name.getMethodName());
TCPRegistry.createServerSocketChannelFor("TopologicalSubscriptionEventTest.host.port");
serverEndpoint = new ServerEndpoint("TopologicalSubscriptionEventTest.host.port", serverAssetTree);
clientAssetTree = new VanillaAssetTree().forRemoteAccess("TopologicalSubscriptionEventTest.host.port", wireType);
} else {
clientAssetTree = serverAssetTree;
}
}
@After
public void preAfter() {
clientAssetTree.close();
if (serverEndpoint != null)
serverEndpoint.close();
serverAssetTree.close();
TcpChannelHub.closeAllHubs();
TCPRegistry.reset();
}
@Ignore("Disabled 31/3/16")
@Test
public void testTopologicalEvents() throws IOException, InterruptedException {
@NotNull final BlockingQueue<TopologicalEvent> eventsQueue = new LinkedBlockingQueue<>();
yamlLoggger(() -> {
try {
YamlLogging.writeMessage("Sets up a subscription to listen to new maps being " +
"added and removed.");
Subscriber<TopologicalEvent> subscription = eventsQueue::add;
clientAssetTree.registerSubscriber("", TopologicalEvent.class, subscription);
{
TopologicalEvent take = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(ExistingAssetEvent.of(null, "", Collections.emptySet()), take);
}
{
clientAssetTree.acquireMap("/group/" + NAME, String.class, String.class).size();
{
TopologicalEvent take = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(ExistingAssetEvent.of("/", "queue", Collections.emptySet()), take);
}
{
TopologicalEvent take = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(AddedAssetEvent.of("/", "group", Collections.emptySet()), take);
}
{
TopologicalEvent take = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(AddedAssetEvent.of("/group", NAME, Collections.emptySet()), take);
}
}
{
serverAssetTree.acquireMap("/group/" + NAME + 2, String.class, String.class);
TopologicalEvent take3 = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(AddedAssetEvent.of("/group", NAME + 2, Collections.emptySet()), take3);
}
{
// the client cannot remove maps yet.
serverAssetTree.acquireAsset("/group").removeChild(NAME);
TopologicalEvent take4 = eventsQueue.poll(1, SECONDS);
Assert.assertEquals(RemovedAssetEvent.of("/group", NAME, Collections.emptySet()), take4);
}
clientAssetTree.unregisterSubscriber(NAME, subscription);
} catch (Exception e) {
throw Jvm.rethrow(e);
}
});
}
}