Showing posts with label groovy. Show all posts
Showing posts with label groovy. Show all posts

Tuesday, 21 November 2017

using java lambdas as groovy closure



using java lambdas from groovy

I have a scala method that takes java.util.function.Supplier as parameter.
class TestKit(system: ActorSystem) {
   def awaitCond(p: Supplier[Boolean]): Unit = tp.awaitCond(p.get)
}
syntactic sugar for Supplier functor would be () -> ... in java, but is not compiled in groovy.
def actorSystem = ActorSystem.create("actor-system")
def verifier = new TestKit(actorSystem)
verifier.awaitCond { -> return verifier.msgAvailable()}

Thursday, 8 November 2012

Hacking on grails and mongodb

Part A : Connecting grails to mongodb

STEP 1 install mongodb
Install mongodb as described in STEP 5 here.

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
$ echo 'deb http://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

$ sudo apt-get update
$ sudo apt-get install mongodb-10gen

Or, there is mongohq.com with upto 512M for sandbox mongodb hosting.

STEP 2 : add mongodb plugin dependency
[METHOD 1]
Add mongodb dependency to grails-app/conf/BuildConfig.groovy

dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        // runtime 'mysql:mysql-connector-java:5.1.20'

        // httpbuilder
        compile('org.codehaus.groovy.modules.http-builder:http-builder:0.5.0') {
                     excludes "commons-logging", "xml-apis", "groovy"
        }
       //mongodb dependency with no need to grails install-plugin mongodb
       compile ":mongodb:1.0.0.GA"
    }
NOTE: 
In older versions of Grails,   
application.properties was the only place where plugin dependencies could be specified. 
In Grails 1.2.X (or thereabouts) 
grails-app/conf/BuildConfig.groovy was introduced as the preferred place to specify plugin dependencies, but application.properties is still supported.

[METHOD 2] 
prayag@prayag:~/workspace_grails/eccount$ grails install-plugin mongodb
 Downloading: spring-data-mongodb-parent-1.0.0.RELEASE.pom.sha1
 Downloading: mongo-java-driver-2.7.1.pom.sha1
 Downloading: grails-datastore-gorm-1.0.7.RELEASE.pom.sha1
 Downloading: grails-datastore-gorm-plugin-support-1.0.7.RELEASE.pom.sha1
 [..]
 Plugin installed.


STEP 3 : remove hibernate plugin dependency
prayag@prayag:~/workspace_grails/eccount$ grails uninstall-plugin hibernate
OR
just remove or comment this line of code runtime ":hibernate:$grailsVersion" in  /grails-app/conf/BuildConfig.groovy
    plugins {
        //runtime ":hibernate:$grailsVersion"
        runtime ":jquery:1.8.0"
        runtime ":resources:1.1.6"

        // Uncomment these (or add new ones) to enable additional resources capabilities

        //runtime ":zipped-resources:1.0"
        //runtime ":cached-resources:1.0"
        //runtime ":yui-minify-resources:0.1.4"

        build ":tomcat:$grailsVersion"


        runtime ":database-migration:1.1"


        compile ':cache:1.0.0'

    }

STEP 4 : Create domain-class
Create domain-class and add some properties with mapping static mapWith="mongo"
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ sudo vi grails-app/domain/whotweetsnepal/Post.groovy

package whotweetsnepal


class Post {

    String username;
    String status;
    Date created = new Date();
    static mapWith="mongo"
    static constraints = {
        created(display:false)
    }
}


STEP 5 : Compile the app
prayag@prayag:~/workspace_grails/whotweetsnepal$ grails compile

STEP 6 : run the app
prayag@prayag:~/workspace_grails/whotweetsnepal$ grails run-app

STEP 7 : check mongodb
prayag@prayag:~$ mongo
MongoDB shell version: 2.2.1
connecting to: test

> show dbs;

WhoTweetsNepal  0.0625GB
local   (empty)
> use WhoTweetsNepal;
switched to db WhoTweetsNepal

If there is a error connecting to mongo, with exception :
$ mongo
MongoDB shell version: 2.2.3
connecting to: test
Sat Aug 31 05:42:52 Error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js:91
exception: connect failed

follow the following commands
$ sudo rm /var/lib/mongodb/mongod.lock
$ sudo -u mongodb mongod -f /etc/mongodb.conf --repair

And then start service mongodb (with sudo privilege) and verify the port with
$ lsof -iTCP
And now try connecting,
$ mongo

Some mongo commands for productivity,

> cls or 
> Ctrl+l   -> clear console

If it's mongohq.com as a mongodb hosting, fire the following command to connect server
$ mongo paulo.mongohq.com:10012/WhoTweetsNepal -u prayagupd -p
MongoDB shell version: 2.2.3
Enter password: 
connecting to: paulo.mongohq.com:10012/WhoTweetsNepal
>

References
http://etcpe9.wordpress.com/2012/01/28/beginning-grails-2-0-with-mongodb/
https://github.com/mpriatel/mongodb-grails/wiki
http://mattwallace.me/mapping-current-grails-domain-classes-to-use
http://blog.mongodb.org/post/18510469058/grails-in-the-land-of-mongodb





Part B Using spring-security-core and spring-security-twitter

STEP 1 Install Spring-Security plugin, a fast and convenient solution for authorizing user access
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails install-plugin spring-security-core
Downloading: spring-security-core-1.2.7.3.pom
| Resolving plugin JAR dependencies

*******************************************************

* You've installed the Spring Security Core plugin.   *
*                                                     *
* Next run the "s2-quickstart" script to initialize   *
* Spring Security and create your domain classes.     *
*                                                     *
*******************************************************
| Plugin installed.



Next run the “s2-quickstart” script to initialize Spring Security and create domain classes.
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails s2-quickstart
| Compiling 153 source files
Usage: grails s2-quickstart <domain-class-package> <user-class-name> <role-class-name> [requestmap-class-name]
Creates a user and role class (and optionally a requestmap class) in the specified package
Example: grails s2-quickstart com.yourapp User Role
Example: grails s2-quickstart com.yourapp Person Authority Requestmap

The above script asks to run it with the specification of the classes names that should be generated.

The final s2-quickstart script will be as follows:
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails s2-quickstart com.zazzercode.whotweetsnepal User Role
| 
*******************************************************
* Created domain classes, controllers, and GSPs. Your *
* grails-app/conf/Config.groovy has been updated with *
* the class names of the configured domain classes;   *
* please verify that the values are correct.          *
*******************************************************


[1.1] Check the views/
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/views/login/
total 8
-rw-rw-r-- 1 prayag prayag 2721 Nov  8 14:40 auth.gsp
-rw-rw-r-- 1 prayag prayag  237 Nov  8 14:40 denied.gsp

The /login/auth.gsp is as follows :
<body>
<div id='login'>
        <div class='inner'>
                <div class='fheader'><g:message code="springSecurity.login.header"/></div>

                <g:if test='${flash.message}'>
                        <div class='login_message'>${flash.message}</div>
                </g:if>

                <form action='${postUrl}' method='POST' id='loginForm' class='cssform' autocomplete='off'>
                        <p>
                                <label for='username'><g:message code="springSecurity.login.username.label"/>:</label>
                                <input type='text' class='text_' name='j_username' id='username'/>
                        </p>

                        <p>
                                <label for='password'><g:message code="springSecurity.login.password.label"/>:</label>
                                <input type='password' class='text_' name='j_password' id='password'/>
                        </p>

                        <p id="remember_me_holder">
                                <input type='checkbox' class='chk' name='${rememberMeParameter}' id='remember_me' <g:if test='${hasCookie}'>checked='checked'</g:if>/>
                                <label for='remember_me'><g:message code="springSecurity.login.remember.me.label"/></label>
                        </p>

                        <p>
                                <input type='submit' id="submit" value='${message(code: "springSecurity.login.button")}'/>
</p>
                </form>
        </div>
</div>
<script type='text/javascript'>
        <!--
        (function() {
                document.forms['loginForm'].elements['j_username'].focus();
        })();
        // -->
</script>
</body>


[1.2] Check the controllers
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/controllers/
total 12
-rw-rw-r-- 1 prayag prayag 4022 Nov  8 14:40 LoginController.groovy
-rw-rw-r-- 1 prayag prayag  356 Nov  8 14:40 LogoutController.groovy
drwxrwxr-x 2 prayag prayag 4096 Nov  6 12:54 whotweetsnepal

[1.3] Check the domains
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/domain/com/zazzercode/whotweetsnepal/
total 12
-rw-rw-r-- 1 prayag prayag  177 Nov  8 14:40 Role.groovy
-rw-rw-r-- 1 prayag prayag  673 Nov  8 14:40 User.groovy
-rw-rw-r-- 1 prayag prayag 1275 Nov  8 14:40 UserRole.groovy


The Role.groovy domain will be as follows :

package com.zazzercode.whotweetsnepal

class Role {


        String authority

        static mapWith="mongo"
        static mapping = {
                cache true
        }

        static constraints = {

                authority blank: false, unique: true
        }
}



The User.groovy domain will be as follows:

package com.zazzercode.whotweetsnepal

class User {


        transient springSecurityService


        String username

        String password
        boolean enabled
        boolean accountExpired
        boolean accountLocked
        boolean passwordExpired
        static mapWith="mongo"
        static constraints = {
                username blank: false, unique: true
                password blank: false
        }

        static mapping = {

                password column: '`password`'
        }

        Set<Role> getAuthorities() {

                UserRole.findAllByUser(this).collect { it.role } as Set
        }

        def beforeInsert() {

                encodePassword()
        }
       
       def beforeUpdate() {
                if (isDirty('password')) {
                        encodePassword()
                }
        }

        protected void encodePassword() {
                password = springSecurityService.encodePassword(password)
        }
}

While the UserRole.groovy domain will be as follows : 
package com.zazzercode.whotweetsnepal

import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

        User user
        Role role
        static mapWith="mongo"
        boolean equals(other) {
                if (!(other instanceof UserRole)) {
                        return false
                }

                other.user?.id == user?.id &&
                        other.role?.id == role?.id
        }

        int hashCode() {
                def builder = new HashCodeBuilder()
                if (user) builder.append(user.id)
                if (role) builder.append(role.id)
                builder.toHashCode()
        }

        static UserRole get(long userId, long roleId) {
                find 'from UserRole where user.id=:userId and role.id=:roleId',
                        [userId: userId, roleId: roleId]
        }
        static UserRole create(User user, Role role, boolean flush = false) {
                new UserRole(user: user, role: role).save(flush: flush, insert: true)
        }

        static boolean remove(User user, Role role, boolean flush = false) {
                UserRole instance = UserRole.findByUserAndRole(user, role)
                if (!instance) {
                        return false
                }

                instance.delete(flush: flush)
                true
        }

        static void removeAll(User user) {
                executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
        }

        static void removeAll(Role role) {
                executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
        }

        static mapping = {
                id composite: ['role', 'user']
                version false
        }

[1.4] The following lines will be added to the grails-app/conf/Config.groovy

prayag@prayag:~/workspace_grails/WhoTweetsNepal$ sudo vi grails-app/conf/Config.groovy
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.zazzercode.whotweetsnepal.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.zazzercode.whotweetsnepal.UserRole'
grails.plugins.springsecurity.authority.className = 'com.zazzercode.whotweetsnepal.Role'

STEP 2 : Change Bootstrap.groovy to create a user on grails app-startup

import com.zazzercode.whotweetsnepal.User
class BootStrap {

    def init = { servletContext ->

          def admin=User.findByUsername("admin")?:
                new User(username:"admin", password:"admin", enabled:true, accountLocked:false,accountExpired:false, passwordExpired:false).save(flush:true)
          if(admin.hasErrors()){
                  admin.errors.each{println it}
          }
    }
    def destroy = {
    }
}


STEP 3 : install spring-security-twitter
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails install-plugin spring-security-twitter
 | Downloading: spring-security-twitter-0.4.3.pom
 | Downloading: spring-parent-3.0.6.RELEASE.pom.sha1
 | Downloading: spring-asm-3.0.6.RELEASE.pom.sha1
 | Downloading: spring-web-3.0.6.RELEASE.pom.sha1
 | Downloading: grails-spring-security-twitter-0.4.3.zip.sha1
 | Downloading: spring-tx-3.0.6.RELEASE.jar.sha1


 the following conf will be added to Config.groovy
 // log4j configuration
log4j = {
    // Example of changing the log pattern for the default console appender:
    //
    //appenders {
    //    console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
    //}

    error  'org.codehaus.groovy.grails.web.servlet',        // controllers

           'org.codehaus.groovy.grails.web.pages',          // GSP
           'org.codehaus.groovy.grails.web.sitemesh',       // layouts
           'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
           'org.codehaus.groovy.grails.web.mapping',        // URL mapping
           'org.codehaus.groovy.grails.commons',            // core / classloading
           'org.codehaus.groovy.grails.plugins',            // plugins
           'org.codehaus.groovy.grails.orm.hibernate',      // hibernate integration
           'org.springframework',
           'org.hibernate',
           'net.sf.ehcache.hibernate'
}

grails installed plugins
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails list-plugins
| Environment set to development.....

Plugins available in the grailsCentral repository are listed below:

[...]

Plug-ins you currently have installed are listed below:

-------------------------------------------------------------
cache               1.0.0            --  Cache Plugin
database-migration  1.1              --  Grails Database Migration Plugin
hibernate           2.1.1            --  Hibernate for Grails
jquery              1.8.0            --  JQuery for Grails
mongodb             1.0.0.GA         --  MongoDB GORM
resources           1.1.6            --  Resources
spring-security-core1.2.7.3          --  Spring Security Core Plugin
spring-security-twitter0.4.3            --  Twitter Authentication
tomcat              2.1.1            --  Apache Tomcat plugin for Grails
webxml              1.4.1            --  WebXmlConfig


STEP 4 : Compile and Run the app
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails compile


The plugins can be viewed as 
prayag@prayag:~$ ls -l .grails/2.1.1/projects/WhoTweetsNepal/plugins/
total 48
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:50 cache-1.0.0
drwxrwxr-x 5 prayag prayag 4096 Nov 22 12:51 database-migration-1.1
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:50 hibernate-2.1.1
drwxrwxr-x 7 prayag prayag 4096 Nov 22 12:51 jquery-1.8.0
drwxrwxr-x 3 prayag prayag 4096 Nov 22 12:56 mongodb-1.0.0.GA
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:51 resources-1.1.6
drwxrwxr-x 5 prayag prayag 4096 Nov 22 12:56 spring-security-core-1.2.7.3
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:55 spring-security-twitter-0.4.3
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:54 spring-social-core-0.1.31
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:52 spring-social-twitter-0.1.31
drwxrwxr-x 3 prayag prayag 4096 Nov 22 12:50 tomcat-2.1.1
drwxrwxr-x 5 prayag prayag 4096 Nov 23 20:41 webxml-1.4.1


run-app
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails run-app
| Running Grails application

Configuring Spring Security Core ...

... finished configuring Spring Security Core
Configuring Spring Security Twitter ...
| Server running. Browse to http://localhost:8080/WhoTweetsNepal

Goto browser and hit http://localhost:8080/WhoTweetsNepal/login/auth, there appears a login screen.

References
 http://grails.org/plugin/spring-security-twitter

Spring Security Grails Plugin. Quick Start and Some Tips, available at
http://sysgears.com/articles/spring-security-grails-plugin-quick-start-and-some-tips/

grails-spring-security-mongodb, available at https://github.com/evilangelist/grails-spring-security-mongodb