package org.zstack.test.multinodes; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import org.zstack.core.Platform; import org.zstack.core.cloudbus.AutoOffEventCallback; import org.zstack.core.cloudbus.CloudBusIN; import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.componentloader.ComponentLoader; import org.zstack.header.AbstractService; import org.zstack.header.Service; import org.zstack.header.managementnode.ManagementNodeInventory; import org.zstack.header.message.LockResourceMessage; import org.zstack.header.message.LockResourceReply; import org.zstack.header.message.Message; import org.zstack.test.Api; import org.zstack.test.ApiSenderException; import org.zstack.test.BeanConstructor; import org.zstack.test.multinodes.SilentLockService.DoLockMessage; import org.zstack.test.multinodes.SilentLockService.SilentLockResourceMsg; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 1. start 2 nodes * 2. instruct node0 to send lock message to node1 * 3. stop node0 * <p> * confirm node1 receives unlock message */ public class TestMultipleNode12 { CLogger logger = Utils.getLogger(TestMultipleNode12.class); ComponentLoader loader; NodeManager nodeMgr; CloudBusIN bus; EventFacade evtf; Api api; volatile boolean locked = false; volatile boolean unlocked = false; @Before public void setUp() throws Exception { BeanConstructor con = new BeanConstructor(); con.addXml("PortalForUnitTest.xml"); con.addXml("AccountManager.xml"); // have to load silentService, otherwise message tracker won't care it con.addXml("silentService.xml"); loader = con.build(); bus = loader.getComponent(CloudBusIN.class); nodeMgr = new NodeManager(); evtf = loader.getComponent(EventFacade.class); api = new Api(); api.startServer(); api.setTimeout(300); } @Test public void test() throws InterruptedException, ApiSenderException { try { final String SERVICE_ID = "toLockService"; Service serv = new AbstractService() { @Override public void handleMessage(Message msg) { if (msg instanceof SilentLockResourceMsg) { final SilentLockResourceMsg dmsg = (SilentLockResourceMsg) msg; locked = true; evtf.on(LockResourceMessage.UNLOCK_CANONICAL_EVENT_PATH, new AutoOffEventCallback() { @Override public boolean run(Map tokens, Object data) { if (dmsg.getUnlockKey().equals(data)) { unlocked = true; return true; } return false; } }); LockResourceReply r = new LockResourceReply(); bus.reply(msg, r); } } @Override public String getId() { return bus.makeLocalServiceId(SERVICE_ID); } @Override public boolean start() { return true; } @Override public boolean stop() { return true; } }; bus.registerService(serv); bus.activeService(serv); nodeMgr.setProperties("-DbFacadeDataSource.maxPoolSize=50") .createLightWeightNodeWithCore(1, 300, Arrays.asList("silentService.xml")); List<ManagementNodeInventory> nodes = api.listManagementNodes(); ManagementNodeInventory target = CollectionUtils.find(nodes, new Function<ManagementNodeInventory, ManagementNodeInventory>() { @Override public ManagementNodeInventory call(final ManagementNodeInventory arg) { if (!arg.getUuid().equals(Platform.getManagementServerId())) { return arg; } return null; } }); DoLockMessage dlmsg = new DoLockMessage(); dlmsg.toLockServiceId = SERVICE_ID; dlmsg.toManagementNodeUuid = Platform.getManagementServerId(); bus.makeServiceIdByManagementNodeId(dlmsg, SilentLockService.SERVICE_ID, target.getUuid()); bus.call(dlmsg); nodeMgr.stopNode(0, 120); TimeUnit.SECONDS.sleep(5); Assert.assertTrue(locked); Assert.assertTrue(unlocked); } finally { nodeMgr.stopNodes(120); } } }