I've been trying to connect to a Cloud SQL instance using HikariCP from App Engine locally so I can make queries. Every time I run App Engine using the ./gradlew appengineRun command, I get a java.net.SocketException: already connected error. This works fine when I deploy it to App Engine, but locally it just won't work. I'm stumped.
Here's the configuration for Hikari:
val config = HikariConfig().apply {
jdbcUrl = "jdbc:postgresql://google/[DB-NAME]"
username = "[USERNAME]"
password = "[PASSWORD]"
addDataSourceProperty("cloudSqlInstance", "[INSTANCE-CONNECTION-NAME")
addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory")
}
private val dataSource = HikariDataSource(config)
private val connection = dataSource.connection
And then to execute the query:
connection.use { connection ->
connection.prepareCall("SELECT EXISTS(SELECT 1 FROM profiles WHERE username = '$username')").use { statement ->
statement.executeQuery().use { resultSet ->
try {
val exists = generateSequence {
if (resultSet.next()) resultSet.getBoolean(1) else null
}.toList()
onComplete(exists.any { it }, null)
} catch (e: Exception) {
onComplete(false, e)
}
}
}
}
I was certain this was the correct configuration to connect to SQL, but I keep getting this stacktrace:
Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: The connection attempt failed.
at com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:597)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:576)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:81)
at appengine.sql.repository.ProfileRepository.<clinit>(ProfileRepository.kt:34)
... 48 more
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:262)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:67)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:216)
at org.postgresql.Driver.makeConnection(Driver.java:406)
at org.postgresql.Driver.connect(Driver.java:274)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:353)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562)
... 51 more
Caused by: java.net.SocketException: already connected
at java.net.Socket.connect(Socket.java:569)
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:668)
at org.postgresql.core.PGStream.<init>(PGStream.java:64)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:133)
... 60 more
Are the connection being properly closed after use? Is it possible the application is attempting to reuse connection after they have been closed by the SQL instance? I'd advise implementing a connection pool within the application for efficient use of connections to the db. Some CloudSQL documentation pages that may help cover these topics [1][2].
[1] https://cloud.google.com/sql/docs/mysql/manage-connections#opening_and_closing_connections
[2] https://cloud.google.com/sql/docs/mysql/diagnose-issues
Related
I get the following error when connecting to my database:
" Caused by: org.postgresql.util.PSQLException: Something unusual has occurred to cause the driver to fail. Please report this exception."
package code.with.cal.timeronservicetutorial
import kotlinx.android.synthetic.main.activity_main.*
import java.sql.DriverManager
class ConnectionHelper {
fun ConnectDB() {
val jdbcUrl = "jdbc:postgresql://HOST/USER"
// get the connection
val connection = DriverManager.getConnection(jdbcUrl, "USER", "PW")
// prints true if the connection is valid
println(connection.isValid(0))
}
}
I suspect I didn't include the dependency of right version in my gradle, but i don't know how to find which driver version i have. I added this one:
implementation 'org.postgresql:postgresql:42.2.5'
I am trying to connect to my local SQL Server with R2DBC, unfortunately, I do not know where I am going wrong, I have a lot of experience with R2DBC, I use it all the time with other databases but this is my first time with MSSQL, below is my MSSQL ConnectionFactorythat is failing:
#Bean
override fun connectionFactory(): ConnectionFactory {
val options = builder()
.option(DRIVER, "sqlserver")
.option(HOST, properties.host)
.option(PORT, properties.port.toInt())
.option(USER, properties.username)
.option(PASSWORD, properties.password)
.option(DATABASE, properties.database)
.option(SSL, false)
.build()
val connectionFactory = ConnectionFactories.get(options)
val configuration = ConnectionPoolConfiguration.builder(connectionFactory)
.maxIdleTime(Duration.ofMillis(1000))
.maxSize(20)
.build()
connectionPool = ConnectionPool(configuration)
return ProxyConnectionFactory.builder(connectionPool)
.build()
}
My properties
com:
#Application database
database:
host: PC_NAME\SQLEXPRESS
port: 51306
database: app_database
username: user
password: pass
When I run my application I get the error below:
09:02:40.151 [reactor-tcp-nio-1] DEBUG reactor.pool.SimpleDequePool - failed to warm up extra resource 9/9: java.net.UnknownHostException: Failed to resolve 'PC_NAME\SQLEXPRESS' after 4 queries
09:02:40.153 [parallel-2] ERROR reactor.core.publisher.Operators - Operator called default onErrorDropped
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.transaction.CannotCreateTransactionException: Could not open R2DBC Connection for transaction; nested exception is java.net.UnknownHostException: Failed to resolve 'PC_NAME\SQLEXPRESS' after 4 queries
Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open R2DBC Connection for transaction; nested exception is java.net.UnknownHostException: Failed to resolve 'PC_NAME\SQLEXPRESS' after 4 queries
I do not understand where I am going wrong, I can confirm that I have enabled TCP and shown below
And enabled remote connection on my server instance
Does anyone know how this works?
I'm trying to access graph api. I'm using MSAL4J to access the graph apis. But I'm getting com.microsoft.aad.msal4j.MsalClientException: java.net.SocketTimeoutException: connect timed out even when I'm not using my vpn.
I'm following this tutorial. I've followed all the steps mentioned in there.
Here the stack trace:
Exception in thread "main" java.util.concurrent.ExecutionException: com.microsoft.aad.msal4j.MsalClientException: java.net.SocketTimeoutException: connect timed out at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) at ClientCredentialGrant.getAccessTokenByClientCredentialGrant(ClientCredentialGrant.java:78) at ClientCredentialGrant.main(ClientCredentialGrant.java:36) Caused by: com.microsoft.aad.msal4j.MsalClientException: java.net.SocketTimeoutException: connect timed out at com.microsoft.aad.msal4j.HttpHelper.executeHttpRequest(HttpHelper.java:53) at com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.executeRequest(AadInstanceDiscoveryProvider.java:218) at com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.sendInstanceDiscoveryRequest(AadInstanceDiscoveryProvider.java:172) at com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.doInstanceDiscoveryAndCache(AadInstanceDiscoveryProvider.java:271) at com.microsoft.aad.msal4j.AadInstanceDiscoveryProvider.getMetadataEntry(AadInstanceDiscoveryProvider.java:56) at com.microsoft.aad.msal4j.AuthenticationResultSupplier.getAuthorityWithPrefNetworkHost(AuthenticationResultSupplier.java:32) at com.microsoft.aad.msal4j.AcquireTokenByAuthorizationGrantSupplier.execute(AcquireTokenByAuthorizationGrantSupplier.java:59) at com.microsoft.aad.msal4j.AcquireTokenByClientCredentialSupplier.acquireTokenByClientCredential(AcquireTokenByClientCredentialSupplier.java:63) at com.microsoft.aad.msal4j.AcquireTokenByClientCredentialSupplier.execute(AcquireTokenByClientCredentialSupplier.java:49) at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:59) at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:17) at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) Caused by: java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673) at sun.net.NetworkClient.doConnect(NetworkClient.java:175) at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264) at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1138) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338) at com.microsoft.aad.msal4j.DefaultHttpClient.readResponseFromConnection(DefaultHttpClient.java:107) at com.microsoft.aad.msal4j.DefaultHttpClient.executeHttpGet(DefaultHttpClient.java:47) at com.microsoft.aad.msal4j.DefaultHttpClient.send(DefaultHttpClient.java:35) at com.microsoft.aad.msal4j.HttpHelper.executeHttpRequestWithRetries(HttpHelper.java:96) at com.microsoft.aad.msal4j.HttpHelper.executeHttpRequest(HttpHelper.java:49) ... 16 more
Any help will be appreciated.
Finally, I figured it out. And writing this answer with hope that it will help someone. com.microsoft.aad.msal4j.MsalClientException: java.net.SocketTimeoutException: connect timed out This exception was occurring due to the proxy issues.
My system was behind the proxy so it was not able to connect with microsoftonline servers.
I have two approaches to get the access_token from azure AD.
First Approach
Using REST API provided by AZURE AD
public String getAccessToken() throws UnsupportedOperationException, IOException {
ObjectMapper mapper = new ObjectMapper();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("your_proxy_address", your_proxy_port));
OkHttpClient client = new OkHttpClient.Builder().proxy(proxy).build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(
"grant_type=client_credentials&client_id=your_client_id&scope=https://graph.microsoft.com/.default&client_secret=your_client_secret",
mediaType);
Request request = new Request.Builder()
.url("https://login.microsoftonline.com/your tenent id/oauth2/v2.0/token")
.method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").build();
Response response = client.newCall(request).execute();
// String token = response.body().string();
return mapper.readTree(response.body().string()).get("access_token").asText();
}
You can get the access_token by using this method. Another approach is, by using the MSAL4J library.
Second approach
First build client object
private static void BuildConfidentialClientObject() throws Exception {
Proxy proxy = AuthProvider.getInstance().getProxy();
app = ConfidentialClientApplication.builder(clientId, ClientCredentialFactory.createFromSecret(secret))
.proxy(proxy).authority(authority).build();
}
Then get the access_token
private static IAuthenticationResult getAccessTokenByClientCredentialGrant() throws Exception {
ClientCredentialParameters clientCredentialParam = ClientCredentialParameters
.builder(Collections.singleton(scope)).build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
return future.join();
}
Now you can access the graph APIs using this access_token and complete your tasks.
PS: I'm using demon approach for my tasks. There are different approaches to fulfill your requirements.
You can have a look here for authentication approach reference.
I'm using doctrine in a project (not symfony). In this project I also use phpstan, i installed both phpstan/phpstan-doctrine and phpstan/extension-installer.
My phpstan.neon is like this:
parameters:
level: 8
paths:
- src/
doctrine:
objectManagerLoader: tests/object-manager.php
Inside tests/object-manager.php it return the result of a call to a function that return the entity manager.
Here is the code that create the entity manager
$database_url = $_ENV['DATABASE_URL'];
$isDevMode = $this->isDevMode();
$proxyDir = null;
$cache = null;
$useSimpleAnnotationReader = false;
$config = Setup::createAnnotationMetadataConfiguration(
[$this->getProjectDirectory() . '/src'],
$isDevMode,
$proxyDir,
$cache,
$useSimpleAnnotationReader
);
// database configuration parameters
$conn = [
'url' => $database_url,
];
// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);
When i run vendor/bin/phpstan analyze i get this error:
Internal error: An exception occurred in the driver: SQLSTATE[08006] [7] could not translate host name "postgres_db" to address: nodename nor servname provided, or not known
This appear because i'm using docker and my database url is postgres://user:password#postgres_db/database postgres_db is the name of my database container so the hostname is known inside the docker container.
When i run phpstan inside the container i do not have the error.
So is there a way to run phpstan outside docker ? Because i'm pretty sure that when i'll push my code the github workflow will fail because of this
Do phpstan need to try to reach the database ?
I opened an issue on the github of phpstan-doctrine and i had an answer by #jlherren that explained :
The problem is that Doctrine needs to know what version of the DB server it is working with in order to instantiate the correct AbstractPlatform implementation, of which there are several available for the same DB vendor (e.g. PostgreSQL94Platform or PostgreSQL100Platform for postgres, and similarly for other DB drivers). To auto-detect this information, it will simply connect to the DB and query the version.
I just changed my database url from:
DATABASE_URL=postgres://user:password#database_ip/database
To:
DATABASE_URL=postgres://user:password#database_ip/database?serverVersion=14.2
I realize this is what would be considered a duplicate topic, but I have followed the recommended steps in the other topics of this same nature with no success.
I am using GGTS 3.6.4 with
Grails 2.3.0
jdk1.7.0_80
Groovy compiler level 2.3
Microsoft SQL Server 2012
I have a grails-app which authenticates users logging in against an LDAP server with Apache Shiro and I have the following code (in the Shiro generated AuthController.groovy) to try and store some information from an external database in the session. (Note: With regards to usernames, passwords, and database names, I've changed all of them here for privacy reasons)
def signIn = {
Subject subject = SecurityUtils.getSubject();
String lowerCaseUserName=params.username.toLowerCase();
def authToken = new UsernamePasswordToken(lowerCaseUserName, params.password)
// Support for "remember me"
if (params.rememberMe) {
authToken.rememberMe = true
}
try{
subject.login(authToken)
if (subject.isAuthenticated())
{
session.username = lowerCaseUserName
// Attempting to get employee id from MS SQL
Sql Database = Sql.newInstance(
'jdbc:sqlserver://myserver;DatabaseName=mydatabase',
'user',
'password',
'com.microsoft.sqlserver.jdbc.SQLServerDriver'
);
Database.eachRow('select empid from table_name where username=${session.username}') { row ->
session.empid = row.empid
}
Database.close();
def targetUri = params.targetUri ?: "/home"
log.info "Redirecting to '${targetUri}'."
redirect(uri: targetUri)
}
}
...
}
However, I get the following error
SQLException occurred when processing request: [POST] /app/auth/signIn - parameters:
username: user
_rememberMe:
targetUri:
password: ***
No suitable driver found for jdbc:sqlserver://myserver;DatabaseName=mydatabase. Stacktrace follows:
java.sql.SQLException: No suitable driver found for jdbc:sqlserver://myserver;DatabaseName=mydatabase
at java.sql.DriverManager.getConnection(DriverManager.java:596)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at app.AuthController$_closure3.doCall(AuthController.groovy:45)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I have tried the following with no success:
Added sqljdbc4.jar to /app/lib/
Manually added /app/lib/ to classpath (via .classpath)
Added sqljdbc4.jar to the classpath via the Properties > Java Build Path > Add JARs
I've tried these variations with sqljdbc4.jar, sqljdbc.jar, and sqlserverjdbc.jar and every combo thereof.
I'm basically stuck. None of the fixes I've read on here, or elsewhere, solve my error. Any help would be greatly appreciated!
Edit 1: Adding Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") above the newInstance call produces the following errors:
ClassNotFoundException occurred when processing request: [POST] /app/auth/signIn - parameters:
username: user
_rememberMe:
targetUri:
password: ***
com.microsoft.sqlserver.jdbc.SQLServerDriver. Stacktrace follows:
java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName(Class.java:195)
at isec.AuthController$_closure3.doCall(AuthController.groovy:45)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Is this a step forward, backward, or are we running in place?
Edit 2: What I ended up having to do was change my DataSource.groovy to this
dataSource {
pooled = true
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
//cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "validate"
url = "jdbc:sqlserver://myserver:1433;databaseName=mydatabase;"
driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
username = "myusername"
password = "mypassword"
}
}
....
}
and changed my AuthController.groovy data access to
try{
subject.login(authToken)
if (subject.isAuthenticated())
{
ShiroUser currentUser = new ShiroUser()
def targetUri = params.targetUri ?: "/home"
log.info "Redirecting to '${targetUri}'."
redirect(uri: targetUri)
}
}
and I have successfully accessed my DB with a modified ShiroUser.groovy file
class ShiroUser {
static hasMany = [ roles: ShiroRole, permissions: String ]
User_Data userData;
static constraints = {
}
def getUsername() {
return userData.username
}
}
where User_Data.groovy is a new domain class containing
class User_Data {
static mapping = {
table "mytablename"
}
...
}
So now I'm onto messing with methods! Not sure why JDBC stuff didn't work out, but GORM is the path I'm taking now.
you definitely need to add sqljdbc4.jar to /app/lib/ which you have already done.
have you tried adding database connection to the BuildConfig.groovy
dataSource {
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
dialect = "org.hibernate.dialect.SQLServerDialect"
url = "jdbc:sqlserver://localhost:1433;databaseName=dbName"
username = "sa"
password = ""
}
Also make sure the SQL server is configured to accept connection on port 1433. It is disabled by default.