PSQLException "Could not open SSL root certificate file" when attempting SSL connection with Postgres via JDBC - postgresql

In Java 15, using the PostgreSQL JDBC Driver (ver. 42.2.18, JDBC4.2) from jdbc.postgresql.org with this DataSource:
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setServerNames( new String[] { "my-server-address" } );
ds.setPortNumbers( new int[] { 25060 } );
ds.setSsl( true );
ds.setDatabaseName( "mydb" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
this.dataSource = ds;
…the code Connection conn = this.dataSource.getConnection(); throws this exception:
org.postgresql.util.PSQLException: Could not open SSL root certificate file /Users/basilbourque/.postgresql/root.crt.
I know my Postgres 12 server is set up for SSL connections, as my IntelliJ Ultimate has a database access feature (DataGrip) that is successfully connecting with SSL (TLS) protection.
So what is wrong my DataSource configuration in JDBC?

Thanks to this Github issue page for the pgjdbc driver, I found this post by davecramer:
As of 42.2.5 ssl=true implies verify-full as per the release notes. If you wish to get the old behaviour use sslmode=require
Sure enough, replacing ds.setSsl( true ); with ds.setSslMode( "require" ); allowed my JDBC driver make a connection via DataSource.
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setServerNames( new String[] { "my-server-address" } );
ds.setPortNumbers( new int[] { 25060 } );
ds.setSslMode( "require" ); // Replaces: ds.setSsl( true );
ds.setDatabaseName( "mydb" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
this.dataSource = ds;
I have no idea what any of these SSL/TLS related options are actually doing, but this worked for me to connect to my DigitalOcean managed Postgres database server.
The following code snippet now runs successfully:
try
(
Connection conn = this.dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
)
{
String sql =
"""
SELECT uuid_generate_v1()
;
""";
try (
ResultSet rs = stmt.executeQuery( sql ) ;
)
{
while ( rs.next() )
{
UUID uuid = rs.getObject( 1 , UUID.class );
System.out.println( "uuid = " + uuid );
}
}
}
catch ( SQLException e )
{
e.printStackTrace();
}

Related

How to connect to heroku postgress database from JDBC?

I use this code
But can anyone suggest me or guide me to a right document which can give me an example of how to connect to heroku postgress database with JDBC ?
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() +
dbUri.getPath();
connectionPool = new BasicDataSource();
if (dbUri.getUserInfo() != null) {
connectionPool.setUsername(dbUri.getUserInfo().split(":")[0]);
connectionPool.setPassword(dbUri.getUserInfo().split(":")[1]);
}
connectionPool.setDriverClassName("org.postgresql.Driver");
connectionPool.setUrl(dbUrl);
connectionPool.setInitialSize(1);
Connection connection = connectionPool.getConnection();
See heroku's documentation
Note:
The DATABASE_URL for the Heroku Postgres add-on follows the below convention
postgres://<username>:<password>#<host>:<port>/<dbname>
However the Postgres JDBC driver uses the following convention:
jdbc:postgresql://<host>:<port>/<dbname>?user=<username>&password=<password>
Sample code to parse DATABASE_URL into Jdbc format:
private static Connection getConnection() throws URISyntaxException, SQLException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath();
return DriverManager.getConnection(dbUrl, username, password);
}

How do I connect to Hive on EMR through Eclipse?

I am trying to connect to Hive on EMR through Eclipse, but I get an error.
Exception in thread "main" java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://localhost:8158: java.net.ConnectException: Connection refused
at org.apache.hive.jdbc.HiveConnection.openTransport(HiveConnection.java:215)
at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:163)
at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:105)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at com.readypulse.sparkanalytics.HiveQLConnector.<init>(HiveQLConnector.java:31)
at com.readypulse.sparkanalytics.HiveQLConnector.main(HiveQLConnector.java:83)
Caused by: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused
You would need a SSH Tunnel to poke a hole to EMR master. And then connect via JDBC.
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
private static String hiveConnectionString = "jdbc:hive2://localhost:8158";
//Need port forwarding
SparkPortForwarding.portForwardForSpark();
Class c = Class.forName(driverName);
Connection connection = DriverManager.getConnection(hiveConnectionString,
"user", "pwd");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
You can do port forwarding via shell as:
ssh -i ~/mykey.pem -N -L 8158:<maserhost>:10000 hadoop#<masterhost>
Or You can use the code using the library JSch
public static void portForwardForSpark() {
try {
if(session != null && session.isConnected()) {
return;
}
JSch jsch = new JSch();
jsch.addIdentity(PATH_TO_SSH_KEY_PEM);
String host = REMOTE_HOST;
session = jsch.getSession(USER, host, 22);
// username and password will be given via UserInfo interface.
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.connect();
int assingedPort = session.setPortForwardingL(LPORT, RHOST, RPORT);
System.out.println("Port forwarding done for the post : " + assingedPort);
} catch (Exception e) {
System.out.println(e);
}
}

stunnel with wss getting ERR_CONNECTION_TIMED_OUT

I'm trying to use stunnel with wss on my site but when I try to connect I always get:
WebSocket connection to 'wss://www.soinfit.com:8443/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
My socket is running on port 8080 as this:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();
My stunnel config is:
debug = 4
output = /var/log/stunnel4/websocket.log
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
cert = /etc/ssl/private/47f2ad52d70c0.crt
key = /etc/ssl/private/soinfit.key
[websocket]
accept = 8443
connect = 8080
I'm using Chrome to connect and I'm using this code:
try {
conn = new WebSocket('wss://www.soinfit.com:8443');
conn.onclose = function (e) {
}
conn.onopen = function(e) {
console.log("test");
};
} catch (error) {
console.log(error);
}
There is nothing in the log file.
What am I doing wrong?
Thanks.

RMI and 2 machines - two way communication

I've got problem with RMI comunication between 2 machines (win 7 and win xp VM). The exception with I have problem is:
java.rmi.ConnectException: Connection refused to host: 169.254.161.21; nested exception is:
java.net.ConnectException: Connection timed out: connect
It's really weired because during connection I use address 192.168.1.4 (server), but exception somehow show sth different. I disabled firewall on both side. Ping working to both side. I tried telnet to server and use server port:
telnet 192.168.1.4 1099 and it's working... I can't figure out where the problem is.
If I run this on host side (eg server side) everything works fine.
How is it look from SERVER:
public class Server
{
public static void main(String args[])
{
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
String portNum, registryURL;
try{
System.out.println("Enter the RMIregistry port number:");
portNum = (br.readLine()).trim();
int RMIPortNum = Integer.parseInt(portNum);
startRegistry(RMIPortNum); // Registry registry = LocateRegistry.createRegistry(RMIPortNum);
ServerSide_Impl exportedObj = new ServerSide_Impl();
registryURL = "rmi://localhost:" + portNum + "/callback";
//registryURL = "rmi://192.168.1.4:" + portNum + "/callback";
Naming.rebind(registryURL, exportedObj);
System.out.println("Callback Server ready.");
}// end try
catch (Exception re) {
System.out.println(
"Exception in HelloServer.main: " + re);
} // end catch
} // end main
//This method starts a RMI registry on the local host, if
//it does not already exists at the specified port number.
private static void startRegistry(int RMIPortNum) throws RemoteException
{
try
{
Registry registry = LocateRegistry.getRegistry(RMIPortNum);
registry.list( );
// This call will throw an exception
// if the registry does not already exist
}
catch (RemoteException e)
{
Registry registry = LocateRegistry.createRegistry(RMIPortNum);
}
} // end startRegistry
} // end class
Client side is look like:
try
{
this.serverAd = serverAddress.getText();
String path = System.getProperty("user.dir");
String pathAfter = path.replace("\\", "/");
String pathFile = "file:/"+pathAfter + "/wideopen.policy";
System.setProperty("java.security.policy", pathFile);
System.setSecurityManager(new RMISecurityManager());
this.hostName = hostNameTextField.getText();
this.portNum = hostPortNumberTextField.getText();
RMIPort = Integer.parseInt(this.portNum);
this.time = Integer.parseInt(timeTextField.getText());
//this.registryURL = "rmi://localhost:" + this.portNum + "/callback";
String registryURLString = "rmi://"+this.serverAd+":" + this.portNum + "/callback";
this.registryURL = registryURLString;
ConsoleTextField.append("\n"+ this.registryURL + "\n");
// find the remote object and cast it to an
// interface object
obj = (ServerSide_Interface)Naming.lookup(this.registryURL);
boolean test = obj.Connect();
if(test)
{
callbackObj = new ClientSide_Impl();
// register for callback
obj.registerForCallback(callbackObj);
isConnected = true;
ConsoleTextField.append("Nawiązano połaczenie z serwerem\n");
TableModel modelTemp = obj.Server_GenerateStartValues();
myDataTable.setModel(modelTemp);
myDataTable.setEnabled(true);
}
else ConsoleTextField.append("Brak połączenia z serwerem\n");
}
catch (Exception ex ){
ConsoleTextField.append(ex + "\n");
System.out.println(ex);
}
This connection is working fine if I run client on host side. If I use VM and try connect between 2 different machines, I can;t figure out what did I do bad
There is something wrong with your etc/hosts file or your DNS setup. It is providing the wrong IP address to the server as the server's external IP address, so RMI embeds the wrong address into the stub, so the client attempts to connect to the wrong IP address.
If you can't fix that, you can set the system property java.rmi.server.hostname to the correct IP address at the server JVM, before exporting any RMI objects (including Registries). That tells RMI to embed that address in the stub.

Guvnor execution server getting 401 when using AD-configured Guvnor as endpoint

We are using:
• Drools Execution Server that came with Drools 5.0.x
• Drools Guvnor 5.2 configured with active directory
The execution server and guvnor run on the same Tomcat and use the same port.
With the execution server you can have a listener for each package within the configuration file. I have two such files, from-file-system.properties that points to a local directory where a drools binary package is manually deployed. This works fine.
But I try to use with-guvnor.properties which points to a package binary on 5.3 Guvnor. Here is the file:
name=ndipiazza
newInstance=true
# Absolute path of the directory containing pc.drl: placeholder replaced by Ant.
url=http://localhost:9109/drools-guvnor/rest/packages/NDD_Test/binary
poll=10
I get the following error:
RuleAgent(ndipiazza) INFO (Mon Jun 18 18:11:32 EDT 2012): Configuring package provider : URLScanner monitoring URLs: http://localhost:9109/drools-guvnor/rest/packages/NDD_Test/binary
RuleAgent(ndipiazza) WARNING (Mon Jun 18 18:11:34 EDT 2012): Was an error contacting http://localhost:9109/drools-guvnor/rest/packages/NDD_Test/binary. Reponse header: {null=[HTTP/1.1 401 Unauthorized]
Some sort of authorization error very likely related to the active directory configuration within Guvnor 5.2.
This used to work for us just fine with an earlier version of Guvnor.
How can I fix this issue?
So we isolated the problem today. Drools Server 5.0.x cannot support a URL endpoint when it has authentication of any sort.
I reported a bug: https://issues.jboss.org/browse/JBRULES-3554
Without these changes, this will not work.
drools-core's org/drools/agent/HttpClientImpl.java
These two methods need to have authentication added in (marked by START and END NDD), and obviously switched with your username/password.
public LastUpdatedPing checkLastUpdated(URL url) throws IOException {
URLConnection con = url.openConnection();
HttpURLConnection httpCon = (HttpURLConnection) con;
try {
// **** START NDD *****
BASE64Encoder enc = new sun.misc.BASE64Encoder();
String userpassword = "ad-user" + ":" + "ad-password";
String encodedAuthorization = enc.encode( userpassword.getBytes() );
httpCon.setRequestProperty("Authorization", "Basic "+
encodedAuthorization);
// **** END NDD *****
httpCon.setRequestMethod( "HEAD" );
String lm = httpCon.getHeaderField( "lastModified" );
LastUpdatedPing ping = new LastUpdatedPing();
ping.responseMessage = httpCon.getHeaderFields().toString();
if ( lm != null ) {
ping.lastUpdated = Long.parseLong( lm );
} else {
long httpLM = httpCon.getLastModified();
if ( httpLM > 0 ) {
ping.lastUpdated = httpLM;
}
}
return ping;
} finally {
httpCon.disconnect();
}
}
public Package fetchPackage(URL url) throws IOException,
ClassNotFoundException {
URLConnection con = url.openConnection();
HttpURLConnection httpCon = (HttpURLConnection) con;
try {
// **** START NDD *****
BASE64Encoder enc = new sun.misc.BASE64Encoder();
String userpassword = "ad-user" + ":" + "ad-password";
String encodedAuthorization = enc.encode( userpassword.getBytes() );
httpCon.setRequestProperty("Authorization", "Basic "+
encodedAuthorization);
// **** END NDD *****
httpCon.setRequestMethod( "GET" );
Object o = DroolsStreamUtils.streamIn( httpCon.getInputStream() );
if ( o instanceof KnowledgePackageImp ) {
return ((KnowledgePackageImp) o).pkg;
} else {
return (Package) o;
}
} finally {
httpCon.disconnect();
}
}
Mystery solved.