Sunday, July 7, 2013

Installing Postgres on Mac OS

My notes on installing Postgres on my MacBook Pro (Snow Leopard)


I use MacPort to install Postgres. See  http://www.macports.org/ to get the installer.
To install Postgres using Port:

@mbp /opt/local$ sudo port install postgresql92-server
@mbp /opt/local$ sudo port install postgresql92

Check that they're installed:
@mbp ~/dev/play$ port installed | grep postgres
  postgresql92 @9.2.4_0 (active)
  postgresql92-server @9.2.4_0 (active)
  postgresql_select @0.1_0 (active)

The installer creates "postgres" users by default.

Create a postgres database
@mbp /opt/local$  sudo su postgres -c '/opt/local/lib/postgresql92/bin/initdb -D /opt/local/var/db/postgresql92/defaultdb' 

postgres$ ls -Fal /opt/local/var/db/postgresql92/defaultdb/
total 80
drwx------  19 postgres  postgres    646 Jul  4 15:49 ./
drwxr-xr-x   3 root      admin       102 Jul  4 15:41 ../
-rw-------   1 postgres  postgres      4 Jul  4 15:41 PG_VERSION
drwx------   5 postgres  postgres    170 Jul  4 15:41 base/
drwx------  42 postgres  postgres   1428 Jul  4 15:49 global/
drwx------   3 postgres  postgres    102 Jul  4 15:41 pg_clog/
-rw-------   1 postgres  postgres   4476 Jul  4 15:41 pg_hba.conf
-rw-------   1 postgres  postgres   1636 Jul  4 15:41 pg_ident.conf
drwx------   4 postgres  postgres    136 Jul  4 15:41 pg_multixact/
drwx------   3 postgres  postgres    102 Jul  4 15:44 pg_notify/
drwx------   2 postgres  postgres     68 Jul  4 15:41 pg_serial/
drwx------   2 postgres  postgres     68 Jul  4 15:41 pg_snapshots/
drwx------   2 postgres  postgres     68 Jul  4 15:49 pg_stat_tmp/
drwx------   3 postgres  postgres    102 Jul  4 15:41 pg_subtrans/
drwx------   2 postgres  postgres     68 Jul  4 15:41 pg_tblspc/
drwx------   2 postgres  postgres     68 Jul  4 15:41 pg_twophase/
drwx------   4 postgres  postgres    136 Jul  4 15:41 pg_xlog/
-rw-------   1 postgres  postgres  19625 Jul  4 15:41 postgresql.conf
-rw-------   1 postgres  postgres     89 Jul  4 15:44 postmaster.opts

To Start:
postgres$ /opt/local/lib/postgresql92/bin/pg_ctl start -D /opt/local/var/db/postgresql92/defaultdb -l /opt/local/var/log/postgresql92/postgres.log 

To Stop:
postgres$ /opt/local/lib/postgresql92/bin/pg_ctl stop -D  /opt/local/var/db/postgresql92/defaultdb

Create a new db:
postgres$ /opt/local/lib/postgresql92/bin/createdb mydb

Create a new role/user called "elousf":
postgres$ /opt/local/lib/postgresql92/bin/psql mydb

mydb=# create role elousf login;
CREATE ROLE


Then as elousf, connect, create a table, and test a transaction:

@mbp ~$ psql mydb -U elousf
psql (9.2.4)
Type "help" for help.

mydb=> create table test_table (id integer, name varchar(64));
CREATE TABLE
mydb=> begin transaction;
BEGIN
mydb=> insert into test_table values (1, 'hello');
INSERT 0 1
mydb=> insert into test_table values (2, 'world');
INSERT 0 1
mydb=> select * from test_table;
 id | name  
----+-------
  1 | hello
  2 | world
(2 rows)

mydb=> rollback;
ROLLBACK
mydb=> select * from test_table;
 id | name 
----+------
(0 rows)

I got myself a Postgres database to play with!

Wednesday, July 3, 2013

My Notes: Configuring SSH to Connect to AWS

To make it easier for me to ssh to my EC2 instance and also to do my git push to my gitrepo on the EC2 instance I create ssh config file which content looks like this:

@mbp ~$ cat ~/.ssh/config
Host smallec2
Hostname ec2-xx-xxx-xxx-xxx.us-west-1.compute.amazonaws.com
User edylou
IdentityFile /Users/elousf/aws/keys/my.pem 


Host miniec2
Hostname ec2-xx-xxx-xx-xx.us-west-1.compute.amazonaws.com
User elousf
IdentityFile /Users/elousf/aws/keys/test.pem 


With that ssh config, instead of doing something like:
$ ssh -i /path/to/my/pem-file elousf@ec2-xx-xx-xxxx-xxx.us-west1.compute.amazonaws.com

I can do
$ ssh elousf@smallec2

Which also simplifies my git remote operations.
Another good effect is since I often turning off my EC2 instance and whenever I need to turn it on I just need to change this ssh config. 

Creating Git Repo on EC2 To Host Playframework App

I have an m1.small Amazon EC2 instance that I use to test and share my web app development with friends. It's time to setup a gitrepo on this shared instance.

On my EC2 instance, first I install git and then setup a bare repo:
[elousf@ip-xx-xxx-xx-xxx ~]$ sudo yum install git

[elousf@ip-xx-xxx-xx-xxx ~]$ mkdir gitrepo 

[elousf@ip-xx-xxx-xx-xxx ~]$ cd gitrepo

[elousf@ip-xx-xxx-xx-xxx gitrepo]$ mkdir myweb.git

[elousf@ip-xx-xxx-xx-xxx gitrepo]$ cd myweb.git/

[elousf@ip-xx-xxx-xx-xxx myweb.git]$ git init --bare

[elousf@ip-xx-xxx-xx-xxx myweb.git]$ ls -laF
total 40
drwxrwxr-x 7 elousf elousf 4096 Jul  4 03:38 ./
drwxrwxr-x 3 elousf elousf 4096 Jul  4 03:38 ../
drwxrwxr-x 2 elousf elousf 4096 Jul  4 03:38 branches/
-rw-rw-r-- 1 elousf elousf   66 Jul  4 03:38 config
-rw-rw-r-- 1 elousf elousf   73 Jul  4 03:38 description
-rw-rw-r-- 1 elousf elousf   23 Jul  4 03:38 HEAD
drwxrwxr-x 2 elousf elousf 4096 Jul  4 03:38 hooks/
drwxrwxr-x 2 elousf elousf 4096 Jul  4 03:38 info/
drwxrwxr-x 4 elousf elousf 4096 Jul  4 03:38 objects/
drwxrwxr-x 4 elousf elousf 4096 Jul  4 03:38 refs/


Setup my local git repo for Playframework development on my local (macbook pro) git
@mbp ~/dev/play/myweb$ git init
Initialized empty Git repository in /Users/elousf/dev/play/myweb/.git/


Play automatically creates .gitignore when I created the app.
@mbp ~/dev/play/myweb$ cat .gitignore
logs
project/project
project/target
target
tmp
.history
dist
/.idea
/*.iml
/out
/.idea_modules
/.classpath
/.project
/RUNNING_PID
/.settings
/.target

Add to local git
@mbp ~/dev/play/myweb$ git add . 

See what were added by using "git status"

Submit the files to local git.
@mbp ~/dev/play/myweb$ git commit -m "Initial commit"

Add remote repo:
@mbp ~/dev/play/myweb$ git remote add origin elousf@myec2:/home/elousf/gitrepo/myweb.git

Finally, push my local git to my gitrepo on EC2 (myec2)

@mbp ~/dev/play/myweb$ git push -u origin master
Counting objects: 189, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (182/182), done.
Writing objects: 100% (189/189), 4.76 MiB | 1.12 MiB/s, done.
Total 189 (delta 18), reused 0 (delta 0)
To elousf@myec2:/home/elousf/gitrepo/myweb.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

That's it to add shared gitrepo on EC2.

Test it out

Login back to my EC2 instance, create a directory to host my playframework code:
@mbp ~$ ssh elousf@myec2

As elousf user on my EC2:
[elousf@ip-xx-xxx-xx-xxx ~]$ mkdir myplayapp

[elousf@ip-xx-xxx-xx-xxx ~]$ git init
Initialized empty Git repository in /home/elousf/myplayapp/.git/

[elousf@ip-xx-xxx-xx-xxx ~]$ git remote add origin elousf@localhost:/home/elousf/gitrepo/myweb

[elousf@ip-xx-xxx-xx-xxx ~]$  git pull origin master
remote: Counting objects: 189, done.
remote: Compressing objects: 100% (164/164), done.
remote: Total 189 (delta 18), reused 189 (delta 18)
Receiving objects: 100% (189/189), 4.76 MiB | 1.81 MiB/s, done.
Resolving deltas: 100% (18/18), done.

[elousf@ip-xx-xxx-xx-xxx ~]$ ls -l
total 5120
drwxr-xr-x  12 elousf  elousf      408 Jul  3 20:55 ./
drwxr-xr-x  10 elousf  elousf      340 Jul  3 20:54 ../
drwxr-xr-x  13 elousf  elousf      442 Jul  3 20:55 .git/
-rw-r--r--   1 elousf  elousf      150 Jul  3 20:55 .gitignore
-rw-r--r--   1 elousf  elousf      757 Jul  3 20:55 README
drwxr-xr-x   6 elousf  elousf      204 Jul  3 20:55 app/
drwxr-xr-x   4 elousf  elousf      136 Jul  3 20:55 conf/
drwxr-xr-x   4 elousf  elousf      136 Jul  3 20:55 docs/
drwxr-xr-x   5 elousf  elousf      170 Jul  3 20:55 project/
drwxr-xr-x   5 elousf  elousf      170 Jul  3 20:55 public/
drwxr-xr-x   4 elousf  elousf      136 Jul  3 20:55 test/

Assuming I already have Playframework and databases setup to run this app I can do:

[elousf@ip-xx-xxx-xx-xxx ~]$ play

[mywebapp] run




My Notes: Playframework with MongoDB Part 2 of 2

Configuring MongoDB Plugin for Play

I use https://github.com/vznet/play-mongo-jackson-mapper as my MongoDB plugin for Play.

Open project/target/Build.scala and add this line to appDependencies:

    "net.vz.mongodb.jackson" %% "play-mongo-jackson-mapper" % "1.1.0" 

My Build.scala looks like this:

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build {

  val appName         = "myweb"
  val appVersion      = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    // Add your project dependencies here,
    javaCore,
    javaJdbc,
    javaEbean,
    "net.vz.mongodb.jackson" %% "play-mongo-jackson-mapper" % "1.1.0" 
  )

  val main = play.Project(appName, appVersion, appDependencies).settings(
    // Add your own project settings here      
   resolvers += "Scala-Tools Maven2 Snapshots Repository" at "http://scala-tools.org/repo-snapshots"
  )
}

Open conf/application.conf and add these lines (I put these below Database Configuration section).
Assuming your MongoDB is installed on the same server (localhost) and listening to the default port of 27017 and you have no password setup.

# MongoDB Jackon Mapper configuration
# ~~~~~
# Configure the database name
mongodb.database=mydb
# Configure credentials
#mongodb.credentials="user:pass"
#mongodb.credentials=
# Configure the servers
mongodb.servers="localhost:27017"
# Configure a custom ObjectMapper to use
#mongodb.objectMapperConfigurer=

Now from your Play console do clean and compile and eclipse (to re-load eclipse's project files with this mongodb plugin in the .classpath)
@mbp ~/dev/play/play-mongo$ play
[info] Loading project definition from /Users/elousf/dev/play/play-mongo/project
[info] Set current project to play-mongo (in build file:/Users/elousf/dev/play/play-mongo/)
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.1.0 (using Java 1.7.0_09 and Scala 2.10.0), http://www.playframework.org

> Type "help play" or "license" for more information.
> Type "exit" or use Ctrl+D to leave this console.

[play-mongo] $ clean
[success] Total time: 0 s, completed Jul 1, 2013 9:30:17 PM
[play-mongo] $ compile
[info] Updating {file:/Users/elousf/dev/play/play-mongo/}play-mongo...
[info] Done updating.                                                                  
[info] Compiling 4 Scala sources and 2 Java sources to /Users/elousf/dev/play/play-mongo/target/scala-2.10/classes...
[success] Total time: 13 s, completed Jul 1, 2013 9:30:32 PM



[play-mongo] $ eclipse
[info] About to create Eclipse project files for your project(s).
[info] Compiling 5 Scala sources and 4 Java sources to /Users/elousf/dev/play/play-mongo/target/scala-2.10/classes...

[info] Successfully created Eclipse project files for project(s):

Create MVC-based Web Page

Let's create a web page that shows detail information about our fish. The format of the url is something like: 
http://localhost:9000/fish/<fish-name> 
<fish-name> is the object id (_id) of the fish stored in MongoDB fakeFish collection (see the previous blog)

3 steps to do this:
  1. create a route to the page in /conf/routes
  2. create a view in /app/views
  3. create a method in a controller, for this we'll create a new controller called FishController
And since we also want physically separating the presentation from the data, the page rendered above does not contain any data but after it loads it makes a web service call to get its data in JSON format and fills the page with the data. I know this may seem very complicated but having to avoid populating the web page with data on server side code (even in MVC model) to me is a very clean separation: let the client code (jquery) do the final rendering. So, for the web service we need:
  1. add an entity object to represent Fish and a helper class to retrieve data from MongoDB
  2. create a route to the ws call in /conf/routes
  3. create a controller to return the data
  4. add javascript (in jquery) on the /fish/<fish-id> page to do ws call and populate the page

Java Class for Fish and MongoDB Util Class

Fish.java


package entity;

import java.util.List;

import javax.persistence.Id;
import play.modules.mongodb.jackson.KeyTyped;


public class Fish implements KeyTyped {
    @Id
    private String fishId; 
    private String name;
    private String latin;
    private List sizeRangeMillimeter;
    private String image;
 
    public String getFishId() {
        return fishId;
    }
    public void setFishId(String fishId) {
        this.fishId = fishId;
    }
    .... getters and setters...
..

MongoUtil.java

package util;

import net.vz.mongodb.jackson.JacksonDBCollection;
import play.modules.mongodb.jackson.MongoDB;
import entity.Fish;


public class MongoUtil {
 public static Fish getFish(String fishId) {
    JacksonDBCollection fishes = MongoDB.getCollection("fakeFish", Fish.class);
    Fish dao = fishes.findOneById(fishId);
    return dao;
  }
}



Create an entry in /conf/routes for the page

Add this line to /conf/routes

GET     /fish/:fishId controllers.FishController.fish(fishId: String)

Create a view in /app/views

Create a new file called showFish.scala.html in /app/views, the content should be like this:

@(fishId: String)
<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8">
<title>Fish</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">

<!-- Bootstrap -->
<link rel="stylesheet" href="@routes.Assets.at("stylesheets/bootstrap.css")">
<!-- Font awesome icon -->
</head>
<body>
   <div class="container">
    <div class="span4">
    <h1>Fish</h1>
    <h2 id="fishNameTitle">Guppy</h2>
<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label" for="inputFishId">Fish Id</label>
    <div class="controls">
      <input type="text" id="inputFishId" placeholder="fish id">
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputName">Name</label>
    <div class="controls">
      <input type="text" id="inputName" placeholder="name">
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputLatin">Scientific Name</label>
    <div class="controls">
      <input type="text" id="inputLatin" placeholder="latin name">
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputSizeFrom">Size (in mm)</label>
    <div class="controls">
      <input type="text" id="inputSizeFrom" placeholder="">
    </div>
  </div>

  <div class="control-group">
    <label class="control-label" for="inputSizeTo">To (in mm)</label>
    <div class="controls">
      <input type="text" id="inputSizeTo" placeholder="">
    </div>
  </div>

    </form>
    </div>
    </div>
    <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")"></script>
    <script>
     function populateForm(fish) {
         $('#inputFishId').val(fish.fishId);
         $('#inputName').val(fish.name);
         $('#inputLatin').val(fish.latin);
         $('#inputSizeFrom').val(fish.sizeRangeMillimeter[0]);
         $('#inputSizeTo').val(fish.sizeRangeMillimeter[1]);
     }
     
    $(document).ready(function() {
    var fishId = '@fishId';
    var url = "/ws/fish/" + fishId;
        $.ajax({
            headers: { 
                'Accept': 'application/json',
                'Content-Type': 'application/json' 
            },
            type: 'GET',
            url: url,
            data: null,
            dataType: 'json'
        }).done(function(data) {
            console.log("data from server", data);
            populateForm(data);
        }).fail(function() {
        }).always(function() {
        });
    });

    </script>
</body>
</html>


Note that first line @(fishId: String). This is how Play passes arguments (or Model) from a Controller to a View. Again, we want to minimize the html mixing with data as much as possible here. The data will be populated by another REST call and handled by ajax. See the javascript in this view.

Create a method to handle the url request in controller.

A new controller class is create here called FishController.java, and it looks like:

package controllers;

import java.util.LinkedHashMap;

import org.codehaus.jackson.map.ObjectMapper;
package controllers;

import java.util.LinkedHashMap;

import org.codehaus.jackson.map.ObjectMapper;

import play.mvc.Content;
import play.mvc.Controller;
import play.mvc.Result;
import util.MongoUtil;
import entity.Fish;


public class FishController extends Controller {
public static Result showFish(String fishId) {
Content html = views.html.showFish.render(fishId);
return ok(html);
}

public static Result getFish(String fishId) {
Fish fish = MongoUtil.getFish(fishId);
String jsonString = "";
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
if (fish != null) {
result.put("fishId", fish.getFishId());
result.put("name", fish.getName());
result.put("latin", fish.getLatin());
result.put("sizeRangeMillimeter", fish.getSizeRangeMillimeter());
ObjectMapper om = new ObjectMapper();
try {
jsonString = om.writeValueAsString(result);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return ok(jsonString).as("application/json");
}
}

The first method, showFish(String fishId) is to return showFish.scala.html view we wrote earlier and the second method getFish(String fishId) is to return data about a fish as json.

Create a route for the web service (REST) call in /conf/routes



GET     /fish/:fishId controllers.FishController.showFish(fishId: String)

GET     /ws/fish/:fishId controllers.FishController.getFish(fishId: String)


Controller to handle the REST call

See getFish(String fishId) method above. The method implements the controller. Note that the routes says /ws/fish/:fishId is handled by controllers.FishController.getFish(fishId: String).

Add javascript (in jquery) on the /fish/<fish-id> page to do ws call and populate the page

See showFish.scala.html above that already contains the javascript required to make the ajax call to /ws/fish/:fishId and function to populate the form.


That's all! Happy Play-ing.

Monday, July 1, 2013

My Notes: Playframework with MongoDB Part 1 of 2

I found Playframework to be easy to use, a great alternative to Java "whatever" MVC framework out there,  and way easier than most of them (yeah, personal preference).
This blog is to document part of what I've learned about Playframework and how to use MongoDB so I can come back here if I forget something about them.

Here, I'm going to create a very simple web app to catalog pet fish.

What I use:
1. MacOS 10.8.4
2. Playframework 2.1.0, get it from http://www.playframework.com
3. MongoDB: get it from http://www.mongodb.org/downloads
4. Eclipse Juno


Getting and installing MongoDB on MacOS:

Download it from http://www.mongodb.org/downloads
The one I have at the time of writing this blog is mongodb-osx-x86_64-2.4.3.tgz.

$ cd ~/dev
$ tar xzvf ~/Downloads/mongodb-osx-x86_64-2.4.3.tgz

Create a symlink
$ ln -s mongodb-osx-x86_64-2.4.3 mongodb

Put ~/dev/mongodb/bin to your $PATH by updating your ~/.bash_profile

By default mongo uses /data/db/ to store its data, so let make the directories and make yourself the owner

$ sudo mkdir -p /data/db
$ sudo chown -R me /data


Now you can start mongo daemon:

$ cd ~/dev/mongodb/bin
$ ./mongod & 

You should see something like this:

Wed May 26 21:39:50.803 [initandlisten] MongoDB starting : pid=2009 port=27017 dbpath=/data/db/ 64-bit host=My-Mac.local
Wed May 26 21:39:50.803 [initandlisten] db version v2.4.3
Wed May 26 21:39:50.803 [initandlisten] git version: fe1743177a5ea03e91e0052fb5e2cb2945f6d95f
Wed May 26 21:39:50.803 [initandlisten] build info: Darwin bs-osx-106-x86-64-1.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386 BOOST_LIB_VERSION=1_49
Wed May 26 21:39:50.803 [initandlisten] allocator: system
Wed May 26 21:39:50.803 [initandlisten] options: {}
Wed May 26 21:39:50.804 [initandlisten] journal dir=/data/db/journal
Wed May 26 21:39:50.804 [initandlisten] recover begin
Wed May 26 21:39:50.805 [initandlisten] recover lsn: 23197557
Wed May 26 21:39:50.805 [initandlisten] recover /data/db/journal/j._0
Wed May 26 21:39:50.806 [initandlisten] recover skipping application of section seq:0 < lsn:23197557
Wed May 26 21:39:50.806 [initandlisten] recover skipping application of section seq:2802916 < lsn:23197557
Wed May 26 21:39:50.807 [initandlisten] recover skipping application of section seq:19276757 < lsn:23197557
Wed May 26 21:39:50.807 [initandlisten] recover skipping application of section seq:19331960 < lsn:23197557
Wed May 26 21:39:50.808 [initandlisten] recover skipping application of section seq:19387211 < lsn:23197557
Wed May 26 21:39:50.808 [initandlisten] recover skipping application of section seq:19442474 < lsn:23197557
Wed May 26 21:39:50.808 [initandlisten] recover skipping application of section seq:19552807 < lsn:23197557
Wed May 26 21:39:50.809 [initandlisten] recover skipping application of section seq:19607957 < lsn:23197557
Wed May 26 21:39:50.809 [initandlisten] recover skipping application of section seq:19773797 < lsn:23197557
Wed May 26 21:39:50.809 [initandlisten] recover skipping application of section more...
Wed May 26 21:39:50.812 [initandlisten] recover cleaning up
Wed May 26 21:39:50.812 [initandlisten] removeJournalFiles
Wed May 26 21:39:50.812 [initandlisten] recover done
Wed May 26 21:39:50.877 [websvr] admin web console waiting for connections on port 28017
Wed May 26 21:39:50.877 [initandlisten] waiting for connections on port 27017


Let's quickly check if your mongo is working.
Launch mongodb shell:

$ cd ~/dev/mongodb/bin
$ ./mongo
MongoDB shell version: 2.4.3
connecting to: test
> _

MongoDB automatically creates database and collections (these are "tables" in relational database) the first time you use them so you don't need to explicitly create them.
Now let's create a new database called mydb

> use mydb
switched to db mydb


Now insert "Guppy" document into "fakeFish" collection (this is, again, table in relational database):

> db.fakeFish.insert( {_id: "guppy", name: "Guppy", latin: "Poecilia reticulata", sizeRangeMilimeter: [40, 60], image: "guppy.jpg"})


Notice that you don't need to create "fakeFish" collection beforehand. MongoDB is document based database so it has no "schema", your application has to know the structure or schema of the documents you are getting from the collections. To make thing simple, you usually group similar documents into their own collections. In this case I'm using "fakeFish" collection and my app knows the structure it's getting.


See what you just added:

> db.fakeFish.find()
{ "_id" : "guppy", "name" : "Guppy", "latin" : "Poecilia reticulata", "sizeRangeMilimeter" : [ 40, 60 ], "image" : "guppy.jpg" }


Let's leave it here and let's install Playframework.

Installing Playframework


Download Playframework from www.playframework.com, unzip it to some directory. Here I just use my home directory:

$ cd ~/
$ unzip play-2.1.0.zip
$ cd play-2.1.0.zip

Edit your ~/.bashrc to put ~/play-2.1.0 to your $PATH

Create playframework app

$ mkdir -p ~/dev/play
$ cd ~/dev/
$ play new play-mongo

       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/

play! 2.1.0 (using Java 1.7.0_09 and Scala 2.10.0), http://www.playframework.org

The new application will be created in /Users/elousf/dev/play/play-mongo

What is the application name? [play-mongo]


Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 2
OK, application play-mongo is created.

Have fun!


Assuming java and javac (JDK) are available, you now have a functional web application and let's quickly test it:

$ cd ~/dev/play/play-mongo   
$ play run

[info] Loading project definition from /Users/elousf/dev/play/play-mongo/project
[info] Set current project to play-mongo (in build file:/Users/elousf/dev/play/play-mongo/)

[info] Updating {file:/Users/elousf/dev/play/play-mongo/}play-mongo...
[info] Done updating.                                                                  
--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)
 

From you web browser go to http://localhost:9000 and you should see the web page with big title

"Your new application is ready"

If this is your fist time using Play I highly recommend you to follow some links on that page, that is how I learned Play.

Setting up Play for Eclipse

If you don't have Eclipse you can download it. Since it's so common and most programmers have no problem using it so installing Eclipse is beyond this blog.

Let's create Eclipse project for the "play-mongo" web app we just created.
Go back to your terminal from where you launch "play run" and press CTRL-D to stop the web app

$ pwd
$ /Users/me/dev/play/play-mongo
$ play


[play-mongo] $ eclipse


That would create eclipse project and your directory should look like this (notice .classpath, .project, and .settings/)

$ ls -l
total 64
drwxr-xr-x  14 me  staff    476 May 26 21:05 ./
drwxr-xr-x   8 me  staff    272 May 26 21:06 ../
-rw-r--r--   1 me  staff  17570 May 26 21:05 .classpath
-rw-r--r--   1 me  staff    141 Feb  4 16:51 .gitignore
-rw-r--r--   1 me  staff    266 May 26 21:05 .project
drwxr-xr-x   4 me  staff    136 May 26 21:05 .settings/
-rw-r--r--   1 me  staff    151 Feb  4 16:51 README
drwxr-xr-x   4 me  staff    136 May 26 20:54 app/
drwxr-xr-x   4 me  staff    136 May 26 20:54 conf/
drwxr-xr-x   3 me  staff    102 May 26 21:00 logs/
drwxr-xr-x   7 me  staff    238 May 26 21:00 project/
drwxr-xr-x   5 me  staff    170 May 26 20:54 public/
drwxr-xr-x   6 me  staff    204 May 26 21:00 target/
drwxr-xr-x   4 me  staff    136 May 26 20:54 test/
 

Launch your eclipse and import the project above. Now let's create some pages before we use MongoDB!

Now, we're ready to create one or two web pages backed by MongoDB... next notes (2/2)


My Notes: Create a new user on Amazon EC2

Login To EC2 Instance

Once I get my pem file (certificate file for ssh access) then login to the ec2 instance as ec2-user user:

$ ssh -i my.pem ec2-user@ec2-xxxxxxx.amazonaws.com


Create a new user

Become root on my EC2 instance:


[ec2-user@ip-xxxxx ~]$ id
uid=222(ec2-user) gid=500(ec2-user) groups=500(ec2-user),10(wheel)

[ec2-user@ip-xxxxx ~]$ sudo su - 
[root@ip-xxxxx ~]# 
[root@ip-xxxxx ~]# useradd elousf
[root@ip-xxxxx ~]# passwd elousf
Changing password for user elousf.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

[root@ip-xxxxx ~]#  cp -r ~ec2-user/.ssh ~elousf/
[root@ip-xxxxx ~]# cd ~elousf/
[root@ip-xxxxx elousf]# ls -ltr .ssh
total 4
-rw------- 1 root root 389 Jul  2 03:28 authorized_keys
[root@ip-xxxxx elousf]# chown -R elousf:elousf .ssh
[root@ip-xxxxx elousf]# chmod 700 .ssh
[root@ip-xxxxx elousf]# chmod 600 .ssh/authorized_keys 
[root@ip-xxxxx elousf]# ls -ltr .ssh
total 4
-rw------- 1 elousf elousf 389 Jul  2 03:28 authorized_keys

[root@ip-xxxxx elousf]# exit
logout
[ec2-user@ip-xxxxx ~]$ exit
logout
Connection to ec2-54-215-48-188.us-west-1.compute.amazonaws.com closed.


Now, I'm back to my macbook pro and login in to EC2 as elousf user:
@mbp ~$ ssh -i my.pem elousf@ec2-54-215-48-188.us-west-1.compute.amazonaws.com

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.03-release-notes/


From now on I can use my user elousf to login to EC2.