1 /* 2 * $Id: DynamicPort.java 22924 2011-09-12 22:08:33Z pablo.kraan $ 3 * -------------------------------------------------------------------------------------- 4 * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com 5 * 6 * The software in this package is published under the terms of the CPAL v1.0 7 * license, a copy of which has been included with this distribution in the 8 * LICENSE.txt file. 9 */ 10 11 package org.mule.tck.junit4.rule; 12 13 import org.apache.commons.logging.Log; 14 import org.apache.commons.logging.LogFactory; 15 import org.junit.rules.ExternalResource; 16 17 /** 18 * Defines a socket port number that will be dynamically assigned as an 19 * external resource. The instance will check that the port has been released 20 * on test shutdown. 21 * To use an instance dynamic socket port: 22 * <pre> 23 * @Rule 24 * public DynamicSocketPortNumber serverPort = new DynamicSocketPortNumber("server_port"); 25 * </pre> 26 * <p/> 27 * In order to use static dynamic ports: 28 * <p/> 29 * <pre> 30 * @ClassRule 31 * public static DynamicPort dynamicPort; 32 * </pre> 33 */ 34 public class DynamicPort extends ExternalResource 35 { 36 37 final static private int MIN_PORT = 5000; 38 final static private int MAX_PORT = 6000; 39 40 protected static FreePortFinder freePortFinder = new FreePortFinder(MIN_PORT, MAX_PORT); 41 42 protected Log logger = LogFactory.getLog(getClass()); 43 44 private final String name; 45 private int number; 46 private boolean initialized = false; 47 48 /** 49 * Creates a dynamic port resource for a given port name. 50 * 51 * @param name the name assigned to the port number. On resource creation 52 * a new system property will be created with that name and the 53 * value will be the port number. 54 */ 55 public DynamicPort(String name) 56 { 57 this.name = name; 58 } 59 60 /** 61 * Initializes the dynamic port. 62 * <p/> 63 * NOTE: this method was made public in order to support the usage of 64 * static dynamic ports because current JUnit version does not support 65 * class rules. 66 * 67 * @throws Throwable 68 */ 69 @Override 70 public void before() throws Throwable 71 { 72 if (initialized) 73 { 74 throw new IllegalArgumentException("Dynamic port was already initialized"); 75 } 76 77 number = freePortFinder.find(); 78 System.setProperty(name, String.valueOf(number)); 79 initialized = true; 80 } 81 82 /** 83 * Checks that the port has been released. For now if it was not released it 84 * just logs a message so we can track the problem. 85 * <p/> 86 * NOTE: this method was made public in order to support the usage of 87 * static dynamic ports because current JUnit version does not support 88 * class rules. 89 * 90 * @throws Throwable 91 */ 92 @Override 93 public void after() 94 { 95 if (!initialized) 96 { 97 throw new IllegalArgumentException("Dynamic port was not initialized"); 98 } 99 100 freePortFinder.releasePort(number); 101 initialized = false; 102 } 103 104 public int getNumber() 105 { 106 return number; 107 } 108 109 public String getName() 110 { 111 return name; 112 } 113 }