I'm trying to find out what protocol the SnowFlake JDBC library uses to communicate with SnowFlake. I see hints here and there that it seems to be using HTTPS as the protocol. Is this true?
To my knowledge, other JDBC libraries like for example for Oracle or PostgreSQL use the lower level TCP protocol to communicate with their database servers, and not the application-level HTTP(S) protocol, so I'm confused.
My organization only supports securely routing http(s)-based communication. Can I use this snowflake jdbc library then?
I have browsed all documentation that I could find, but wasn't able to answer this question.
My issue on GitHub didn't get an answer either.
Edit: Yes, I've seen this question, but I don't feel that it answers my question. SSL/TLS is an encryption, but that doesn't specify the data format.
It looks like the jdbc driver uses HTTP Client HttpUtil.initHttpClient(httpClientSettingsKey, null);, as you can see in here
The HTTP Utility Class is available here
Putting an excerpt of the session open method here in case the link goes bad/dead.
/**
* Open a new database session
*
* #throws SFException this is a runtime exception
* #throws SnowflakeSQLException exception raised from Snowflake components
*/
public synchronized void open() throws SFException, SnowflakeSQLException {
performSanityCheckOnProperties();
Map<SFSessionProperty, Object> connectionPropertiesMap = getConnectionPropertiesMap();
logger.debug(
"input: server={}, account={}, user={}, password={}, role={}, database={}, schema={},"
+ " warehouse={}, validate_default_parameters={}, authenticator={}, ocsp_mode={},"
+ " passcode_in_password={}, passcode={}, private_key={}, disable_socks_proxy={},"
+ " application={}, app_id={}, app_version={}, login_timeout={}, network_timeout={},"
+ " query_timeout={}, tracing={}, private_key_file={}, private_key_file_pwd={}."
+ " session_parameters: client_store_temporary_credential={}",
connectionPropertiesMap.get(SFSessionProperty.SERVER_URL),
connectionPropertiesMap.get(SFSessionProperty.ACCOUNT),
connectionPropertiesMap.get(SFSessionProperty.USER),
!Strings.isNullOrEmpty((String) connectionPropertiesMap.get(SFSessionProperty.PASSWORD))
? "***"
: "(empty)",
connectionPropertiesMap.get(SFSessionProperty.ROLE),
connectionPropertiesMap.get(SFSessionProperty.DATABASE),
connectionPropertiesMap.get(SFSessionProperty.SCHEMA),
connectionPropertiesMap.get(SFSessionProperty.WAREHOUSE),
connectionPropertiesMap.get(SFSessionProperty.VALIDATE_DEFAULT_PARAMETERS),
connectionPropertiesMap.get(SFSessionProperty.AUTHENTICATOR),
getOCSPMode().name(),
connectionPropertiesMap.get(SFSessionProperty.PASSCODE_IN_PASSWORD),
!Strings.isNullOrEmpty((String) connectionPropertiesMap.get(SFSessionProperty.PASSCODE))
? "***"
: "(empty)",
connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY) != null
? "(not null)"
: "(null)",
connectionPropertiesMap.get(SFSessionProperty.DISABLE_SOCKS_PROXY),
connectionPropertiesMap.get(SFSessionProperty.APPLICATION),
connectionPropertiesMap.get(SFSessionProperty.APP_ID),
connectionPropertiesMap.get(SFSessionProperty.APP_VERSION),
connectionPropertiesMap.get(SFSessionProperty.LOGIN_TIMEOUT),
connectionPropertiesMap.get(SFSessionProperty.NETWORK_TIMEOUT),
connectionPropertiesMap.get(SFSessionProperty.QUERY_TIMEOUT),
connectionPropertiesMap.get(SFSessionProperty.TRACING),
connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY_FILE),
!Strings.isNullOrEmpty(
(String) connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY_FILE_PWD))
? "***"
: "(empty)",
sessionParametersMap.get(CLIENT_STORE_TEMPORARY_CREDENTIAL));
HttpClientSettingsKey httpClientSettingsKey = getHttpClientKey();
logger.debug(
"connection proxy parameters: use_proxy={}, proxy_host={}, proxy_port={}, proxy_user={},"
+ " proxy_password={}, non_proxy_hosts={}, proxy_protocol={}",
httpClientSettingsKey.usesProxy(),
httpClientSettingsKey.getProxyHost(),
httpClientSettingsKey.getProxyPort(),
httpClientSettingsKey.getProxyUser(),
!Strings.isNullOrEmpty(httpClientSettingsKey.getProxyPassword()) ? "***" : "(empty)",
httpClientSettingsKey.getNonProxyHosts(),
httpClientSettingsKey.getProxyProtocol());
// TODO: temporarily hardcode sessionParameter debug info. will be changed in the future
SFLoginInput loginInput = new SFLoginInput();
loginInput
.setServerUrl((String) connectionPropertiesMap.get(SFSessionProperty.SERVER_URL))
.setDatabaseName((String) connectionPropertiesMap.get(SFSessionProperty.DATABASE))
.setSchemaName((String) connectionPropertiesMap.get(SFSessionProperty.SCHEMA))
.setWarehouse((String) connectionPropertiesMap.get(SFSessionProperty.WAREHOUSE))
.setRole((String) connectionPropertiesMap.get(SFSessionProperty.ROLE))
.setValidateDefaultParameters(
connectionPropertiesMap.get(SFSessionProperty.VALIDATE_DEFAULT_PARAMETERS))
.setAuthenticator((String) connectionPropertiesMap.get(SFSessionProperty.AUTHENTICATOR))
.setOKTAUserName((String) connectionPropertiesMap.get(SFSessionProperty.OKTA_USERNAME))
.setAccountName((String) connectionPropertiesMap.get(SFSessionProperty.ACCOUNT))
.setLoginTimeout(loginTimeout)
.setAuthTimeout(authTimeout)
.setUserName((String) connectionPropertiesMap.get(SFSessionProperty.USER))
.setPassword((String) connectionPropertiesMap.get(SFSessionProperty.PASSWORD))
.setToken((String) connectionPropertiesMap.get(SFSessionProperty.TOKEN))
.setPasscodeInPassword(passcodeInPassword)
.setPasscode((String) connectionPropertiesMap.get(SFSessionProperty.PASSCODE))
.setConnectionTimeout(httpClientConnectionTimeout)
.setSocketTimeout(httpClientSocketTimeout)
.setAppId((String) connectionPropertiesMap.get(SFSessionProperty.APP_ID))
.setAppVersion((String) connectionPropertiesMap.get(SFSessionProperty.APP_VERSION))
.setSessionParameters(sessionParametersMap)
.setPrivateKey((PrivateKey) connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY))
.setPrivateKeyFile((String) connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY_FILE))
.setPrivateKeyFilePwd(
(String) connectionPropertiesMap.get(SFSessionProperty.PRIVATE_KEY_FILE_PWD))
.setApplication((String) connectionPropertiesMap.get(SFSessionProperty.APPLICATION))
.setServiceName(getServiceName())
.setOCSPMode(getOCSPMode())
.setHttpClientSettingsKey(httpClientSettingsKey);
// propagate OCSP mode to SFTrustManager. Note OCSP setting is global on JVM.
HttpUtil.initHttpClient(httpClientSettingsKey, null);
SFLoginOutput loginOutput =
SessionUtil.openSession(loginInput, connectionPropertiesMap, tracingLevel.toString());
isClosed = false;
authTimeout = loginInput.getAuthTimeout();
sessionToken = loginOutput.getSessionToken();
masterToken = loginOutput.getMasterToken();
idToken = loginOutput.getIdToken();
mfaToken = loginOutput.getMfaToken();
setDatabaseVersion(loginOutput.getDatabaseVersion());
setDatabaseMajorVersion(loginOutput.getDatabaseMajorVersion());
setDatabaseMinorVersion(loginOutput.getDatabaseMinorVersion());
httpClientSocketTimeout = loginOutput.getHttpClientSocketTimeout();
masterTokenValidityInSeconds = loginOutput.getMasterTokenValidityInSeconds();
setDatabase(loginOutput.getSessionDatabase());
setSchema(loginOutput.getSessionSchema());
setRole(loginOutput.getSessionRole());
setWarehouse(loginOutput.getSessionWarehouse());
setSessionId(loginOutput.getSessionId());
setAutoCommit(loginOutput.getAutoCommit());
// Update common parameter values for this session
SessionUtil.updateSfDriverParamValues(loginOutput.getCommonParams(), this);
String loginDatabaseName = (String) connectionPropertiesMap.get(SFSessionProperty.DATABASE);
String loginSchemaName = (String) connectionPropertiesMap.get(SFSessionProperty.SCHEMA);
String loginRole = (String) connectionPropertiesMap.get(SFSessionProperty.ROLE);
String loginWarehouse = (String) connectionPropertiesMap.get(SFSessionProperty.WAREHOUSE);
if (loginDatabaseName != null && !loginDatabaseName.equalsIgnoreCase(getDatabase())) {
sqlWarnings.add(
new SFException(
ErrorCode.CONNECTION_ESTABLISHED_WITH_DIFFERENT_PROP,
"Database",
loginDatabaseName,
getDatabase()));
}
if (loginSchemaName != null && !loginSchemaName.equalsIgnoreCase(getSchema())) {
sqlWarnings.add(
new SFException(
ErrorCode.CONNECTION_ESTABLISHED_WITH_DIFFERENT_PROP,
"Schema",
loginSchemaName,
getSchema()));
}
if (loginRole != null && !loginRole.equalsIgnoreCase(getRole())) {
sqlWarnings.add(
new SFException(
ErrorCode.CONNECTION_ESTABLISHED_WITH_DIFFERENT_PROP, "Role", loginRole, getRole()));
}
if (loginWarehouse != null && !loginWarehouse.equalsIgnoreCase(getWarehouse())) {
sqlWarnings.add(
new SFException(
ErrorCode.CONNECTION_ESTABLISHED_WITH_DIFFERENT_PROP,
"Warehouse",
loginWarehouse,
getWarehouse()));
}
// start heartbeat for this session so that the master token will not expire
startHeartbeatForThisSession();
}
I am generating the envelope and document via the DocuSign Salesforce API, and the recipient's first and last name apparently can only be set when it's concatenated. Is there a way to add a space between the first and last name? You'll see in the code below where I try adding a space, and when I do, I get the following exception:
System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: The recipient you have identified is not a valid recipient of the specified envelope. faultcode=soap:Client faultactor=https://demo.docusign.net/api/3.0/dsapi.asmx`
Code:
// Recipient
DocuSignAPI.Recipient recipient = new DocuSignAPI.Recipient();
recipient.ID = 1;
recipient.Type_x = Constants.const_Signer;
recipient.RoutingOrder = 1;
recipient.Email = cnt.EmailAddress1__c;
recipient.RoleName = Constants.const_RoleCustomer;
recipient.UserName = cnt.FirstName__c + cnt.LastName__c; //tried adding a space here...
recipient.RequireIDLookup = false;
recipient.captiveInfo = new DocuSignAPI.RecipientCaptiveInfo();
recipient.captiveInfo.ClientUserId = clientUserID;
DocuSignAPI.ArrayOfRecipient1 Recipients = new DocuSignAPI.ArrayOfRecipient1();
Recipients.Recipient = new DocuSignAPI.Recipient[1];
Recipients.Recipient[0] = recipient;
envelope.Recipients = new DocuSignAPI.ArrayOfRecipient();
envelope.Recipients.Recipient = new DocuSignAPI.Recipient[1];
envelope.Recipients.Recipient[0] = recipient;
envelope.AccountId = objConstantSetting.Docusign_Account_ID__c;
envelope.Autonavigation = true;
// Envelope needs Documents, Recipients, Tabs and a Subject.
envelope.Tabs = new DocuSignAPI.ArrayOfTab();
envelope.Tabs.Tab = new List<DocuSignAPI.Tab>();
DocuSignAPI.Tab t = new DocuSignAPI.Tab();
t.Name = 'Name';
t.Type_x = 'FullName';
DocuSignAPI.AnchorTab at = new DocuSignAPI.AnchorTab();
at.AnchorTabString = dsTag.AnchorTabString__c;
t.RecipientID = recipient.ID;
t.CustomTabRequired = true;
at.IgnoreIfNotPresent = true;
t.AnchorTabItem = at;
envelope.Tabs.Tab.add(t);
envelope.Subject = Label.Docusign_Email_Subject; // + account.AccountNumber;
Above error normally comes when you are trying to generate the RequestRecipientToken for embedded signers, and the recipient's details which you are passing in RequestRecipientToken API call is not the same which are present in the envelope.
Below is the SOAP API call, to create Envelope with FullName tab and recipient name has space in it and its coming fine on the document. Try testing the flow using SOAPUI.
Create Envelope call:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.docusign.net/API/3.0">
<soapenv:Header/>
<soapenv:Body>
<ns:CreateAndSendEnvelope>
<ns:Envelope>
<ns:AccountId>e6043e37-08a9-4892-9e12-75b4d8bfef2a</ns:AccountId>
<ns:Documents>
<ns:Document>
<ns:ID>32093411</ns:ID>
<ns:Name>Document Name</ns:Name>
<ns:PDFBytes>PDFBytes</ns:PDFBytes>
<ns:FileExtension>pdf</ns:FileExtension>
</ns:Document>
</ns:Documents>
<ns:Recipients>
<ns:Recipient>
<ns:ID>45399085</ns:ID>
<ns:UserName>FirstName LastName</ns:UserName>
<ns:Email>email#gmail.com</ns:Email>
<ns:Type>Signer</ns:Type>
<ns:RoutingOrder>1</ns:RoutingOrder>
<ns:CaptiveInfo>
<ns:ClientUserId>1234</ns:ClientUserId>
</ns:CaptiveInfo>
</ns:Recipient>
</ns:Recipients>
<ns:Tabs>
<ns:Tab>
<ns:DocumentID>32093411</ns:DocumentID>
<ns:RecipientID>45399085</ns:RecipientID>
<ns:PageNumber>1</ns:PageNumber>
<ns:XPosition>71</ns:XPosition>
<ns:YPosition>500</ns:YPosition>
<ns:ScaleValue>1</ns:ScaleValue>
<ns:Type>FullName</ns:Type>
<ns:Name>FullName</ns:Name>
<ns:TabLabel>Name d39c7430-7321-4c97-a1b9-5d980fda7883</ns:TabLabel>
<ns:CustomTabRequired>false</ns:CustomTabRequired>
<ns:CustomTabLocked>false</ns:CustomTabLocked>
<ns:TemplateLocked>false</ns:TemplateLocked>
<ns:TemplateRequired>false</ns:TemplateRequired>
<ns:Font>LucidaConsole</ns:Font>
<ns:FontColor>Black</ns:FontColor>
<ns:FontSize>Size9</ns:FontSize>
</ns:Tab>
</ns:Tabs>
<ns:Subject>Email Subject</ns:Subject>
<ns:EmailBlurb>Email Blurb</ns:EmailBlurb>
</ns:Envelope>
</ns:CreateAndSendEnvelope>
</soapenv:Body>
</soapenv:Envelope>
RequestRecipientToken:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.docusign.net/API/3.0">
<soapenv:Header/>
<soapenv:Body>
<ns:RequestRecipientToken>
<ns:EnvelopeID>ece0d433-52a7-4e0c-a502-c57ff205df3c</ns:EnvelopeID>
<ns:ClientUserID>1234</ns:ClientUserID>
<ns:Username>FirstName LastName</ns:Username>
<ns:Email>email#gmail.com</ns:Email>
<ns:AuthenticationAssertion>
<ns:AuthenticationInstant>2017-08-09T01:25:33Z</ns:AuthenticationInstant>
<ns:AssertionID>1234</ns:AssertionID>
<ns:AuthenticationMethod>Password</ns:AuthenticationMethod>
<ns:SecurityDomain>www.google.com</ns:SecurityDomain>
</ns:AuthenticationAssertion>
<ns:ClientURLs>
<ns:OnSigningComplete><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnSigningComplete>
<ns:OnViewingComplete><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnViewingComplete>
<ns:OnCancel><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnCancel>
<ns:OnDecline><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnDecline>
<ns:OnSessionTimeout><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnSessionTimeout>
<ns:OnTTLExpired><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnTTLExpired>
<ns:OnException><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnException>
<ns:OnAccessCodeFailed><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnAccessCodeFailed>
<ns:OnIdCheckFailed><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnIdCheckFailed>
<ns:OnFaxPending><![CDATA[http://www.google.com?envId=[[envelopeId]]&recipientEmail=[[recipientEmail]]]]></ns:OnFaxPending>
</ns:ClientURLs>
</ns:RequestRecipientToken>
</soapenv:Body>
</soapenv:Envelope>
Need help in copying a file from received email on BlackBerry z10. Allredy tryed to find a solution without sucesss.
Task is to load a file from received email by clicking on it. Allredy implement, that my App opens on clicking a file with ending .kdp.
bar-descriptor.xml:
<invoke-target id="com.example.MyApp">
<invoke-target-type>application</invoke-target-type>
<invoke-target-name>Name of my App</invoke-target-name>
<icon>
<image>icon.png</image>
</icon>
<filter>
<action>bb.action.OPEN</action>
<mime-type>*</mime-type>
<property var="exts" value="kdp"/>
<property var="uris" value="file://,data://"/>
</filter>
</invoke-target>
next step i connect InvokeManager with a slot:
m_invokeManager = new InvokeManager(this);
bool connectResult;
connectResult = m_invokeManager->connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), this, SLOT(onInvoke(const bb::system::InvokeRequest&)));
What i'm looking for is a good solution for copying the file, which was clicked:
void ApplicationUI::onInvoke(const bb::system::InvokeRequest& request) {
qDebug() << "called on clicked file.kdp";
InvokeRequest myRequest = (request);
myRequest.setFileTransferMode(bb::system::FileTransferMode::CopyReadOnly);
QFile appFile(QDir::currentPath() + "/data/data.kdp");
appFile.open(QIODevice::WriteOnly);
appFile.close();
QString from = myRequest.uri().toString();
QString to = QDir::currentPath() + "/data/data.kdp";
bool test = QFile::copy(from, to);// don't work
qDebug() << test; // <--is false, don't work
qDebug() << "URL r: " + request.uri().toString();//<-- can see the path to file, but allways different
qDebug() << "URL m: " + myRequest.uri().toString();}
data.kdp is a like a zip format, need just to copy the file from email to my App...
please help:D
QString m_uri = request.uri().toString(); QFile textfile(m_uri.replace("file://","").toUtf8().constData());
Just replace "file://" in path!
I am implementing a server for communication using the OMA DM 1.2 SyncML protocol and reffers to the OMA Device Management Security document. I am having issues with authentication. The client sends a challenge to the server as:
<Chal>
<Meta>
<Format xmlns="syncml:metinf">b64</Format>
<Type xmlns="syncml:metinf">syncml:auth-md5</Type>
<NextNonce xmlns="syncml:metinf">RLLe7tWM313qHMq9ooUZUPJX0RqU9mEZuyoVF+jXhqQ=</NextNonce>
</Meta>
</Chal>
I then calculate the md5-digest to return to the device using the java code, where nonce is the Base64 string in "NextNonce" in challenge above:
MessageDigest digest = MessageDigest.getInstance("MD5");
String usrPwd = username + ":" + password;
String usrPwdHash = Base64.encodeBase64String(digest.digest(usrPwd.getBytes("utf-8")));
String usrPwdNonce = usrPwdHash + ":" + nonce;
String usrPwdNonceHash = Base64.encodeBase64String(digest.digest(usrPwdNonce.getBytes("utf-8")));
return usrPwdNonceHash;
Then this hash is returned to the device as:
<Cred>
<Meta>
<ns2:Type>syncml:auth-md5</ns2:Type>
<ns2:Format>b64</ns2:Format>
</Meta>
<Data>QpbMtvvfNGRIavJ0jqcxaw==</Data>
</Cred>
But the device returns with a status 401 and a new challenge. Is there something wrong with how i calculate the md5-hash or must there be some other issue?
Found my error. The nonce should be the decoded Base64 string value, not the Base64 string.
nonce = new String(Base64.decodeBase64("RLLe7tWM313qHMq9ooUZUPJX0RqU9mEZuyoVF+jXhqQ="), "utf-8");
Iam building a cloud application with google apps.While establishing a connection with cloud database instance iam getting an error . I have also downloaded and configured appengine-api-1.0-sdk-1.6.5 in Tomcat7.0 server library , i have also installed the rdbms package , but still the error is same .The code is as given below
<%# page import="com.google.appengine.api.rdbms.*, java.io.*,java.sql.*"%>
<%
Connection c = null;
DriverManager.registerDriver(new AppEngineDriver());
c = DriverManager.getConnection("jdbc:google:rdbms://ctsteaching:ctsdatabase/ctsdb");
String fname = request.getParameter("fname");
String content = request.getParameter("content");
if (fname == "" || content == "") {
out.println("<html><head></head><body>You are missing either a message or a name! Try again! Redirecting in 3 seconds...</body></html>");
} else {
String statement ="INSERT INTO entries (guestName, content) VALUES(?,?)";
PreparedStatement stmt = c.prepareStatement(statement);
stmt.setString(1,fname);
stmt.setString(2,content);
int success = 2;
success = stmt.executeUpdate();
if(success == 1) {
out.println("<html><head></head><body>Success! Redirecting in 3 seconds...</body> </html>");
} else if (success == 0)
{
out.println("<html><head></head><body>Failure! Please try again! Redirecting in 3 seconds...</body></html>");
}
}
%>
The error is as given below
com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'rdbms' or call 'OpenConnection()' was not found.
com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98)
com.google.appengine.api.rdbms.RdbmsApiProxyClient$ApiProxyBlockingInterface.makeSyncCall(RdbmsApiProxyClient.java:95)
com.google.appengine.api.rdbms.RdbmsApiProxyClient$ApiProxyBlockingInterface.openConnection(RdbmsApiProxyClient.java:73)
com.google.cloud.sql.jdbc.internal.SqlProtoClient.openConnection(SqlProtoClient.java:58)
com.google.cloud.sql.jdbc.Driver.connect(Driver.java:66)
com.google.cloud.sql.jdbc.Driver.connect(Driver.java:26)
java.sql.DriverManager.getConnection(Unknown Source)
java.sql.DriverManager.getConnection(Unknown Source)
org.apache.jsp.abcd.test_jsp._jspService(test_jsp.java:70)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
It looks like you are using the wrong jar file. You need to set some extra jvm_flags when developing locally.
https://developers.google.com/cloud-sql/docs/developers_guide_java#with_eclipse