/*
* 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.core.registry;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.mule.runtime.core.api.MuleContext;
import org.mule.runtime.api.exception.MuleException;
import org.mule.runtime.core.api.registry.RegistryBroker;
import org.mule.runtime.core.internal.construct.DefaultFlowBuilder;
import org.mule.tck.junit4.AbstractMuleContextTestCase;
import org.mule.tck.testmodels.fruit.Apple;
import org.mule.tck.testmodels.fruit.Kiwi;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
public class RegistryBrokerTestCase extends AbstractMuleContextTestCase {
private String tracker;
@Override
protected void doSetUp() throws Exception {
super.doSetUp();
tracker = new String();
}
@Override
protected boolean isStartContext() {
return false;
}
@Test
public void testCrossRegistryLifecycleOrder() throws MuleException {
TransientRegistry reg1 = new TransientRegistry(muleContext);
reg1.initialise();
TransientRegistry reg2 = new TransientRegistry(muleContext);
reg2.initialise();
reg1.registerObject("flow", new LifecycleTrackerFlow("flow", muleContext));
reg2.registerObject("flow2", new LifecycleTrackerFlow("flow2", muleContext));
muleContext.addRegistry(reg1);
muleContext.addRegistry(reg2);
muleContext.start();
// Both connectors are started before either flow
assertEquals("flow2-start flow-start ", tracker.toString());
tracker = new String();
muleContext.stop();
// Both services are stopped before either connector
assertEquals("flow2-stop flow-stop ", tracker);
}
class LifecycleTrackerFlow extends DefaultFlowBuilder.DefaultFlow {
public LifecycleTrackerFlow(String name, MuleContext muleContext) {
super(name, muleContext);
}
@Override
protected void doStart() throws MuleException {
super.doStart();
tracker += name + "-start ";
}
@Override
protected void doStop() throws MuleException {
super.doStop();
tracker += name + "-stop ";
}
}
@Test
public void testConcurrentRegistryAddRemove() throws Exception {
final RegistryBroker broker = new DefaultRegistryBroker(muleContext);
final int N = 50;
final CountDownLatch start = new CountDownLatch(1);
final CountDownLatch end = new CountDownLatch(N);
final AtomicInteger errors = new AtomicInteger(0);
for (int i = 0; i < N; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
start.await();
broker.addRegistry(new TransientRegistry(muleContext));
broker.lookupByType(Object.class);
} catch (Exception e) {
errors.incrementAndGet();
} finally {
end.countDown();
}
}
}, "thread-eval-" + i).start();
}
start.countDown();
end.await();
if (errors.get() > 0) {
fail();
}
}
@Test
public void registerWhenNoRegistriesManuallyAddedYet() throws Exception {
final String KEY1 = "apple";
final Object VALUE1 = new Apple();
final String KEY2 = "Kiwi";
final Object VALUE2 = new Kiwi();
muleContext.getRegistry().registerObject(KEY1, VALUE1);
muleContext.getRegistry().registerObject(KEY2, VALUE2);
assertThat(muleContext.getRegistry().get(KEY1), is(VALUE1));
assertThat(muleContext.getRegistry().get(KEY2), is(VALUE2));
assertThat(muleContext.getRegistry().lookupObject(Apple.class), is(VALUE1));
assertThat(muleContext.getRegistry().lookupObject(Kiwi.class), is(VALUE2));
}
}