Java to JavaScript journey

Being a Java guy, I started off spending time understanding what are good web frameworks for someone with strong Java background. In the beginning of my journey, I hated Javascript as I hate seeing famous “undefined” errors in browser, but that somewhat changed in the end. For most of my learning, I wanted to stick with current bestpractices/tools like Bootstrap, HTML5, Responsive Webdesign (RWD), Single Page Application (SPA), Model View View Model (MVVM)

Let me start with Java world:

In Java world, there are 2 competing frameworks where you can pretty much do all the best practices of web development like HTML5, Bootstrap, RWD, SPA. Vaadin (www.vaadin.com), ZKOSS (www.zkoss.org). Both take different approaches. Vaadin is built heavily on GWT (http://www.gwtproject.org/) and it is 100% java code including frontend markup. Vaadin 7 the latest edition has a poor support for CSS. I liked ZKOSS a lot.

  • It has a nice blend of markup and Java support,
  • it has good support for CSS (SCSS),
  • it has Bootstrap theme out of the box,
  • it encourages SPA a lot and
  • it has a decent MVVM support, but you have to pay for it, I would rate Knockout.js much better than this.

I ended up building a decent excel based application on Heroku. As I proceeded to do complex things, I realized that in Java we end up with lot of boilerplate coding. I stumbled up on http://projectlombok.org/ to reduce some boilerplate, but still lot of boilerplate… this forced me to think if this is the reason people move towards modern programming languages like Scala, Groovy, and my latest favorite Clojure.

Clojure in particular is interesting because it is JVM based, follows Lisp way of working, you can write efficient code and avoid boilerplate, and has ClojureScript for web development. I did spend close to 1month exploring if it is good for web development.. the good thing is I learnt a new language. The big disadvantage is it has a huge learning curve, and it is not for weak hearted, you need to be good in emacs and some good frameworks like http://hoplon.io/ only work in UNIX platforms.

Javascript world:

In essence, I realized that if you want to be good web development person you cannot avoid Javascript, love it or hate it, embrace it. Again my journey started with understanding Ember.js. It is a good framework, but poor documentation and heavyweight. One of my friend pointed me to Knockout.js (it has a strong MVVM support), I loved it. I was also looking for a SPA, I stumbled upon, http://durandaljs.com/ , according to me this is the right direction for SPA.

If you want a good IDE for Javascript, NetBeans IDE is one of the best. I am spoilt by STS IDE, features like intellisense, code formatting, running the app from within the IDE are a must. Luckily NetBeans supports all of these and more, it is tightly integrated with Chrome browser and has a plugin within Chrome for running and debugging frontend (much better than firebugs etc..).

Finally for server side, there were 2 candidates I was exploring, Node.Js and Grails. Again I have this love / hate relationship with Javascript I am still not sold on Nodejs . I am settling with Grails because it has strong STS IDE support. I am trying to rewrite my “excel on the web” application, I deployed on Heroku with durandaljs, Knockoutjs on the client side and Grails/ Groovy on the serverside, with strong JSON contracts. I will share some of these learning

Conclusion:

As I mentioned earlier, embrace Javascript, there is lot of matured frameworks in JS (Ember.js, Angular.js, Backbone.js, Knockout.js are popular ones). If you have a good IDE you can actually be productive. Also on the server side there are alternatives to Java like Groovy, Node.js. My preference is Groovy because I come from Spring background and I love STS IDE.

An insight on Big data

OLTP: Refers to Online Transaction Processing

It’s a bunch of programs that used to help and manage transactions (insert, update, delete and get) oriented applications. Most of the OLTP applications are faster because the database is designed using 3NF. OLTP systems are vertically scalable.

OLAP:  Refers to Online Analytical Processing

The OLAP is used for Business Analytics, Data Warehousing kind of transactions. The data processing is pretty slow because it enables users to analyze multidimensional data interactively from multiple data sources. The database schema used in OLAP applications are STAR (Facts and Dimensions, normalization is given a pass, redundancy is the order of the day).  OLAP systems are horizontally scaling.

OLTP vs. OLAP: There are some major difference between OLTP and OLAP.

Data Sharding:

Traditional way of database architecture implements vertical scaling that means splitting the table into number of columns and keeping them separately in physical or logically grouping (tree structure). This will lead into performance trouble when the data is growing. Need to increase the memory, CPU and disk space each and every time when we hit the performance problem.

To eliminate the above problem Data Sharding or Shared nothing concept is evolved, in which the database are scaled horizontally instead of vertically using the master/slave architecture by breaking the database into shards and spreading those into number of vertically scalable servers.

The Data Sharding concept is discussed detail in this link.

MPP (Massive Parallel Processing systems): Refers to the use of a large number of processors (or separate computers) to perform a set of coordinated computations in parallel.

MPP is also known as cluster computing or shared nothing architecture discussed above.

The examples for MPP are TeraData, GreenPlum.

Vertical and Horizontal Scaling:

Horizontal scaling means that you scale by adding more machines into your pool of resources where vertical scaling means that you scale by adding more power (CPU, RAM) to your existing machine.

In a database world horizontal-scaling is often based on partitioning of the data i.e. each node contains only part of the data, in vertical-scaling the data resides on a single node and scaling is done through multi-core i.e. spreading the load between the CPU and RAM resources of that machine.

With horizontal-scaling it is often easier to scale dynamically by adding more machines into the existing pool – Vertical-scaling is often limited to the capacity of a single machine.

Below are the differences between vertical and horizontal scaling.

CAP Theorem: The description for the CAP Theorem is discussed in this link.

Some insight on CAP: http://www.slideshare.net/ssachin7/scalability-design-principles-internal-session

Greenplum:  Greenplum Database is a massively parallel processing (MPP) database server based on PostgreSQL open-source technology. MPP (also known as shared nothing architecture) refers to systems with two or more processors which cooperate to carry out an operation – each processor with its own memory, operating system and disks.

The high-level overview of GreenPlum is discussed in this link.

Some Interesting Links:

http://www.youtube.com/watch?v=ph4bFhzqBKU,

http://www.youtube.com/watch?v=-7CpIrGUQjo

Hbase:  HBase is the Hadoop database. It is distributed, scalable, big data storage. It is used to provide real-time read and write access to large database which uses cluster (master/slave) architecture to store/retrieve data.

  • Hadoop is open source software developed by Apache to store large data.
    • MapReduce is used for distributed processing of large data sets on clusters (master/slave). MapReduce takes care of scheduling tasks, monitoring them and re-executing any failed tasks. The primary objective of Map/Reduce is to split the input data set into independent chunks and send to the cluster. The MapReduce sorts the outputs of the maps, which are then input to the reduce tasks. Typically, both the input and the output of the job are stored in a file system.
    • The Hadoop Distributed File System (HDFS) primary objective of HDFS is to store data consistently even in the presence of failures. HDFS uses a master/slave architecture in which one device (the master) controls one or more other devices (the slaves). The HDFS cluster consists of one or more slaves who actually contain the file system and a master server manages the file system namespace and regulates access to files.

Hbase documentation is provided in this link.

Some Interesting Links:

http://www.youtube.com/watch?v=UkbULonrP2o

http://www.youtube.com/watch?v=1Qx3uvmjIyU

http://www-01.ibm.com/software/data/infosphere/hadoop/hbase/

1. Do GreenPlum achieve MPP? Is GreenPlum uses Hadoop file system?

A)     GreenPlum VS MPP: GreenPlum follows MPP(Massive Parallel Processing) architecture. The architecture is discussed with the use case here.

B)      GreenPlum VS Hadoop: Yes, GreenPlum can use Hadoop internally. The use case is discussed detail in this link.

2. What are the different storage methodologies? Compare them.

Data Storage methodologies: There are three different methodologies, they are.

  • Row based storage
  • Column based storage
    • Difference between row and column based database are described in this link.
    • NoSQL : Is described detail in this link. It has three different concepts,
      • Key Value 
      • §  Document Store
      • §  Column Store

Some key points on different storage methodologies are,

Storage Methodologies Description Common Use Case Strength Weakness Size of DB Key Players
Row-based Data structured or stored in Rows. Used in transaction processing, interactive transaction applications. Robust, proven technology to capture intermediate transactions. Scalability and query processing time for huge data. Sybase, Oracle, My SQL, DB2 Sybase, Oracle, My SQL, DB2
Column-based Data is vertically partitioned and stored in Columns. Historical data analysis, data warehousing and business Intelligence. Faster query (specially ad-hoc queries) on large data. Not suitable for transaction, import export seep & heavy computing resource utilization. Several GB to 50 TB. Info Bright, Asterdata, Vertica, Sybase IQ, Paraccel
NoSQL-Key Value Stored Data stored in memory with some persistent backup. Used in cache for storing frequently requested data in applications. Scalable, faster retrieval of data , supports Unstructured and partial structured data. All data should fit to memory, does not support complex query. Several GBs to several TBs. Amazon S3, MemCached, Redis, Voldemort
NoSQL- Document Store Persistent storage of unstructured or semi-structured data along with some SQL Querying functionality. Web applications or any application which needs better performance and scalability without defining columns in RDBMS. Persistent store with scalability and better query support than key-value store. Lack of sophisticated query capabilities. Several TBs to PBs. MongoDB, CouchDB, SimpleDb
NoSQL- Column Store Very large data store and supports Map-Reduce. Real time data logging in Finance and web analytics. Very high throughput for Big Data, Strong Partitioning Support, random read-write access. Complex query, availability of APIs, response time. Several TBs to PBs HBase, Big Table, Cassandra

Incorporating LDAP with Play 2.x (Scala) application

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I extend my earlier blog Incorporating Authorization into Play 2.x (Scala) application to integrate with LDAP instead of database.

Again there might be better ways to do this, but right now there is no clear documentation. A quick googling will display this Google group link and this link and this Github code. All of them were of little help to me. So I took the 1st step and put one of these. I have used Unboundid LDAP SDK‘s InMemoryDirectoryServer.

As a first step we need to add the below dependency in Build.scala,

"com.unboundid" % "unboundid-ldapsdk" % "2.3.1",

Next we implement an in memory LDAP helper class LdapUtil.scala as below,

  def start(): InMemoryDirectoryServer = {
    val config = new InMemoryDirectoryServerConfig("dc=org");
    val listenerConfig = new InMemoryListenerConfig("test", null, 12345, null, null, null);
    config.setListenerConfigs(listenerConfig);
    config.setSchema(null); // do not check (attribute) schema
    val server = new InMemoryDirectoryServer(config);
    server.startListening();
...
    server.add("dn: cn=user@test.com,dc=staticsecurity,dc=geomajas,dc=org", "objectClass: person", "locale: nl_BE",
      "sn: NormalUser", "givenName: Joe", "memberOf: cn=testgroup,dc=roles,dc=geomajas,dc=org", "userPassword: password");
    server.add("dn: cn=admin@test.com,dc=staticsecurity,dc=geomajas,dc=org", "objectClass: person", "locale: nl_BE",
      "sn: Administrator", "givenName: Cindy", "memberOf: cn=testgroup,dc=roles,dc=geomajas,dc=org", "userPassword: password");

    server
  }

  def authenticate(email: String, password: String): Option[Account] = {
    val server = start

    val conn = server.getConnection();
    val entry = conn.getEntry("cn=" + email + ",dc=staticsecurity,dc=geomajas,dc=org");

    val permission = entry.getAttributeValue("sn").toString
    val retPass = entry.getAttributeValue("userPassword")
    server.shutDown(true)

    if (retPass.equals(password)) {
      println("password valid")
      val account = new Account(email, password, permission)
      toOption(account)
    } else {
      None
    }
  }

  def findByEmail(email: String): Option[Account] = {
    val server = start
    val conn = server.getConnection();
    val entry = conn.getEntry("cn=" + email + ",dc=staticsecurity,dc=geomajas,dc=org");

    val permission = entry.getAttributeValue("sn").toString
    val retPass = entry.getAttributeValue("userPassword")
    server.shutDown(true)

    val account = new Account(email, retPass, permission)
    toOption(account)
  }

If you notice the normal user rights are email:= user@test.com, pwd:= password and admin rights are email:= admin@test.com, pwd:= password. As in my earlier blog, we need to customize the AuthConfig as below,

trait AuthConfigImpl extends AuthConfig {
  type Id = String
  type User = Account
  type Authority = String
  val idTag = classTag[Id]
...
  def resolveUser(email: Id) = LdapUtil.findByEmail(email)
...
  def authorize(user: User, authority: Authority) = (user.permission, authority) match {
    case ("Administrator", _) => true
    case ("NormalUser", "NormalUser") => true
    case _ => false
  }
}

Login form looks as below as in Application.scala,

  val loginForm = Form {
    mapping("email" -> email, "password" -> text)(LdapUtil.authenticate)(_.map(u => (u.email, "")))
      .verifying("Invalid email or password", result => result.isDefined)
  }

Finally the usage looks as below refer CoffeesControler.scala,

def create = StackAction(AuthorityKey -> "Administrator") { implicit request =>
    database withSession {
      Ok(html.coffees.createForm(form, supplierSelect))
    }
  }

I hope this blog helped.

Incorporating Authorization into Play 2.x (Scala) application

For people in hurry here is the code and the steps.

In continuation of Play 2.x (Scala) is it a Spring MVC contender? – Introduction, in this blog, I will demonstrate how to use play20-auth to adopt to coffee example.

As a first step for this example we need to add dependency in Build.scala as below,

    "jp.t2v" %% "play2.auth"      % "0.9",
    "jp.t2v" %% "play2.auth.test" % "0.9" % "test",

We need to define a Account.scala domain object with permissions as below,

object Account extends Table[Account]("ACCOUNT") {
  lazy val database = Database.forDataSource(DB.getDataSource())

  def id = column[Int]("ID")
  def email = column[String]("EMAIL")
  def password = column[String]("PASSWORD")
  def name = column[String]("NAME")
  def permission = column[Permission]("PERMISSION")
  // Every table needs a * projection with the same type as the table's type parameter
  def * = id ~ email ~ password ~ name ~ permission <> (Account.apply _, Account.unapply _)

In order for Account object to accept Permission.scala object as one of the column we need to implement MappedTypeMapper for the Permission as below,

  implicit val PermissionTimeMapper = MappedTypeMapper.base[Permission, String](
    d => Permission.stringValueOf(d),
    t => Permission.valueOf(t))

  def valueOf(value: String): Permission = value match {
    case "Administrator" => Administrator
    case "NormalUser" => NormalUser
    case _ => throw new IllegalArgumentException()
  }

  def stringValueOf(value: Permission): String = value match {
    case Administrator => "Administrator"
    case NormalUser => "NormalUser"
    case _ => throw new IllegalArgumentException()
  }

Next step is, we need to implement a trait AuthConfigImpl extending AuthConfig in Application.scala indicating what is the User class to authenticate, what is the column that contains the Permission information and what is the redirecting page as below,

trait AuthConfigImpl extends AuthConfig {

  type Id = Int

  type User = Account

  type Authority = Permission

  val idTag = classTag[Id]

  val sessionTimeoutInSeconds = 3600

  def resolveUser(id: Id) = Account.findById(id)

  def loginSucceeded(request: RequestHeader) = Redirect(routes.CoffeesController.index)

  def logoutSucceeded(request: RequestHeader) = Redirect(routes.Application.login)

  def authenticationFailed(request: RequestHeader) = Redirect(routes.Application.login)

  def authorizationFailed(request: RequestHeader) = Forbidden("no permission")

  def authorize(user: User, authority: Authority) = (user.permission, authority) match {
    case (Administrator, _) => true
    case (NormalUser, NormalUser) => true
    case _ => false
  }
}

Now we need to submit the loginForm to authenticate a user in Application.scala as below,

  val loginForm = Form {
    mapping("email" -> email, "password" -> text)(Account.authenticate)(_.map(u => (u.email, "")))
      .verifying("Invalid email or password", result => result.isDefined)
  }

Account.scala authenticate method looks as below,

  def authenticate(email: String, password: String): Option[Account] = {
    findByEmail(email).filter { account => password.equals(account.password) }
  }

For details about integration with the action in the controller refer CoffeesController.scala as below,

object CoffeesController extends Controller with AuthElement with AuthConfigImpl {
  def delete(pk: String) = StackAction(AuthorityKey -> Administrator) { implicit request =>
    database withSession {
      Home.flashing(Coffees.findByPK(pk).delete match {
        case 0 => "failure" -> "Entity has Not been deleted"
        case x => "success" -> s"Entity has been deleted (deleted $x row(s))"
      })
    }
  }
}

Notice how we use StackAction and validate for Administrator permission in the controller.

I hope this blog helped you.