Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

init Spring II

  • Loading branch information...
commit 7b6da5de8d08d8211903e27172d37439ba618d78 0 parents
@smaldini authored
15 .gitignore
@@ -0,0 +1,15 @@
+*.iws
+*Db.properties
+*Db.script
+.settings
+stacktrace.log
+/*.zip
+/plugin.xml
+/*.log
+/*DB.*
+/cobertura.ser
+.DS_Store
+/target/
+/out/
+/web-app/plugins
+/web-app/WEB-INF/classes
93 EventsSiGrailsPlugin.groovy
@@ -0,0 +1,93 @@
+import org.grails.plugin.platform.events.publisher.SpringIntegrationEventsPublisher
+import org.grails.plugin.platform.events.publisher.EventsPublisherGateway
+import org.grails.plugin.platform.events.registry.SpringIntegrationEventsRegistry
+
+class EventsSiGrailsPlugin {
+ // the plugin version
+ def version = "1.0-beta"
+ // the version or versions of Grails the plugin is designed for
+ def grailsVersion = "2.0 > *"
+ // the other plugins this plugin depends on
+ def dependsOn = ['pluginPlatform': '1.0 > *']
+ // resources that are excluded from plugin packaging
+ def pluginExcludes = [
+ "grails-app/**"
+ ]
+
+ def loadAfter = ['pluginPlatform']
+
+ // TODO Fill in these fields
+ def title = "Events Si Plugin" // Headline display name of the plugin
+ def author = "Stephane Maldini"
+ def authorEmail = "stephane.maldini@gmail.com"
+ def description = '''\
+Standard Events system for Grails implementation.
+This plugin is a Spring Integration implementation and uses its artefacts to map listeners, senders and events messages.
+'''
+
+ // URL to the plugin's documentation
+ def documentation = "http://grails.org/plugin/events-si"
+
+ // Extra (optional) plugin metadata
+
+ // License: one of 'APACHE', 'GPL2', 'GPL3'
+ def license = "APACHE"
+
+ // Details of company behind the plugin (if there is one)
+ def organization = [name: "GrailsRocks", url: "http://www.grailsrocks.com/"]
+
+ // Any additional developers beyond the author specified above.
+ def developers = [[name: "Marc Palmer", email: "marc@anyware.co.uk"], [name: "Stephane Maldini", email: "stephane.maldini@gmail.com"]]
+
+ // Location of the plugin's issue tracker.
+// def issueManagement = [ system: "JIRA", url: "http://jira.grails.org/browse/GPMYPLUGIN" ]
+
+ // Online location of the plugin's browseable source code.
+// def scm = [ url: "http://svn.grails-plugins.codehaus.org/browse/grails-plugins/" ]
+
+ def doWithSpring = {
+// grailsEventsListener(DefaultEventsListener)
+// grailsEventsRegistry(DefaultEventsRegistry)
+
+ xmlns si: 'http://www.springframework.org/schema/integration'
+ xmlns task: "http://www.springframework.org/schema/task"
+
+ task.executor(id: "grailsTopicExecutor", 'pool-size': 10)//todo config
+
+ def grailsChannel = "grailsPipeline" //todo config
+
+ si.'publish-subscribe-channel'(id:grailsChannel)
+
+ si.'chain'('input-channel':grailsChannel){
+ si.'transformer'(expression:"payload.getData()")
+ si.'header-value-router'('header-name': EventsPublisherGateway.TARGET_CHANNEL)
+ }
+
+ si.gateway(
+ id: 'eventsPublisherGateway',
+ 'service-interface': EventsPublisherGateway.class.name,
+ 'default-request-channel': 'grailsPipeline'
+ ){
+ si.method(name:'sendAsync', requestChannel: grailsChannel)
+ si.method(name:'send', requestChannel: grailsChannel)
+ }
+
+ grailsEventsPublisher(SpringIntegrationEventsPublisher){
+ eventsPublisherGateway = ref('eventsPublisherGateway')
+ }
+ grailsEventsRegistry(SpringIntegrationEventsRegistry)
+ }
+
+
+
+ def onChange = { event ->
+ // TODO Implement code that is executed when any artefact that this plugin is
+ // watching is modified and reloaded. The event contains: event.source,
+ // event.application, event.manager, event.ctx, and event.plugin.
+ }
+
+ def onConfigChange = { event ->
+ // TODO Implement code that is executed when the project configuration changes.
+ // The event is the same as for 'onChange'.
+ }
+}
6 application.properties
@@ -0,0 +1,6 @@
+#Grails Metadata file
+#Mon Jan 02 17:14:49 CET 2012
+app.grails.version=2.0.0
+app.name=events-si
+app.version=0.1
+plugins.svn=1.0.1
32 grails-app/conf/BuildConfig.groovy
@@ -0,0 +1,32 @@
+grails.project.class.dir = "target/classes"
+grails.project.test.class.dir = "target/test-classes"
+grails.project.test.reports.dir = "target/test-reports"
+grails.project.target.level = 1.5
+//grails.project.war.file = "target/${appName}-${appVersion}.war"
+grails.plugin.location.'pluginPlatform' = '../../grails-plugin-platform'
+
+grails.project.dependency.resolution = {
+ inherits("global") {
+ excludes("xml-apis", "commons-digester")
+ }
+ log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
+ repositories {
+ grailsCentral()
+ }
+ dependencies {
+ runtime('org.springframework.integration:spring-integration-core:2.1.0.RC2') {
+ excludes 'spring-context', 'spring-aop'
+ }
+ // runtime 'mysql:mysql-connector-java:5.1.5'
+ }
+
+ plugins {
+ build(":tomcat:$grailsVersion",
+ ":release:1.0.0",
+ ":hibernate:$grailsVersion"
+ ) {
+ export = false
+ }
+
+ }
+}
24 grails-app/conf/Config.groovy
@@ -0,0 +1,24 @@
+// configuration for plugin testing - will not be included in the plugin zip
+
+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'
+
+ warn 'org.mortbay.log'
+}
26 grails-app/controllers/SampleController.groovy
@@ -0,0 +1,26 @@
+import org.grails.plugin.platform.events.Event
+/**
+ * @file
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @date 02/01/12
+
+ * @section DESCRIPTION
+ *
+ * [Does stuff]
+ */
+ class SampleController {
+
+ def grailsEventsPublisher
+
+ def test(){
+ grailsEventsPublisher.event(new Event(event:'sampleHello', data:"world"))
+ println "ok"
+ grailsEventsPublisher.eventAsync(new Event(event: 'sampleHello', data:"world 2"))
+ println "ok async"
+ grailsEventsPublisher.eventAsync(new Event(event: 'sampleHello', data:"world 3")).get()
+ println "ok async wait"
+
+ render "ok"
+ }
+}
19 grails-app/services/SampleService.groovy
@@ -0,0 +1,19 @@
+import org.grails.plugin.platform.events.Listener
+/**
+ * @file
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @date 02/01/12
+
+ * @section DESCRIPTION
+ *
+ * [Does stuff]
+ */
+ class SampleService {
+
+
+ @Listener('sampleHello')
+ def testEvent(data){
+ println "Hello $data"
+ }
+}
11 grails-app/views/error.gsp
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Grails Runtime Exception</title>
+ <meta name="layout" content="main">
+ <link rel="stylesheet" href="${resource(dir: 'css', file: 'errors.css')}" type="text/css">
+ </head>
+ <body>
+ <g:renderException exception="${exception}" />
+ </body>
+</html>
13 src/java/org/grails/plugin/platform/events/dispatcher/SprintIntegrationEventsDispatcher.java
@@ -0,0 +1,13 @@
+package org.grails.plugin.platform.events.dispatcher;
+
+/**
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @file
+ * @date 02/01/12
+ * @section DESCRIPTION
+ * <p/>
+ * [Does stuff]
+ */
+public class SprintIntegrationEventsDispatcher {
+}
24 src/java/org/grails/plugin/platform/events/publisher/EventsPublisherGateway.java
@@ -0,0 +1,24 @@
+package org.grails.plugin.platform.events.publisher;
+
+import org.grails.plugin.platform.events.Event;
+import org.springframework.integration.annotation.Header;
+
+import java.util.concurrent.Future;
+
+/**
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @file
+ * @date 02/01/12
+ * @section DESCRIPTION
+ * <p/>
+ * [Does stuff]
+ */
+public interface EventsPublisherGateway {
+
+ public static final String TARGET_CHANNEL = "targetChannel";
+
+ public Object send(Event event, @Header(TARGET_CHANNEL) String targetChannel);
+
+ public Future<Object> sendAsync(Event event, @Header(TARGET_CHANNEL) String targetChannel);
+}
40 src/java/org/grails/plugin/platform/events/publisher/SpringIntegrationEventsPublisher.java
@@ -0,0 +1,40 @@
+package org.grails.plugin.platform.events.publisher;
+
+import org.grails.plugin.platform.events.Event;
+import org.grails.plugin.platform.events.registry.EventsRegistry;
+import org.springframework.integration.Message;
+import org.springframework.integration.message.GenericMessage;
+
+import java.util.concurrent.Future;
+
+/**
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @file
+ * @date 02/01/12
+ * @section DESCRIPTION
+ * <p/>
+ * [Does stuff]
+ */
+public class SpringIntegrationEventsPublisher implements EventsPublisher {
+
+
+ private EventsPublisherGateway eventsPublisherGateway;
+
+ public void setEventsPublisherGateway(EventsPublisherGateway eventsPublisherGateway) {
+ this.eventsPublisherGateway = eventsPublisherGateway;
+ }
+
+ public Object event(Event event) {
+ return eventsPublisherGateway.send(event, EventsRegistry.GRAILS_TOPIC_PREFIX+event.getEvent());
+ }
+
+ public Future<Object> eventAsync(Event event) {
+ return eventsPublisherGateway.sendAsync(event, EventsRegistry.GRAILS_TOPIC_PREFIX+event.getEvent());
+ }
+
+ public void eventAsync(Event event, Runnable onComplete) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+}
72 src/java/org/grails/plugin/platform/events/registry/SpringIntegrationEventsRegistry.java
@@ -0,0 +1,72 @@
+package org.grails.plugin.platform.events.registry;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.integration.channel.PublishSubscribeChannel;
+import org.springframework.integration.handler.ServiceActivatingHandler;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author Stephane Maldini <smaldini@doc4web.com>
+ * @version 1.0
+ * @file
+ * @date 02/01/12
+ * @section DESCRIPTION
+ * <p/>
+ * [Does stuff]
+ */
+public class SpringIntegrationEventsRegistry implements EventsRegistry, BeanFactoryAware, ApplicationContextAware {
+
+ static final private Logger log = Logger.getLogger(SpringIntegrationEventsRegistry.class);
+
+ private ApplicationContext ctx;
+ private ConfigurableBeanFactory beanFactory;
+
+ private PublishSubscribeChannel getOrCreateChannel(String topic) {
+ if (topic == null || topic.isEmpty()) {
+ throw new RuntimeException("topic name must not be null or empty");
+ }
+
+ String channelName = GRAILS_TOPIC_PREFIX + topic;
+ PublishSubscribeChannel channel = null;
+
+ try{
+ channel = ctx.getBean(channelName, PublishSubscribeChannel.class);
+ }catch(BeansException be){
+ log.debug("creating channel because "+be.getMessage());
+ }
+
+ if (channel == null) {
+ channel = new PublishSubscribeChannel();
+ channel.setBeanName(channelName);
+ beanFactory.registerSingleton(channelName, channel);
+ }
+ return channel;
+ }
+
+ public void addListener(String topic, Object bean, String callbackName) {
+ PublishSubscribeChannel channel = getOrCreateChannel(topic);
+ ServiceActivatingHandler serviceActivatingHandler = new ServiceActivatingHandler(bean, callbackName);
+ channel.subscribe(serviceActivatingHandler);
+ }
+
+ public void addListener(String topic, Object bean, Method callback) {
+ PublishSubscribeChannel channel = getOrCreateChannel(topic);
+ ServiceActivatingHandler serviceActivatingHandler = new ServiceActivatingHandler(bean, callback);
+ channel.subscribe(serviceActivatingHandler);
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.ctx = applicationContext;
+ }
+
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ this.beanFactory = (ConfigurableBeanFactory) beanFactory;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.