Cloud SQL/MySQL, App engine and bitcoinj - java

I'm developing a web app that uses app engine (java) as a backend. I need the backend to listen for received transactions and broadcast transactions on the bitcoin network. I have bitcoinj set up to handle this functionality but I can't seem to get the blockstore object initialize.
Bitcoinj allows me to use mysql to store blocks. The connection is set up like this:
public static void getBlockStore(){
int fullStoreDepth = 1000;
String db = "databasename";
String un = "root";
String pw = "";
String host = "/cloudsql/database-instance-id";//I have also used the ip address, but it didn't work
try {
blockStore = new MySQLFullPrunedBlockStore(network, fullStoreDepth, host, db, un, pw);
logger.info("Blockstore created is " + blockStore);
} catch (BlockStoreException e) {
logger.info("Blockstore error " + e);
}
}
But in the backend I receive a connection error when trying to connect to my database. I don't have or don't know which port to connect to. The other information is all correct. I have tried with another mysql db from godaddy but I got the same error.
How can I get connected to a mysql database either in cloud sql or a normal mysql database?

Related

Connect to MySQL with Java - JDBC without showing credentials in Java source code

I am trying to learn how you would tackle the task of creating a Java console application, connect to a (in this case) MySQL DB and send or retrieve data, without showing your username and password in the source code of the Java application. I currently have no trouble
creating a connection showing credentials.
// JDBC driver name and database URL
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String DB_URL = "jdbc:mysql://192.168.1.159:3306/javahelper";
// Database credentials
private static final String USER = "xxxx";
private static final String PASS = "RandomString";
/**
* #return
*/
public Connection openConnection() {
Connection connection = null;
try {
Class.forName(JDBC_DRIVER);
// opening connection
connection = (Connection) DriverManager.getConnection(DB_URL,USER,PASS);
} catch (ClassNotFoundException e) {
System.out.println("This is from openConnection method");
e.printStackTrace();
} catch (SQLException f) {
System.out.println("This is from openConnection method");
f.printStackTrace();
}
return connection;
}
From what information I can gather you always need to show your credentials somewhere in the application. But how do you than achieve "safe" connection between a application and a DB, so others can't misuse your credentials for malicious reasons?
one way of doing it is using a properties file having your credentials or having your data in a xml file.
create a properties file like the one below
// database.properties
DB_URL=jdbc:mysql://localhost:3306/UserDB
DB_USERNAME=user_name
DB_PASSWORD=password
Use this information in your code to get the username and passwords.
Properties properties= new Properties();
FileInputStream input = null;
try{
input = new FileInputStream("database.properties");
props.load(input );
con = DriverManager.getConnection(props.getProperty("DB_URL"),props.getProperty("DB_USERNAME"),props.getProperty("DB_PASSWORD"));
}
you can use encrypt the username and password.The best opensource encryptor(My personal view) is jbcrypt
// Hash a password for the first time
String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
// gensalt's log_rounds parameter determines the complexity
// the work factor is 2**log_rounds, and the default is 10
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
System.out.println("It matches");
else
System.out.println("It does not match");
Sharing what i find
Creating and using the propertise file
I created a database.properties file(normal text file) and placed it in the src folder of the Java project.
JDBC_DRIVER=com.mysql.jdbc.Driver
USER=YourUser
PASS=YourPassword
DB_URL=jdbc:mysql://IP:PORT/DB
Afterwards i edited my openConnection() method to use the properties file for loading the credientials of the connection.
public Connection openConnection() {
Properties properties = new Properties();
Connection connection = null;
String path = System.getProperty("user.dir");
path += "/src/database.properties";
try(FileInputStream fin = new FileInputStream(path);) {
properties.load(fin);
try {
Class.forName(properties.getProperty("JDBC_DRIVER"));
// opening connection
connection = (Connection) DriverManager.getConnection(properties.getProperty("DB_URL"),properties.getProperty("USER"),properties.getProperty("PASS"));
} catch (ClassNotFoundException e) {
System.out.println("This is from openConnection method");
e.printStackTrace();
} catch (SQLException f) {
System.out.println("This is from openConnection method");
f.printStackTrace();
}
} catch (IOException io) {
System.out.println("This is from openConnection method");
io.printStackTrace();
}
return connection;
}
Sending username and password, Java application -> MySQL
From what i can read on the web, it dosent matter much if you encrypt or hash the password before you send it towards the sequel service from your Java application. An example i found is that the sequel service dosent have a "receive hash method and authenticate". And even if it did the hash would need to be in the program somewhere. And when the program has access to it, others also have access to it if they really want it. Also if the hash is whats needed to authenticate than your back to where you can just as well use the clear text password.
The discussion than ends on "what is the best approach". Some suggest a keyserver / auth system in between the application and sequel service, using a datastore setup on the server side, using the OS "wallet" (example Windows registry) or creating a database user with minimum permissions to just get the job done / or a read only DB "read_only=1 in my.cnf".
I tried the 3'rd option and created a "DBaccess" user, with only the select permission to retrieve data, no administrative rights and random generated password by MySQL.

How to connect to a Cloud Foundry MySQL database connection in Java?

create mysql as service on Cloud Foundry and tunnel to mysql database
this provides me connection string to mysql database i pass that information to my app.
it works from my machine but when i deployed that app on Cloud Foundry server then it gives an error in connection
this is my connection code, tell me what needs to change to be deployed on Cloud Foundry
public class DB {
private static Connection connection = null;
public static Connection getConnection() {
String url = "jdbc:mysql://127.0.0.1:10100/db8dad2d02e114ef6bc9d24e68367e33e";
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url,"uC0ag3NRJCT8c","p1nyZ38zadwfa");
System.out.println("Connect success fully");
return connection;
} catch (Exception e) {
System.out.println("Error");
System.out.println(e);
e.printStackTrace();
}
return null;
}
}
jayesh's answer is technically correct, but basically, the best way to deal with retrieving those information when inside a java app (assuming non-spring) is to use the cloudfoundry-runtime library: https://github.com/cloudfoundry/vcap-java/tree/master/cloudfoundry-runtime The README has examples of usage.
For completness, if using Spring, then things are even easier and chances are you don't even need to do anything special
Problem is here:
jdbc:mysql://127.0.0.1:10100
In this you're connecting to 127.0.0.1, it is a localhost, try giving the actual IP of your cloud server. Then it should work fine.
try {
String vcap_services = System.getenv("VCAP_SERVICES");
String hostname = "";
String dbname = "";
String user = "";
String password = "";
String port = "";
//for cloud config
if (vcap_services != null && vcap_services.length() > 0) {
JsonRootNode root = new JdomParser().parse(vcap_services);
JsonNode mysqlNode = root.getNode("mysql-5.1");
JsonNode credentials = mysqlNode.getNode(0).getNode(
"credentials");
dbname = credentials.getStringValue("name");
hostname = credentials.getStringValue("hostname");
user = credentials.getStringValue("user");
password = credentials.getStringValue("password");
port = credentials.getNumberValue("port");
String dbUrl = "jdbc:mysql://" + hostname + ":" + port + "/"
+ dbname;
System.out.println(dbUrl);
System.out.println(user + "password " + password);
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(dbUrl, user, password);
return connection;
} else {
//for local configuration
Class.forName("com.mysql.jdbc.Driver");
String url = jdbc:mysql://127.0.0.1:10100/db8dad2d02e114ef6bc9d24e68367e33e
connection = DriverManager.getConnection(url, "user name",
"password");
return connection;
}
} catch (Exception e) {
e.printStackTrace();
}
You're using information from vmc tunnel to try to connect. This is not going to work on the Cloud. You need to do what jayesh shows, and read the connection credentials from the Cloud Foundry environment instead. Eric's answer is even more complete :-)
I have the same problem. You must notice that "10100" is a port fortwarding to the mysql remote service.
you could use this just locally.Deploying your program locally with your database connection pointing to the forwarding port (101100).
But this won't work when you push your war to the Cloud Foundry Instance-
One solution is to use Spring based cloud beans. In my case i don't wan't to use this approach so i'm trying another solution...
I don't know if with the credentials (user, password, tc) created for the remote connection you could stablish a connection once you pushed your war to Cloud Foundry changing the forwarding port and using the default mysql port (3360)
In my case i don't want to use Spring Cloud Beans because the production application won't be deployed into a cloud storage.

Can not read response from server

I have written a Java Program and the program connects to a database on my server, to find records, write records, update and delete. for some reason finding records works, but most of the time when i try to save or write a record it gives an error message saying:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 9,787 milliseconds ago. The last packet sent successfully to the server was 8,183 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more
Can anyone explain why this is happening?
Usuually this gives me the error message when trying to add a record, after i had the software running for more than about half a minute. seems to loose connection or something. when i run the program and quickly write a new record, it works
I was having the same sort of issue. I referred many post and comments but the thing worked for me was changing some parameters of the my.cnf file. Hope it will help you also ....
Set following parameters in my.cnf [mysqld] section
interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"
wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"
max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"
skip-name-resolve # "Don't resolved host names. All host names are IP's"
Sometimes this problem comes due to size of system RAM.May be you are inserting the data using buffer through RAM. To get out of this problem.
Set the Auto commit disable before inserting the data.
insert some amount of data appropriate to your System RAM (not the
whole).
Commit the query.
Do the steps 2 and 3 again until the whole insertion will not be
done.
You can understand this by the following code.
public static void main(string args[])
{
Connection con = null;
Statement stm = null;
int i;
float ratio;
ratio=1.0f;
try
{
Class.forName("com.mysql.jdbc.Driver");
// Connecting to the database
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
"ashish", "impetus");
File f = new File("filler"); // taking the random text data from the file
// filler.txt and inserting that string
// in filler field of the relations
RandomAccessFile r = new RandomAccessFile(f,"r");
Random randomGenerator = new Random();
String strLine=new String();
int r1,flag=0;
stm = con.createStatement();
con.setAutoCommit(false) ;
int k=0;
i=0;
long sum2=0;
while(k%50000==0)
{
final long start = currentTimeMillis();
final StringBuilder builder =
new StringBuilder("INSERT INTO accounts
(aid, bid,abalance,filler) VALUES ");
while(i!=naccounts*ratio*scale )
{
int j=i+1;
for(int l=0;l<40;l++)
{
strLine+=((char)r.read());
r.skipBytes(0);
}
r1=randomGenerator.nextInt(1500);
if(strLine.equals(""))
{
flag=1;
}
if(flag!=1)
{
strLine=strLine.replaceAll("\\s","");
strLine=strLine.replaceAll("\\t","");
}
flag=0;
if (i%50000!=0)
{
builder.append(",");
}
builder.append(format("(%s, %s, %s, '%s')", j,
i/naccounts+1, 0, strLine));
strLine="";
r.seek(r1);
i++;
if(i%50000==0||i>=naccounts*ratio*scale)
{
final String query = builder.toString();
final PreparedStatement statement1 = con.prepareStatement(query);
statement1.execute();
con.commit();
final long stop= currentTimeMillis();
sum2=sum2+(stop-start);
statement1.close();
}
if(i%50000==0||i>=naccounts*ratio*scale)
{
break;
}
}
k=k+50000;
if(k>naccounts*ratio*scale)
{
break;
}
}
System.out.println(i+" rows inserted accounts table ");
System.out.println("time taken = "+sum2+" milliseconds");
}
catch (SQLException e)
{
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return;
}
catch (Exception e)
{
e.printStackTrace();
}
}
Did you follow/read this tutorial :
Connectivity with MYSQL
You have a part for your exception which can be useful for you.
I will quote something about your specific exception, just try that :
If you get a SQLException: Connection refused or Connection timed out
or a MySQL specific CommunicationsException: Communications link
failure, then it means that the DB isn't reachable at all. This can
have one or more of the following causes:
IP address or hostname in JDBC URL is wrong. Hostname in JDBC URL is
not recognized by local DNS server. Port number is missing or wrong in
JDBC URL. DB server is down. DB server doesn't accept TCP/IP
connections. DB server has run out of connections. Something in
between Java and DB is blocking connections, e.g. a firewall or proxy.
To solve the one or the other, follow the following advices:
Verify and test them with ping. Refresh DNS or use IP address in JDBC
URL instead. Verify it based on my.cnf of MySQL DB. Start the DB.
Verify if mysqld is started without the --skip-networking option.
Restart the DB and fix your code accordingly that it closes
connections in finally. Disable firewall and/or configure
firewall/proxy to allow/forward the port.

can't connect to MySQL on localhost

i am trying to connect to Mysql database using the code below , yet my attempt fails.
this is my attempt:
private static Connection conn = null;
private static String url = "jdbc:mysql://localhost/";
private static String dbName = "proj1";
private static String driver = "com.mysql.jdbc.Driver";
private static String userName = "root";
private static String password = "root";
public static int setupConnection ()
{
try{
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,"root","root");
return 1;
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, e.getMessage());
return 0;
}
}
when installing MySQL i remember entering the password "root" , but im not 100% sure if the username is autmatically assigned "root" , i really appreciate your help.
i get the error message : com.mysql.jdbc.Driver
You need to add the MySQL Connector/J driver to the build-path/classpath of your Netbeans project. Otherwise it cannot be loaded.
Unfortunately you did not mention what kind of failure you got.
But here are some tips.
My JDBC URL looks like the following. jdbc:mysql://localhost:3306/MYSCHEMA. So port and schema name are missing in yours.
To check your credentials try to connect to your DB using command line client:
mysql -uroot -proot
Read the error message if you fail. If you cannot restore credentials, re-install MySql. It takes 3 minutes. Do not try to connect to DB using your code unless you can do it using existing clients.
Good luck.
you should connect to port address 3306,
change the url as below :
private static String url = "jdbc:mysql://localhost:3306/";
I am considering that you are not getting any compilation error and you have added mysql java api..
Start by trying to log into mysql from a command shell. If you can't, JDBC won't be able to, either.
This might help if you can't remember:
http://www.cyberciti.biz/tips/recover-mysql-root-password.html

Someone knows a mail (SMTP) delivery library for Java?

I'd like to send mail without bothering with the SMTP-Server which is used for delivery.
So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.
I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.
I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.
An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.
Or does anyone know about other libraries I could use?
One possible solution: get the MX record on your own and use JavaMail API.
You can get the MX record using the dnsjava project:
Maven2 dependency:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>2.0.1</version>
</dependency>
Method for MX record retrieval:
public static String getMXRecordsForEmailAddress(String eMailAddress) {
String returnValue = null;
try {
String hostName = getHostNameFromEmailAddress(eMailAddress);
Record[] records = new Lookup(hostName, Type.MX).run();
if (records == null) { throw new RuntimeException("No MX records found for domain " + hostName + "."); }
if (log.isTraceEnabled()) {
// log found entries for debugging purposes
for (int i = 0; i < records.length; i++) {
MXRecord mx = (MXRecord) records[i];
String targetString = mx.getTarget().toString();
log.trace("MX-Record for '" + hostName + "':" + targetString);
}
}
// return first entry (not the best solution)
if (records.length > 0) {
MXRecord mx = (MXRecord) records[0];
returnValue = mx.getTarget().toString();
}
} catch (TextParseException e) {
throw new RuntimeException(e);
}
if (log.isTraceEnabled()) {
log.trace("Using: " + returnValue);
}
return returnValue;
}
private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
String parts[] = mailAddress.split("#");
if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
return parts[1];
}
Sending mail via JavaMail code:
public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
String smtpServer = getMXRecordsForEmailAddress(toAddress);
// create session
Properties props = new Properties();
props.put("mail.smtp.host", smtpServer);
Session session = Session.getDefaultInstance(props);
// create message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(fromAddress));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
msg.setSubject(subject);
msg.setText(body);
// send message
Transport.send(msg);
}
This is completely the wrong way to handle this.
Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.
You WANT to leverage because they do several things for you.
1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.
2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.
3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.
4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.
Don't.
Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.
Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.

Categories

Resources