You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by io...@apache.org on 2011/05/19 20:20:03 UTC

svn commit: r1125040 - in /karaf/cellar/trunk: ./ bundle/ bundle/src/ bundle/src/main/ bundle/src/main/java/ bundle/src/main/java/org/ bundle/src/main/java/org/apache/ bundle/src/main/java/org/apache/karaf/ bundle/src/main/java/org/apache/karaf/cellar/...

Author: iocanel
Date: Thu May 19 18:20:02 2011
New Revision: 1125040

URL: http://svn.apache.org/viewvc?rev=1125040&view=rev
Log:
[KARAF-628] Added cellar event,synchronizer,listener and handler for replicating bundle states

Added:
    karaf/cellar/trunk/bundle/
    karaf/cellar/trunk/bundle/pom.xml
    karaf/cellar/trunk/bundle/src/
    karaf/cellar/trunk/bundle/src/main/
    karaf/cellar/trunk/bundle/src/main/java/
    karaf/cellar/trunk/bundle/src/main/java/org/
    karaf/cellar/trunk/bundle/src/main/java/org/apache/
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleState.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSupport.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java
    karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/RemoteBundleEvent.java
    karaf/cellar/trunk/bundle/src/main/resources/
    karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/
    karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/
    karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
Modified:
    karaf/cellar/trunk/pom.xml
    karaf/cellar/trunk/src/main/resources/feature.xml

Added: karaf/cellar/trunk/bundle/pom.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/pom.xml?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/pom.xml (added)
+++ karaf/cellar/trunk/bundle/pom.xml Thu May 19 18:20:02 2011
@@ -0,0 +1,69 @@
+<?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.bundle</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: Cellar :: Bundle</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <osgi.import>
+            !org.apache.karaf.cellar.bundle*,
+            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.bundle*;version="${project.version}"
+        </osgi.export>
+    </properties>
+
+    <dependencies>
+        <!-- Internal Dependencies -->
+        <dependency>
+            <groupId>org.apache.karaf.cellar</groupId>
+            <artifactId>org.apache.karaf.cellar.core</artifactId>
+        </dependency>
+
+        <!-- Configuration Admin -->
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configadmin</artifactId>
+        </dependency>
+
+        <!-- Logging Dependencies -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleEventHandler.java Thu May 19 18:20:02 2011
@@ -0,0 +1,111 @@
+/*
+ * 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.bundle;
+
+
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+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.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * @author iocanel
+ */
+public class BundleEventHandler extends BundleSupport implements EventHandler<RemoteBundleEvent> {
+
+	private static final Logger logger = LoggerFactory.getLogger(BundleEventHandler.class);
+	public static final String SWITCH_ID = "com.upstreamsystems.curry.cluster.bundle.handler";
+
+	private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
+    private Node node;
+
+	/**
+	 * Handles remote bundle events.
+	 * @param event
+	 */
+	public void handle(RemoteBundleEvent event) {
+
+        if (event == null || event.getSourceGroup() == null || node == null || node.equals(event.getSourceNode()))
+            return;
+
+        Group group = event.getSourceGroup();
+        String groupName = group.getName();
+        String bundleLocation = event.getLocation();
+
+        Map<String, BundleState> bundleTable = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+
+		try {
+             //Check if the pid is marked as local.
+            if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, bundleLocation, EventType.INBOUND)) {
+				BundleState state = new BundleState();
+				state.setLocation(event.getLocation());
+				state.setStatus(event.getType());
+
+				if(event.getType() == BundleEvent.INSTALLED) {
+					installBundleFromLocation(event.getLocation());
+					bundleTable.put(event.getId(),state);
+				} else if(event.getType() == BundleEvent.UNINSTALLED) {
+					uninstallBundle(event.getSymbolicName(), event.getVersion());
+					bundleTable.remove(event.getId());
+				} else if(event.getType() == BundleEvent.STARTED) {
+					 startBundle(event.getSymbolicName(),event.getVersion());
+					 bundleTable.put(event.getId(),state);
+				} else if(event.getType() == BundleEvent.STOPPED) {
+					 stopBundle(event.getSymbolicName(), event.getVersion());
+					 state.setStatus(BundleEvent.INSTALLED);
+					 bundleTable.put(event.getId(),state);
+				} else if(event.getType() == BundleEvent.UPDATED) {
+					updateBundle(event.getSymbolicName(), event.getVersion());
+				}
+			} else logger.debug("Bundle with symbolicName {} is marked as BLOCKED INBOUND",event.getSymbolicName());
+		} catch (BundleException e) {
+			logger.info("Failed to install bundle.");
+		}
+	}
+
+
+    /**
+     * Initialization Method.
+     */
+    public void init() {
+        if (clusterManager != null) {
+            node = clusterManager.getNode();
+        }
+    }
+
+    /**
+     * Destruction Method.
+     */
+    public void destroy() {
+
+    }
+
+    public Switch getSwitch() {
+        return eventSwitch;
+    }
+
+    public Class<RemoteBundleEvent> getType() {
+        return RemoteBundleEvent.class;
+    }
+}

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleState.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleState.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleState.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleState.java Thu May 19 18:20:02 2011
@@ -0,0 +1,53 @@
+/*
+ * 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.bundle;
+
+import java.io.Serializable;
+
+/**
+ * @author iocanel
+ */
+public class BundleState implements Serializable {
+
+    private static final long serialVersionUID = 5933673686648413918L;
+
+    private String location;
+	private int status;
+	private byte[] data;
+
+	public String getLocation() {
+		return location;
+	}
+
+	public void setLocation(String location) {
+		this.location = location;
+	}
+
+	public int getStatus() {
+		return status;
+	}
+
+	public void setStatus(int status) {
+		this.status = status;
+	}
+
+	public byte[] getData() {
+		return data;
+	}
+
+	public void setData(byte[] data) {
+		this.data = data.clone();
+	}
+}

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSupport.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSupport.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSupport.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSupport.java Thu May 19 18:20:02 2011
@@ -0,0 +1,158 @@
+/*
+ * 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.bundle;
+
+import org.apache.karaf.cellar.core.CellarSupport;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * @author iocanel
+ */
+public class BundleSupport extends CellarSupport {
+
+    private static final Logger logger = LoggerFactory.getLogger(CellarSupport.class);
+
+	protected BundleContext bundleContext;
+
+	/**
+	 * Reads a {@code Dictionary} object and creates a property object out of it.
+	 *
+	 * @param dictionary
+	 * @return
+	 */
+	public Properties dictionaryToProperties(Dictionary dictionary) {
+		Properties properties = new Properties();
+		if (dictionary != null && dictionary.keys() != null) {
+
+			Enumeration keys = dictionary.keys();
+			while (keys.hasMoreElements()) {
+				String key = (String) keys.nextElement();
+				if (key != null && dictionary.get(key) != null) {
+					properties.put(key, dictionary.get(key));
+				}
+			}
+		}
+		return properties;
+	}
+
+
+	/**
+	 * Installs a bundle using its location.
+	 */
+	public void installBundleFromLocation(String location) throws BundleException {
+	   getBundleContext().installBundle(location);
+	}
+
+	/**
+	 * Uninstalls a bundle using its Symbolic name and version.
+	 * @param symbolicName
+	 * @param version
+	 * @throws BundleException
+	 */
+	public void uninstallBundle(String symbolicName, String version) throws BundleException {
+	   Bundle[] bundles = getBundleContext().getBundles();
+	   if(bundles != null) {
+		   for(Bundle bundle:bundles) {
+			   if(bundle.getSymbolicName().equals(symbolicName) && bundle.getVersion().toString().equals(version)) {
+				   bundle.uninstall();
+			   }
+		   }
+	   }
+	}
+
+    /**
+	 * Starts a bundle using its Symbolic name and version.
+	 * @param symbolicName
+	 * @param version
+	 * @throws BundleException
+	 */
+	public void startBundle(String symbolicName, String version) throws BundleException {
+	   Bundle[] bundles = getBundleContext().getBundles();
+	   if(bundles != null) {
+		   for(Bundle bundle:bundles) {
+			   if(bundle.getSymbolicName().equals(symbolicName) && bundle.getVersion().toString().equals(version)) {
+				   bundle.start();
+			   }
+		   }
+	   }
+	}
+
+	/**
+	 * Stops a bundle using its Symbolic name and version.
+	 * @param symbolicName
+	 * @param version
+	 * @throws BundleException
+	 */
+	public void stopBundle(String symbolicName, String version) throws BundleException {
+	   Bundle[] bundles = getBundleContext().getBundles();
+	   if(bundles != null) {
+		   for(Bundle bundle:bundles) {
+			   if(bundle.getSymbolicName().equals(symbolicName) && bundle.getVersion().toString().equals(version)) {
+				   bundle.stop();
+			   }
+		   }
+	   }
+	}
+
+	/**
+	 * Updates a bundle using its Symbolic name and version.
+	 * @param symbolicName
+	 * @param version
+	 * @throws BundleException
+	 */
+	public void updateBundle(String symbolicName, String version) throws BundleException {
+	   Bundle[] bundles = getBundleContext().getBundles();
+	   if(bundles != null) {
+		   for(Bundle bundle:bundles) {
+			   if(bundle.getSymbolicName().equals(symbolicName) && bundle.getVersion().toString().equals(version)) {
+				   bundle.update();
+			   }
+		   }
+	   }
+	}
+
+	/**
+	 * 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;
+	}
+
+	public ConfigurationAdmin getConfigurationAdmin() {
+		return configurationAdmin;
+	}
+
+	public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
+		this.configurationAdmin = configurationAdmin;
+	}
+}

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/BundleSynchronizer.java Thu May 19 18:20:02 2011
@@ -0,0 +1,175 @@
+/*
+ * 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.bundle;
+
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.Synchronizer;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.event.EventType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleReference;
+import org.osgi.service.cm.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author iocanel
+ */
+public class BundleSynchronizer extends BundleSupport implements Synchronizer {
+
+    private static final Logger logger = LoggerFactory.getLogger(BundleSynchronizer.class);
+
+    private List<EventProducer> producerList;
+
+
+    /**
+     * Registration method
+     */
+    public void init() {
+        Set<Group> groups = groupManager.listLocalGroups();
+        if (groups != null && !groups.isEmpty()) {
+            for (Group group : groups) {
+                if (isSyncEnabled(group)) {
+                    pull(group);
+                    push(group);
+                }
+            }
+        }
+    }
+
+    /**
+     * Destruction method
+     */
+    public void destroy() {
+
+    }
+
+    /**
+     * Reads the configuration from the remote map.
+     */
+    public void pull(Group group) {
+        if (group != null) {
+            String groupName = group.getName();
+            Map<String, BundleState> bundleTable = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+
+            for (Map.Entry<String,BundleState> entry : bundleTable.entrySet()) {
+                String id = entry.getKey();
+                BundleState state = entry.getValue();
+
+                //Check if the pid is marked as local.
+                String[] tokens = id.split("/");
+                String symbolicName = tokens[0];
+                String version = tokens[1];
+                if (tokens != null && tokens.length > 2) {
+                    if (state != null) {
+                        String bundleLocation = state.getLocation();
+                        if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.INBOUND)) {
+                            try {
+                                if (state.getStatus() == BundleEvent.INSTALLED) {
+                                    installBundleFromLocation(state.getLocation());
+                                    startBundle(symbolicName, version);
+                                } else if (state.getStatus() == BundleEvent.STARTED) {
+                                    installBundleFromLocation(state.getLocation());
+                                }
+                            } catch (BundleException e) {
+                                logger.error("Error while pulling bundle", e);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Publishses local configuration to the cluster.
+     */
+
+    public void push(Group group) {
+
+        if (group != null) {
+            String groupName = group.getName();
+            Map<String, BundleState> bundleTable = clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
+            Bundle[] bundles;
+            BundleContext bundleContext = ((BundleReference) getClass().getClassLoader()).getBundle().getBundleContext();
+
+            bundles = bundleContext.getBundles();
+            for (Bundle bundle : bundles) {
+                String symbolicName = bundle.getSymbolicName();
+                String version = bundle.getVersion().toString();
+                String bundleLocation = bundle.getLocation();
+                int status = bundle.getState();
+                String id = symbolicName + "/" + version;
+
+                //Check if the pid is marked as local.
+                if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.OUTBOUND)) {
+
+                    BundleState bundleState = new BundleState();
+                    bundleState.setLocation(bundleLocation);
+                    bundleState.setStatus(status);
+
+                    BundleState existingState = bundleTable.get(id);
+                    RemoteBundleEvent event = null;
+                    if (existingState == null) {
+                        event = new RemoteBundleEvent(symbolicName, version, bundleLocation, status);
+                    } else if (bundleState.getStatus() == BundleEvent.STARTED) {
+                        event = new RemoteBundleEvent(symbolicName, version, bundleLocation, status);
+                    }
+                    if (producerList != null && !producerList.isEmpty() && event != null) {
+                        for (EventProducer producer : producerList) {
+                            producer.produce(event);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    @Override
+    public Boolean isSyncEnabled(Group group) {
+        Boolean result = Boolean.FALSE;
+        String groupName = group.getName();
+
+        try {
+            Configuration configuration = configurationAdmin.getConfiguration(Configurations.GROUP);
+            Dictionary<String, String> properties = configuration.getProperties();
+            String propertyKey = groupName + Configurations.SEPARATOR + Constants.CATEGORY + Configurations.SEPARATOR + Configurations.SYNC;
+            String propertyValue = properties.get(propertyKey);
+            result = Boolean.parseBoolean(propertyValue);
+        } catch (IOException e) {
+            logger.error("Error while checking if sync is enabled.", e);
+        }
+        return result;
+    }
+
+    public List<EventProducer> getProducerList() {
+        return producerList;
+    }
+
+    public void setProducerList(List<EventProducer> producerList) {
+        this.producerList = producerList;
+    }
+}

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/Constants.java Thu May 19 18:20:02 2011
@@ -0,0 +1,25 @@
+/*
+ * 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.bundle;
+
+/**
+ * @author iocanel
+ */
+public class Constants {
+    public static final String CATEGORY = "bundle";
+	public static final String BUNDLE_MAP = "org.apache.karaf.cellar.bundle.map";
+
+    private Constants(){}
+}

Added: karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/LocalBundleListener.java Thu May 19 18:20:02 2011
@@ -0,0 +1,96 @@
+/*
+ * 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.bundle;
+
+
+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.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author iocanel
+ */
+public class LocalBundleListener extends BundleSupport implements BundleListener {
+
+    private static final Logger logger = LoggerFactory.getLogger(LocalBundleListener.class);
+
+    private List<EventProducer> producerList;
+
+    private Node node;
+
+    /**
+     * Process {@link BundleEvent}s.
+     *
+     * @param event
+     */
+    public void bundleChanged(BundleEvent event) {
+        if (event != null && event.getBundle() != null) {
+            Set<Group> groups = groupManager.listLocalGroups();
+
+            if (groups != null && !groups.isEmpty()) {
+                for (Group group : groups) {
+
+                    String symbolicName = event.getBundle().getSymbolicName();
+                    String version = event.getBundle().getVersion().toString();
+                    String bundleLocation = event.getBundle().getLocation();
+                    int type = event.getType();
+                    if (isAllowed(group, Constants.CATEGORY, bundleLocation, EventType.OUTBOUND)) {
+                        RemoteBundleEvent remoteBundleEvent = new RemoteBundleEvent(symbolicName, version, bundleLocation, type);
+                        remoteBundleEvent.setSourceGroup(group);
+                        remoteBundleEvent.setSourceNode(node);
+                        if (producerList != null && !producerList.isEmpty()) {
+                            for (EventProducer producer : producerList) {
+                                producer.produce(remoteBundleEvent);
+                            }
+                        }
+                    } else logger.debug("Bundle with symbolicName {} is marked as BLOCKED OUTBOUND");
+                }
+            }
+        }
+    }
+
+    /**
+     * 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/bundle/src/main/java/org/apache/karaf/cellar/bundle/RemoteBundleEvent.java
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/RemoteBundleEvent.java?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/RemoteBundleEvent.java (added)
+++ karaf/cellar/trunk/bundle/src/main/java/org/apache/karaf/cellar/bundle/RemoteBundleEvent.java Thu May 19 18:20:02 2011
@@ -0,0 +1,75 @@
+/*
+ * 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.bundle;
+
+
+import org.apache.karaf.cellar.core.event.Event;
+
+/**
+ * @author iocanel
+ */
+public class RemoteBundleEvent extends Event {
+
+	private String symbolicName;
+	private String version;
+	private String location;
+	private int type;
+
+	/**
+	 * Constructor
+	 * @param symbolicName
+	 * @param version
+	 * @param location
+	 */
+	public RemoteBundleEvent(String symbolicName,String version, String location, int type) {
+		super(symbolicName+"/"+version);
+		this.symbolicName=symbolicName;
+		this.version=version;
+		this.location=location;
+		this.type=type;
+	}
+
+	public String getSymbolicName() {
+		return symbolicName;
+	}
+
+	public void setSymbolicName(String symbolicName) {
+		this.symbolicName = symbolicName;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public String getLocation() {
+		return location;
+	}
+
+	public void setLocation(String location) {
+		this.location = location;
+	}
+
+	public int getType() {
+		return type;
+	}
+
+	public void setType(int type) {
+		this.type = type;
+	}
+}

Added: karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml?rev=1125040&view=auto
==============================================================================
--- karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml (added)
+++ karaf/cellar/trunk/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml Thu May 19 18:20:02 2011
@@ -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="bundleListener" class="org.apache.karaf.cellar.bundle.LocalBundleListener" 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"/>
+        <property name="bundleContext" ref="blueprintBundleContext"/>
+    </bean>
+
+    <!-- Configuration Tracker -->
+    <bean id="tracker" class="org.apache.karaf.cellar.bundle.BundleTracker"/>
+
+    <!-- Configuration Synchronizer -->
+    <bean id="synchronizer" class="org.apache.karaf.cellar.bundle.BundleSynchronizer"
+          init-method="init" destroy-method="destroy" depends-on="eventHandler">
+        <property name="configurationAdmin" ref="configurationAdmin"/>
+        <property name="groupManager" ref="groupManager"/>
+        <property name="clusterManager" ref="clusterManager"/>
+        <property name="producerList" ref="groupEventProducers"/>
+        <property name="bundleContext" ref="blueprintBundleContext"/>
+    </bean>
+
+    <bean id="eventHandler" class="org.apache.karaf.cellar.bundle.BundleEventHandler"
+          init-method="init" destroy-method="destroy">
+        <property name="tracker" ref="tracker"/>
+        <property name="configurationAdmin" ref="configurationAdmin"/>
+        <property name="clusterManager" ref="clusterManager"/>
+        <property name="bundleContext" ref="blueprintBundleContext"/>
+    </bean>
+
+    <!-- OSGi Services  & References -->
+    <service ref="eventHandler" 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-list id="groupEventProducers" member-type="service-object"
+                    interface="org.apache.karaf.cellar.core.event.EventProducer" filter="(type=group)"/>
+
+</blueprint>

Modified: karaf/cellar/trunk/pom.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/pom.xml?rev=1125040&r1=1125039&r2=1125040&view=diff
==============================================================================
--- karaf/cellar/trunk/pom.xml (original)
+++ karaf/cellar/trunk/pom.xml Thu May 19 18:20:02 2011
@@ -168,6 +168,7 @@
         <module>core</module>
         <module>config</module>
         <module>features</module>
+        <module>bundle</module>
         <module>shell</module>
         <module>hazelcast</module>
         <module>utils</module>

Modified: karaf/cellar/trunk/src/main/resources/feature.xml
URL: http://svn.apache.org/viewvc/karaf/cellar/trunk/src/main/resources/feature.xml?rev=1125040&r1=1125039&r2=1125040&view=diff
==============================================================================
--- karaf/cellar/trunk/src/main/resources/feature.xml (original)
+++ karaf/cellar/trunk/src/main/resources/feature.xml Thu May 19 18:20:02 2011
@@ -45,4 +45,9 @@
         </configfile>
     </feature>
 
+    <feature name='cellar-bundle' description='Cellar bundle module' version='${project.version}' resolver='(obr)'>
+        <feature version='${project.version}'>cellar</feature>
+        <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.bundle/${project.version}</bundle>
+    </feature>
+
 </features>
\ No newline at end of file