PageRenderTime 148ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/testsuite/protocol/modules/src/main/java/org/jboss/test/as/protocol/support/process/MockProcessManager.java

https://github.com/jwulf/jboss-as
Java | 328 lines | 242 code | 59 blank | 27 comment | 19 complexity | 18d1afffa71b16154924c768f09f2d1c MD5 | raw file
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2010, Red Hat, Inc., and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.test.as.protocol.support.process;
  23. import java.io.IOException;
  24. import java.io.InputStream;
  25. import java.net.InetAddress;
  26. import java.net.Socket;
  27. import java.util.List;
  28. import java.util.Map;
  29. import java.util.concurrent.BlockingQueue;
  30. import java.util.concurrent.ConcurrentHashMap;
  31. import java.util.concurrent.CountDownLatch;
  32. import java.util.concurrent.LinkedBlockingQueue;
  33. import java.util.concurrent.TimeUnit;
  34. import java.util.concurrent.atomic.AtomicInteger;
  35. import org.jboss.as.communication.InitialSocketRequestException;
  36. import org.jboss.as.communication.SocketConnection;
  37. import org.jboss.as.communication.SocketListener;
  38. import org.jboss.as.communication.SocketListener.SocketHandler;
  39. import org.jboss.as.process.Status;
  40. import org.jboss.as.process.StreamUtils;
  41. import org.jboss.as.process.SystemExiter;
  42. import org.jboss.as.process.ProcessOutputStreamHandler.Master;
  43. import org.jboss.logging.Logger;
  44. /**
  45. *
  46. * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
  47. * @version $Revision: 1.1 $
  48. */
  49. public class MockProcessManager implements Master{
  50. static {
  51. SystemExiter.initialize(new NoopExiter());
  52. }
  53. private volatile SocketListener listener;
  54. Logger log = Logger.getLogger(MockProcessManager.class);
  55. volatile MockManagedProcess serverManager = new MockManagedProcess(this, "ServerManager", null);
  56. final Map<String, MockManagedProcess> serverProcesses = new ConcurrentHashMap<String, MockManagedProcess>();
  57. final int expectedProcessCount;
  58. final AtomicInteger addCount = new AtomicInteger();
  59. final AtomicInteger startCount = new AtomicInteger();
  60. final AtomicInteger stopCount = new AtomicInteger();
  61. final AtomicInteger removeCount = new AtomicInteger();
  62. volatile CountDownLatch serveManagerLatch = new CountDownLatch(1);
  63. volatile CountDownLatch addLatch;
  64. volatile CountDownLatch startLatch;
  65. volatile CountDownLatch stopLatch;
  66. volatile CountDownLatch removeLatch;
  67. volatile BlockingQueue<String> reconnectServers = new LinkedBlockingQueue<String>();
  68. volatile NewConnectionListener newConnectionListener;
  69. private final CountDownLatch shutdownServersLatch = new CountDownLatch(1);
  70. public static final String SERVER_NAME_AND_CONNECTION_SEPARATOR = "%";
  71. private MockProcessManager(int expectedProcessCount) {
  72. this.expectedProcessCount = expectedProcessCount;
  73. addLatch = new CountDownLatch(expectedProcessCount);
  74. startLatch = new CountDownLatch(expectedProcessCount);
  75. stopLatch = new CountDownLatch(expectedProcessCount);
  76. removeLatch = new CountDownLatch(expectedProcessCount);
  77. }
  78. public static MockProcessManager create(int expectedProcessCount) throws IOException {
  79. MockProcessManager pm = new MockProcessManager(expectedProcessCount);
  80. pm.start();
  81. return pm;
  82. }
  83. private void start() throws IOException {
  84. listener = SocketListener.createSocketListener("PM", new ProcessManagerSocketHandler(), InetAddress.getLocalHost(), 0, 10);
  85. listener.start();
  86. }
  87. public MockManagedProcess getServerManager() {
  88. return serverManager;
  89. }
  90. public MockManagedProcess getProcess(String processName) {
  91. MockManagedProcess proc = serverProcesses.get(processName);
  92. if (proc == null && processName.equals("ServerManager"))
  93. proc = getServerManager();
  94. return proc;
  95. }
  96. public void shutdown() {
  97. listener.shutdown();
  98. }
  99. public InetAddress getAddress() {
  100. return listener.getAddress();
  101. }
  102. public Integer getPort() {
  103. return listener.getPort();
  104. }
  105. private void waitForLatch(CountDownLatch latch) {
  106. try {
  107. if (!latch.await(10, TimeUnit.SECONDS))
  108. throw new RuntimeException("Latch timed out");
  109. } catch (InterruptedException e) {
  110. throw new RuntimeException(e);
  111. }
  112. }
  113. public MockManagedProcess waitForServerManager() {
  114. waitForLatch(serveManagerLatch);
  115. return serverManager;
  116. }
  117. public void waitForAddedProcesses() {
  118. waitForLatch(addLatch);
  119. }
  120. public void waitForStartedProcesses() {
  121. waitForLatch(startLatch);
  122. }
  123. public void waitForRemovedProcesses() {
  124. waitForLatch(removeLatch);
  125. }
  126. public void waitForStoppedProcesses() {
  127. waitForLatch(stopLatch);
  128. }
  129. public String waitForReconnectServers() throws InterruptedException {
  130. String info = reconnectServers.poll(10, TimeUnit.SECONDS);
  131. if (info == null)
  132. throw new RuntimeException("Read timed out");
  133. return info;
  134. }
  135. public void resetAddLatch(int count) {
  136. addLatch = new CountDownLatch(count);
  137. }
  138. public void resetStartLatch(int count) {
  139. startLatch = new CountDownLatch(count);
  140. }
  141. public void resetStopLatch(int count) {
  142. stopLatch = new CountDownLatch(count);
  143. }
  144. public void resetRemoveLatch(int count) {
  145. removeLatch = new CountDownLatch(count);
  146. }
  147. public void resetReconnectServers() {
  148. reconnectServers.clear();
  149. }
  150. public int getAddCount() {
  151. return addCount.get();
  152. }
  153. public int getStartCount() {
  154. return startCount.get();
  155. }
  156. public int getStopCount() {
  157. return stopCount.get();
  158. }
  159. public int getRemoveCount() {
  160. return removeCount.get();
  161. }
  162. public void setNewConnectionListener(NewConnectionListener newConnectionListener) {
  163. this.newConnectionListener = newConnectionListener;
  164. }
  165. @Override
  166. public synchronized void addProcess(String processName, List<String> command, Map<String, String> env, String workingDirectory) {
  167. log.info("Adding process " + processName);
  168. serverProcesses.put(processName, new MockManagedProcess(this, processName, command));
  169. addCount.incrementAndGet();
  170. addLatch.countDown();
  171. }
  172. @Override
  173. public void startProcess(String processName) {
  174. log.info("Starting process " + processName);
  175. serverProcesses.get(processName).start();
  176. startCount.incrementAndGet();
  177. startLatch.countDown();
  178. }
  179. @Override
  180. public void stopProcess(String processName) {
  181. try {
  182. log.info("Stopping process " + processName);
  183. MockManagedProcess process = processName.equals("ServerManager") ? serverManager : serverProcesses.get(processName);
  184. if (process == null) {
  185. log.error("No process called " + processName);
  186. return;
  187. }
  188. stopCount.incrementAndGet();
  189. process.stop();
  190. stopLatch.countDown();
  191. } catch (IOException e) {
  192. throw new RuntimeException(e);
  193. }
  194. }
  195. @Override
  196. public void removeProcess(String processName) {
  197. log.info("Removing process " + processName);
  198. serverProcesses.remove(processName);
  199. removeCount.incrementAndGet();
  200. removeLatch.countDown();
  201. }
  202. @Override
  203. public void broadcastMessage(String sender, List<String> msg) {
  204. }
  205. @Override
  206. public void broadcastMessage(String sender, byte[] msg) {
  207. }
  208. @Override
  209. public void sendMessage(String sender, String recipient, List<String> msg) {
  210. }
  211. @Override
  212. public void sendMessage(String sender, String recipient, byte[] msg) {
  213. }
  214. @Override
  215. public void serversShutdown() {
  216. shutdownServersLatch.countDown();
  217. }
  218. public void waitForServerShutdown() {
  219. waitForLatch(shutdownServersLatch);
  220. }
  221. @Override
  222. public void downServer(String serverName) {
  223. }
  224. @Override
  225. public void reconnectServersToServerManager(String smAddress, String smPort) {
  226. reconnectServers.add(smAddress + ":" + smPort);
  227. }
  228. @Override
  229. public void reconnectProcessToServerManager(String server, String smAddress, String smPort) {
  230. reconnectServers.add(server + SERVER_NAME_AND_CONNECTION_SEPARATOR + smAddress + ":" + smPort);
  231. }
  232. class ProcessManagerSocketHandler implements SocketHandler {
  233. @Override
  234. public void initializeConnection(Socket socket) throws IOException, InitialSocketRequestException {
  235. InputStream in = socket.getInputStream();
  236. StringBuilder sb = new StringBuilder();
  237. //TODO Timeout on the read?
  238. Status status = StreamUtils.readWord(in, sb);
  239. if (status != Status.MORE) {
  240. throw new InitialSocketRequestException("Process acceptor: received '" + sb.toString() + "' but no more");
  241. }
  242. if (!sb.toString().equals("CONNECTED")) {
  243. throw new InitialSocketRequestException("Process acceptor: received unknown start command '" + sb.toString() + "'");
  244. }
  245. sb = new StringBuilder();
  246. while (status == Status.MORE) {
  247. status = StreamUtils.readWord(in, sb);
  248. }
  249. String processName = sb.toString();
  250. SocketConnection conn = SocketConnection.accepted(socket);
  251. if (processName.equals("ServerManager")) {
  252. serverManager.setPmConnection(conn);
  253. serveManagerLatch.countDown();
  254. }
  255. else {
  256. MockManagedProcess process = serverProcesses.get(processName);
  257. if (process != null) {
  258. process.setPmConnection(conn);
  259. }
  260. }
  261. if (newConnectionListener != null)
  262. newConnectionListener.acceptedConnection(processName, conn);
  263. log.info("PM got connection from " + processName);
  264. }
  265. }
  266. public interface NewConnectionListener{
  267. void acceptedConnection(String processName, SocketConnection conn);
  268. }
  269. }