Your SlideShare is downloading. ×
  • Like
淺談 Groovy 與 AWS 雲端應用開發整合
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

淺談 Groovy 與 AWS 雲端應用開發整合

  • 3,769 views
Published

使用 Groovy 相關工具及技術,讓現代 Java 軟體開發更省時省力,是 Java 程式設計師提升工作效率的捷徑。本次議程分享的內容包括: …

使用 Groovy 相關工具及技術,讓現代 Java 軟體開發更省時省力,是 Java 程式設計師提升工作效率的捷徑。本次議程分享的內容包括:
(1)撰寫 Groovy Script 的妙用;
(2)自動化的 Gradle 專案建置;
(3)認識 Grails 敏捷網站開發框架;
(4)利用 Geb 進行網頁自動化測試;
(5)部署 Amazon Web Services 雲端應用

於 Oracle 主辦的 2014 Java Developer Day 發表。
http://www.codedata.com.tw/event/javaday/2014/agenda.html

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,769
On SlideShare
0
From Embeds
0
Number of Embeds
13

Actions

Shares
Downloads
77
Comments
0
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Groovy & AWS! 雲端應⽤用開發整合 林彥宏! 思創軟體 Senior Software Developer! lyhcode.info / lyhcode@gmail.com
  • 2. 3 Polyglot Programming for Java developers Scala Clojure JRuby Jython Rhino Groovy
  • 3. 4 A language that doesn't affect the way you think about programming, is not worth knowing. — Alan Perlis “
  • 4. 5 Hello, Groovy. very good and enjoyable fashionable, modern, and fun
  • 5. 6 2003 1.0 2007 designed by James Strachan project manager Guillaume LaForge glaforge.appspot.com 2.0 2012 https://github.com/groovy/groovy-core Apache License, Version 2.0 3.0 ? JSR-241 Groovy – A New Standard Programming Language for the Java Platform 2004 2.3.5 2.4.0-beta Groovy History J2SE 5.0 Java SE 6 Java SE 7 1.8 20112006 JAX 2007 Innovation Awards 2008 2009 1995 Spring, VMware
  • 6. 7 JSR-223 Scripting for the Java Platform JSR-241 The Groovy Programming Language
  • 7. Groovy for Java Developers • Scripting language • Almost-zero learning curve • More productive • Get things done faster, better, and more easily 8
  • 8. 9 本投影⽚片所包含的商標與⽂文字皆屬原著作者所有
  • 9. 10 Java Groovy Groovy Second language to learn after Java. Gradle A better way to build your Java (EE) projects. Geb The best way to test your web applications automatically. Language Development Tools Framework Grails Rapid web development framework based on Groovy and Java.
  • 10. INSTALL GROOVY 11
  • 11. GVM • Groovy enVironment Manager ! • Like RVM for Ruby or NVM for Node.js 12
  • 12. Install GVM 13 # install gvm curl -s get.gvmtool.net | bash Platform supported: • Linux • Mac OSX • Windows (with Cygwin) • Solaris • FreeBSD
  • 13. Using GVM 14 gvm install groovy 2.3.4 gvm install grails 2.4.2 gvm install gradle 2.0 candidate version
  • 14. 15 gvm ls groovy gvm use groovy 2.3.4
  • 15. GETTING STARTED 16
  • 16. 17 groovy the interpreter groovyc the compiler groovysh Groovy Shell, REPL (Read-eval-print loop) groovyConsole GUI editor for groovy Compiling Groovy code to Java bytecode
  • 17. 18 Groovy Console
  • 18. 19 Groovy Web Console groovyconsole.appspot.com
  • 19. 20 Code Editor v.s. IDE 1. Groovy / Grails Tool Suite
 (Eclipse-based) 2. NetBeans 6.5+ 3. IntelliJ IDEA 1. Vim 2. Sublime Text 3. Gedit
  • 20. Hello World in Java 21 1. public class HelloWorld { 2. public static void main(String[] args) { 3. System.out.println("Hello! World!"); 4. } 5. } 6.
  • 21. From Java To Groovy 22 1. public class HelloWorld { 2. public static void main(String[] args) { 3. System.out.println("Hello! World!"); 4. } 5. } 6.
  • 22. Hello World in Groovy 23 1. println "Hello! World!" 2.
  • 23. Create Object 24 1. class Person { 2. def name 3. def age 4. } 5. 6. def john = new Person(name: 'John', age: 35) 7. println john.name 8. dynamic typing
  • 24. GString 25 1. println "Name: ${john.name}, Age: ${john.age}" 2. 3. println "Birth year: ${2014 - john.age}" 4.
  • 25. Regex (regular expression) 26 1. pattern = /[0-9]{4}-[0-9]{2}-[0-9]{2}/ 2. 3. assert "2014-08-01" ==~ pattern 4. 5. // Assertion failed 6. assert "103-08-01" ==~ pattern 7.
  • 26. Closure 27 1. def add = { x, y -> 2. x + y 3. } 4. 5. def z 6. 7. z = add 1, 2 8.
  • 27. GDK (Groovy JDK) 28 1. new File('input.txt').text 2. 3. new URL('http://java.com/').text 4.
  • 28. GDK (Groovy JDK) 29 1. new File('/tmp').eachFileMatch(~/.*.sock/) { 2. file -> 3. println file.absolutePath 4. } 5.
  • 29. Metaprogramming 30 1. String.metaClass.hello = { 2. "Hello ${delegate}" 3. } 4. 5. // Say Hello to John 6. "John".hello() 7.
  • 30. Metaprogramming 31 1. String.metaClass.escapeHtml = { 2. delegate 3. .replaceAll('<', '&lt;') 4. .replaceAll('>', '&gt;') 5. .replaceAll(' ', '&nbsp;') 6. } 7. 8. "<p>line1<br />line2</p>".escapeHtml() 9.
  • 31. List 32 1. def books = ["Java Cookbook", "Java in a Nutshell"] 2. 3. assert books instanceof ArrayList //;true 4. 5. println books.size() 6. println books[0] 7. 8. books << "Functional Programming in Java" 9. 10. books.each { println it } 11.
  • 32. Map 33 1. def votes = [java: 9, groovy: 12, scala: 7] 2. 3. assert votes instanceof HashMap //;true 4. 5. votes.jruby = 5 6. votes << [clojure: 11] 7. 8. println votes.size() 9. println votes.java 10. 11. votes.each { println "${it.key} = ${it.value}" } 12.
  • 33. 34 1. ArrayList list = [1, 2, 3] + [4, 5, 6] 2. 3. list += [7, 8] 4. list << 9 5. 6. 7. HashMap map = [a: 1, b: 2, c: 3] + [d: 4, e: 5] 8. 9. map += [f: 6, g: 7] 10. map << [h: 8] 11.
  • 34. JSON Support • Groovy 1.8 introduces a build-in JSON builder and parser ! groovy.json.JsonSlurper groovy.json.JsonBuilder 35
  • 35. Using JsonSlurper 36 1. import groovy.json.* 2. 3. def result = new JsonSlurper().parseText(''' 4. { 5. "first_name": "John", 6. "last_name": "Smith" 7. } 8. ''') 9. 10. result.first_name 11. result.last_name 12.
  • 36. sample.json 37 1. { 2. "events": [ 3. { 4. "name": "2014 Java Developer Day", 5. "date": "2014/08/01" 6. }, 7. { 8. "name": "JCConf TW 2014", 9. "date": "2014/11/15" 10. } 11. ] 12. } 13.
  • 37. Reading JSON 38 1. import groovy.json.* 2. 3. def payload = new File('sample.json') 4. // or new URL(‘http://.../sample.json’) 5. 6. def slurper = new JsonSlurper() 7. def result = slurper.parse(payload, 'UTF-8') 8.
  • 38. Reading JSON 39 1. result.events.size() 2. //;;=> 2 3. 4. result.events.first().name 5. //;;=> 2014 Java Developer Day 6. 7. // List all events 8. result.events.each { 9. println it.name 10. } 11.
  • 39. Building JSON 40 1. def builder = new groovy.json.JsonBuilder() 2. def root = builder.people { 3. person { 4. firstName 'John' 5. lastName 'Smith' 6. } 7. } 8. 9. builder.toPrettyString() 10. { "people": { "person": { "firstName": "John", "lastName": "Smith" } } } program output
  • 40. 41 Groovy and DSL (Domain-Specific Languages)
  • 41. Groovy DSL • DSL: Domain-Specific Language • Could be implemented with Groovy Builders 42 sendmail { from me to someone message “leave a message” } (pseudo code)
  • 42. AntBuilder 43 1. new AntBuilder().zip( 2. destFile: 'file1.zip', 3. basedir: 'dir' 4. ) 5. Using AntBuilder to compress a folder
  • 43. 44 1. new AntBuilder().mail( 2. mailhost: 'smtp.gmail.com', 3. mailport: 465, ssl: true, 4. user: 'username', password: 'password', 5. messagemimetype: 'text/html', 6. subject: 'Test Sending E-Mail with AntBuilder') 7. { 8. from name: 'AntBuilder', address: 'john@company' 9. to address: 'jack@company' 10. cc address: 'jackson@company' 11. message "<p><b>Test</b> only.</p>" 12. } Using AntBuilder to send a email
  • 44. GRADLE Development Tools 45
  • 45. Gradle • Build automation for Java/Java EE/Groovy projects. • Based on Groovy. 46
  • 46. 47 Apache Ant XML (build.xml) Apache Maven XML (pom.xml) Gradle Groovy DSL (build.gradle)
  • 47. Define a Gradle Task 48 1. task hello { 2. doLast { 3. println "Hello" 4. } 5. } 6. build.gradle gradle hello
  • 48. Default Java Project Layout 49 src/main/ java groovy resources webapp src/test/ java groovy resources build.gradle
  • 49. Build a Java project 50 1. apply plugin: 'java' 2. 3. repositories { 4. mavenCentral() 5. } 6. 7. dependencies { 8. compile 'commons-codec:commons-codec:1.8' 9. } 10. Use the Maven Central Repository Dependencies Management
  • 50. Execute a Gradle Task 51 gradle build gradle test gradle war gradle jettyRun gradle javadoc task command
  • 51. Gradle Plugins 52 1. apply plugin: 'java' 2. apply plugin: 'groovy' 3. apply plugin: 'scala' 4. apply plugin: 'war' 5. apply plugin: 'maven' 6. apply plugin: 'wrapper' 7. apply plugin: 'application' 8. apply plugin: 'jetty' 9. apply plugin: 'java' 10. apply plugin: 'eclipse' 11. apply plugin: 'idea' 12. apply plugin: 'codenarc' 13. apply plugin: 'checkstyle' 14. // and more 15.
  • 52. Gradle Wrapper 53 ./gradlew build gradlew.bat build For Linux, Mac OS X users… For Windows users…
  • 53. Gradle Test Report 54
  • 54. GEB Development Tools 55
  • 55. Geb • A browser automation solution. • Based on Groovy and Selenium WebDriver. 56
  • 56. Getting Started 57 1. @Grapes([ 2. @Grab('org.gebish:geb-core:0.9.2'), 3. @Grab('org.seleniumhq.selenium:selenium-firefox-driver:2.42.0'), 4. @Grab('org.seleniumhq.selenium:selenium-support:2.42.0') 5. ]) 6. import geb.Browser ! 8. Browser.drive { 9. go "http://www.google.com.tw/" 10. } 11.
  • 57. Geb Navigator API 58 1. println $('h3.heading').text() 2. $('input', name: 'fullName').value('user1') 3. $('button#btnSubmit').click() 4. 1. <h3 class=“heading”>…</h3> 2. <form action=“…”> 3. <input name=“fullName” value=“” /> 4. <button id=“btnSubmit” class=“btn-primary”>Submit</button> 5. </form> HTML Geb
  • 58. Browser Automation 59 1. Browser.drive { 2. go 'https://www.google.com.tw/' 3. 4. $('input', name: 'q').value('CodeData') 5. $('input', name: 'btnI').click() 6. 7. waitFor { title.endsWith('CodeData') } 8. 9. println $('div.article h3 a').text() 10. } 11.
  • 59. GROOVY SCRIPTING 60
  • 60. 61 Groovy Scripts Java Library Command- line Tools Run with Shell or Cron jobs
  • 61. Execute a Groovy Script 62 groovy myscript.groovy arg1 myscript arg1
  • 62. Execute Groovy as Shell Script 1. #!/usr/bin/env groovy 2. 3. args.each { 4. println "arg: ${it}" 5. } 6. 63 chmod a+x myscript ./myscript arg1 ! file name: myscript
  • 63. DIVE INTO AWS 64
  • 64. 65 S3 (Simple Storage Service) Elastic Beanstalk EC2 (Elastic Compute Cloud) RDS (Amazon Relational Database Service) CloudFront (CDN) Using AWS SDK with Groovy Script
  • 65. Grapes and @Grab() 66 1. @Grab('com.amazonaws:aws-java-sdk:1.8.3') 2. import com.amazonaws.auth.* 3. import com.amazonaws.services.s3.* 4. Grapes will do: 1. Resolving dependencies 2. Download packages (*.jar) from Maven repositories group artifact com.amazonaws:aws-java-sdk:1.8.3 version
  • 66. 67 aws-java-sdk-1.8.3.jar commons-logging-1.1.1.jar httpclient-4.2.jar httpcore-4.2.jar commons-codec-1.3.jar jackson-core-2.1.1.jar jackson-databind-2.1.1.jar jackson-annotations-2.1.1.jar joda-time-2.3.jar ~/.groovy/grapes depends on All *.jar files will be stored in this folder
  • 67. s3upload.groovy 68 1. def credentials = new BasicAWSCredentials( 2. accessKey, 3. secretKey 4. ) 5. 6. // Get S3 client 7. def s3client = new AmazonS3Client(credentials) 8.
  • 68. 69 9. // Create a S3 Bucket 10. s3client.createBucket('s3.myhost') 11. 12. // Upload a file to S3 13. def localFile = new File('path-to-local-file') ! 15. s3client.putObject( 16. 's3.myhost', 17. 'key-for-remote-file', 18. localFile 19. ) 20.
  • 69. WAR Deployment on AWS 70 Local WAR file MyApp-1.0.war Amazon S3 Bucket Amazon Amazon Elastic BeansTalk ! Application upload Environmentdeploy Create or update an environment
  • 70. 71 Accessing Elastic Beanstalk services with Groovy Script + Applications
  • 71. eb_deploy.groovy 72 1. @Grab('com.amazonaws:aws-java-sdk:1.8.3') 2. import com.amazonaws.auth.* 3. import com.amazonaws.services.s3.* 4. import com.amazonaws.services.elasticbeanstalk.* 5. import com.amazonaws.services.elasticbeanstalk.model.* 6. 7. def credentials = new BasicAWSCredentials(accessKey, secretKey) 8. 9. def s3client = new AmazonS3Client(credentials) 10. def ebclient = new AWSElasticBeanstalkClient(credentials) 11.
  • 72. 73 12. 13. def bucket = ebclient.createStorageLocation().s3Bucket 14. s3client.putObject(bucket, objectKey, warFile) 15. 16. def request = new CreateApplicationVersionRequest() 17. request.applicationName = 'applicationName' 18. request.versionLabel = 'versionLabel' 19. request.description = 'description' 20. request.autoCreateApplication = true 21. request.sourceBundle = new S3Location(bucket, objectKey) 22. elasticBeanstalk.createApplicationVersion(request) 23. 24. request = new UpdateEnvironmentRequest() 25. request.environmentName = 'environmentName' 26. request.versionLabel = 'versionLabel' 27. elasticBeanstalk.updateEnvironment(request) 28. ① Upload .war to S3 ② Create application version ③ Update environment
  • 73. GRAILS FRAMEWORK 74
  • 74. 75 Grails Architecture Grails Groovy Java Virtual Machine Spring Hibernate SiteMesh Java EE
  • 75. Create a Grails Project 76 grails create-app example cd example
  • 76. Run 77 grails run-app grails -Dserver.port=8000 run-app Specifies the HTTP port:
  • 77. 78 Browse http://localhost:8080/example
  • 78. 79 BuildConfig Config BootStrap DataSource UrlMappings Tag Library Filter Domain Class View Controller Service Configuration MVC Spock, JUnit Testing
  • 79. 80 1. grails.project.dependency.resolution = { 2. repositories { 3. grailsPlugins() 4. grailsHome() 5. mavenLocal() 6. grailsCentral() 7. mavenCentral() 8. } 9. dependencies { 10. runtime 'mysql:mysql-connector-java:5.1.29' 11. } 12. plugins { 13. build ":tomcat:7.0.54" ! 15. compile ":scaffolding:2.1.2" 16. compile ':cache:1.1.7' 17. compile ":asset-pipeline:1.8.11" ! 19. runtime ":hibernate4:4.3.5.4" 20. runtime ":database-migration:1.4.0" 21. runtime ":jquery:1.11.1" 22. } 23. } grails-app/conf/BuildConfig.groovy
  • 80. 81 GORM Grails Object Relational Mapping DataSource.groovy RDBMS Domain Class
  • 81. 82 grails create-domain-class User 1. class User { 2. String firstName 3. String lastName 4. Integer age 5. 6. static constraints = { 7. age range: 0..99 8. } 9. } 10.
  • 82. 83 1. @TestFor(User) 2. class UserSpec extends Specification { 3. void "The new user must have first and last names"() { 4. when: 5. def user = new User() 6. then: 7. !user.validate() 8. when: 9. user = new User(firstName: 'John', lastName: 'Smith') 10. then: 11. user.validate() 12. } 13. } grails test-app
  • 83. Test Report 84
  • 84. 85 grails create-controller User 1. class UserController { 2. def index() { 3. redirect action: 'list' 4. } 5. def list() { 6. [ 7. users: User.list() 8. ] 9. } 10. }
  • 85. 86 Views .gsp + = SiteMesh Layout .gsp Main content area and additional head tags. Theme, libraries and full page layout. Final HTML output to browsers. Decorated HTML TagLib Using custom tags in views.
  • 86. 87 1. <!DOCTYPE html> 2. <html> 3. <head> 4. <meta name="layout" content="bootstrap3"/> 5. <title>…</title> 6. </head> 7. <body> 8. <p>Totals: ${users.size()}</p> 9. </body> 10. </html> grails-app/views/user/list.gsp SiteMesh
  • 87. 88 1. <!DOCTYPE html> 2. <html> 3. <head> 4. <title>…</title> 5. <link rel="stylesheet" href="css/bootstrap.min.css"> 6. <link rel="stylesheet" href="css/bootstrap-theme.min.css"> 7. <script src="js/bootstrap.min.js"></script> 8. <g:layoutHead/> 9. </head> 10. <body> 11. <g:layoutBody/> 12. </body> 13. </html> grails-app/views/layout/bootstrap3.gsp
  • 88. 89 1. class BootstrapTagLib { 2. static namespace = "bs3" 3. def alert = { attrs, body -> 4. out << """<div class="alert alert-${attrs.type?:'success'}">""" 5. out << body() 6. out << '</div>' 7. } 8. } 9. 1. <bs3:alert type="warning">Warning messages.</bs3:alert> 2. 3. <!-- Outputs: 4. <div class="alert alert-warning”>Warning messages.</div> 5. -->
  • 89. 90 http://localhost:8080/project/controller/action/ID Default URL Mapping 1. class UserController { 2. def show(long id) { 3. [user: User.get(id)] 4. } 5. } …/user/show/1
  • 90. 91 localhost:8080/user/list.html 1. class UserController { 2. … 3. def list() { 4. def users = User.list() 5. withFormat { 6. html users: users 7. xml { render users as XML } 8. json { render users as JSON } 9. } 10. } 11. } localhost:8080/user/list.xml localhost:8080/user/list.json Multiple Response Content-Type
  • 91. Grails Application Packaging 92 grails war
  • 92. 93 Grails Web Application Elastic Beanstalk RDS EC2 project-1.0.war Database 1. MySQL 2. PostgreSQL 3. Oracle 4. SQL Server Pre-configured VMs 1. Linux 2. Java 3. Tomcat Virtual Machine
  • 93. Install Elastic Beanstalk Plugin 94 1. grails.project.dependency.resolution = { 2. … 3. plugins { 4. … 5. compile ':aws-elastic-beanstalk:0.3' 6. } 7. } 8. grails-app/conf/BuildConfig.groovy
  • 94. Setup Elastic Beanstalk Plugin 95 grails-app/conf/Config.groovy 1. grails { 2. plugin { 3. awsElasticBeanstalk { 4. applicationName = 'myApplication' 5. environmentName = 'myEnvironment' 6. savedConfigurationName = 'default' 7. systemProperties = [ 8. 'property.name.1': 'property-value-1', 9. 'property.name.2': 'property-value-2'] 10. } 11. } 12. } 13.
  • 95. 96 grails-app/conf/Config.groovy 1. environments { 2. production { 3. grails.logging.jul.usebridge = false 4. grails.serverURL = "http://{environment_ name}.elasticbeanstalk.com" 5. } 6. } 7.
  • 96. 97 grails-app/conf/DataSource.groovy 1. production { 2. dataSource { 3. username = "{user}" 4. password = "{password}" 5. pooled = true 6. dbCreate = "update" 7. driverClassName = "com.mysql.jdbc.Driver" 8. url = "jdbc:mysql://{endpoint}:{port_number}/ebdb" 9. dialect = org.hibernate.dialect.MySQL5InnoDBDialect 10. properties { 11. validationQuery = "SELECT 1" 12. testOnBorrow = true 13. testOnReturn = true 14. testWhileIdle = true 15. timeBetweenEvictionRunsMillis = 1800000 16. numTestsPerEvictionRun = 3 17. minEvictableIdleTimeMillis = 1800000 18. } 19. } 20. } 21. xxxxxxxxxxxxxxx
  • 97. ! 2. dataSource { ! 4. def prop = System.properties ! 6. username = "${prop.RDS_USERNAME}" 7. password = "${prop.RDS_PASSWORD}" ! 9. url = "jdbc:mysql://${prop.RDS_HOSTNAME}:${prop.RDS_PORT}/ebdb" 10. … 11. } 12. 98 1. RDS_USERNAME 2. RDS_PASSWORD 3. RDS_HOSTNAME 4. RDS_PORT 5. RDS_DB_NAME RDS System Properties
  • 98. Deploy to Elastic Beanstalk 99 grails aws-eb-deploy
  • 99. 100 EC2 Instance Load Balancer Amazon CloudFront Amazon S3 Bucket Web Application Server Assets (CSS, JavaScript, Images) CDN (Content delivery network) Deploy Grails web application assets to S3 and CloudFront.
  • 100. CDN Asset Pipeline Grails Plugin 101 1. grails.project.dependency.resolution = { 2. … 3. plugins { 4. … 5. compile ':cdn-asset-pipeline:0.3.5' 6. } 7. } 8. grails-app/conf/BuildConfig.groovy
  • 101. CDN Asset Pipeline Grails Plugin 102 1. grails { 2. assets { 3. cdn { 4. provider = 's3' 5. directory = 'my-bucket' 6. accessKey = '{MY_S3_ACCESS_KEY}' 7. secretKey = '{MY_S3_SECRET_KEY}' 8. storagePath = "assets/${appName}-${appVersion}/" 9. expires = 365 10. gzip = true 11. } 12. } 13. } 14. grails-app/conf/Config.groovy Use the {version} value to prevent outdated CDN cache.
  • 102. Use CDN-based Assets 103 1. // S3 Only 2. grails.assets.url = "https://{bucketName}.s3.amazonaws.com/
 my-bucket/assets/${appName}-${appVersion}” 3. 4. // S3 + CloudFront 5. grails.assets.url = "https://{identity}.cloudfront.net/
 my-bucket/assets/${appName}-${appVersion}" 6. grails-app/conf/Config.groovy
  • 103. 104 Use Groovy, Gradle or Grails for your next project.
  • 104. Learn More 105 Search CodeData+Groovy
  • 105. 106 THANK YOU lyhcode@gmail.com Q&A