You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2012/02/01 15:49:37 UTC

svn commit: r1239154 - in /karaf/cellar/trunk: ./ assembly/src/main/resources/ event/ event/src/ event/src/main/ event/src/main/java/ event/src/main/java/org/ event/src/main/java/org/apache/ event/src/main/java/org/apache/karaf/ event/src/main/java/org...

Author: jbonofre
Date: Wed Feb  1 14:49:36 2012
New Revision: 1239154

URL: http://svn.apache.org/viewvc?rev=1239154&view=rev
Log:
[KARAF-1176] Add support of OSGi events broadcasting

Added:
    karaf/cellar/trunk/event/
    karaf/cellar/trunk/event/NOTICE
    karaf/cellar/trunk/event/pom.xml
    karaf/cellar/trunk/event/src/
    karaf/cellar/trunk/event/src/main/
    karaf/cellar/trunk/event/src/main/java/
    karaf/cellar/trunk/event/src/main/java/org/
    karaf/cellar/trunk/event/src/main/java/org/apache/
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/Constants.java
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java
    karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java
    karaf/cellar/trunk/event/src/main/resources/
    karaf/cellar/trunk/event/src/main/resources/OSGI-INF/
    karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/
    karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/blueprint.xml
    karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarEventTest.java
    karaf/cellar/trunk/manual/src/main/webapp/user-guide/event.conf
Modified:
    karaf/cellar/trunk/assembly/src/main/resources/features.xml
    karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarTestSupport.java
    karaf/cellar/trunk/manual/src/main/webapp/manual.conf
    karaf/cellar/trunk/manual/src/main/webapp/user-guide/index.conf
    karaf/cellar/trunk/pom.xml

Modified: karaf/cellar/trunk/assembly/src/main/resources/features.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/assembly/src/main/resources/features.xml?rev=1239154&r1=1239153&r2=1239154&view=diff
==============================================================================
--- karaf/cellar/trunk/assembly/src/main/resources/features.xml (original)
+++ karaf/cellar/trunk/assembly/src/main/resources/features.xml Wed Feb  1 14:49:36 2012
@@ -52,13 +52,19 @@
         </configfile>
     </feature>
 
-    <feature name='cellar-obr' description='Alias to org.apache.karaf.cellar.features.obr feature' version='${project.version}' resolver='(obr)'>
+    <feature name='cellar-obr' description='OBR support in Cellar clusters' version='${project.version}' resolver='(obr)'>
         <feature>obr</feature>
         <feature version='${project.version}'>cellar</feature>
         <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.obr/${project.version}</bundle>
     </feature>
 
-    <feature name='cellar-cloud' description='Alias to org.apache.karaf.cellar.features.cloud feature' version='${project.version}' resolver='(obr)'>
+    <feature name='cellar-event' description='OSGi events broadcasting in Cellar clusters' version='${project.version}' resolver='(obr)'>
+        <feature>eventadmin</feature>
+        <feature version='${project.version}'>cellar</feature>
+        <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.event/${project.version}</bundle>
+    </feature>
+
+    <feature name='cellar-cloud' description='Cloud blobstore support in Cellar clusters' version='${project.version}' resolver='(obr)'>
         <feature version="${project.version}">cellar</feature>
         <feature version="${jclouds.version}">jclouds</feature>
         <!-- Adding S3 as the default Blobstore -->
@@ -67,7 +73,7 @@
         <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.cloud/${project.version}</bundle>
     </feature>
 
-    <feature name='cellar-webconsole' description='Alias to org.apache.karaf.cellar.features.webconsole feature' version='${project.version}' resolver='(obr)'>
+    <feature name='cellar-webconsole' description='Karaf WebConsole plug for Cellar' version='${project.version}' resolver='(obr)'>
         <feature version="${project.version}">cellar</feature>
         <feature>webconsole</feature>
         <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.webconsole/${project.version}</bundle>

Added: karaf/cellar/trunk/event/NOTICE
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/NOTICE?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/NOTICE (added)
+++ karaf/cellar/trunk/event/NOTICE Wed Feb  1 14:49:36 2012
@@ -0,0 +1,48 @@
+Apache Karaf Cellar
+Copyright 2011 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software written by
+Antony Lesuisse.
+Licensed under Public Domain.
+
+
+II. Used Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+OPS4J (http://www.ops4j.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+FUSE Source (http://www.fusesource.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JClouds (http://www.jclouds.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JLine (http://jline.sourceforge.net).
+Licensed under the BSD License.
+
+This product uses software developed at
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product includes software from http://www.json.org.
+Copyright (c) 2002 JSON.org
+
+
+III. License Summary
+- Apache License 2.0

Added: karaf/cellar/trunk/event/pom.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/pom.xml?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/pom.xml (added)
+++ karaf/cellar/trunk/event/pom.xml Wed Feb  1 14:49:36 2012
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        Licensed to the Apache Software Foundation (ASF) under one or more
+        contributor license agreements.  See the NOTICE file distributed with
+        this work for additional information regarding copyright ownership.
+        The ASF licenses this file to You under the Apache License, Version 2.0
+        (the "License"); you may not use this file except in compliance with
+        the License.  You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an "AS IS" BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf</groupId>
+        <artifactId>cellar</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.cellar</groupId>
+    <artifactId>org.apache.karaf.cellar.event</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: Cellar :: Event Support</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <osgi.import>
+            !org.apache.karaf.cellar.event*,
+            org.apache.karaf.cellar.core*;version="${project.version}",
+            *
+        </osgi.import>
+        <osgi.dynamic.import>javax.*,org.w3c.*,org.xml.*</osgi.dynamic.import>
+        <osgi.export>
+            org.apache.karaf.cellar.event*;version="${project.version}"
+        </osgi.export>
+    </properties>
+
+    <dependencies>
+        <!-- Internal Dependencies -->
+        <dependency>
+            <groupId>org.apache.karaf.cellar</groupId>
+            <artifactId>org.apache.karaf.cellar.core</artifactId>
+        </dependency>
+
+        <!-- Logging Dependencies -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>
\ No newline at end of file

Added: karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/Constants.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/Constants.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/Constants.java (added)
+++ karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/Constants.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,24 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.event;
+
+public class Constants {
+
+    public static final String CATEGORY = "event";
+    public static final String EVENT_PROCESSED_KEY = "org.apache.karaf.cellar.event.processed";
+    public static final String EVENT_PROCESSED_VALUE = "true";
+    public static final String EVENT_SOURCE_GROUP_KEY = "org.apache.karaf.cellar.event.source.group";
+    public static final String EVENT_SOURCE_NODE_KEY = "org.apache.karaf.cellar.event.source.node";
+
+}

Added: karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java (added)
+++ karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,108 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.event;
+
+import org.apache.karaf.cellar.core.CellarSupport;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class EventSupport extends CellarSupport {
+    
+    protected EventAdmin eventAdmin;
+
+    /**
+     * Reads a {@code Event} object and creates a map object out of it.
+     *
+     * @param event the event to read
+     * @return the map
+     */
+    public Map<String, Serializable> getEventProperties(Event event) {
+        String[] propertyNames = event.getPropertyNames();
+
+        Map<String, Serializable> properties = new HashMap<String, Serializable>();
+
+        for (String propertyName : propertyNames) {
+            Object property = event.getProperty(propertyName);
+            if (property instanceof Serializable) {
+                properties.put(propertyName, (Serializable) property);
+            }
+        }
+        
+        return properties;
+    }
+
+    /**
+     * Reads {@code Event} object and checks if a property exists.
+     *
+     * @param event the event to read.
+     * @param name  the property name to check.
+     * @return true if the property exists in the event, false else.
+     */
+    public boolean hasEventProperty(Event event, String name) {
+        String[] propertyNames = event.getPropertyNames();
+
+        for (String propertyName : propertyNames) {
+            if (propertyName.equals(name)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Post events via {@link EventAdmin}.
+     *
+     * @param topicName the topic name.
+     * @param properties the event properties.
+     */
+    public void postEvent(String topicName, Map<String, Serializable> properties) {
+        if (topicName == null) {
+            LOGGER.error("CELLAR EVENT: failed to post event");
+            return;
+        }
+
+        final Event event = new Event(topicName, properties);
+        eventAdmin.postEvent(event);
+    }
+
+    /**
+     * Send events via {@link EventAdmin}.
+     *
+     * @param topicName the topic name.
+     * @param properties the event properties.
+     */
+    public void sendEvent(String topicName, Map<String, Serializable> properties) {
+        if (topicName == null) {
+            LOGGER.error("CELLAR EVENT: failed to send event");
+            return;
+        }
+
+        final Event event = new Event(topicName, properties);
+        eventAdmin.sendEvent(event);
+    }
+
+    public EventAdmin getEventAdmin() {
+        return this.eventAdmin;
+    }
+
+    public void setEventAdmin(EventAdmin eventAdmin) {
+        this.eventAdmin = eventAdmin;
+    }
+
+}

Added: karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java (added)
+++ karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,108 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.event;
+
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.Node;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.event.EventType;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class LocalEventListener extends EventSupport implements EventHandler {
+
+    private static final transient Logger LOGGER = LoggerFactory.getLogger(LocalEventListener.class);
+
+    private List<EventProducer> producerList;
+
+    private Node node;
+
+    @Override
+    public void handleEvent(Event event) {
+        try {
+            if (event != null && event.getTopic() != null) {
+                Set<Group> groups = null;
+                try {
+                    groups = groupManager.listLocalGroups();
+                } catch (Exception e) {
+                    LOGGER.warn("Failed to list local groups. Is Cellar uninstalling ?");
+                    return;
+                }
+
+                // filter already processed events
+                if (hasEventProperty(event, Constants.EVENT_PROCESSED_KEY)) {
+                    if (event.getProperty(Constants.EVENT_PROCESSED_KEY).equals(Constants.EVENT_PROCESSED_VALUE)){
+                        LOGGER.debug("CELLAR EVENT: filtered out event {}", event.getTopic());
+                        return;
+                    }
+                }
+
+                if (groups != null && !groups.isEmpty()) {
+                    for (Group group : groups) {
+                        String topicName = event.getTopic();
+                        Map<String, Serializable> properties = getEventProperties(event);
+                        if (isAllowed(group, Constants.CATEGORY, topicName, EventType.OUTBOUND)) {
+                            RemoteEvent remoteEvent = new RemoteEvent(topicName, properties);
+                            remoteEvent.setSourceGroup(group);
+                            remoteEvent.setSourceNode(node);
+                            
+                            LOGGER.debug("CELLAR EVENT: broadcast event {}", topicName);
+
+                            // broadcast the event
+                            if (producerList != null && !producerList.isEmpty()) {
+                                for (EventProducer producer : producerList) {
+                                    producer.produce(remoteEvent);
+                                }
+                            }
+                        } else LOGGER.warn("CELLAR EVENT: event {} is marked as BLOCKED OUTBOUND", topicName);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("CELLAR EVENT: failed to handle event", e);
+        }
+    }
+
+    /**
+     * Initialization method.
+     */
+    public void init() {
+        if (clusterManager != null) {
+            node = clusterManager.getNode();
+        }
+    }
+
+    /**
+     * Destruction method.
+     */
+    public void destroy() {
+
+    }
+
+    public List<EventProducer> getProducerList() {
+        return producerList;
+    }
+
+    public void setProducerList(List<EventProducer> producerList) {
+        this.producerList = producerList;
+    }
+
+}

Added: karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java (added)
+++ karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,48 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.event;
+
+import org.apache.karaf.cellar.core.event.Event;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class RemoteEvent extends Event {
+
+    private String topicName;
+    private Map<String, Serializable> properties;
+
+    public RemoteEvent(String topicName, Map<String, Serializable> properties) {
+        super(topicName);
+        this.topicName = topicName;
+        this.properties = properties;
+    }
+
+    public String getTopicName() {
+        return this.topicName;
+    }
+    
+    public void setTopicName(String topicName) {
+        this.topicName = topicName;
+    }
+
+    public Map<String, Serializable> getProperties() {
+        return this.properties;
+    }
+
+    public void setProperties(Map<String, Serializable> properties) {
+        this.properties = properties;
+    }
+
+}

Added: karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java (added)
+++ karaf/cellar/trunk/event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,76 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.cellar.event;
+
+import org.apache.karaf.cellar.core.Node;
+import org.apache.karaf.cellar.core.control.BasicSwitch;
+import org.apache.karaf.cellar.core.control.Switch;
+import org.apache.karaf.cellar.core.event.Event;
+import org.apache.karaf.cellar.core.event.EventHandler;
+import org.apache.karaf.cellar.core.event.EventType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class RemoteEventHandler extends EventSupport implements EventHandler<RemoteEvent> {
+
+    private static final transient Logger LOGGER = LoggerFactory.getLogger(RemoteEventHandler.class);
+
+    public static final String SWITCH_ID = "org.apache.karaf.cellar.event.handler";
+    private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
+
+    private Node node;
+
+    public void handle(RemoteEvent event) {
+        try {
+            // check if the pid is marked as local
+            if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, event.getTopicName(), EventType.INBOUND)) {
+                Map<String, Serializable> properties = event.getProperties();
+                properties.put(Constants.EVENT_PROCESSED_KEY, Constants.EVENT_PROCESSED_VALUE);
+                properties.put(Constants.EVENT_SOURCE_GROUP_KEY, event.getSourceGroup());
+                properties.put(Constants.EVENT_SOURCE_NODE_KEY, event.getSourceNode());
+                postEvent(event.getTopicName(), properties);
+            } else LOGGER.warn("CELLAR EVENT: event {} is marked as BLOCKED INBOUND", event.getTopicName());
+        } catch (Exception e) {
+            LOGGER.error("CELLAR EVENT: failed to handle event", e);
+        }
+    }
+
+    /**
+     * Initialization method.
+     */
+    public void init() {
+        if (clusterManager != null) {
+            node = clusterManager.getNode();
+        }
+    }
+
+    /**
+     * Destroy method.
+     */
+    public void destroy() {
+
+    }
+
+    public Switch getSwitch() {
+        return eventSwitch;
+    }
+    
+    public Class<RemoteEvent> getType() {
+        return RemoteEvent.class;
+    }
+
+}

Added: karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/blueprint.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/blueprint.xml?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/blueprint.xml (added)
+++ karaf/cellar/trunk/event/src/main/resources/OSGI-INF/blueprint/blueprint.xml Wed Feb  1 14:49:36 2012
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <!-- Cluster Configuration Listener -->
+    <bean id="localEventListener" class="org.apache.karaf.cellar.event.LocalEventListener" init-method="init" destroy-method="destroy">
+        <property name="producerList" ref="groupEventProducers"/>
+        <property name="clusterManager" ref="clusterManager"/>
+        <property name="groupManager" ref="groupManager"/>
+        <property name="configurationAdmin" ref="configurationAdmin"/>
+    </bean>
+
+    <!-- Event Handler -->
+    <bean id="remoteEventHandler" class="org.apache.karaf.cellar.event.RemoteEventHandler" init-method="init" destroy-method="destroy">
+        <property name="configurationAdmin" ref="configurationAdmin"/>
+        <property name="clusterManager" ref="clusterManager"/>
+        <property name="eventAdmin" ref="eventAdmin"/>
+    </bean>
+
+    <!-- OSGi Service & References -->
+    <service ref="localEventListener">
+        <interfaces>
+            <value>org.osgi.service.event.EventHandler</value>
+        </interfaces>
+        <service-properties>
+            <entry key="event.topics">
+                <array value-type="java.lang.String">
+                    <value>*</value>
+                </array>
+            </entry>
+        </service-properties>
+    </service>
+
+    <service ref="remoteEventHandler" interface="org.apache.karaf.cellar.core.event.EventHandler">
+        <service-properties>
+            <entry key="managed" value="true"/>
+        </service-properties>
+    </service>
+
+    <reference id="clusterManager" interface="org.apache.karaf.cellar.core.ClusterManager"/>
+    <reference id="groupManager" interface="org.apache.karaf.cellar.core.GroupManager"/>
+    <reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>
+    <reference id="eventAdmin" interface="org.osgi.service.event.EventAdmin" />
+    <reference id="eventProducer" interface="org.apache.karaf.cellar.core.event.EventProducer"/>
+    <reference-list id="groupEventProducers" member-type="service-object"
+        interface="org.apache.karaf.cellar.core.event.EventProducer" filter="(type=group)"/>
+
+</blueprint>
\ No newline at end of file

Added: karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarEventTest.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarEventTest.java?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarEventTest.java (added)
+++ karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarEventTest.java Wed Feb  1 14:49:36 2012
@@ -0,0 +1,60 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.karaf.cellar.itests;
+
+import org.apache.karaf.cellar.core.ClusterManager;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openengsb.labs.paxexam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ExamReactorStrategy;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
+
+import static org.junit.Assert.assertNotNull;
+import static org.openengsb.labs.paxexam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.openengsb.labs.paxexam.karaf.options.KarafDistributionOption.logLevel;
+
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class CellarEventTest extends CellarTestSupport {
+
+    @Test
+    public void testCellarEventSupport() throws Exception {
+        installCellar();
+        Thread.sleep(DEFAULT_TIMEOUT);
+        ClusterManager clusterManager = getOsgiService(ClusterManager.class);
+        assertNotNull(clusterManager);
+        
+        System.err.println(executeCommand("features:install cellar-event"));
+    }
+
+    @After
+    public void tearDown() {
+        try {
+            unInstallCellar();
+        } catch (Exception ex) {
+            //Ignore
+        }
+    }
+
+    @Configuration
+    public Option[] config() {
+        return new Option[]{
+                cellarDistributionConfiguration(), keepRuntimeFolder(), logLevel(LogLevelOption.LogLevel.ERROR)};
+    }
+
+}

Modified: karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarTestSupport.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarTestSupport.java?rev=1239154&r1=1239153&r2=1239154&view=diff
==============================================================================
--- karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarTestSupport.java (original)
+++ karaf/cellar/trunk/itests/src/test/java/org/apache/karaf/cellar/itests/CellarTestSupport.java Wed Feb  1 14:49:36 2012
@@ -109,9 +109,9 @@ public class CellarTestSupport {
      * Installs the Cellar feature
      */
     protected void installCellar() {
-        System.err.println(executeCommand("feature:add-url " + CELLAR_FEATURE_URL));
-        System.err.println(executeCommand("feature:list-url"));
-        System.err.println(executeCommand("feature:list"));
+        System.err.println(executeCommand("features:addurl " + CELLAR_FEATURE_URL));
+        System.err.println(executeCommand("features:listurl"));
+        System.err.println(executeCommand("features:list"));
         executeCommand("features:install cellar");
     }
 
@@ -160,7 +160,7 @@ public class CellarTestSupport {
      * Destroys the child node.
      */
     protected void destroyCellarChild(String name) {
-        System.err.println(executeCommand("admin:connect " + name + " feature:uninstall cellar"));
+        System.err.println(executeCommand("admin:connect " + name + " features:uninstall cellar"));
         System.err.println(executeCommand("admin:stop " + name));
     }
 

Modified: karaf/cellar/trunk/manual/src/main/webapp/manual.conf
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/manual/src/main/webapp/manual.conf?rev=1239154&r1=1239153&r2=1239154&view=diff
==============================================================================
--- karaf/cellar/trunk/manual/src/main/webapp/manual.conf (original)
+++ karaf/cellar/trunk/manual/src/main/webapp/manual.conf Wed Feb  1 14:49:36 2012
@@ -34,6 +34,7 @@ h1. User Guide
 {include:user-guide/nodes.conf}
 {include:user-guide/groups.conf}
 {include:user-guide/obr.conf}
+{include:user-guide/event.conf}
 {include:user-guide/cloud.conf}
 
 h1. Architecture Guide

Added: karaf/cellar/trunk/manual/src/main/webapp/user-guide/event.conf
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/manual/src/main/webapp/user-guide/event.conf?rev=1239154&view=auto
==============================================================================
--- karaf/cellar/trunk/manual/src/main/webapp/user-guide/event.conf (added)
+++ karaf/cellar/trunk/manual/src/main/webapp/user-guide/event.conf Wed Feb  1 14:49:36 2012
@@ -0,0 +1,21 @@
+h1. OSGi Event Broadcasting support
+
+Apache Karaf Cellar is able to listen all OSGi events on the cluster nodes, and broadcast each events to other nodes.
+
+h2. Enable OSGi Event Broadcasting support
+
+OSGi Event Broadcasting is an optional feature. To enable it, you have to install the cellar-event feature:
+
+{code}
+karaf@root> feature:install cellar-event
+{code}
+
+Of course, it Cellar is already installed, you can use Cellar itself to install cellar-event feature on all nodes:
+
+{code}
+karaf@root> cluster:feature-install group cellar-event
+{code}
+
+h2. OSGi Event Broadcast in action
+
+As soon as the cellar-event feature is installed, Cellar listens all OSGi events, and broadcast these events to all nodes of the same cluster group.
\ No newline at end of file

Modified: karaf/cellar/trunk/manual/src/main/webapp/user-guide/index.conf
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/manual/src/main/webapp/user-guide/index.conf?rev=1239154&r1=1239153&r2=1239154&view=diff
==============================================================================
--- karaf/cellar/trunk/manual/src/main/webapp/user-guide/index.conf (original)
+++ karaf/cellar/trunk/manual/src/main/webapp/user-guide/index.conf Wed Feb  1 14:49:36 2012
@@ -5,4 +5,5 @@ h1. Karaf Cellar User Guide
 * [Nodes in Karaf Cellar|/user-guide/nodes]
 * [Groups in Karaf Cellar|/user-guide/groups]
 * [OBR in Karaf Cellar|/user-guide/obr]
+* [OSGi Event broadcast with Karaf Cellar|/user-guide/event]
 * [Cellar Cloud Discovery|/user-guide/cloud]

Modified: karaf/cellar/trunk/pom.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/pom.xml?rev=1239154&r1=1239153&r2=1239154&view=diff
==============================================================================
--- karaf/cellar/trunk/pom.xml (original)
+++ karaf/cellar/trunk/pom.xml Wed Feb  1 14:49:36 2012
@@ -59,6 +59,7 @@
         <module>bundle</module>
         <module>obr</module>
         <module>dosgi</module>
+        <module>event</module>
         <module>shell</module>
         <module>hazelcast</module>
         <module>utils</module>