The starting point for this tutorial is the solution to the user management tutorial.
In that tutorial, we had a UserService
that stored user data in memory. In this tutorial, we'll put that into the
database.
As we're getting quite late into term, the solution will be posted immediately -- you can have a look at what you
need to do by comparing the master
branch with the solution
branch. I recommend checking out the master
branch,
and occasionally looking at the solution
branch on github.com when you are stuck.
The first step has already been done for you -- adding the database driver to the dependencies in build.sbt
libraryDependencies ++= Seq(
"org.mindrot" % "jbcrypt" % "0.3m",
"org.mongodb" % "mongodb-driver" % "3.0.2"
)
In UserService.java
, we make a connection to the database. In this case, we've hardcoded the connection string, but
normally we would look this up from a configuration variable (which in turn usually looks up an environment variable)
protected MongoClient mongoClient;
protected UserService() {
mongoClient = new MongoClient("127.0.0.1", 27017);
}
We've also added a protected method for accessing your database; you should change the name of the database you access
to comp391_username
, where username
is your username on turing.
protected MongoDatabase getDB() {
// TODO: Change your database name, to avoid clashing with others on turing
return mongoClient.getDatabase("comp391_yourusername");
}
I've then written a protected method that uses this to get the chitterUser
collection.
protected MongoCollection<Document> getChitterCollection() {
return getDB().getCollection("chitterUser");
}
The next thing we need is a method that can translate the User
class to BSON and back, to save it in the database.
I recommend changing how the ID is allocated -- at the moment, we've allocated a Java UUID and stored it as a String in
the ID field. If instead, you generate BSON ObjectIDs, you should still be able to hold them as Strings in Java, but they
will be convertible to ObjectIds to store in the database. In UserService
, expose a method to allocate IDs, as you'll
probably also want to use an ObjectId for the session key.
NB: If you do change to ObjectIDs, clear the cookie from your browser -- otherwise you'll still have a Java UUID as your session key, and they do not translate into ObjectIds happily!
(If you're stuck, peek at the solution!)
Note that to save User
s, you will also need to be able to translate Session
objects to BSON and back.
You're going to need to implement these. The Java Driver Quick Tour has examples for you.
protected static Document userToBson(User u) {
// TODO: You need to implement this
Document d = new Document();
throw new NotImplementedException();
}
protected static User userFromBson(Document d) {
// TODO: You need to implement this
throw new NotImplementedException();
}
Once you can serialise Users, you can save them. I've added methods UserService.insert
and UserService.update
to
help with this.
Now you need to modify the UserService
to use the database. I recommend starting with changing the UserService.registerUser
method -- change it to save the user in the database. Then try it, and using mongo
at the command line, check that
the user really turned up in the database
use "comp391_username"
db.chitterUser.find()
Now that you've done this, you should migrate the rest of the UserService
class to use the database instead of an
in-memory data structure.
One you're done, check that you can still log in, log out, and remote log out.
** Something to remember **
While we were working in memory, we pushed users into the session using User.pushSession
. But the Java User
objects
are now transient -- the data is persisted by putting it into the DB, not by hanging onto the object between requests.
So, you're going to need to put a method into UserService
that pushes a Session
into the User
in the database.
This could work by pushing it into the User
Java object, and then calling UserService.update
to save the object. Or
you could do an update query directly on the database entry.