mcdcorp / opentest

Open source test automation tool for web applications, mobile apps and APIs
https://getopentest.org
MIT License
452 stars 108 forks source link

Communications link failure when trying to connect to DB #529

Closed galegor closed 2 years ago

galegor commented 2 years ago

Getting error when trying to connect to DB using java jdbc connector. Problem is most likely related to one of the dependencies. Noticed it when updated OpenTest Build: 1.2.4 Sep 14, 22:52 to current, downgrading back to 1.2.4 did not helped and getting same issue after that. Tested on multiple physical computers and Docker machines. Same test is working on old images and is not working if image is recreated based on same config.

Connector placed in user-jars: mysql-connector-java-8.0.18.jar Sample test code:

description: jdbc test
actors:
  - actor: API
    segments:
      - segment: 1
        actions:
          - description: run query
            script: |
                  $runAction("org.getopentest.actions.db.JdbcQuery", {
                    jdbcUrl: "jdbc:mysql://xxx",
                    user: test
                    password: test
                    sql: "SELECT * from.."
                  });

Error

Caused by: java.lang.RuntimeException: java.lang.RuntimeException: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at org.getopentest.base.TestActor.executeActionByClassName(TestActor.java:1626)
        at org.getopentest.base.TestActor.executeActionByDef(TestActor.java:1705)
        ... 20 more
Caused by: java.lang.RuntimeException: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at org.getopentest.actions.db.JdbcQuery.run(JdbcQuery.java:65)
        at org.getopentest.base.TestActor.executeAction(TestActor.java:1527)
        at org.getopentest.base.TestActor.executeActionByClassName(TestActor.java:1603)
        ... 21 more
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
        at java.sql.DriverManager.getConnection(Unknown Source)
        at java.sql.DriverManager.getConnection(Unknown Source)
        at org.getopentest.actions.db.JdbcQuery.run(JdbcQuery.java:32)
        ... 23 more
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
        at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:338)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
        at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1340)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
        ... 29 more
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.HandshakeContext.<init>(Unknown Source)
        at sun.security.ssl.ClientHandshakeContext.<init>(Unknown Source)
        at sun.security.ssl.TransportContext.kickstart(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:316)
        at com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188)
        at com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99)
        at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:329)
        ... 36 more

15.48.46 Test session has completed
adrianth commented 2 years ago

I am not able to look at this in depth right now, but a quick search indicates this is more likely related to either the JRE version and configuration or machine configuration. I think that what the error is saying is that the protocol and/or cipher suites supported by your DB engine are not available (or acceptable) on the client side (the JDBC driver). Please take a look at this SO answer and see if it helps: https://stackoverflow.com/questions/38205947/sslhandshakeexception-no-appropriate-protocol. I'm sure there's a lot more useful information about this error out there, I only tried one search string and only skimmed the Google results.

galegor commented 2 years ago

Thanks for the quick response. I have created MySql DB on freesqldatabase and was able to connect without any issue on machine which was getting error on my test DB. Creating ticket with AWS, will update this one with an answer.

galegor commented 2 years ago

Issue resolved. What I found out is: connector/J does not enable connections with TLSv1.2 and higher by default due to compatibility issues, when connecting to servers that restrict connections to use those higher TLS versions, you might encounter com.mysql.cj.exceptions.CJCommunicationsException: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). You need to enable connections with TLSv1.2 and higher versions using the enabledTLSProtocols connection property. See Section 6.9, “Connecting Securely Using SSL” for details here https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-rQeference-using-ssl.html My implementation of above in opentest included just adding enabledTLSProtocols and fixed issue.

jdbcUrl: "jdbc:mysql://myDB.us-east-1.rds.amazonaws.com/DB_name?enabledTLSProtocols=TLSv1.2",

Alternatively to connect to mySql DB without any TLS issues MariaDB also can be used (tested using mariadb-java-client-2.7.4.jar).