/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.test.dunit.rules; import static org.apache.geode.distributed.ConfigurationProperties.NAME; import static org.apache.geode.test.dunit.Host.getHost; import org.apache.geode.test.dunit.Invoke; import org.apache.geode.test.dunit.VM; import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder; import org.junit.After; import org.junit.Before; import org.junit.rules.ExternalResource; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Properties; /** * A rule to help you start locators and servers inside of a * <a href="https://cwiki.apache.org/confluence/display/GEODE/Distributed-Unit-Tests">DUnit * test</a>. This rule will start Servers and Locators inside of the four remote {@link VM}s created * by the DUnit framework. */ public class LocatorServerStartupRule extends ExternalResource implements Serializable { /** * This is only available in each Locator/Server VM, not in the controller (test) VM. */ public static ServerStarterRule serverStarter; /** * This is only available in each Locator/Server VM, not in the controller (test) VM. */ public static LocatorStarterRule locatorStarter; private DistributedRestoreSystemProperties restoreSystemProperties = new DistributedRestoreSystemProperties(); private TemporaryFolder temporaryFolder = new SerializableTemporaryFolder(); private List<Member> members; @Before public void before() throws Throwable { restoreSystemProperties.before(); temporaryFolder.create(); Invoke.invokeInEveryVM("Stop each VM", this::stopServerOrLocatorInThisVM); members = new ArrayList<>(4); } @After public void after() { restoreSystemProperties.after(); temporaryFolder.delete(); Invoke.invokeInEveryVM("Stop each VM", this::stopServerOrLocatorInThisVM); } /** * Starts a locator instance with the given configuration properties inside * {@code getHost(0).getVM(index)}. * * @return VM locator vm */ public Locator startLocatorVM(int index, Properties locatorProperties) throws IOException { String name = "locator-" + index; locatorProperties.setProperty(NAME, name); File workingDir = createWorkingDirForMember(name); VM locatorVM = getHost(0).getVM(index); int locatorPort = locatorVM.invoke(() -> { System.setProperty("user.dir", workingDir.getCanonicalPath()); locatorStarter = new LocatorStarterRule(locatorProperties); locatorStarter.startLocator(); return locatorStarter.locator.getPort(); }); Locator locator = new Locator(locatorVM, locatorPort, workingDir); members.add(index, locator); return locator; } public Locator startLocatorVMWithPulse(int index, Properties locatorProperties) throws IOException { String name = "locator-" + index; locatorProperties.setProperty(NAME, name); File workingDir = createWorkingDirForMember(name); // Setting gemfire.home to this value allows locators started by the rule to run Pulse String geodeInstallDir = new File(".").getAbsoluteFile().getParentFile().getParentFile() .toPath().resolve("geode-assembly").resolve("build").resolve("install") .resolve("apache-geode").toString(); System.out.println("Current dir is " + new File(".").getCanonicalPath()); System.out.println("Setting gemfire.home to " + geodeInstallDir); VM locatorVM = getHost(0).getVM(index); int locatorPort = locatorVM.invoke(() -> { System.setProperty("user.dir", workingDir.getCanonicalPath()); System.setProperty("gemfire.home", geodeInstallDir); locatorStarter = new LocatorStarterRule(locatorProperties); locatorStarter.startLocator(); return locatorStarter.locator.getPort(); }); Locator locator = new Locator(locatorVM, locatorPort, workingDir); members.add(index, locator); return locator; } public Locator startLocatorVM(int index) throws IOException { return startLocatorVM(index, new Properties()); } /** * starts a cache server that does not connect to a locator * * @return VM node vm */ public Server startServerVM(int index, Properties properties) throws IOException { return startServerVM(index, properties, 0); } public Server startServerVM(int index, int locatorPort) throws IOException { return startServerVM(index, new Properties(), locatorPort); } /** * Starts a cache server that connect to the locator running at the given port. */ public Server startServerVM(int index, Properties properties, int locatorPort) throws IOException { String name = "server-" + index; properties.setProperty(NAME, name); File workingDir = createWorkingDirForMember(name); VM serverVM = getHost(0).getVM(index); int port = serverVM.invoke(() -> { System.setProperty("user.dir", workingDir.getCanonicalPath()); serverStarter = new ServerStarterRule(properties); serverStarter.startServer(locatorPort); return serverStarter.server.getPort(); }); Server server = new Server(serverVM, port, workingDir); members.add(index, server); return server; } /** * Returns the {@link Member} running inside the VM with the specified {@code index} */ public Member getMember(int index) { return members.get(index); } public TemporaryFolder getTempFolder() { return temporaryFolder; } private void stopServerOrLocatorInThisVM() { if (serverStarter != null) { serverStarter.after(); } if (locatorStarter != null) { locatorStarter.after(); } } private File createWorkingDirForMember(String dirName) throws IOException { File workingDir = new File(temporaryFolder.getRoot(), dirName); if (!workingDir.exists()) { temporaryFolder.newFolder(dirName); } return workingDir; } }