Index: event =================================================================== --- event (revision 0) +++ event (working copy) Property changes on: event ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,4 ## +.classpath +.project +.settings +target Index: event/pom.xml =================================================================== --- event/pom.xml (revision 0) +++ event/pom.xml (working copy) @@ -0,0 +1,69 @@ + + + + + + 4.0.0 + + + org.apache.karaf + cellar + 2.2.4-SNAPSHOT + ../pom.xml + + + org.apache.karaf.cellar + org.apache.karaf.cellar.event + bundle + Apache Karaf :: Cellar :: Event + + + UTF-8 + + !org.apache.karaf.cellar.event*, + org.apache.karaf.cellar.core*;version="${project.version}", + * + + javax.*,org.w3c.*,org.xml.* + + org.apache.karaf.cellar.event*;version="${project.version}" + + + + + + + org.apache.karaf.cellar + org.apache.karaf.cellar.core + + + + + org.apache.felix + org.apache.felix.configadmin + + + + + org.slf4j + slf4j-api + + + + Index: event/src/main/java/org/apache/karaf/cellar/event/Constants.java =================================================================== --- event/src/main/java/org/apache/karaf/cellar/event/Constants.java (revision 0) +++ event/src/main/java/org/apache/karaf/cellar/event/Constants.java (working copy) @@ -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"; + +} Index: event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java =================================================================== --- event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java (revision 0) +++ event/src/main/java/org/apache/karaf/cellar/event/EventSupport.java (working copy) @@ -0,0 +1,134 @@ +/* + * 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.framework.BundleContext; +import org.osgi.service.cm.ConfigurationAdmin; +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 BundleContext bundleContext; + + protected EventAdmin eventAdmin; + + /** + * Reads a {@code Event} object and creates a map object out of it. + * + * @param event + */ + public Map getEventProperties(Event event) { + String[] propertyNames = event.getPropertyNames(); + Map properties = new HashMap(); + + for (String name : propertyNames) { + Object property = event.getProperty(name); + + if (property instanceof Serializable) + properties.put(name, (Serializable)property); + } + + return properties; + } + + /** + * Reads a {@code Event} object and checks if a property exists. + * + * @param event + * @param name + */ + 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 + * @param properties + */ + public void postEvent(String topicName, Map properties) { + if (topicName == null) { + LOGGER.error("CELLAR EVENT: failed to post event"); + } + + final Event event = new Event(topicName, properties); + eventAdmin.postEvent(event); + } + + /** + * Send events via {@link EventAdmin}. + * + * @param topicName + * @param properties + */ + public void sendEvent(String topicName, Map properties) { + if (topicName == null) { + LOGGER.error("CELLAR EVENT: failed to send event"); + } + + final Event event = new Event(topicName, properties); + eventAdmin.sendEvent(event); + } + + /** + * Returns the {@link BundleContext}. + * + * @return + */ + public BundleContext getBundleContext() { + return this.bundleContext; + } + + /** + * Sets the {@link BundleContext}. + * + * @param bundleContext + */ + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + /** + * Sets the {@link EventAdmin}. + * + * @param eventAdmin + */ + public void setEventAdmin(EventAdmin eventAdmin) { + this.eventAdmin = eventAdmin; + } + + public ConfigurationAdmin getConfigurationAdmin() { + return configurationAdmin; + } + + public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) { + this.configurationAdmin = configurationAdmin; + } + +} Index: event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java =================================================================== --- event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java (revision 0) +++ event/src/main/java/org/apache/karaf/cellar/event/LocalEventListener.java (working copy) @@ -0,0 +1,113 @@ +/* + * 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 producerList; + + private Node node; + + /** + * Process {@link Event}s. + * + * @param event + */ + @Override + public void handleEvent(Event event) { + try { + if (event != null && event.getTopic() != null) { + Set groups = null; + try { + groups = groupManager.listLocalGroups(); + } catch (Exception ex) { + LOGGER.warn("Failed to list local groups. Is Cellar uninstalling ?"); + } + + // 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 properties = getEventProperties(event); + if (isAllowed(group, Constants.CATEGORY, topicName, EventType.OUTBOUND)) { + RemoteEvent remoteBundleEvent = new RemoteEvent(topicName, properties); + remoteBundleEvent.setSourceGroup(group); + remoteBundleEvent.setSourceNode(node); + + LOGGER.info("CELLAR EVENT: broadcast event {}", topicName); + + // broadcast the event + if (producerList != null && !producerList.isEmpty()) { + for (EventProducer producer : producerList) { + producer.produce(remoteBundleEvent); + } + } + } else LOGGER.debug("CELLAR EVENT: event {} is marked as BLOCKED OUTBOUND", topicName); + } + } + } + } catch (Exception ex) { + LOGGER.error("CELLAR EVENT: failed to handle event", ex); + } + } + + /** + * Initialization Method. + */ + public void init() { + if (clusterManager != null) { + node = clusterManager.getNode(); + } + } + + /** + * Destruction Method. + */ + public void destroy() { + + } + + public List getProducerList() { + return producerList; + } + + public void setProducerList(List producerList) { + this.producerList = producerList; + } + +} Index: event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java =================================================================== --- event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java (revision 0) +++ event/src/main/java/org/apache/karaf/cellar/event/RemoteEvent.java (working copy) @@ -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 java.io.Serializable; +import java.util.Map; + +import org.apache.karaf.cellar.core.event.Event; + +public class RemoteEvent extends Event { + + private String topicName; + private Map properties; + + public RemoteEvent(String topicName, Map properties) { + super(topicName); + this.topicName = topicName; + this.properties = properties; + } + + public String getTopicName() { + return topicName; + } + + public void setTopicName(String topicName) { + this.topicName = topicName; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} Index: event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java =================================================================== --- event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java (revision 0) +++ event/src/main/java/org/apache/karaf/cellar/event/RemoteEventHandler.java (working copy) @@ -0,0 +1,81 @@ +/* + * 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 java.io.Serializable; +import java.util.Map; + +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.EventHandler; +import org.apache.karaf.cellar.core.event.EventType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RemoteEventHandler extends EventSupport implements EventHandler { + + private static final 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; + + /** + * Handles remote events. + * + * @param event + */ + 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 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.debug("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(); + } + } + + /** + * Destruction Method. + */ + public void destroy() { + + } + + public Switch getSwitch() { + return eventSwitch; + } + + public Class getType() { + return RemoteEvent.class; + } + +} Index: event/src/main/resources/OSGI-INF/blueprint/blueprint.xml =================================================================== --- event/src/main/resources/OSGI-INF/blueprint/blueprint.xml (revision 0) +++ event/src/main/resources/OSGI-INF/blueprint/blueprint.xml (working copy) @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + org.osgi.service.event.EventHandler + + + + + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: pom.xml =================================================================== --- pom.xml (revision 1238193) +++ pom.xml (working copy) @@ -57,6 +57,7 @@ config features bundle + event obr dosgi shell