View Javadoc

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 }