unitaria tutorial test springboot prueba example español ejemplos con java http tomcat ssl jenkins

java - tutorial - Prueba JUnit con Embedded Tomcat Server, ¿cómo especificar puertos automáticos para ambos conectores http y https?



spring boot test repository (2)

No lo he intentado pero desde el código parece

  1. Puede setRedirectPort después de que se haya iniciado el servidor

  2. Puede usar Connector.getLocalPort para obtener un puerto real

Así que creo que podrías intentar agregar algo como

mTomcat.start(); // <-- your existing code defaultConnector.setRedirectPort(SSLConnector.getLocalPort())

Descripción

Hice una prueba JUnit que se enfoca en tratar de probar una llamada a un servicio web SOAP.

Estoy utilizando un servidor tomcat integrado para mi prueba con el fin de ejecutar mi prueba con un servidor simulado.

También estoy usando conectores http y https.

Necesito usar puertos automáticos para estos dos conectores porque la prueba se está ejecutando en un servidor Jenkins y no puedo usar el puerto 443 o 8443 ya que ya están ocupados.

Entiendo que usar el puerto 0 como puerto estándar resultará en tomcat usando la asignación automática de puertos pero no puedo usarlo con ambos conectores.

Comportamiento esperado

Me gustaría utilizar la asignación de puertos automática también para mi conector ssl personalizado.

¿Es posible hacerlo de alguna manera?

Código de muestra

Aquí está el código para mi instancia de tomcat:

@Before public void setup() throws Throwable { File tomcatWorkingDir = new File(mWorkingDir); //Empty the target/tomcat-working-dir directory if it exist //Create the directory otherwise if(tomcatWorkingDir.exists() && tomcatWorkingDir.isDirectory()){ LOGGER.info("cleaning tomcat-working-dir directory"); FileUtils.cleanDirectory(new File(mWorkingDir)); } else { LOGGER.info("create tomcat-working-dir directory"); tomcatWorkingDir.mkdir(); } LOGGER.info("disabling ssl certification validation"); //Disable JVM ssl sockets connection disableJVMCertificate(); //Add server certificate createServerCertificate(); //Custom SSL Connector Connector SSLConnector = getSSLConnector(); mTomcat = new Tomcat(); //Standard http startup port mTomcat.setPort(0); //Set up base directory //Otherwise, tomcat would use the current directory mTomcat.setBaseDir(mWorkingDir); LOGGER.info("setting the ssl connector in TOMCAT"); Service service = mTomcat.getService(); service.addConnector(SSLConnector); //Redirect current port Connector defaultConnector = mTomcat.getConnector(); defaultConnector.setRedirectPort(SERVER_HTTPS_PORT); //Configure the way WAR are managed by the engine mTomcat.getHost().setAutoDeploy(true); mTomcat.getHost().setDeployOnStartup(true); //Add mock server into our webApp String servletName = "/server"; File webApp = new File(mWorkingDir,"../../../ws-mock-server/src/main/webapp"); mTomcat.addWebapp(mTomcat.getHost(), servletName, webApp.getAbsolutePath()); //start tomcat LOGGER.info("starting TOMCAT"); mTomcat.start(); }

y aquí para mi conector ssl personalizado.

private static Connector getSSLConnector(){ Connector connector = new Connector(); connector.setPort(SERVER_HTTPS_PORT); connector.setSecure(true); //Http protocol Http11AprProtocol connector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol"); //Maximum threads allowedd on this instance of tomcat connector.setAttribute("maxThreads","200"); connector.setAttribute("SSLEnabled", true); //No client Authentification is required in order to connect connector.setAttribute("clientAuth", false); //SSL TLSv1 protocol connector.setAttribute("sslProtocol","TLS"); //Ciphers configuration describing how server will encrypt his messages //A common cipher suite need to exist between server and client in an ssl //communication in order for the handshake to succeed connector.setAttribute("ciphers","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"); LOGGER.info("setting keystore file"); //Here an absolute file path is needed in order to properly set up the keystore attribute connector.setAttribute("keystoreFile",new File(".").getAbsolutePath().replace("//", "/")+"/"+mWorkingDir+"/server.jks"); LOGGER.info("setting keystore pass"); connector.setAttribute("keystorePass","changeit"); return connector; }


Tengo dos soluciones para este problema:

Seleccione el puerto SSL manualmente

El constructor ServerSocket (0) selecciona automáticamente un puerto libre. El Tomcat usa este método también.

try (ServerSocket testSocket = new ServerSocket(0)) { int randomFreePort = testSocket.getLocalPort(); sslConnector.setPort(randomFreePort); defaultConnector.setRedirectPort( randomFreePort); } // At this point the testSocket.close() called tomcat.start();

Lo sé, hay una probabilidad de que otro proceso asigne el mismo puerto entre testSocket.close() y tomcat.start() , pero puede detectar esta situación con LifecycleState.FAILED.equals(sslConnector.getState()) prueba.

Use oyentes del ciclo de vida

Los conectores Tomcat son conscientes del ciclo de vida, por lo que se le notificará sobre los eventos ''before_init'' y ''after_init''. Tomcat inicializa los conectores en el orden cuando los agregó al Servicio.

  1. Agregue el conector ssl.
  2. Agrega un conector http. (Ese será el conector ''predeterminado''. No llame al mTomcat.getConnector() porque obtiene el primero o crea un nuevo conector.)
  3. Cuando se completa la inicialización del conector ssl, puede obtener el puerto elegido con la llamada getLocalPort () .
  4. Antes de la inicialización del conector http, llame al setRedirectPort

Ejemplo completo:

Tomcat mTomcat = new Tomcat(); Connector sslConnector = getSSLConnector(); mTomcat.getService().addConnector(sslConnector); Connector defaultConnector = new Connector(); defaultConnector.setPort(0); mTomcat.getService().addConnector(defaultConnector); // Do the rest of the Tomcat setup AtomicInteger sslPort = new AtomicInteger(); sslConnector.addLifecycleListener(event->{ if( "after_init".equals(event.getType()) ) sslPort.set(sslConnector.getLocalPort()); }); defaultConnector.addLifecycleListener(event->{ if( "before_init".equals(event.getType()) ) defaultConnector.setRedirectPort(sslPort.get()); }); mTomcat.start();