use of org.apache.sling.discovery.TopologyEvent in project sling by apache.
the class TestSlowViewStateManager method testClusterSyncService_withConcurrency.
//TODO test takes env 10sec
@Category(Slow.class)
@Test
public void testClusterSyncService_withConcurrency() throws Exception {
final org.apache.log4j.Logger commonsLogger = LogManager.getRootLogger().getLogger("org.apache.sling.discovery.commons.providers");
final org.apache.log4j.Level logLevel = commonsLogger.getLevel();
// change here to DEBUG in case of issues with this test
commonsLogger.setLevel(Level.INFO);
final Semaphore serviceSemaphore = new Semaphore(0);
final Semaphore testSemaphore = new Semaphore(0);
final ReentrantLock lock = new ReentrantLock();
final ClusterSyncServiceWithSemaphore cs = new ClusterSyncServiceWithSemaphore(lock, serviceSemaphore);
mgr = new ViewStateManagerImpl(lock, cs);
final DummyListener listener = new DummyListener();
mgr.bind(listener);
TestHelper.assertNoEvents(listener);
mgr.handleActivated();
TestHelper.assertNoEvents(listener);
final String slingId1 = UUID.randomUUID().toString();
final String slingId2 = UUID.randomUUID().toString();
final String slingId3 = UUID.randomUUID().toString();
final String clusterId = UUID.randomUUID().toString();
final DefaultClusterView cluster = new DefaultClusterView(clusterId);
final DummyTopologyView view1 = new DummyTopologyView().addInstance(slingId1, cluster, true, true).addInstance(slingId2, cluster, false, false).addInstance(slingId3, cluster, false, false);
final DummyTopologyView view2 = DummyTopologyView.clone(view1).removeInstance(slingId2);
final DummyTopologyView view3 = DummyTopologyView.clone(view1).removeInstance(slingId2).removeInstance(slingId3);
async(new Runnable() {
public void run() {
mgr.handleNewView(view1);
}
});
Thread.sleep(1000);
TestHelper.assertNoEvents(listener);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
// release the first one only
serviceSemaphore.release(1);
Thread.sleep(1000);
assertEvents(listener, EventHelper.newInitEvent(view1));
mgr.handleChanging();
assertEquals(0, mgr.waitForAsyncEvents(500));
assertEvents(listener, EventHelper.newChangingEvent(view1));
async(new Runnable() {
public void run() {
mgr.handleNewView(view2);
}
});
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
logger.debug("run: asserting no events");
TestHelper.assertNoEvents(listener);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
assertFalse("should not be locked", lock.isLocked());
logger.debug("run: issuing a second event");
// before releasing, issue another event, lets do a combination of changing/changed
async(new Runnable() {
public void run() {
logger.debug("run2: calling handleChanging...");
mgr.handleChanging();
try {
logger.debug("run2: done with handleChanging, acquiring testSemaphore...");
testSemaphore.acquire();
logger.debug("run2: calling handleNewView...");
mgr.handleNewView(view3);
logger.debug("run2: done with handleNewView...");
} catch (InterruptedException e) {
// fail
logger.error("interrupted: " + e, e);
}
}
});
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
int remainingAsyncEvents = mgr.waitForAsyncEvents(2000);
logger.info("run: result of waitForAsyncEvent is: " + remainingAsyncEvents);
assertEquals("should have one thread now waiting", 1, serviceSemaphore.getQueueLength());
assertEquals("should be acquiring (by thread2)", 1, testSemaphore.getQueueLength());
// releasing the testSemaphore
testSemaphore.release();
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
assertEquals("should have two async events now in the queue or being sent", 2, mgr.waitForAsyncEvents(500));
assertEquals("but should only have 1 thread actually sitting on the semaphore waiting", 1, serviceSemaphore.getQueueLength());
logger.debug("run: releasing consistencyService");
// release the first one only
serviceSemaphore.release(1);
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
assertFalse("should not be locked", lock.isLocked());
// this should not have triggered any event
TestHelper.assertNoEvents(listener);
// then release the 2nd one
serviceSemaphore.release(1);
logger.debug("run: waiting 1sec");
Thread.sleep(1000);
logger.debug("run: asserting 1 event");
final TopologyEvent changedEvent = EventHelper.newChangedEvent(view1, view3);
assertEvents(listener, changedEvent);
// back to default
commonsLogger.setLevel(Level.INFO);
}
use of org.apache.sling.discovery.TopologyEvent in project sling by apache.
the class TestHelper method assertEvents.
public static void assertEvents(ViewStateManagerImpl mgr, DummyListener listener, TopologyEvent... events) {
waitForAsyncEvents(mgr);
assertEquals(events.length, listener.countEvents());
for (int i = 0; i < events.length; i++) {
TopologyEvent e = events[i];
assertEquals(e.getType(), listener.getEvents().get(i).getType());
switch(e.getType()) {
case TOPOLOGY_INIT:
{
assertNull(listener.getEvents().get(i).getOldView());
assertEquals(e.getNewView(), listener.getEvents().get(i).getNewView());
break;
}
case TOPOLOGY_CHANGING:
{
assertEquals(e.getOldView(), listener.getEvents().get(i).getOldView());
assertNull(listener.getEvents().get(i).getNewView());
break;
}
case PROPERTIES_CHANGED:
case TOPOLOGY_CHANGED:
{
assertEquals(e.getOldView(), listener.getEvents().get(i).getOldView());
assertEquals(e.getNewView(), listener.getEvents().get(i).getNewView());
break;
}
default:
{
fail("no other type supported yet");
}
}
}
listener.clearEvents();
}
use of org.apache.sling.discovery.TopologyEvent in project sling by apache.
the class TestViewStateManager method testPropertiesChanged.
@Test
public void testPropertiesChanged() throws Exception {
final DummyListener listener = new DummyListener();
mgr.handleActivated();
mgr.bind(listener);
mgr.handleChanging();
DummyTopologyView oldView = new DummyTopologyView().addInstance();
DefaultInstanceDescription localInstance = (DefaultInstanceDescription) oldView.getLocalInstance();
localInstance.setProperty("foo", "bar1");
mgr.handleNewView(oldView);
TopologyEvent initEvent = EventHelper.newInitEvent(oldView.clone());
assertEvents(listener, initEvent);
DummyTopologyView newView = oldView.clone();
oldView.setNotCurrent();
localInstance = (DefaultInstanceDescription) newView.getLocalInstance();
localInstance.setProperty("foo", "bar2");
mgr.handleNewView(newView);
Thread.sleep(2000);
TopologyEvent propertiesChangedEvent = EventHelper.newPropertiesChangedEvent(oldView.clone(), newView.clone());
assertEvents(listener, propertiesChangedEvent);
}
use of org.apache.sling.discovery.TopologyEvent in project sling by apache.
the class NoClusterDiscoveryService method bindTopologyEventListener.
@SuppressWarnings("unused")
private void bindTopologyEventListener(final TopologyEventListener listener) {
logger.debug("Binding TopologyEventListener {}", listener);
boolean inform = true;
synchronized (lock) {
final List<TopologyEventListener> currentList = new ArrayList<TopologyEventListener>(Arrays.asList(listeners));
currentList.add(listener);
this.listeners = currentList.toArray(new TopologyEventListener[currentList.size()]);
if (this.currentTopologyView != null) {
listener.handleTopologyEvent(new TopologyEvent(Type.TOPOLOGY_INIT, null, this.currentTopologyView));
}
}
}
use of org.apache.sling.discovery.TopologyEvent in project sling by apache.
the class NoClusterDiscoveryService method createNewView.
private void createNewView(final Type eventType, boolean inform) {
final TopologyEventListener[] registeredServices;
final TopologyView newView;
final TopologyView oldView;
synchronized (lock) {
// invalidate old view
if (this.currentTopologyView != null) {
this.currentTopologyView.invalidate();
oldView = currentTopologyView;
} else {
oldView = null;
}
final InstanceDescription myInstanceDescription = new InstanceDescriptionImpl(this.settingsService.getSlingId(), this.cachedProperties);
this.currentTopologyView = new TopologyViewImpl(myInstanceDescription);
registeredServices = this.listeners;
newView = this.currentTopologyView;
if (inform) {
for (final TopologyEventListener da : registeredServices) {
da.handleTopologyEvent(new TopologyEvent(eventType, oldView, newView));
}
}
}
}
Aggregations