What's wrong with Google endpoints -- Cloud SQL connection? - mysql

I'm trying to connect from a Google Endpoints server to a Google Cloud SQL server. I'm modifying the Greetings.getGreeting() method in this tutorial:
https://cloud.google.com/appengine/docs/java/endpoints/getstarted/backend/helloendpoints
to call the Cloud mysql database as demonstrated in this tutorial (see doGet method):
https://cloud.google.com/appengine/docs/java/cloud-sql/#enable_connector_j
I have made sure that I can connect to the database from my machine mysql client. The database instance "simple" has a single table "simpletable" who's rows hold an entityID and a string. (But I'm not able to connect, so that's not too important yet.)
This is my endpoints code:
package com.example.helloendpoints;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.users.User;
import java.sql.*;
import java.util.ArrayList;
import javax.inject.Named;
/**
* Defines v1 of a helloworld API, which provides simple "greeting" methods.
*/
#Api(
name = "helloworld",
version = "v1",
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID,
Constants.ANDROID_CLIENT_ID,
Constants.IOS_CLIENT_ID,
Constants.API_EXPLORER_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE}
)
public class Greetings {
public static ArrayList<HelloGreeting> greetings = new ArrayList<HelloGreeting>();
static {
greetings.add(new HelloGreeting("hello world!"));
greetings.add(new HelloGreeting("goodbye world!"));
}
public HelloGreeting getGreeting(#Named("id") Integer id) throws NotFoundException {
// pair to use when running local endpoint server
String urlFromDev = "jdbc:mysql://173.194.XXX.90:3306/simple?user=root";
String classForNameFromDev = "com.mysql.jdbc.Driver";
// pair to use when running cloud endpoint server
String classForNameFromCloud = "com.mysql.jdbc.GoogleDriver";
String urlFromCloud = "jdbc:google:mysql://"
+ Constants.PROJECT_ID + ":"
+ Constants.CLOUD_SQL_INSTANCE_NAME +"/"
+ Constants.DATABASE_NAME + "?user=root";
HelloGreeting helloGreeting = new HelloGreeting();
try {
Class.forName(classForNameFromDev);
// Class.forName(classForNameFromCloud);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Connection connection = DriverManager.getConnection(urlFromDev);
// Connection connection = DriverManager.getConnection(urlFromCloud);
try {
String statement = "Select simplestring from simpletable where entryID = ?";
PreparedStatement preparedStatement = connection.prepareStatement(statement);
preparedStatement.setInt(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.wasNull()) {
helloGreeting.setMessage(resultSet.getString("simplestring"));
} else {
throw new NotFoundException("Greeting not found with an index: " + id);
}
} finally {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return helloGreeting;
}
#ApiMethod(name = "greetings.multiply", httpMethod = "post")
public HelloGreeting insertGreeting(#Named("times") Integer times, HelloGreeting greeting) {
HelloGreeting response = new HelloGreeting();
StringBuilder responseBuilder = new StringBuilder();
for (int i = 0; i < times; i++) {
responseBuilder.append(greeting.getMessage());
}
response.setMessage(responseBuilder.toString());
return response;
}
#ApiMethod(name = "greetings.authed", path = "hellogreeting/authed")
public HelloGreeting authedGreeting(User user) {
HelloGreeting response = new HelloGreeting("hello " + user.getEmail());
return response;
}
}
I have tried to enable mysql connector/j in my appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<use-google-connector-j>true</use-google-connector-j>
<application>backendapitutorial-1XXX</application>
<version>${app.version}</version>
<threadsafe>true</threadsafe>
<system-properties>
<property name="java.util.logging.config.file" value="WEB- INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Whichever way I build+depl0y it (Dev or cloud), I always get
java.sql.SQLException: No suitable driver found for jdbc:mysql://173.194.XXX.90:3306/simple?user=root
or
java.sql.SQLException: No suitable driver found for jdbc:google:mysql://backendapitutorial-XXXX:simple/simple?user=root
(I replaced the real IP and project name with "X"s for this post).
I've already looked at these:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/dbname
ClassNotFoundException: com.mysql.jdbc.GoogleDriver
What does 'Class.forName("org.sqlite.JDBC");' do?
I'm building with Maven and working on IntelliJ IDE.
Any help is greatly appreciated. Thanks.

Related

Google Cloud SQL Exception

I am trying to do a SQL database in Google Cloud SQL and with a Java project make many queries to the database, but I have this answer:
Buckets:
Exception in thread "main" com.google.cloud.storage.StorageException: java.lang.NullPointerException: Required parameter project must be specified.
at com.google.cloud.storage.StorageException.translateAndThrow(StorageException.java:73)
at com.google.cloud.storage.StorageImpl.listBuckets(StorageImpl.java:288)
at com.google.cloud.storage.StorageImpl.list(StorageImpl.java:257)
at package1.Auth.authExplicit(Auth.java:46)
at package1.Main.main(Main.java:21)
Caused by: java.lang.NullPointerException: Required parameter project must be specified
public static void main(String[] args) throws IOException {
String instanceConnectionName="";
String databaseName="prueba";
String username="root";
String password="root";
String sql="SELECT * FROM alumnos";
String jsonPath="/Users/franciscomanuelpozodelmoral/Downloads/Team5-c4e75c7cb498.json";
Auth.authExplicit(jsonPath);
try {
Class.forName("com.mysql.jdbc.Driver");
String jdbcURL=String.format("jdbc:mysql://google/%s?cloudSqlInstance=%s&" +
"socketFactory=com.google.cloud.sql.mysql.SocketFactory",databaseName,instanceConnectionName);
Connection connection=DriverManager.getConnection(jdbcURL, username, password);
Statement statement=connection.createStatement();
ResultSet rs=statement.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getString("DNI") + rs.getString("Nombre") + rs.getString("Apellidos") + rs.getInt("Telefono")+rs.getInt("Curso"));
}
} catch(Exception e) {
e.printStackTrace();
}
}
public class Auth {
static void authImplicit() {
// If you don't specify credentials when constructing the client, the client library will
// look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
//Storage storage = StorageOptions.getDefaultInstance().getService();
Storage storage=StorageOptions.getDefaultInstance().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
static void authExplicit(String jsonPath) throws IOException {
// You can specify a credential file by providing a path to GoogleCredentials.
// Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
// for (Bucket bucket : buckets.iterateAll()) {
// System.out.println(bucket.toString());
// }
}
}
Can you help me? Thanks (The instanceConnectionName is group5...)

Starting and stopping instances on google compute engine

I want to start/resume and stop/suspend instances on google compute engine, but it gives "java.lang.UnsupportedOperationException".Is there any alternative way
to perform these operations?
public class Example {
public static void main(String[] args)
{
String provider = "google-compute-engine";
String identity = "****#developer.gserviceaccount.com";
String credential = "path to private key";
String groupName = "newgroup";
credential = getCredentialFromJsonKeyFile(credential);
Iterable<Module> modules = ImmutableSet.<Module> of(
new SshjSshClientModule(),
new SLF4JLoggingModule(),
new EnterpriseConfigurationModule());
ContextBuilder builder = ContextBuilder.newBuilder(provider)
.credentials(identity, credential)
.modules(modules);
ComputeService compute=builder.buildView(ComputeServiceContext.class).getComputeService();
compute.suspendNode("Instance id");
//compute.suspendNodesMatching(Predicates.<NodeMetadata> and(inGroup(groupName)));
System.out.println("suspended");
compute.getContext().close();
}
private static String getCredentialFromJsonKeyFile(String filename) {
try {
String fileContents = Files.toString(new File(filename), UTF_8);
Supplier<Credentials> credentialSupplier = new GoogleCredentialsFromJson(fileContents);
String credential = credentialSupplier.get().credential;
return credential;
} catch (IOException e) {
System.err.println("Exception reading private key from '%s': " + filename);
e.printStackTrace();
System.exit(1);
return null;
}
}
}
Output:
suspending node(node id)
Exception in thread "main" java.lang.UnsupportedOperationException: suspend is not supported by GCE
at org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter.suspendNode(GoogleComputeEngineServiceAdapter.java:251)
at org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies.suspendNode(AdaptingComputeServiceStrategies.java:171)
at org.jclouds.compute.internal.BaseComputeService.suspendNode(BaseComputeService.java:503)
at org.jclouds.examples.compute.basics.Example.main(Example.java:79)
It is not directly supported in the portable jclouds ComputeService, but from the ComputeServiceContext you can get the GoogleComputeEngineApi and the InstanceApi, and use the start/stop methods in there.
FYI, there is an ongoing patch to add support for the start/stop operations in the ComputeService: https://github.com/jclouds/jclouds-labs-google/pull/141
You can stop an instance from the API.
POST https://www.googleapis.com/compute/v1/projects/<project>/zones/<zone>/instances/<instance>/stop
Where :
project in URL is you project id.
zone in URL is the name of zone for the request.
instance in URL is the name of instances to stop.
Here's the docs

Using JAVA API update Rally Team membership

My Java API compares Team members from another application with Rally. The compared results is updated in Rally. It takes the reference of Project name and Res name.
The code throws "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" error. I coudn't spot the error. Could some one help? Following is the code and the output
package teammembership;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.QueryRequest;
import com.rallydev.rest.response.QueryResponse;
import com.rallydev.rest.request.UpdateRequest;
import com.rallydev.rest.response.UpdateResponse;
import com.rallydev.rest.util.Fetch;
import com.rallydev.rest.util.QueryFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.*;
import java.sql.*;
import javax.xml.parsers.DocumentBuilder;
import org.apache.soap.util.xml.*;
import org.w3c.dom.*;
//import org.json.*;
//import static projectteammembers.JsonUtil.getJsonValue;
public class TeamMembership {
public static Connection makeConnection(String propertiesFile) throws SQLException, Exception {
Connection conn = null;
DocumentBuilder docBuilder = XMLParserUtils.getXMLDocBuilder();
Document doc = docBuilder.parse(new File(propertiesFile));
// Retrieve database parameters
Element database = (Element) doc.getElementsByTagName("database").item(0);
String url = database.getAttribute("url");
String serviceId = database.getAttribute("serviceId");
String username = database.getAttribute("username");
String password = database.getAttribute("password");
String host = url.substring(url.indexOf("//"), url.indexOf(";"));
String connectString = "jdbc:oracle:thin:#" + host + "/" + serviceId;
// Load JDBC Driver
String driverClass = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverClass);
try {
conn = DriverManager.getConnection(connectString, username, password);
} catch (SQLException ex) {
throw new SQLException(ex);
} catch (Exception ex) {
throw new Exception(ex);
}
return conn;
}
public static void main(String[] args) throws URISyntaxException, IOException, SQLException {
String host = "https://rally1.rallydev.com";
String username = "username#abc.com";
String password = "password";
//String userRef = "";
String applicationName = "update team membership";
//int queryLimit = 4000;
Connection conn = null;
String propertiesFile = "";
propertiesFile = "c:/app/c/properties_prod.xml";
String projid = "";
String resid = "";
//String returnValue = "";
String selectString = "";
RallyRestApi restApi = new RallyRestApi(
new URI(host),
username,
password);
restApi.setApplicationName(applicationName);
System.out.println(restApi.getWsapiVersion());
try {
conn = makeConnection(propertiesFile);
// Select compared records of Team member present in table1 not in table2
selectString += "select Prj_name ";
selectString += ",res_name";
selectString += " from CUST_table1_v c ";
selectString += " WHERE NOT EXISTS( select 1 from CUST_table2_v r";
selectString += " where c.prj_name = r.Prj_name and c.res_name = r.res_name)";
// Create select statement
Statement st = (Statement) conn.createStatement();
// Execute select statement
ResultSet rs = st.executeQuery(selectString);
while (rs.next()) {
projid = rs.getString("Prj_name");
resid = "(" + rs.getString("res_name") + ")";
System.out.println(projid);
System.out.println(resid);
QueryRequest projectRequest = new QueryRequest("Project");
projectRequest.setFetch(new Fetch("Name"));
projectRequest.setQueryFilter(new QueryFilter("Name", "=", projid));
QueryResponse projectQueryResponse = restApi.query(projectRequest);
JsonObject projectObj = projectQueryResponse.getResults().get(0).getAsJsonObject();
QueryRequest userRequest = new QueryRequest("User");
userRequest.setFetch(new Fetch("UserPermissions", "TeamMemberships"));
userRequest.setQueryFilter(new QueryFilter("DisplayName", "contains", resid));
QueryResponse userQueryResponse = restApi.query(userRequest);
System.out.println(userQueryResponse);
JsonObject userObject = userQueryResponse.getResults().get(0).getAsJsonObject();
//JsonObject projectObj = new JsonObject(projid);
String userRef = userObject.get("_ref").toString();
System.out.println("Found User with Ref: " + userRef);
JsonArray existTeamMemberships = (JsonArray) userQueryResponse.getResults().get(0).getAsJsonObject().get("TeamMemberships");
// add or remove projects for user
existTeamMemberships.add(projectObj);
// Setup update fields/values for Team Membership
JsonObject updateUserTeamMembershipObj = new JsonObject();
updateUserTeamMembershipObj.add("TeamMemberships", existTeamMemberships);
UpdateRequest updateTeamMembershipsRequest = new UpdateRequest(userRef, updateUserTeamMembershipObj);
UpdateResponse updateTeamMembershipResponse = restApi.update(updateTeamMembershipsRequest);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
restApi.close();
conn.close();
}
}
}
Following is the error out put
v2.0
DT-E2E Automation
(tmanjunath)
com.rallydev.rest.response.QueryResponse#193d23b
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at com.google.gson.JsonArray.get(JsonArray.java:92)
at teammembership.TeamMembership.main(TeamMembership.java:125)
BUILD SUCCESSFUL (total time: 11 seconds)
You have a List (an ArrayList to be exact) which contains nothing (no single object) and you try to access the first object (which doesn't exist). That's what the error tells you. You try to access index 0 (the first position in the list) but there is no element in it (so the size is 0). It happens around line 125. Since your formatting in the question doesn't seem to be correct, I can only guess which line in your question is line 125 (and I don't want to read 125 lines of code by the way). So I think the exception occurs here:
JsonObject userObject = userQueryResponse.getResults().get(0).getAsJsonObject();
Try to track it down. Make sure the list returned from userQueryResponse.getResults() contains something:
list = userQueryResponse.getResults();
System.out.println(list.size());
If not, that's your problem. If you cannot solve it, ask a specific question about this problem without posting 150 line of code.
get("_ref").toString() used to work with the older versions, and the code you refer to is older. When using 2.0.4 jar (which by default uses the most recent version of WS API in production, v2.0) replace all instances of it with get("_ref").getAsString().
For example,
String userRef = userObject.get("_ref").toString();
will generate java.lang.NullPointerException: key == null

set mysql connection behind ssh in groovy script SoapUI

From groovy script in SoapUI I need to connect to a mysql database to perform some queries. The problem is that due to security reasons no external access is possible.
Therefore it is required to get an ssh access (like a tunnel) and invoke mysql locally.
Initially I was reading the below project properties and then connect to mysql:
ServerUrl=jdbc:mysql://10.255.255.122:3306/db
ServerDbUser=user
ServerDbPwd=password
ServerDriver=com.mysql.jdbc.Driver
def url=testRunner.testCase.testSuite.project.getPropertyValue("ServerUrl")
def usr=testRunner.testCase.testSuite.project.getPropertyValue("ServerDbUser")
def pwd=testRunner.testCase.testSuite.project.getPropertyValue("ServerDbPwd")
def driver=testRunner.testCase.testSuite.project.getPropertyValue("ServerDriver")
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver(driver)
sqlServer = Sql.newInstance(url, usr, pwd, driver)`
But this didn't work so now it is required to establish first a ssh connection to the server with the IP 10.255.255.122 and then open the mysql connection locally. So I guess the Server Url will change to:
ServerUrl=jdbc:mysql://127.0.0.1:3306/db
But I don't know how to set first the ssh connection to the server.
Can someone help me with this?
Thanks.
Have a look at http://forum.soapui.org/viewtopic.php?t=15400 and connect to remote mysql database through ssh using java
It will give you an idea about implementing it in soapUI.
Below is the code by Ripon Al Wasim which is available as an answer at the stackoverflow link mentioned above
package mypackage;
import java.sql.*;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class UpdateMySqlDatabase {
static int lport;
static String rhost;
static int rport;
public static void go(){
String user = "ripon";
String password = "wasim";
String host = "myhost.ripon.wasim";
int port=22;
try
{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
lport = 4321;
rhost = "localhost";
rport = 3306;
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
}
catch(Exception e){System.err.print(e);}
}
public static void main(String[] args) {
try{
go();
} catch(Exception ex){
ex.printStackTrace();
}
System.out.println("An example for updating a Row from Mysql Database!");
Connection con = null;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + rhost +":" + lport + "/";
String db = "testDB";
String dbUser = "wasim";
String dbPasswd = "riponalwasim123";
try{
Class.forName(driver);
con = DriverManager.getConnection(url+db, dbUser, dbPasswd);
try{
Statement st = con.createStatement();
String sql = "UPDATE MyTableName " +
"SET email = 'ripon.wasim#smile.com' WHERE email='peace#happy.com'";
int update = st.executeUpdate(sql);
if(update >= 1){
System.out.println("Row is updated.");
}
else{
System.out.println("Row is not updated.");
}
}
catch (SQLException s){
System.out.println("SQL statement is not executed!");
}
}
catch (Exception e){
e.printStackTrace();
}
}
}

SQL exception thrown when the method is called otherwise working fine

I am making a web application project using JSP in Netbeans IDE.
I have a java Class called Login which has a static method called authenticate.When I am running this file it gives me the required output. Now I have a web page called auth.jsp which calls the method authenticate but when I try to run this web page the value returned by the method is "error" that is sql exception is being thrown by the method. Could someone please tell why this is happening? Thanks in advance.
package server;
import java.sql.*;
public class Login {
public static void main(String args[]) {
System.out.print(authenticate("260","abc"));
}
public static String authenticate(String username, String password) {
String auth="",pass="";
int blocked_status=0;
String url = "jdbc:mysql://localhost:3306/radio";
try{
Connection conn = DriverManager.getConnection(url,"root","rishabh");
Statement stmt = conn.createStatement();
String sql = "select password,blocked from user where username = \"" + username + "\"";
ResultSet rs = stmt.executeQuery(sql);
int flag=0;
while(rs.next()){
pass = rs.getString("password");
blocked_status = rs.getInt("blocked");
flag++;
}
if(flag>0) {
if(blocked_status==1)
auth = "blocked";
else if(pass.equals(password))
auth = "authenticated";
else if(pass.equalsIgnoreCase(pass))
auth = "wrong_case";
else
auth = "wrong_password";
}
else{
auth = "incorrect_username";
}
} catch(SQLException e){
auth = "sqlerror";
System.out.print(" ERROR " );
}
return auth;
}
}