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 2016/10/20 05:43:15 UTC
karaf-cellar git commit: [KARAF-4747] Add cluster KAR support
Repository: karaf-cellar
Updated Branches:
refs/heads/master 76c1aa5f8 -> 5cf48dd71
[KARAF-4747] Add cluster KAR support
Project: http://git-wip-us.apache.org/repos/asf/karaf-cellar/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf-cellar/commit/5cf48dd7
Tree: http://git-wip-us.apache.org/repos/asf/karaf-cellar/tree/5cf48dd7
Diff: http://git-wip-us.apache.org/repos/asf/karaf-cellar/diff/5cf48dd7
Branch: refs/heads/master
Commit: 5cf48dd7183da9edfb4d20f0f5fd298961ef7e26
Parents: 76c1aa5
Author: Jean-Baptiste Onofr� <jb...@apache.org>
Authored: Thu Oct 20 07:42:38 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Thu Oct 20 07:42:38 2016 +0200
----------------------------------------------------------------------
assembly/src/main/resources/features.xml | 9 ++
kar/NOTICE | 39 ++++++++
kar/pom.xml | 96 ++++++++++++++++++++
.../karaf/cellar/kar/ClusterKarEvent.java | 47 ++++++++++
.../org/apache/karaf/cellar/kar/Constants.java | 24 +++++
.../karaf/cellar/kar/KarEventHandler.java | 77 ++++++++++++++++
.../cellar/kar/internal/osgi/Activator.java | 81 +++++++++++++++++
.../cellar/kar/shell/InstallKarCommand.java | 85 +++++++++++++++++
.../cellar/kar/shell/UninstallKarCommand.java | 75 +++++++++++++++
manual/src/main/asciidoc/user-guide/groups.adoc | 20 ++++
pom.xml | 6 ++
11 files changed, 559 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/assembly/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/assembly/src/main/resources/features.xml b/assembly/src/main/resources/features.xml
index c10087b..d9706a3 100644
--- a/assembly/src/main/resources/features.xml
+++ b/assembly/src/main/resources/features.xml
@@ -59,6 +59,14 @@
</conditional>
</feature>
+ <feature name="cellar-kar" description="Karaf kar cluster support" version="${project.version}">
+ <conditional>
+ <condition>kar</condition>
+ <feature dependency="true">cellar-hazelcast</feature>
+ <bundle>mvn:org.apache.karaf.cellar/org.apache.karaf.cellar.kar/${project.version}</bundle>
+ </conditional>
+ </feature>
+
<feature name="cellar-bundle" description="Bundle cluster support" version="${project.version}">
<conditional>
<condition>bundle</condition>
@@ -81,6 +89,7 @@
<feature>cellar-config</feature>
<feature>cellar-bundle</feature>
<feature>cellar-features</feature>
+ <feature>cellar-kar</feature>
<requirement>
karaf.cellar.provider
</requirement>
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/NOTICE
----------------------------------------------------------------------
diff --git a/kar/NOTICE b/kar/NOTICE
new file mode 100644
index 0000000..64cb235
--- /dev/null
+++ b/kar/NOTICE
@@ -0,0 +1,39 @@
+Apache Karaf Cellar
+Copyright 2011-2015 The Apache Software Foundation
+
+I. Used Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+Hazelcast (http://www.hazelcast.com/).
+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
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product includes software from http://www.json.org.
+Copyright (c) 2002 JSON.org
+
+II. License Summary
+- Apache License 2.0
+- MIT License
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/pom.xml
----------------------------------------------------------------------
diff --git a/kar/pom.xml b/kar/pom.xml
new file mode 100644
index 0000000..cda8af7
--- /dev/null
+++ b/kar/pom.xml
@@ -0,0 +1,96 @@
+<?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>4.0.3-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.karaf.cellar</groupId>
+ <artifactId>org.apache.karaf.cellar.kar</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Cellar :: KAR</name>
+
+ <dependencies>
+ <!-- Internal dependencies -->
+ <dependency>
+ <groupId>org.apache.karaf.cellar</groupId>
+ <artifactId>org.apache.karaf.cellar.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.kar</groupId>
+ <artifactId>org.apache.karaf.kar.core</artifactId>
+ </dependency>
+
+ <!-- Karaf features -->
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.karaf.tooling</groupId>
+ <artifactId>karaf-services-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ !org.apache.karaf.cellar.kar.internal.osgi,
+ org.apache.karaf.cellar.kar*
+ </Export-Package>
+ <Import-Package>
+ org.slf4j;version="[1.6,2)";resolution:=optional,
+ org.apache.karaf.shell*;resolution:=optional,
+ *
+ </Import-Package>
+ <Private-Package>
+ org.apache.karaf.cellar.kar.internal.osgi,
+ org.apache.karaf.util,
+ org.apache.karaf.util.tracker;-split-package:=merge-first
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/ClusterKarEvent.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/ClusterKarEvent.java b/kar/src/main/java/org/apache/karaf/cellar/kar/ClusterKarEvent.java
new file mode 100644
index 0000000..e5b8e8f
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/ClusterKarEvent.java
@@ -0,0 +1,47 @@
+/*
+ * 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.kar;
+
+import org.apache.karaf.cellar.core.event.Event;
+import org.apache.karaf.cellar.core.event.EventType;
+
+/**
+ * Cluster kar event.
+ */
+public class ClusterKarEvent extends Event {
+
+ private String name;
+ private boolean install;
+
+ public ClusterKarEvent(String id, boolean install) {
+ super(id);
+ this.install = install;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isInstall() {
+ return install;
+ }
+
+ public void setInstall(boolean install) {
+ this.install = install;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/Constants.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/Constants.java b/kar/src/main/java/org/apache/karaf/cellar/kar/Constants.java
new file mode 100644
index 0000000..9668cf4
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/Constants.java
@@ -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.kar;
+
+/**
+ * Kar configuration constants.
+ */
+public class Constants {
+
+ // configuration category
+ public static final String CATEGORY = "kar";
+
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/KarEventHandler.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/KarEventHandler.java b/kar/src/main/java/org/apache/karaf/cellar/kar/KarEventHandler.java
new file mode 100644
index 0000000..8f3e719
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/KarEventHandler.java
@@ -0,0 +1,77 @@
+/*
+ * 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.kar;
+
+import org.apache.karaf.cellar.core.CellarSupport;
+import org.apache.karaf.cellar.core.Configurations;
+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.kar.KarService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Handler for cluster KAR event.
+ */
+public class KarEventHandler extends CellarSupport implements EventHandler<ClusterKarEvent> {
+
+ public static final String SWITCH_ID = "org.apache.karaf.cellar.event.kar.handler";
+
+ private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
+
+ @Reference
+ private KarService karService;
+
+ @Override
+ public void handle(ClusterKarEvent event) {
+ if (event.isInstall()) {
+ try {
+ String karUrl = event.getId();
+ karService.install(new URI(karUrl));
+ } catch (Exception e) {
+ LOGGER.error("CELLAR KAR: can't install {}", event.getId(), e);
+ return;
+ }
+ } else {
+ try {
+ karService.uninstall(event.getId());
+ } catch (Exception e) {
+ LOGGER.error("CELLAR KAR: can't uninstall {}", event.getId(), e);
+ return;
+ }
+ }
+ }
+
+ @Override
+ public Class<ClusterKarEvent> getType() {
+ return ClusterKarEvent.class;
+ }
+
+ @Override
+ public Switch getSwitch() {
+ return eventSwitch;
+ }
+
+ public KarService getKarService() {
+ return karService;
+ }
+
+ public void setKarService(KarService karService) {
+ this.karService = karService;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/internal/osgi/Activator.java b/kar/src/main/java/org/apache/karaf/cellar/kar/internal/osgi/Activator.java
new file mode 100644
index 0000000..8a3ad4a
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/internal/osgi/Activator.java
@@ -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.kar.internal.osgi;
+
+import org.apache.karaf.cellar.core.ClusterManager;
+import org.apache.karaf.cellar.core.GroupManager;
+import org.apache.karaf.cellar.core.event.EventHandler;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.kar.KarEventHandler;
+import org.apache.karaf.kar.KarService;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.util.tracker.annotation.ProvideService;
+import org.apache.karaf.util.tracker.annotation.RequireService;
+import org.apache.karaf.util.tracker.annotation.Services;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Hashtable;
+
+@Services(
+ provides = {
+ @ProvideService(EventHandler.class)
+ },
+ requires = {
+ @RequireService(ClusterManager.class),
+ @RequireService(GroupManager.class),
+ @RequireService(EventProducer.class),
+ @RequireService(ConfigurationAdmin.class),
+ @RequireService(KarService.class)
+ }
+)
+public class Activator extends BaseActivator {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(Activator.class);
+
+ private KarEventHandler karEventHandler;
+
+ @Override
+ public void doStart() throws Exception {
+
+ ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
+ if (configurationAdmin == null)
+ return;
+ ClusterManager clusterManager = getTrackedService(ClusterManager.class);
+ if (clusterManager == null)
+ return;
+ GroupManager groupManager = getTrackedService(GroupManager.class);
+ if (groupManager == null)
+ return;
+ EventProducer eventProducer = getTrackedService(EventProducer.class);
+ if (eventProducer == null)
+ return;
+ KarService karService = getTrackedService(KarService.class);
+ if (karService == null)
+ return;
+
+ LOGGER.debug("CELLAR KAR: init event handler");
+ karEventHandler = new KarEventHandler();
+ karEventHandler.setConfigurationAdmin(configurationAdmin);
+ karEventHandler.setClusterManager(clusterManager);
+ karEventHandler.setGroupManager(groupManager);
+ karEventHandler.setKarService(karService);
+ Hashtable props = new Hashtable();
+ props.put("managed", "true");
+ register(new Class[]{ EventHandler.class }, karEventHandler, props);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/shell/InstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/shell/InstallKarCommand.java b/kar/src/main/java/org/apache/karaf/cellar/kar/shell/InstallKarCommand.java
new file mode 100644
index 0000000..5ae7bed
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/shell/InstallKarCommand.java
@@ -0,0 +1,85 @@
+/*
+ * 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.kar.shell;
+
+import org.apache.karaf.cellar.core.CellarSupport;
+import org.apache.karaf.cellar.core.Configurations;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.control.SwitchStatus;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.event.EventType;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.apache.karaf.cellar.kar.ClusterKarEvent;
+import org.apache.karaf.cellar.kar.Constants;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+import java.util.Map;
+
+@Command(scope = "cluster", name = "kar-install", description = "Install a KAR in a cluster group")
+@Service
+public class InstallKarCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "url", description = "The URL of the KAR file to install on the cluster", required = true, multiValued = false)
+ String url;
+
+ @Reference
+ private EventProducer eventProducer;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ // check if the group exists
+ Group group = groupManager.findGroupByName(groupName);
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ // check if the producer is ON
+ if (eventProducer.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
+ System.err.println("Cluster event producer is OFF");
+ return null;
+ }
+
+ CellarSupport support = new CellarSupport();
+ support.setConfigurationAdmin(configurationAdmin);
+ support.setGroupManager(groupManager);
+ support.setClusterManager(clusterManager);
+
+ // check if the kar is allowed
+ if (support.isAllowed(group, Constants.CATEGORY, url, EventType.OUTBOUND)) {
+ // broadcast cluster event
+ ClusterKarEvent clusterEvent = new ClusterKarEvent(url, true);
+ clusterEvent.setSourceGroup(group);
+ clusterEvent.setInstall(true);
+ eventProducer.produce(clusterEvent);
+ } else {
+ System.err.println("KAR " + url + " is blocked outbound for cluster group " + groupName);
+ }
+ return null;
+ }
+
+ public EventProducer getEventProducer() {
+ return eventProducer;
+ }
+
+ public void setEventProducer(EventProducer eventProducer) {
+ this.eventProducer = eventProducer;
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/kar/src/main/java/org/apache/karaf/cellar/kar/shell/UninstallKarCommand.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/cellar/kar/shell/UninstallKarCommand.java b/kar/src/main/java/org/apache/karaf/cellar/kar/shell/UninstallKarCommand.java
new file mode 100644
index 0000000..8dcb775
--- /dev/null
+++ b/kar/src/main/java/org/apache/karaf/cellar/kar/shell/UninstallKarCommand.java
@@ -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.kar.shell;
+
+import org.apache.karaf.cellar.core.CellarSupport;
+import org.apache.karaf.cellar.core.Group;
+import org.apache.karaf.cellar.core.control.SwitchStatus;
+import org.apache.karaf.cellar.core.event.EventProducer;
+import org.apache.karaf.cellar.core.event.EventType;
+import org.apache.karaf.cellar.core.shell.CellarCommandSupport;
+import org.apache.karaf.cellar.kar.ClusterKarEvent;
+import org.apache.karaf.cellar.kar.Constants;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "cluster", name = "kar-uninstall", description = "Uninstall a KAR from a cluster group")
+@Service
+public class UninstallKarCommand extends CellarCommandSupport {
+
+ @Argument(index = 0, name = "group", description = "The cluster group name", required = true, multiValued = false)
+ String groupName;
+
+ @Argument(index = 1, name = "name", description = "The name of the KAR file to uninstall from the cluster", required = true, multiValued = false)
+ String name;
+
+ @Reference
+ private EventProducer eventProducer;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ // check if the group exists
+ Group group = groupManager.findGroupByName(groupName);
+ if (group == null) {
+ System.err.println("Cluster group " + groupName + " doesn't exist");
+ return null;
+ }
+
+ // check if the producer is ON
+ if (eventProducer.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
+ System.err.println("Cluster event producer is OFF");
+ return null;
+ }
+
+ CellarSupport support = new CellarSupport();
+ support.setConfigurationAdmin(configurationAdmin);
+ support.setGroupManager(groupManager);
+ support.setClusterManager(clusterManager);
+
+ // check if the kar is allowed
+ if (support.isAllowed(group, Constants.CATEGORY, name, EventType.OUTBOUND)) {
+ // broadcast cluster event
+ ClusterKarEvent clusterEvent = new ClusterKarEvent(name, true);
+ clusterEvent.setSourceGroup(group);
+ clusterEvent.setInstall(false);
+ eventProducer.produce(clusterEvent);
+ } else {
+ System.err.println("KAR " + name + " is blocked outbound for cluster group " + groupName);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/manual/src/main/asciidoc/user-guide/groups.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/user-guide/groups.adoc b/manual/src/main/asciidoc/user-guide/groups.adoc
index 74ae35f..afcb3a1 100644
--- a/manual/src/main/asciidoc/user-guide/groups.adoc
+++ b/manual/src/main/asciidoc/user-guide/groups.adoc
@@ -286,6 +286,26 @@ You can modify this list using the same command, or by editing the `etc/org.apac
config.excluded.properties = service.factoryPid, felix.fileinstall.filename, felix.fileinstall.dir, felix.fileinstall.tmpdir, org.ops4j.pax.url.mvn.defaultRepositories
----
+===== KAR
+
+Karaf Cellar is able to send cluster event for KAR files installation and uninstallation.
+
+However, due to KAR limitations, it's not possible to fully store the KAR files state on the cluster.
+
+To install a KAR file on the cluster, you have to use the `cluster:kar-install` command:
+
+----
+karaf@root()> cluster:kar-install cluster_group mvn:...kar
+----
+
+This will send a cluster event to all members of the cluster group and it will install the KAR file on those nodes.
+
+On the other hand, you can uninstall a KAR from a cluster group using `cluster:kar-uninstall` command:
+
+----
+karaf@root()> cluster:kar-uninstall cluster_group kar_name
+----
+
===== OBR (optional)
See the link:obr[OBR section] for details.
http://git-wip-us.apache.org/repos/asf/karaf-cellar/blob/5cf48dd7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9da01ac..d400188 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,6 +57,7 @@
<module>core</module>
<module>config</module>
<module>features</module>
+ <module>kar</module>
<module>bundle</module>
<module>obr</module>
<module>dosgi</module>
@@ -234,6 +235,11 @@
<version>${karaf.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.karaf.kar</groupId>
+ <artifactId>org.apache.karaf.kar.core</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.core</artifactId>
<version>${karaf.version}</version>