Thursday, October 30, 2014

How to export your datas easily in different format with Grails ( pdf, excel ... )


In my business web site, I have array with datas and I want a way to publish it in severeal format.
To achieve this, it exists the Grails export plugin.Here is what you will have under your array :



This tutorial will explain how to quickly use the export plugin and problems I met.

Plugin install


To install, the plugin I added in BuildConfig.groovy :


repositories {
...
mavenRepo "http://repo.grails.org/grails/core"
...
}
plugins {
...

compile ":export:1.6"
...
}


If you don't add, the Maven Repositories, you will have this error :

Resolve error obtaining dependencies: Could not find artifact org.odftoolkit:odfdom-java:jar:0.8.5 in grailsCentral (http://repo.grails.org/grails/plugins) (Use --stacktrace to see the full trace)
Error |


Modify your GSP

 <head>
     ... 
     <r:require module="export"/>
     ... 
 </head>
 <body>
     <export:formats /> 
 </body>

The export tag will display icons and the require will had required css.
If you clic on pdf button,

Notes :
  • You can put the export tag where you want in the GSP
  • You can specify format you want :

<export:formats formats="['csv', 'excel', 'ods', 'pdf', 'rtf', 'xml']" /> 


Modify your controller

Here is my controller :


class ToolsController {

    // Export service provided by Export plugin

    def exportService

    def grailsApplication  //inject GrailsApplication

    def index() {

        if(!params.max) {

            params.max = 10

        }

        if ((params.extension != null)) {

            log.info(params.get('zest'))

            def format=params.extension

            if ("xls".equals(params.extension)) {

                format="excel"

            }

            if(format && format != "html"){

                response.contentType = grailsApplication.config.grails.mime.types[format]

                response.setHeader("Content-disposition", "attachment; filename=check.${params.extension}")

                List fields = ["machineName", "fileName", "confServerName"]

                Map labels = ["machineName": "Nom de machine", "fileName": "Nom de fichier",   "confServerName":"Valeur du ServerName"]

                Map formatters = new HashMap()

                Map parameters = new HashMap()

                exportService.export(format, response.outputStream,Check.list(params), fields, labels, formatters, parameters)

            }

        }

   }

}

I had a Check domain class with 3 fields : machineName, fileName, confServerName.These fields will be display in the pdf


Notes :
  • I had some problem with params.format values.In my case, it was always null and I don't know why.That's why my code is not exactly the same of the documentation
  • You can also format text and adjust column size with formatters and parameters.See documentation for more details.

If you want more details about plugin installation, you could see the documentation : http://grails.org/plugin/export
Here is my Grails configuration :
  • Grails 2.3.11
  • Plugin ; runtime ":resources:1.2.1"

Tuesday, September 16, 2014

Grails : database management in multiple environments


With Grails, you can use a database for a specific environments.If you change environments, Grails will use the database you define.

For example, you can define the following environments :

  • development: In memory database
  • test:               Mysql on localhost
  • production :   Mysql on production machine

Define your environments in DataSource.groovy



hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
//    cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
}

// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
        dataSource_lookup {
            pooled = true
            driverClassName = "org.h2.Driver"
            username = "sa"
            password = ""
        }
    }
    test {
        dataSource {
            pooled = true
            driverClassName = "com.mysql.jdbc.Driver"
            dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
            dbCreate = "create-drop"
            url = "jdbc:mysql://localhost/toolprod"
            username = "root"
            password = ""
        }

    }
    production {
        grails.config.locations = ["file:/opt/apache-tomcat-7.0.47/conf/ConfigToolprod.groovy"]
    }
}  


Production Environment


As you can see, the way you define production environment is quite different.You define a path where are stored datasource.
With this sort of configuration, you doesn't have to build your Grails project an other time if you want to change the login and password.Moreover, authentication is only in one place.I find it much better.

Below, there is an example of my ConfigToolprod.groovy file. An important thing, this configuration will permit Mysql database to reconnect automaticaly.

Comment : File contains a lot parameter because they had a bug in a old version of Grails.You certainly doesn't need all parameters.



ConfigToolprod.groovy


dataSource {
    pooled = true
    dbCreate = "update"
    url = "jdbc:mysql://localhost/toolprod"
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    username = "LOGIN"
    password = "PASSWORD"
    properties {
       // Documentation for Tomcat JDBC Pool
       // http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes
       // https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/PoolConfiguration.html
       jmxEnabled = true
       initialSize = 5
       maxActive = 50
       minIdle = 5
       maxIdle = 25
       maxWait = 10000
       maxAge = 10 * 60000
       timeBetweenEvictionRunsMillis = 5000
       minEvictableIdleTimeMillis = 60000
       validationQuery = "SELECT 1"
       validationQueryTimeout = 3
       validationInterval = 15000
       testOnBorrow = true
       testWhileIdle = true
       testOnReturn = false
       ignoreExceptionOnPreLoad = true
       // http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#JDBC_interceptors
       jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
       defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED // safe default
       // controls for leaked connections
       abandonWhenPercentageFull = 100 // settings are active only when pool is full
       removeAbandonedTimeout = 120
       removeAbandoned = true
       // use JMX console to change this setting at runtime
       logAbandoned = false // causes stacktrace recording overhead, use only for debugging
       // JDBC driver properties
       // Mysql as example
       dbProperties {
           // Mysql specific driver properties
           // http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
           // let Tomcat JDBC Pool handle reconnecting
           autoReconnect=false
           // truncation behaviour
           jdbcCompliantTruncation=false
           // mysql 0-date conversion
           zeroDateTimeBehavior='convertToNull'
           // Tomcat JDBC Pool's StatementCache is used instead, so disable mysql driver's cache
           cachePrepStmts=false
           cacheCallableStmts=false
           // Tomcat JDBC Pool's StatementFinalizer keeps track
           dontTrackOpenResources=true
           // performance optimization: reduce number of SQLExceptions thrown in mysql driver code
           holdResultsOpenOverStatementClose=true
           // enable MySQL query cache - using server prep stmts will disable query caching
           useServerPrepStmts=false
           useServerPrepStmts=false
           // metadata caching
           cacheServerConfiguration=true
           cacheResultSetMetadata=true
           metadataCacheSize=100
           // timeouts for TCP/IP
           connectTimeout=15000
           socketTimeout=120000
           // timer tuning (disable)
           maintainTimeStats=false
           enableQueryTimeouts=false
           // misc tuning
           noDatetimeStringSync=true
       }
    }
}




Sunday, August 31, 2014

Upgrading Grails 2.3.6

Today, I decided to upgrade my Grails web site.
Now, I use Grails 2.3.6 and I decided to test severeal solution to upgrade my web site.
One note about how I upgrade my Grails version.I used "Change Grails SDK" feature of Grails plugin in IntelliJ.It simple and you can go back easily !

Grails 2.3.6 with JDK 1.8_05


This upgrade wasn't successful.Grails 2.3.6 doesn't work with JDK 1.8.
I rode forum and it seems normal.

I had the following message : Java HotSpot(TM) Server VM warning: ignoring option PermSize=256m; support was removed in 8.0 

opt/drieu/jdk1.8.0_05/bin/java -Dgrails.home=/opt/drieu/grails-2.3.6 -Dbase.dir=/home/drieu/workspaces/toolprod -Dtools.jar=/opt/drieu/jdk1.8.0_05/lib/tools.jar -Dgroovy.starter.conf=/opt/drieu/grails-2.3.6/conf/groovy-starter.conf -Xmx768M -Xms768M -XX:MaxPermSize=256m -XX:PermSize=256m -javaagent:/opt/drieu/grails-2.3.6/lib/org.springsource.springloaded/springloaded-core/jars/springloaded-core-1.1.4.jar -noverify -Dspringloaded=profile=grails -Didea.launcher.port=7532 -Didea.launcher.bin.path=/opt/drieu/intellij/idea-IU-12.1.6/bin -Dfile.encoding=UTF-8 -classpath /opt/drieu/grails-2.3.6/lib/org.codehaus.groovy/groovy-all/jars/groovy-all-2.1.9.jar:/opt/drieu/grails-2.3.6/dist/grails-bootstrap-2.3.6.jar:/opt/drieu/intellij/idea-IU-12.1.6/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain org.codehaus.groovy.grails.cli.support.GrailsStarter --main org.codehaus.groovy.grails.cli.GrailsScriptRunner --conf /opt/drieu/grails-2.3.6/conf/groovy-starter.conf run-app
Java HotSpot(TM) Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
Java HotSpot(TM) Server VM warning: ignoring option PermSize=256m; support was removed in 8.0
| Loading Grails 2.3.6
| Configuring classpath
| Configuring classpath.
| Environment set to development
| Environment set to development.
| Environment set to development..
| Environment set to development...
| Environment set to development....
| Environment set to development.....
| Packaging Grails application
| Packaging Grails application.
| Packaging Grails application..
| Packaging Grails application...
| Packaging Grails application....
| Packaging Grails application.....
| Running Grails application
Java HotSpot(TM) Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
[ERROR] 2014-08-30 19:29:07,296 ScaffoldingGrailsPlugin - Error configuration scaffolding: startup failed:
script1409426946353650946897.groovy: -1: Repetitive method name/signature for method 'java.lang.Object withFormat(groovy.lang.Closure)' in class 'toolprod.ServerController'.
 @ line -1, column -1.
script1409426946353650946897.groovy: -1: Repetitive method name/signature for method 'java.lang.Object withFormat(groovy.lang.Closure)' in class 'toolprod.ServerController'.
 @ line -1, column -1.
2 errors
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1409426946353650946897.groovy: -1: Repetitive method name/signature for method 'java.lang.Object withFormat(groovy.lang.Closure)' in class 'toolprod.ServerController'.
 @ line -1, column -1.
script1409426946353650946897.groovy: -1: Repetitive method name/signature for method 'java.lang.Object withFormat(groovy.lang.Closure)' in class 'toolprod.ServerController'.
 @ line -1, column -1.
2 errors
    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1065)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:572)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:550)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:527)
    at ScaffoldingGrailsPlugin.createScaffoldedInstance(ScaffoldingGrailsPlugin.groovy:183)
    at ScaffoldingGrailsPlugin.configureScaffoldingController(ScaffoldingGrailsPlugin.groovy:138)
    at ScaffoldingGrailsPlugin.configureScaffolding(ScaffoldingGrailsPlugin.groovy:113)
    at ScaffoldingGrailsPlugin$_closure2.doCall(ScaffoldingGrailsPlugin.groovy:88)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
[INFO ] 2014-08-30 19:29:07,523 conf.BootStrap - ENVIRONNEMENT : DEVELOPMENT
[INFO ] 2014-08-30 19:29:07,523 conf.BootStrap - Nothing to load at startup ...
| Server running. Browse to http://localhost:8080/toolprod


Grails 2.3.6 to 2.4.3


I also test the following use case.I upgraded to 2.4.3 my web site.
However,  I had compilation error :


Grails 2.4.3 with jdk7

me/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:42: error: no interface expected here
public class ScaffoldingViewResolver extends GrailsViewResolver {
                                             ^
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldedGroovyPageView.java:87: error: method createResponseWriter in class GroovyPageView cannot be applied to given types;
            out = createResponseWriter(response);
                  ^
  required: GrailsWebRequest,HttpServletResponse
  found: HttpServletResponse
  reason: actual and formal argument lists differ in length
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldedGroovyPageView.java:75: error: method does not override or implement a method from a supertype
    @Override
    ^
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:88: error: cannot find symbol
        return super.createFallbackView(viewName);
               ^
  symbol:   variable super
  location: class ScaffoldingViewResolver
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:58: error: method does not override or implement a method from a supertype
    @Override
    ^
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:97: error: cannot find symbol
        view.setApplicationContext(getApplicationContext());
                                   ^
  symbol:   method getApplicationContext()
  location: class ScaffoldingViewResolver
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:98: error: cannot find symbol
        view.setServletContext(getServletContext());
                               ^
  symbol:   method getServletContext()
  location: class ScaffoldingViewResolver
/home/drieu/workspaces/toolprod/target/work/plugins/scaffolding-2.0.1/src/java/org/codehaus/groovy/grails/scaffolding/view/ScaffoldingViewResolver.java:99: error: cannot find symbol
        view.setTemplateEngine(templateEngine);
                               ^
  symbol:   variable templateEngine
  location: class ScaffoldingViewResolver
8 errors


1 error

Process finished with exit code 1


The right choice


It isn't a suprise but the right choice is to update Grails 2.3.6 to 2.3.11.
It 's easy and it works ;-)

Monday, August 25, 2014

Web Component


This paper is a synthesis about I heared and rode about Web Components.
To make this article, I used mainly InfoQ video of Julien Vey and html5rocks web site.

Web Components is W3C standard which is at DRAFT status.So, you will have to wait before it arrived. However, it is possible to use because main actors of the web (Mozilla, Google ...) started to work on this specification.


What is a Web Component ?


Here is a good definition I found on article of Julien Vey d'InfoQ :
Web Components permit developpers to create HTML tags which are reusable and customizable.For example, here is a tag <my-own-tag> : 
<element name="my-own-tag">
 <template>
   html tag here
 </template>
 <script>
   // JavaScript
 </script>
</element

Note : When it will be implemented and approved by W3C, it will be possible to reuse a component on all web navigator !

Why look at Web Component now ?


- It is a web standard of W3C.
- Main actor of web began to implement it.
- It will change way of working in web developpement because components will be reusable on all navigators.

Web navigators and Web Components


A good summary of specification and implementation is avaible here : are we component yet ?
Now, there is a lot web navigators that doesn't support Web Component.However, it exists emulation for Web Component : polyfills.Polyfills permits to start using Web Component.

Here are some project :
  • x-tags : x-tags is a Mozilla JavaScript library which works on all Web Navigators.
  • Polylemer  is a Google library ( there is a talk on Google I/O )
  • UI library for Dart : web-ui
  • toolkitchen

Web Components 


Templates


Here is an example of template :

 <template id="">
 </template>

Template is simply a reusable peace of code.You have to note that Web Component are parsed but not executed and picture aren't load in memory.

Shadow DOM


Shadow DOM permits to make encapsulation without iframes. So we will mask implementation of a tag.

For example :

In the source we have our tag :

<div id="mondiv"></div>


When we will show the HTML web page, we will have :

<div id="mondiv">
<h2>mon contenu</h2>
</div>

The content are fill at execution.
To instanciate this shadow DOM, you can :


  • Use JavaScript

For example :

var shadow = ....
shadow.innerHtml="<h2>mon contenu</h2>"


  • Use Insertion point

We define a div with our content :

<div id="host">
</div>

This tag will permit to show our content :

<content></content>


Custom element


A Custom element will contain all we saw before :

<element name="moncomposant" extends="button" constructor="moncomposant>
     <template>
    </template>
    <scritp>....</script>
</element>

In my web page :

<link rel="component" href="moncomposant">
<moncomposant></moncomposant>

Other things


In this paper, I didn't address mutation observer and model driven view which permit to make databinding and evaluate performance...

More infos


http://www.html5rocks.com
http://www.infoq.com/fr/presentations/web-components
http://www.infoq.com/fr/news/2013/06/webcomponents

Friday, May 30, 2014

Deploy your Tomcat Grails website on OpenShift






Deploy your Grails web site on OpenShift

I use OpenShift cloud to deploy my web site made with Grails. This article will give you a summary of what you have to do if you want to deploy a web site on OpenShift cloud. It will also give some advice and feedback.

 

 Which way to deploy your Grails application on OpenShift ?

The best way I found to deploy my Grails application is to build a war and then deploy it on Openshift.

By default, Grails has the war command available : grails war

See also the Grails web site for more details about it : http://grails.org/doc/2.2.1/ref/Command%20Line/war.html


Note :

  • You can use Tomcat plugin to makes Tomcat the default servlet container for Grails at development time.
  •  You can delete unwanted files in your war by adding some configuration in Config.groovy :
    1:  grails.war.resources = {  
    2:     stagingDir -> delete(dir: "$stagingDir/selenium")   
    3:  }   
    


Install and configure Openshift client


First of all you have to create an account on Openshift then you will be able to install and configure openshift tools. You only have to install rubygems and git package. For example, on Gentoo, type the following commands :

 emerge dev-ruby/rubygems  
 emerge git   


If you don't have Gentoo, you can see on the openshift website : https://www.openshift.com/get-started#cli
Then, you only have to execute following command :

 gem install rhc  
 su - user  
 rhc-setup   


Here is an example :

#rhc setup
OpenShift Client Tools (RHC) Setup Wizard

This wizard will help you upload your SSH keys, set your application namespace, and check that other programs like Git are properly installed.

Using XXXX to login to openshift.redhat.com
Password: ******

OpenShift can create and store a token on disk which allows to you to access the server without using your password. The key is stored in your home directory and should be kept secret.  You can delete the key at any time by running 'rhc
logout'.
Generate a token now? (yes|no) yes
Generating an authorization token for this client ... lasts about 1 month

Saving configuration to /home/USER/.openshift/express.conf ... done
Checking for git ... found git version 1.8.5.5
Checking common problems .. done
Checking for a domain ... MYDOMAIN
Checking for applications ... found 1
  opendoowap http://opendoowap-totalprog.rhcloud.com/

  You are using 1 of 3 total gears
  The following gear sizes are available to you: small

Your client tools are now configured.



Deploy your application on the cloud

Once, you can access with ssh and you have a war application, you only have to copy it on your account.OpenShift uses Git to push your application on the cloud : https://www.openshift.com/developers/deploying-and-building-applications

In our case, you had to make some change if you want it works. See my tips : http://totalprogus.blogspot.fr/2013/12/problem-while-deploying-rootwar-on.html

Access in your application

 

How to connect with ssh ?

  • Go and Log in openshift website.
  • Clic on Application tab
  • Clic on your application









  • At the right of the screen, clic on the link : "Want to log in your application 
  • Copy the line in your console.

For example :

#ssh 529e2274e0b???b@myapp.rhcloud.com


Usefull commands

help
tail_all
ctl_app stop
ctl_app start

If you want more details, here is usefull links :

  • https://www.openshift.com/developers/remote-access#keys
  • https://www.openshift.com/get-started#cli


Visit your website

 The access link for your web site is in the openshift website ( Clic on your Application in the Application detail ).

Response time very long

I had a problem with very long time to first access to my web site.I found solution on StackOverFlow :

 openshift : my local gears often timeout and go down which cause response time very long

If you do not access your application for 24 hours, it will get idled (if this is a free acount), and depending on how large your application is, it could take awhile to spin back up when you do access it again.



To conclude


Deploy a web site on OpenShift cloud was not really diffcult.Just keep in mind that whit free account you have to access every 24 hours to your web site. Some people has also difficulties with proxy configuration ...
If you wan to see an example of source code, you can look at my GitHub project example : https://github.com/drieu/fjLearning.You can also visit the project on the web at opendoowap-totalprog.rhcloud.com