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