Grails … un ejemplo

ec564-shomecode4

En este post crearemos un mini sistema para la gestión de tickets de soporte técnico.

¿Qué necesitamos?

  1. Tener instalado el JDK 8
  2. Tener instalado Grails
  3. Tener una BD (usaremos PostgreSQL en este ejemplo)

Tenemos los departamentos o áreas ).

areas

Se levantan los tickets

tickets

El encargado de dar soporte técnico responderá a las peticiones.

respuesta

Analizamos las relaciones.

Un Departamento tiene muchos Ticket(s)

Un Ticket pertenece a un Departamento

Una Respuesta pertenece a un Ticket

Tendremos en total tres clases:

  1. Departamento.groovy
  2. Ticket.groovy
  3. Respuesta.groovy

c2cd9-seleccic3b3n_008

Primer paso: crear el proyecto

$ grails create-app crud-app

Segundo paso: ubicarnos en la carpeta del proyecto creado

$ cd crud-app

Tercer paso: crear las tres clases

$ grails create-domain-class com.codemonkey.model.Departamento
$ grails create-domain-class com.codemonkey.model.Ticket
$ grails create-domain-class com.codemonkey.model.Respuesta

Departamento.groovy

package com.codemonkey.model

class Departamento {
    int iddepartamento
    String nombre
    String responsable

    static constraints = {
        nombre(blank: false)
        responsable(blank: false)
    }

    //Un Departamento tiene muchos Tickets
    static hasMany = [tickets: Ticket]

    String toString(){
        "**Departamento\nId:"+id+"\nNombre:"+nombre+"\nResponsable:"+responsable
    }
}

Ticket.groovy

package com.codemonkey.model

class Ticket {
    int idticket
    Date fecha
    String asunto
    String descripcion

    static constraints = {
        asunto(blank: false)
        descripcion(black: false)
    }

    //Una Tickets pertenece a un Departamento
    static belongsTo = [departamentos: Departamento]

    String toString(){
        "**Ticket\nId:"+id+"\nFecha:"+fecha+"\nAsunto:"+asunto+"\nDescripcion:"+descripcion
    }
}

Respuesta.groovy

package com.codemonkey.model

class Respuesta {
    int idrespuesta
    boolean solucionado
    String descripcion

    static constraints = {
        descripcion(blank: false)
    }

    //Una Respuesta pertenece a un Tickets
    static belongsTo = [tickets: Ticket]

    String toString(){
        String result = solucionado == true? "Solucionado" : "En espera"
        "**Respuesta\nId:"+id+"\nDescripcion:"+descripcion+"\nSolucionado:"+result
    }
}

Cuarto paso: configurar las dependencias necesarias y la conexión a la BD

build.gradle

 buildscript {
repositories {
mavenLocal()
maven { url “https://repo.grails.org/grails/core” }
}
dependencies {
classpath “org.grails:grails-gradle-plugin:$grailsVersion”
classpath “org.grails.plugins:hibernate5:${gormVersion-“.RELEASE”}”
classpath “com.bertramlabs.plugins:asset-pipeline-gradle:2.14.8”
}
}

version “0.1”
group “crud.app”

apply plugin:”eclipse”
apply plugin:”idea”
apply plugin:”war”
apply plugin:”org.grails.grails-web”
apply plugin:”asset-pipeline”
apply plugin:”org.grails.grails-gsp”

repositories {
mavenLocal()
maven { url “https://repo.grails.org/grails/core” }
}

dependencies {
runtime(‘org.postgresql:postgresql’)

compile “org.springframework.boot:spring-boot-starter-logging”
compile “org.springframework.boot:spring-boot-autoconfigure”
compile “org.grails:grails-core”
compile “org.springframework.boot:spring-boot-starter-actuator”
compile “org.springframework.boot:spring-boot-starter-tomcat”
compile “org.grails:grails-web-boot”
compile “org.grails:grails-logging”
compile “org.grails:grails-plugin-rest”
compile “org.grails:grails-plugin-databinding”
compile “org.grails:grails-plugin-i18n”
compile “org.grails:grails-plugin-services”
compile “org.grails:grails-plugin-url-mappings”
compile “org.grails:grails-plugin-interceptors”
compile “org.grails.plugins:cache”
compile “org.grails.plugins:async”
compile “org.grails.plugins:scaffolding”
compile “org.grails.plugins:events”
compile “org.grails.plugins:hibernate5”
compile “org.hibernate:hibernate-core:5.1.5.Final”
compile “org.grails.plugins:gsp”
console “org.grails:grails-console”
profile “org.grails.profiles:web”
runtime “org.glassfish.web:el-impl:2.1.2-b03”
runtime “com.h2database:h2”
runtime “org.apache.tomcat:tomcat-jdbc”
runtime “com.bertramlabs.plugins:asset-pipeline-grails:2.14.8”
testCompile “org.grails:grails-gorm-testing-support”
testCompile “org.grails:grails-web-testing-support”
testCompile “org.grails.plugins:geb:1.1.2”
testRuntime “org.seleniumhq.selenium:selenium-chrome-driver:2.47.1”
testRuntime “org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1”
testRuntime “net.sourceforge.htmlunit:htmlunit:2.18”
}

bootRun {
jvmArgs(‘-Dspring.output.ansi.enabled=always’)
addResources = true
String springProfilesActive = ‘spring.profiles.active’
systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}

tasks.withType(Test) {
systemProperty “geb.env”, System.getProperty(‘geb.env’)
systemProperty “geb.build.reportsDir”, reporting.file(“geb/integrationTest”)
systemProperty “webdriver.chrome.driver”, System.getProperty(‘webdriver.chrome.driver’)
systemProperty “webdriver.gecko.driver”, System.getProperty(‘webdriver.gecko.driver’)
}

assets {
minifyJs = true
minifyCss = true
}

configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 10, ‘minutes’
}

project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each {
println ‘ [Dependencias] ‘
println ‘artifact: ‘+it.name
println ‘referencia: ‘+it.file
println ‘**************************’
}

application.yml

---
grails:
    profile: web
    codegen:
        defaultPackage: crud.app
    gorm:
        reactor:
            # Whether to translate GORM events into Reactor events
            # Disabled by default for performance reasons
            events: false
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    main:
        banner-mode: "off"
    groovy:
        template:
            check-template-location: false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    jmx:
        enabled: true

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            all: '*/*'
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            form: application/x-www-form-urlencoded
            html:
              - text/html
              - application/xhtml+xml
            js: text/javascript
            json:
              - application/json
              - text/json
            multipartForm: multipart/form-data
            pdf: application/pdf
            rss: application/rss+xml
            text: text/plain
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8
    views:
        default:
            codec: html
        gsp:
            encoding: UTF-8
            htmlcodec: xml
            codecs:
                expression: html
                scriptlets: html
                taglib: none
                staticparts: none
endpoints:
    jmx:
        unique-names: true

---
hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false
dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.postgresql.Driver # org.h2.Driver
    username: postgres #sa
    password: 5432 #''

environments:
    development:
        dataSource:
            dbCreate: update
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    test:
        dataSource:
            dbCreate: update
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    production:
        dataSource:
            dbCreate: none
            url: jdbc:postgresql://localhost:5432/inventario #jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED

Quinto paso: generar las vistas, etc.

$ grails generate-all "*"

Sexto paso: ejecutar aplicación

$ grails run-app

Abrir el navegador en: http://127.0.0.1:8080/

Es todo por el momento.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s