Upgrade to PRO for Only $50/Yearโ€”Limited-Time Offer! ๐Ÿ”ฅ

Giving back to the Grails Community - Migrating...

Giving back to the Grails Community - Migrating plugins from Grails 2 to Grailsย 3

Giving back to the Grails Community - Migrating plugins to Grails 3

Avatar for Puneet Behl

Puneet Behl

June 03, 2016
Tweet

Other Decks in Programming

Transcript

  1. www.tothenew.com About Me Puneet Behl Associate Technical Lead TO THE

    NEW Digital [email protected] GitHub: https://github.com/puneetbehl/ Twitter: @puneetbhl LinkedIn: https://in.linkedin.com/in/puneetbhl
  2. www.tothenew.com About Me โ€ข Working on Groovy & Grails from

    last 4 years โ€ข Always excited about how can I contribute to community โ€ข Active member on Grails Slack
  3. www.tothenew.com โ€ข Few folks attended GR8Conf last year โ€ข Grails

    3 launched โ€ข git clone Grails :-) โ€ข Could not migrate :( - because old plugins not supported โ€ข Someone need to migrate == opportunity โ€ข Migration == read documentation :-) How it all started?
  4. www.tothenew.com What so far?? โ€ข Migrated around 8+ plugins to

    Grails 3, including Jodatime, RabbitMQ, Elasticsearch, Grails Asynchronous Mail, Export, Grails Remote Control, CKEditor etc. โ€ข Organized a whole day workshop, where we migrated around 6-7 plugins in a day โ€ข Leading a team of enthusiasts involved in migrating 21+ plugins to Grails 3
  5. www.tothenew.com โ€ข Removal of before & after interceptors โ€ข Project

    structure โ€ข File locations โ€ข Configurations โ€ข Package name โ€ข Legacy Gant Scripts โ€ข Gradle Build Systems Things to consider
  6. www.tothenew.com File Location Differences Grails 2 Grails 3 grails-app/conf/BuildConfig.groovy build.gradle

    grails-app/conf/Config.groovy grails-app/config/application.groovy grails/conf/UrlMappings.groovy grails-app/controllers/UrlMappings.groovy grails-app/conf/BootStrap.groovy grails-app/init/BootStrap.groovy scripts src/main/scripts src/groovy src/main/groovy src/java src/main/java
  7. www.tothenew.com File Location Differences Grails 2 Grails 3 test/unit src/test/groovy

    test/integration src/integration-test/groovy web-app src/main/webapp or src/main/resources/ *GrailsPlugin.groovy src/main/groovy/
  8. www.tothenew.com New Files in Grails 3 File Description build.gradle The

    Gradle build descriptor location in the root of project. Replaces the BuildConfig.groovy gradle.properties Properties file defining the Grails and Gradle versions grails-app/conf/logback.groovy Logging previously defined in Config.groovy is now defined using Logback, replacing log4j grails-app/conf/application.(yml, groovy) Configuration can now also be defined using YAML or Groovy grails-app/init/<package>/Application.groovy The class used By Spring Boot to start the application
  9. www.tothenew.com Files Not Present in Grails 3 File Description application.properties

    The application name and version is now defined in build.gradle grails-app/conf/DataSource.groovy Merged together into application.yml or application. groovy lib/ Dependency resolution should be used to resolve JAR files web-app/WEB-INF/applicationContext.xml Removed, beans can be defined in grails- app/conf/spring/resources.groovy
  10. www.tothenew.com Files Not Present in Grails 3 File Description src/templates/war/web.xml

    Grails 3.0 no longer requires web.xml. Customizations can be done via Spring web-app/WEB-INF/sitemesh.xml Removed, sitemesh filter no longer present. web-app/WEB-INF/tld Removed, can be restored in src/main/webapp or src/main/resources/WEB-INF
  11. www.tothenew.com Few things, I prefer to do before migration โ€ข

    Fork the existing repository โ€ข Star it - Bookmark it so itโ€™s easy to find โ€ข Watching - be notified of all the conversations โ€ข Create an issue in existing plugin, โ€œMigrate to Grails 3โ€ and mention that you are working on it
  12. www.tothenew.com Create a new branch for previous version on forked

    repo โ€ข Note the previous version of plugin from the plugin descriptor file โ€ข Create a new branch for migration. Run the following commands if youโ€™ ve already forked and cloned the repo on your dev machine git pull origin master git checkout -b 1.0.x git push origin 1.0.x git checkout master
  13. www.tothenew.com Letโ€™s get startedโ€ฆ โ€ข Create a new plugin in

    Grails 3 with the same name โ€œgrails create-plugin asynchronous-mailโ€
  14. www.tothenew.com โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”‚ โ””โ”€โ”€ wrapper โ”œโ”€โ”€ gradle.properties

    โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ grails-app โ”‚ โ”œโ”€โ”€ assets โ”‚ โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ controllers โ”‚ โ”œโ”€โ”€ domain โ”‚ โ”œโ”€โ”€ i18n โ”‚ โ”œโ”€โ”€ init โ”‚ โ”œโ”€โ”€ services โ”‚ โ”œโ”€โ”€ taglib โ”‚ โ”œโ”€โ”€ utils โ”‚ โ””โ”€โ”€ views โ””โ”€โ”€ src โ”œโ”€โ”€ integration-test โ”œโ”€โ”€ main โ””โ”€โ”€ test โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ grails-app โ”‚ โ”œโ”€โ”€ assets โ”‚ โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ domain โ”‚ โ”œโ”€โ”€ jobs โ”‚ โ”œโ”€โ”€ services โ”‚ โ””โ”€โ”€ views โ”œโ”€โ”€ scripts โ”œโ”€โ”€ src โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”œโ”€โ”€ java โ”‚ โ””โ”€โ”€ webapp โ”œโ”€โ”€ test โ”‚ โ”œโ”€โ”€ integration โ”‚ โ””โ”€โ”€ unit โ””โ”€โ”€ web-app โ””โ”€โ”€ css Forked Project Barebone Grails 3 Plugin
  15. www.tothenew.com . โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”‚ โ””โ”€โ”€ wrapper โ”œโ”€โ”€

    gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ grails-app โ””โ”€โ”€ src โ”œโ”€โ”€ integration-test โ”œโ”€โ”€ main โ””โ”€โ”€ test . โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”‚ โ””โ”€โ”€ wrapper โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ build โ”œโ”€โ”€ grails-app โ”œโ”€โ”€ scripts โ”œโ”€โ”€ src โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”œโ”€โ”€ java โ”‚ โ”œโ”€โ”€ templates โ”œโ”€โ”€ test โ”‚ โ”œโ”€โ”€ integration โ”‚ โ””โ”€โ”€ unit โ””โ”€โ”€ web-app Barebone Grails 3 Plugin Forked Project Copy Files
  16. www.tothenew.com โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€

    gradlew.bat โ”œโ”€โ”€ grails-app โ”‚ โ”œโ”€โ”€ assets โ”‚ โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ controllers โ”‚ โ”œโ”€โ”€ domain โ”‚ โ”œโ”€โ”€ i18n โ”‚ โ”œโ”€โ”€ init โ”‚ โ”œโ”€โ”€ services โ”‚ โ”œโ”€โ”€ taglib โ”‚ โ”œโ”€โ”€ utils โ”‚ โ””โ”€โ”€ views โ””โ”€โ”€ src โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ grails-app โ”‚ โ”œโ”€โ”€ assets โ”‚ โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ domain โ”‚ โ”œโ”€โ”€ init โ”‚ โ”œโ”€โ”€ jobs โ”‚ โ”œโ”€โ”€ services โ”‚ โ””โ”€โ”€ views โ”œโ”€โ”€ scripts โ”œโ”€โ”€ src โ”œโ”€โ”€ test โ””โ”€โ”€ web-app Barebone Grails 3 Plugin Forked Project Copy Files
  17. www.tothenew.com โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€

    gradlew.bat โ”œโ”€โ”€ grails-app โ”‚ โ”œโ”€โ”€ assets โ”‚ โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ controllers โ”‚ โ”œโ”€โ”€ domain โ”‚ โ”œโ”€โ”€ i18n โ”‚ โ”œโ”€โ”€ init โ”‚ โ”œโ”€โ”€ services โ”‚ โ”œโ”€โ”€ taglib โ”‚ โ”œโ”€โ”€ utils โ”‚ โ””โ”€โ”€ views โ””โ”€โ”€ src โ”œโ”€โ”€ integration-test โ”œโ”€โ”€ main โ””โ”€โ”€ test โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€ gradle โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ grails-app โ”œโ”€โ”€ grails-asynchronous-mail.iml โ”œโ”€โ”€ scripts โ”œโ”€โ”€ src โ”‚ โ”œโ”€โ”€ docs โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”œโ”€โ”€ java โ”‚ โ”œโ”€โ”€ integration-test โ”‚ โ”œโ”€โ”€ main โ”‚ โ”œโ”€โ”€ test โ”‚ โ””โ”€โ”€ templates โ”œโ”€โ”€ test โ””โ”€โ”€ web-app Barebone Grails 3 Plugin Forked Project Copy Files
  18. www.tothenew.com grails-app/ โ”œโ”€โ”€ assets โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ application.yml โ”‚

    โ””โ”€โ”€ logback.groovy โ”œโ”€โ”€ controllers โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ UrlMappings.groovy โ”œโ”€โ”€ domain โ”œโ”€โ”€ i18n โ”œโ”€โ”€ init โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ Application.groovy โ”œโ”€โ”€ services โ”œโ”€โ”€ taglib โ”œโ”€โ”€ utils โ””โ”€โ”€ views grails-app โ”œโ”€โ”€ assets โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ BuildConfig.groovy โ”‚ โ”œโ”€โ”€ DataSource.groovy โ”‚ โ””โ”€โ”€ DefaultAsynchronousMailConfig.groovy โ”‚ โ”œโ”€โ”€ application.yml โ”‚ โ””โ”€โ”€ logback.groovy โ”œโ”€โ”€ domain โ”œโ”€โ”€ init โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ Application.groovy โ”œโ”€โ”€ jobs โ”œโ”€โ”€ services โ””โ”€โ”€ views Barebone Grails 3 Plugin - grails-app Forked Project - grails-app Copy Files
  19. www.tothenew.com grails-app/ โ”œโ”€โ”€ assets โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ application.yml โ”‚

    โ””โ”€โ”€ logback.groovy โ”œโ”€โ”€ controllers โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ UrlMappings.groovy โ”œโ”€โ”€ domain โ”œโ”€โ”€ i18n โ”œโ”€โ”€ init โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ Application.groovy โ”œโ”€โ”€ services โ”œโ”€โ”€ taglib โ”œโ”€โ”€ utils โ””โ”€โ”€ views grails-app โ”œโ”€โ”€ assets โ”œโ”€โ”€ conf โ”‚ โ”œโ”€โ”€ application.yml โ”‚ โ”œโ”€โ”€ logback.groovy โ”‚ โ”œโ”€โ”€ BuildConfig.groovy โ”‚ โ”œโ”€โ”€ DataSource.groovy โ”‚ โ””โ”€โ”€ DefaultAsynchronousMailConfig.groovy โ”œโ”€โ”€ domain โ”œโ”€โ”€ init โ”‚ โ””โ”€โ”€ asynchronous โ”‚ โ””โ”€โ”€ mail โ”‚ โ””โ”€โ”€ Application.groovy โ”œโ”€โ”€ jobs โ”œโ”€โ”€ services โ””โ”€โ”€ views Barebone Grails 3 Plugin Forked Project Copy Files
  20. www.tothenew.com Forked Project โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ build.gradle โ”œโ”€โ”€

    gradle โ”œโ”€โ”€ gradle.properties โ”œโ”€โ”€ gradlew โ”œโ”€โ”€ gradlew.bat โ”œโ”€โ”€ grails-app โ”œโ”€โ”€ grails-asynchronous-mail.iml โ”œโ”€โ”€ scripts โ”œโ”€โ”€ src โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”œโ”€โ”€ java โ”‚ โ”œโ”€โ”€ integration-test โ”‚ โ”œโ”€โ”€ main โ”‚ โ”œโ”€โ”€ test โ”‚ โ””โ”€โ”€ templates โ”œโ”€โ”€ test โ”‚ โ”œโ”€โ”€ integration โ”‚ โ””โ”€โ”€ unit โ””โ”€โ”€ web-app โ””โ”€โ”€ css
  21. www.tothenew.com src/ โ”œโ”€โ”€ groovy โ”‚ โ””โ”€โ”€ grails โ”‚ โ””โ”€โ”€ plugin

    โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ”œโ”€โ”€ AsynchronousMailMessageBuilder.groovy โ”‚ โ””โ”€โ”€ AsynchronousMailMessageBuilderFactory. groovy โ”œโ”€โ”€ java โ”‚ โ””โ”€โ”€ grails โ”‚ โ””โ”€โ”€ plugin โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ””โ”€โ”€ Validator.java โ”œโ”€โ”€ templates โ””โ”€โ”€ webapp Now, move files from src to src/main src/ โ”œโ”€โ”€ integration-test โ”‚ โ””โ”€โ”€ groovy โ”œโ”€โ”€ main โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”‚ โ””โ”€โ”€ grails โ”‚ โ”‚ โ””โ”€โ”€ plugin โ”‚ โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ”‚ โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”‚ โ”‚ โ”œโ”€โ”€ AsynchronousMailMessageBuilder.groovy โ”‚ โ”‚ โ”œโ”€โ”€ AsynchronousMailMessageBuilderFactory.groovy โ”‚ โ”‚ โ””โ”€โ”€ enums โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ MessageStatus.groovy | | โ””โ”€โ”€ Validator.java โ”‚ โ”œโ”€โ”€ scripts โ”‚ โ”‚ โ””โ”€โ”€ CreateAsynchronousMailController.groovy โ”‚ โ””โ”€โ”€ templates โ”‚ โ””โ”€โ”€ test โ””โ”€โ”€ groovy Copy source files from src/groovy & src/java to src/main/g roovy
  22. www.tothenew.com src/ โ”œโ”€โ”€ integration-test โ”‚ โ””โ”€โ”€ groovy โ”‚ โ””โ”€โ”€ grails

    โ”‚ โ””โ”€โ”€ plugin โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ”œโ”€โ”€ AsyncMailServiceSpec.groovy โ”‚ โ”œโ”€โ”€ AsynchronousMailPersistenceServiceSpec.groovy โ”‚ โ””โ”€โ”€ AsynchronousMailServiceSpec.groovy โ”œโ”€โ”€ main โ”‚ โ”œโ”€โ”€ groovy โ”‚ โ”œโ”€โ”€ scripts โ”‚ โ””โ”€โ”€ templates โ””โ”€โ”€ test โ””โ”€โ”€ groovy โ””โ”€โ”€ grails โ””โ”€โ”€ plugin โ””โ”€โ”€ asyncmail โ”œโ”€โ”€ AsynchronousMailAttachmentSpec.groovy โ”œโ”€โ”€ AsynchronousMailMessageBuilderSpec.groovy โ”œโ”€โ”€ AsynchronousMailMessageSpec.groovy โ”œโ”€โ”€ AsynchronousMailProcessServiceSpec.groovy โ”œโ”€โ”€ CompareMessageBuilderSpec.groovy โ””โ”€โ”€ ValidatorSpec.groovy Move Unit & Integration Tests โ”œโ”€โ”€ AsynchronousMailGrailsPlugin.groovy โ”œโ”€โ”€ application.properties โ”œโ”€โ”€ grails-app โ”œโ”€โ”€ src โ”œโ”€โ”€ test โ”‚ โ”œโ”€โ”€ integration โ”‚ โ”‚ โ””โ”€โ”€ grails โ”‚ โ”‚ โ””โ”€โ”€ plugin โ”‚ โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ”‚ โ”œโ”€โ”€ AsynchronousMailMessageBuilderTests.groovy โ”‚ โ”‚ โ”œโ”€โ”€ AsynchronousMailPersistenceServiceTests. groovy โ”‚ โ”‚ โ””โ”€โ”€ AsynchronousMailTests.groovy โ”‚ โ””โ”€โ”€ unit โ”‚ โ””โ”€โ”€ grails โ”‚ โ””โ”€โ”€ plugin โ”‚ โ””โ”€โ”€ asyncmail โ”‚ โ”œโ”€โ”€ AsynchronousMailAttachmentTests.groovy โ”‚ โ”œโ”€โ”€ AsynchronousMailMessageTests.groovy โ”‚ โ”œโ”€โ”€ AsynchronousMailProcessServiceTests.groovy โ”‚ โ”œโ”€โ”€ AsynchronousMailSendServiceTests.groovy โ”‚ โ”œโ”€โ”€ CompareMessageBuildersTests.groovy โ”‚ โ””โ”€โ”€ ValidatorTests.java โ””โ”€โ”€ web-app Copy test case from test folder to src/test/ groovy & src/integ ration- test/groo vy
  23. www.tothenew.com Move Configurations grails.project.work.dir = 'target' grails.project.source.level = 1.6 grails.project.dependency.resolver

    = "maven" // or ivy grails.project.dependency.resolution = { inherits 'global' log 'warn' repositories { grailsCentral() grailsPlugins() grailsHome() mavenLocal() mavenCentral() // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories mavenRepo 'http://snapshots.repository.codehaus.org' mavenRepo 'http://repository.codehaus.org' mavenRepo 'http://download.java.net/maven/2/' mavenRepo 'http://repository.jboss.com/maven2/' } dependencies { compile "org.codehaus.gpars:gpars:1.2.1" } โ€ฆ buildscript { ext { grailsVersion = project.grailsVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" } } version "2.0.0.RC2" group "org.grails.plugins" apply plugin: 'idea' apply plugin:"org.grails.grails-plugin" apply plugin:"org.grails.grails-plugin-publish" apply plugin:"org.grails.grails-gsp" ext { grailsVersion = project.grailsVersion gradleWrapperVersion = project.gradleWrapperVersion } repositories { mavenLocal() maven { url "https://repo.grails.org/grails/core" } } dependencyManagement { imports { mavenBom "org.grails:grails-bom:$grailsVersion" } applyMavenExclusions false } โ€ฆ grails-app/conf/BuildConfig.groovy build.gradle Copy you maven repositories here Update plugin version and group
  24. www.tothenew.com Move Configurations grails.project.work.dir = 'target' grails.project.source.level = 1.6 grails.project.dependency.resolver

    = "maven" // or ivy grails.project.dependency.resolution = { inherits 'global' log 'warn' repositories { grailsCentral() grailsPlugins() grailsHome() mavenLocal() mavenCentral() // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories mavenRepo 'http://snapshots.repository.codehaus.org' mavenRepo 'http://repository.codehaus.org' mavenRepo 'http://download.java.net/maven/2/' mavenRepo 'http://repository.jboss.com/maven2/' } dependencies { compile "org.codehaus.gpars:gpars:1.2.1" } plugins { test(":hibernate:3.6.10.16") { export = false } compile(':mail:1.0.7'){ excludes 'spring-test' } compile ':quartz:1.0.2' build(':release:3.0.1', ':rest-client-builder:2.0.3') { export = false } } } โ€ฆ dependencyManagement { imports { mavenBom "org.grails:grails-bom:$grailsVersion" } applyMavenExclusions false } dependencies { 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-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" console "org.grails:grails-console" profile "org.grails.profiles:web-plugin:$grailsVersion" provided "org.grails:grails-plugin-services" provided "org.grails:grails-plugin-domain-class" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:hibernate4" compile "org.grails.plugins:mail:2.0.0.RC6" compile "org.grails.plugins:quartz:2.0.8" } task wrapper(type: Wrapper) { gradleVersion = gradleWrapperVersion } โ€ฆ grails-app/conf/BuildConfig.groovy build.gradle Copy plugins under dependencie s
  25. www.tothenew.com Move Configurations grails.project.work.dir = 'target' grails.project.source.level = 1.6 grails.project.dependency.resolver

    = "maven" // or ivy grails.project.dependency.resolution = { inherits 'global' log 'warn' repositories { grailsCentral() grailsPlugins() grailsHome() mavenLocal() mavenCentral() // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories mavenRepo 'http://snapshots.repository.codehaus.org' mavenRepo 'http://repository.codehaus.org' mavenRepo 'http://download.java.net/maven/2/' mavenRepo 'http://repository.jboss.com/maven2/' } dependencies { compile "org.codehaus.gpars:gpars:1.2.1" } plugins { test(":hibernate:3.6.10.16") { export = false } compile(':mail:1.0.7'){ excludes 'spring-test' } compile ':quartz:1.0.2' build(':release:3.0.1', ':rest-client-builder:2.0.3') { export = false } } } โ€ฆ task wrapper(type: Wrapper) { gradleVersion = gradleWrapperVersion } grailsPublish { userOrg = 'kefirsf' license { name = 'Apache-2.0' } websiteUrl = 'https://grails.org/plugin/asynchronous-mail' issueTrackerUrl = 'https://github.com/kefirfromperm/grails-asynchronous-mail/issues' vcsUrl = 'https://github.com/kefirfromperm/grails-asynchronous-mail.git' title = "Grails Asynchronous Mail plugin" desc = "The plugin realises asynchronous mail sending. It stores messages in a DB and sends them asynchronously by a quartz job." developers = [ kefirfromperm:"Vitalii Samolovskikh", stokito:"Sergey Ponomarev", ilopmar:"Ivรกn Lรณpez", burtbeckwith:"Burt Beckwith", puneetbehl:"Puneet Behl", aberbenni:"Alessandro Berbenni", dpcasady:"Danny Casady", SAgrawal14:"Shashank Agrawal", visheshd:"Vishesh", 'micke-a':"Mikael Andersson" ] } grails-app/conf/BuildConfig.groovy build.gradle Plugin-publish related configurations
  26. www.tothenew.com Move Configurations asynchronous.mail.default.attempt.interval=300000l // Five minutes asynchronous.mail.default.max.attempts.count=1 asynchronous.mail.send.repeat.interval=60000l //

    One minute asynchronous.mail.expired.collector.repeat.interval=607000l asynchronous.mail.messages.at.once=100 asynchronous.mail.send.immediately=true asynchronous.mail.override=false asynchronous.mail.clear.after.sent=false asynchronous.mail.disable=false asynchronous.mail.useFlushOnSave=true asynchronous.mail.persistence.provider='hibernate' // Possible values are 'hibernate', 'hibernate4', 'mongodb' asynchronous.mail.gparsPoolSize=1 asynchronous.mail.newSessionOnImmediateSend=false grails { profile = 'web-plugin' codegen { defaultPackage = 'grails.plugin.asyncmail' } } info { app { name = '@info.app.name@' version = '@info.app.version@' grailsVersion = '@info.app.grailsVersion@' } } spring { groovy { template."check-template-location" = false } } asynchronous.mail.default.attempt.interval=300000l // Five minutes asynchronous.mail.default.max.attempts.count=1 asynchronous.mail.send.repeat.interval=60000l // One minute asynchronous.mail.expired.collector.repeat.interval=607000l asynchronous.mail.messages.at.once=100 asynchronous.mail.send.immediately=true asynchronous.mail.clear.after.sent=false asynchronous.mail.disable=false asynchronous.mail.useFlushOnSave=true asynchronous.mail.persistence.provider='hibernate4' // Possible values are 'hibernate', 'hibernate4', 'mongodb' asynchronous.mail.newSessionOnImmediateSend=false โ€ฆ grails-app/conf/DefaultAsyncMailConfig.groovy application.groovy
  27. www.tothenew.com Move Configurations โ€ฆ asynchronous.mail.default.attempt.interval=300000l // Five minutes asynchronous.mail.default.max.attempts.count=1 asynchronous.mail.send.repeat.interval=60000l

    // One minute asynchronous.mail.expired.collector.repeat.interval=607000l asynchronous.mail.messages.at.once=100 asynchronous.mail.send.immediately=true asynchronous.mail.clear.after.sent=false asynchronous.mail.disable=false asynchronous.mail.useFlushOnSave=true asynchronous.mail.persistence.provider='hibernate4' // Possible values are 'hibernate', 'hibernate4', 'mongodb' asynchronous.mail.newSessionOnImmediateSend=false environments { test { dataSource { pooled = true jmxExport = true driverClassName = 'org.h2.Driver' username = 'sa' password = '' dbCreate = 'update' url = 'jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000; DB_CLOSE_ON_EXIT=FALSE' } quartz.jdbcStore = false } } application.groovy // environment specific settings environments { test { dataSource { pooled = true driverClassName = "org.h2.Driver" username = "sa" password = "" dbCreate = "create-drop" url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000" } hibernate { cache.use_second_level_cache = false cache.use_query_cache = false } } } grails-app/conf/DataSource.groovy
  28. www.tothenew.com โ€ข Extend the descriptor with grails.plugins.Plugin โ€ข Refer Plugin

    descriptor file from new plugin to copy and update all the required methods. โ€ข In addition you should remove the โ€œversionโ€ property from the descriptor as this is now defined in โ€œbuild.gradleโ€. Change Plugin Descriptor file
  29. www.tothenew.com โ€ข In Grails 3.x all internal APIs can be

    found in the org.grails package. โ€ข All public facing APIs in the grails package. โ—ฆ The โ€œorg.codehaus.groovy.grailsโ€ package no longer exists. โ—ฆ All package declaration in sources should be modified for the new location of the respective classes. Example org.codehaus.groovy.grails.commons. GrailsApplication is now grails.core.GrailsApplication. Modify Package Import
  30. www.tothenew.com โ€ข Delete the files which are no longer used,

    such as - โ—ฆ BuildConfig.groovy โ—ฆ Config.groovy โ—ฆ DataSource.groovy โ—ฆ Plugin Descriptor etc. Cleanup...
  31. www.tothenew.com Update Unit Test Cases package grails.plugin.asyncmail import grails.test.mixin.TestFor import

    spock.lang.Specification import static grails.plugin.asyncmail. AsynchronousMailAttachment.DEFAULT_MIME_TYPE @TestFor(AsynchronousMailAttachment) class AsynchronousMailAttachmentSpec extends Specification { void "testing default constructor"() { when: AsynchronousMailAttachment attachment = new AsynchronousMailAttachment() then: !attachment.attachmentName attachment.mimeType == DEFAULT_MIME_TYPE !attachment.content !attachment.inline } ... } import grails.test.mixin.TestFor /** * Attachment unit tests */ @TestFor(AsynchronousMailAttachment) class AsynchronousMailAttachmentTests { void testDefault(){ def attachment = new AsynchronousMailAttachment() assertNull attachment.attachmentName assertEquals AsynchronousMailAttachment.DEFAULT_MIME_TYPE, attachment.mimeType assertNull attachment.content assertFalse attachment.inline } โ€ฆ }
  32. www.tothenew.com Update Integration Test Cases package grails.plugin.asyncmail import grails.test.mixin.integration.Integration import

    grails.transaction.Rollback import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import static grails.plugin.asyncmail.enums.MessageStatus.CREATED @Integration @Rollback class AsynchronousMailServiceSpec extends Specification { public static final String VALUE_MAIL = '[email protected]' @Autowired AsynchronousMailService asynchronousMailService void testSendAsynchronousMail(){ when: asynchronousMailService.sendMail { to VALUE_MAIL subject 'Test' text 'Test' immediate false } AsynchronousMailMessage message = AsynchronousMailMessage. findAll()[0] then: VALUE_MAIL == message.to[0] CREATED == message.status } } package grails.plugin.asyncmail class AsynchronousMailTests extends GroovyTestCase { public static final String VALUE_MAIL = 'test@example. com' AsynchronousMailService asynchronousMailService; void testSendAsynchronousMail(){ asyncMailService.sendMail { to VALUE_MAIL subject 'Test' text 'Test' immediate false } AsynchronousMailMessage message = AsynchronousMailMessage.findAll()[0] assertEquals(VALUE_MAIL, message.to[0]) assertEquals(MessageStatus.CREATED, message.status) } }
  33. www.tothenew.com Checklist Before Sending Pull Request โ All unused files

    are removed/deleted. โ All unused imports are removed. โ All Unit/Integration test cases are passing. โ All functional tests are passing.
  34. www.tothenew.com Publish Plugin โ€ข Signup/Signin to https://bintray.com (one-click signin with

    GitHub or Twitter) โ€ข Create a new maven repository called plugins on your account โ€ข Edit โ€œbuild.gradleโ€ to customize default configurations โ€ข Now, to public run โ€œgradle bintrayUploadโ€
  35. www.tothenew.com Few useful tips โ€ข Default plugin configuration file ==

    plugin.(yml/groovy) โ€ข Travis Integration - Nicely indicates & reports if new changes and pull request breaks something in test cases โ€ข Demo Application โ€ข Goto Grails slack #questions & #plugin channel for more help โ€ข Use @Commons on plugin descriptor class or @Slf4j for log support โ€ข grails install to install plugin locally and use it direclty in your project