karaf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (KARAF-5783) Change implementation of Cave Deployer REST to mimic Cave Server
Date Tue, 04 Sep 2018 16:13:01 GMT

    [ https://issues.apache.org/jira/browse/KARAF-5783?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16603254#comment-16603254 ] 

ASF GitHub Bot commented on KARAF-5783:
---------------------------------------

fpapon closed pull request #12: [KARAF-5783] Introduce the cave main feature and use an unique rest bundle
URL: https://github.com/apache/karaf-cave/pull/12
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/assembly/src/main/resources/features.xml b/assembly/src/main/resources/features.xml
index e1e5116..18983b6 100644
--- a/assembly/src/main/resources/features.xml
+++ b/assembly/src/main/resources/features.xml
@@ -20,10 +20,15 @@
 
     <repository>mvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features</repository>
 
+    <feature name="cave" version="${project.version}">
+        <feature prerequisite="true">cave-server</feature>
+        <feature prerequisite="true">cave-deployer</feature>
+        <feature>cave-rest</feature>
+    </feature>
+
     <feature name="cave-server" version="${project.version}">
         <feature>cave-server-storage</feature>
         <feature>cave-server-http</feature>
-        <feature>cave-server-rest</feature>
         <feature>cave-server-maven</feature>
     </feature>
 
@@ -50,14 +55,6 @@
         <bundle>mvn:org.apache.karaf.cave.server/org.apache.karaf.cave.server.http/${project.version}</bundle>
     </feature>
 
-    <feature name="cave-server-rest" version="${project.version}">
-        <feature prerequisite="true">http</feature>
-        <requirement>osgi.service;effective:=active;filter:=(objectClass=org.osgi.service.http.HttpService)</requirement>
-        <feature version="[3,4)">cxf-jaxrs</feature>
-        <feature>cave-server-storage</feature>
-        <bundle>mvn:org.apache.karaf.cave.server/org.apache.karaf.cave.server.rest/${project.version}</bundle>
-    </feature>
-
     <feature name="cave-server-maven" version="${project.version}">
         <feature prerequisite="true">http</feature>
         <requirement>osgi.service;effective:=active;filter:=(objectClass=org.osgi.service.http.HttpService)</requirement>
@@ -65,9 +62,9 @@
     </feature>
 
     <feature name="cave-deployer" version="${project.version}">
-        <feature version="${project.version}">cave-deployer-rest</feature>
-        <feature version="${project.version}">cave-deployer-command</feature>
-        <feature version="${project.version}">cave-deployer-management</feature>
+        <feature>cave-deployer-service</feature>
+        <feature>cave-deployer-command</feature>
+        <feature>cave-deployer-management</feature>
     </feature>
 
     <feature name="cave-deployer-service" version="${project.version}">
@@ -82,17 +79,6 @@
         </config>
     </feature>
 
-    <feature name="cave-deployer-rest" version="${project.version}">
-        <feature version="${cxf.version}">cxf-jaxrs</feature>
-        <feature version="${project.version}">cave-deployer-service</feature>
-        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-core/2.4.6</bundle>
-        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-annotations/2.4.6</bundle>
-        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-databind/2.4.6</bundle>
-        <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.4.6</bundle>
-        <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.4.6</bundle>
-        <bundle>mvn:org.apache.karaf.cave.deployer/org.apache.karaf.cave.deployer.rest/${project.version}</bundle>
-    </feature>
-
     <feature name="cave-deployer-command" version="${project.version}">
         <feature version="${project.version}">cave-deployer-service</feature>
         <conditional>
@@ -109,6 +95,18 @@
         </conditional>
     </feature>
 
+    <feature name="cave-rest" version="${project.version}">
+        <feature prerequisite="true">http</feature>
+        <requirement>osgi.service;effective:=active;filter:=(objectClass=org.osgi.service.http.HttpService)</requirement>
+        <feature version="${cxf.version}">cxf-jaxrs</feature>
+        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-core/2.4.6</bundle>
+        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-annotations/2.4.6</bundle>
+        <bundle dependency="true">mvn:com.fasterxml.jackson.core/jackson-databind/2.4.6</bundle>
+        <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.4.6</bundle>
+        <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.4.6</bundle>
+        <bundle>mvn:org.apache.karaf.cave/org.apache.karaf.cave.rest/${project.version}</bundle>
+    </feature>
+
     <feature name="cave-documentation" description="Documentation of Karaf Cave sub-project in HTML" version="${project.version}">
         <feature>war</feature>
         <bundle>mvn:org.apache.karaf.cave/manual/${project.version}</bundle>
diff --git a/client/NOTICE b/client/NOTICE
deleted file mode 100644
index 2bd5453..0000000
--- a/client/NOTICE
+++ /dev/null
@@ -1,29 +0,0 @@
-Apache Karaf Cave
-Copyright 2010-2014 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.
-
-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
-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
diff --git a/client/pom.xml b/client/pom.xml
deleted file mode 100644
index 67e017b..0000000
--- a/client/pom.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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>cave</artifactId>
-        <version>4.0.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.apache.karaf.cave</groupId>
-    <artifactId>org.apache.karaf.cave.client</artifactId>
-    <name>Apache Karaf :: Cave :: Client</name>
-    <packaging>bundle</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.cxf</groupId>
-            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.bundlerepository</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/client/src/main/java/org/apache/karaf/cave/client/RepositoryAdminProxy.java b/client/src/main/java/org/apache/karaf/cave/client/RepositoryAdminProxy.java
deleted file mode 100644
index 8012916..0000000
--- a/client/src/main/java/org/apache/karaf/cave/client/RepositoryAdminProxy.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.client;
-
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.felix.bundlerepository.DataModelHelper;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resource;
-import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
-import org.apache.felix.bundlerepository.impl.RepositoryImpl;
-import org.osgi.framework.InvalidSyntaxException;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- *  Implementation of the OSGi RepositoryAdmin service which proxy to a Karaf Cave server.
- */
-public class RepositoryAdminProxy implements RepositoryAdmin {
-
-    private final String caveServerUrl;
-
-    private final Map<String, RepositoryImpl> repositories = new HashMap<String, RepositoryImpl>();
-    private final DataModelHelper dataModelHelper = new DataModelHelperImpl();
-
-    public RepositoryAdminProxy(String caveServerUrl) {
-        this.caveServerUrl = caveServerUrl;
-    }
-
-    public Resource[] discoverResources(String filter) throws InvalidSyntaxException {
-        // check if the syntax is valid
-        dataModelHelper.filter(filter);
-        // delegate to the Cave server
-        WebClient client = WebClient.create(caveServerUrl + "/obr/resources");
-
-    }
-
-    public Resource[] discoverResources(Requirement[] requirements) {
-        WebClient client = WebClient.create(caveServerUrl + "/obr/resources");
-    }
-
-
-}
diff --git a/deployer/pom.xml b/deployer/pom.xml
index 84833b2..7ff173c 100644
--- a/deployer/pom.xml
+++ b/deployer/pom.xml
@@ -38,7 +38,6 @@
         <module>service</module>
         <module>command</module>
         <module>management</module>
-        <module>rest</module>
     </modules>
 
 </project>
\ No newline at end of file
diff --git a/deployer/rest/src/main/resources/OSGI-INF/blueprint/rest.xml b/deployer/rest/src/main/resources/OSGI-INF/blueprint/rest.xml
deleted file mode 100644
index 3fb0313..0000000
--- a/deployer/rest/src/main/resources/OSGI-INF/blueprint/rest.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    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.
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-           xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
-           xmlns:cxf="http://cxf.apache.org/blueprint/core"
-           xsi:schemaLocation="
-             http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
-             http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
-             http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
-             ">
-
-    <cxf:bus>
-        <cxf:features>
-            <cxf:logging/>
-        </cxf:features>
-    </cxf:bus>
-
-    <jaxrs:server id="deployerRest" address="/cave/deployer">
-        <jaxrs:serviceBeans>
-            <ref component-id="serviceBean" />
-        </jaxrs:serviceBeans>
-        <jaxrs:providers>
-            <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
-        </jaxrs:providers>
-    </jaxrs:server>
-
-    <reference id="deployer" interface="org.apache.karaf.cave.deployer.api.Deployer"/>
-
-    <bean id="serviceBean" class="org.apache.karaf.cave.deployer.rest.DeployerRest">
-        <property name="deployer" ref="deployer"/>
-    </bean>
-
-</blueprint>
diff --git a/manual/src/main/asciidoc/index.adoc b/manual/src/main/asciidoc/index.adoc
index 34026f4..558fc16 100644
--- a/manual/src/main/asciidoc/index.adoc
+++ b/manual/src/main/asciidoc/index.adoc
@@ -41,3 +41,5 @@ include::user-guide/maven-wrapper.adoc[]
 include::user-guide/administrate-cave.adoc[]
 
 include::user-guide/features-gateway.adoc[]
+
+include::user-guide/deployer.adoc[]
diff --git a/manual/src/main/asciidoc/overview.adoc b/manual/src/main/asciidoc/overview.adoc
index a974c7f..c7cc296 100644
--- a/manual/src/main/asciidoc/overview.adoc
+++ b/manual/src/main/asciidoc/overview.adoc
@@ -16,8 +16,12 @@
 
 Apache Karaf Cave is an Apache Karaf sub-project.
 
-Cave is an implementation of the OSGi Repository specification, providing additional features such as a
-complete Maven repository support, a REST API for management, support of remote repository proxy.
+Apache Karaf Cave is an implementation an artifact repository and deployment platform for Apache Karaf supporting:
+
+* OSGi Repository specification
+* Maven Repository manager
+* Deployer
+* REST API
 
 Cave deals with the requirements and capabilities of all artifacts.
 
@@ -27,17 +31,13 @@ Apache Karaf Cave provides the following features:
 is designed in a plugin way, you can implement your own backend (for instance, JDBC or LDAP backend).
 * *Repository Metadata Generation*: Cave creates the repository metadata for you, using the artifacts presents in the
 repository storage.
-* *Maven support*: Cave repositories act as a complete Maven repository, allowing you to use Cave directly with Maven.
+* *Maven Repository*: Cave repositories act as a complete Maven repository, allowing you to use Cave directly with Maven.
 * *REST API*: Cave provides a REST API to manipulate the repositories.
 * *Artifact Upload*: Users can upload OSGi bundle in a Cave repository. It supports URLs like mvn:groupId/artifactId/version,
 file:, http:, etc.
-* *Repository proxy*: Cave is able to proxy an existing repository, for instance an existing Maven repository.
+* *OSGi Repository proxy*: Cave is able to proxy an existing repository, for instance an existing Maven repository.
 The artifacts are located on the "external" repository, Cave handles the repository metadata. Cave supports file: and http:
 URLs, it means that Cave is able to browse a remote HTTP Maven repository for instance.
-* *Repository population*: Cave is able to get artifacts present on an "external" repository (local file: or
+* *OSGi Repository population*: Cave is able to get artifacts present on an "external" repository (local file: or
 remote http:), looking for OSGi bundles, and copy the artifacts in the Cave repository storage.
-
-Karaf Cave provides two components:
-
-* the cave-server is the full OSGi repository service, including the storage, the management layer, the REST service layer, etc.
-* the cave-client is a local repository service proxy that use a remote Cave server (not yet available).
+* *Deployer*: Cave Deployer is able to control and deployer applications on a "farm" of Apache Karaf instances.
diff --git a/manual/src/main/asciidoc/user-guide/administrate-cave.adoc b/manual/src/main/asciidoc/user-guide/administrate-cave.adoc
index cf32283..432c678 100644
--- a/manual/src/main/asciidoc/user-guide/administrate-cave.adoc
+++ b/manual/src/main/asciidoc/user-guide/administrate-cave.adoc
@@ -50,8 +50,5 @@ http://localhost:8181/cave/rest
 8181 is the default port of the Apache Karaf HTTP service.
 ====
 
-You can get the WADL:
-
-----
-http://localhost:8181/cave/rest?_wadl
-----
+* `/cave/rest/repository` allows you to manipulate the Cave repositories.
+* `/cave/rest/deployer` allows you to manipulate the Cave deployer.
diff --git a/manual/src/main/asciidoc/user-guide/cave-repository.adoc b/manual/src/main/asciidoc/user-guide/cave-repository.adoc
index 0819b16..4c38e6f 100644
--- a/manual/src/main/asciidoc/user-guide/cave-repository.adoc
+++ b/manual/src/main/asciidoc/user-guide/cave-repository.adoc
@@ -17,7 +17,7 @@
 A Cave repository is a container for:
 
 * Artifacts (files)
-* Repository metadata
+* Repository metadata (optional, only used for OSGi repository)
 
 By default, a repository uses a filesystem backend for the storage, the directory used is KARAF_BASE/cave.
 
diff --git a/manual/src/main/asciidoc/user-guide/deployer.adoc b/manual/src/main/asciidoc/user-guide/deployer.adoc
new file mode 100644
index 0000000..bbbf13b
--- /dev/null
+++ b/manual/src/main/asciidoc/user-guide/deployer.adoc
@@ -0,0 +1,126 @@
+//
+// 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.
+//
+
+=== Deployer
+
+Cave Deployer allows you to manage a "farm" of Apache Karaf instances local or remote from the deployer itself.
+
+You have specific commands: `cave:deployer-*`.
+
+==== Connections
+
+The first component of the deployer is the connection. A connection describe an access to a Apache Karaf instance.
+
+You can create a connection via `cave:deployer-connection-register` command or the REST Deployer API.
+
+A connection contains:
+
+* an unique name for the connection
+* the JMX URL to the give Apache Karaf instance
+* the name of the Apache Karaf instance
+* username and password to connect to the Apache Karaf instance
+
+For instance:
+
+----
+karaf@root()> cave:deployer-connection-register myconnection service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root root karaf karaf
+----
+
+You can list the connections using the `cave:deployer-connection` command:
+
+----
+karaf@root()> cave:deployer-connection
+Name         │ JMX URL                                                 │ Instance │ Username │ Password
+─────────────┼─────────────────────────────────────────────────────────┼──────────┼──────────┼─────────
+myconnection │ service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root │ root     │ karaf    │ *****
+
+----
+
+or via REST (with `curl` for instance):
+
+----
+curl -X GET -H "Content-Type: application/json" http://localhost:8181/cave/rest/deployer/connections
+[{"name":"myconnection","jmxUrl":"service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root","karafName":"root","user":"karaf","password":"karaf"}]
+----
+
+You can remove a connection using `cave:deployer-connection-delete` command:
+
+----
+karaf@root()> cave:deployer-connection-delete myconnection
+----
+
+or via REST:
+
+----
+curl -X DELETE http://localhost:8181/cave/rest/deployer/connections/myconnection
+----
+
+==== Artifacts
+
+Cave Deployer to extract zip or kar files to a given Maven repository or local directory, thanks to the `cave:deployer-explode` and `cave:deployer-extract` commands
+and the `/cave/rest/deployer/artifact/explode` and `/cave/rest/deployer/artifact/extract` REST operations.
+
+You can also download an artifact from a Maven repository with the `cave:deployer-download` command (or `/cave/rest/deployer/artifact/download` REST operation)
+or even upload an artifact to a Maven repository thanks to the `cave:deployer-upload` command (or `/cave/rest/deployer/artifact/upload` REST operation).
+
+==== Features
+
+Apache Karaf Cave Deployer provides the "classy" operations that you can do around Karaf features:
+
+* add a features repository
+* remove a features repository
+* list of features repositories
+* installing a feature
+* uninstalling a feature
+* list of features
+
+You have dedicated Cave Deployer commands and REST operations for that.
+
+You can also create a new "meta" feature by assembling existing features, configurations and bundles. This is done by the `assemble` operation:
+
+* `cave:deployer-assemble-feature`
+* `/cave/rest/deployer/feature/assemble`
+
+==== Bundles
+
+Apache Karaf Cave Deployer supports:
+
+* install bundle
+* start bundle
+* stop bundle
+* uninstall bundle
+* list bundles
+
+==== KAR
+
+Apache Karaf Cave Deployer supports:
+
+* install KAR
+* uninstall KAR
+* list KARs
+
+==== Config
+
+Apache Karaf Cave Deployer supports:
+
+* creating a new configuration
+* update an existing configuration
+* add a new property to a configuration
+* delete a property from a configuration
+* delete a configuration
+* list of configurations
+
+==== Cellar
+
+Apache Karaf Cave Deployer supports features handling on a Cellar cluster.
\ No newline at end of file
diff --git a/manual/src/main/asciidoc/user-guide/installation.adoc b/manual/src/main/asciidoc/user-guide/installation.adoc
index d74cd4d..07c5d2a 100644
--- a/manual/src/main/asciidoc/user-guide/installation.adoc
+++ b/manual/src/main/asciidoc/user-guide/installation.adoc
@@ -30,35 +30,19 @@ Apache Karaf Cave 4.0.x is designed to work on Apache Karaf 4.0.x.
 Simply register the Apache Karaf Cave features URL in your Apache Karaf instance:
 
 ----
-karaf@root()> feature:repo-add cave 4.0.0
-Adding feature url mvn:org.apache.karaf.cave/apache-karaf-cave/4.0.0/xml/features
+karaf@root()> feature:repo-add cave
+Adding feature url mvn:org.apache.karaf.cave/apache-karaf-cave/4.1.1/xml/features
 ----
 
-Now Apache Karaf Cave features are available, ready to be installed:
-
-----
-karaf@root()> feature:list|grep -i cave
-cave-server                     | 4.0.0                   |          | Uninstalled | karaf-cave-4.0.0 |
-cave-storage                    | 4.0.0                   |          | Uninstalled | karaf-cave-4.0.0 |
-cave-http                       | 4.0.0                   |          | Uninstalled | karaf-cave-4.0.0 |
-cave-rest                       | 4.0.0                   |          | Uninstalled | karaf-cave-4.0.0 |
-cave-maven                      | 4.0.0                   |          | Uninstalled | karaf-cave-4.0.0 |
-----
-
-==== Starting Apache Karaf Cave Server
+==== Starting Apache Karaf Cave
 
 The Apache Karaf Cave Server is installed by the 'cave-server' feature:
 
 ----
-karaf@root()> feature:install cave-server
+karaf@root()> feature:install cave
 ----
 
-The cave-server feature is a meta-feature which actually installs:
-
-* cave-storage feature providing the Cave filesystem default storage.
-* cave-http feature providing the Cave HTTP service allowing a remote access to the repositories.
-* cave-rest feature providing the Cave REST API allowing to manipulate the repository remotely with any REST HTTP client.
-* cave-maven feature providing a complete Maven repository for the Cave repositories.
+The `cave` feature installs all Cave features, including the repositories server and the deployer.
 
 After the installation of the cave-server feature, new commands are available:
 
@@ -67,4 +51,5 @@ karaf@root()> cave:<TAB>
 cave:repositories            cave:repository-create       cave:repository-destroy
 cave:repository-install      cave:repository-populate     cave:repository-proxy
 cave:repository-uninstall    cave:repository-update       cave:repository-upload
+...
 ----
diff --git a/manual/src/main/asciidoc/user-guide/maven-wrapper.adoc b/manual/src/main/asciidoc/user-guide/maven-wrapper.adoc
index f062cbc..3f5ff82 100644
--- a/manual/src/main/asciidoc/user-guide/maven-wrapper.adoc
+++ b/manual/src/main/asciidoc/user-guide/maven-wrapper.adoc
@@ -33,7 +33,7 @@ my-repository | /opt/apache-karaf-4.0.0/data/cave/my-repository
 You can access the corresponding Maven repository using:
 
 ----
-http://localhost:8181/cave/maven
+http://localhost:8181/cave/maven/repositories/my-repository
 ----
 
 [NOTE]
@@ -44,11 +44,11 @@ The port 8181 is the default one of the Apache Karaf HTTP service.
 You can see that the URL follows the format:
 
 ----
-http://[cave_server_hostname]:[http_service_port]/cave/maven/
+http://[cave_server_hostname]:[http_service_port]/cave/maven/repositories/my-repository
 ----
 
 For instance, if a Cave repository contains the commons-lang 2.6 artifact, it's accessible using:
 
 ----
-http://localhost:8181/cave/maven/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
+http://localhost:8181/cave/maven/repositories/my-repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
 ----
diff --git a/pom.xml b/pom.xml
index 7f7ec13..2df9f1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,8 +53,8 @@
 
     <modules>
         <module>server</module>
-        <!-- <module>client</module> -->
         <module>deployer</module>
+        <module>rest</module>
         <module>manual</module>
         <module>assembly</module>
     </modules>
@@ -464,7 +464,9 @@
                             <excludes>
                                 <exclude>**/target/**/*</exclude>
                                 <exclude>**/*.iml</exclude>
+                                <exclude>**/*.kar</exclude>
                             </excludes>
+                            <consoleOutput>true</consoleOutput>
                         </configuration>
                     </plugin>
                 </plugins>
diff --git a/deployer/rest/pom.xml b/rest/pom.xml
similarity index 60%
rename from deployer/rest/pom.xml
rename to rest/pom.xml
index 8448ebf..7fa2f5d 100644
--- a/deployer/rest/pom.xml
+++ b/rest/pom.xml
@@ -22,15 +22,15 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.karaf.cave</groupId>
-        <artifactId>org.apache.karaf.cave.deployer</artifactId>
+        <groupId>org.apache.karaf</groupId>
+        <artifactId>cave</artifactId>
         <version>4.1.1-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <groupId>org.apache.karaf.cave.deployer</groupId>
-    <artifactId>org.apache.karaf.cave.deployer.rest</artifactId>
-    <name>Apache Karaf :: Cave :: Deployer :: REST</name>
+    <groupId>org.apache.karaf.cave</groupId>
+    <artifactId>org.apache.karaf.cave.rest</artifactId>
+    <name>Apache Karaf :: Cave :: REST</name>
     <packaging>bundle</packaging>
 
     <dependencies>
@@ -39,6 +39,11 @@
             <artifactId>org.apache.karaf.cave.deployer.api</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.cave.server</groupId>
+            <artifactId>org.apache.karaf.cave.server.api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-rt-frontend-jaxrs</artifactId>
@@ -49,6 +54,28 @@
             <artifactId>cxf-rt-transports-http</artifactId>
             <version>${cxf.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+            <version>2.9.6</version>
+        </dependency>
+        <dependency>
+            <groupId>${servlet.spec.groupId}</groupId>
+            <artifactId>${servlet.spec.artifactId}</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>org.apache.karaf.util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.cmpn</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>junit</groupId>
@@ -66,17 +93,25 @@
 
     <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>
-                <extensions>true</extensions>
-                <inherited>true</inherited>
                 <configuration>
                     <instructions>
                         <Import-Package>
-                            org.apache.karaf.cave.deployer.api,
+                            org.apache.karaf.cave.server.api;resolution:=optional,
+                            org.apache.karaf.cave.deployer.api;resolution:=optional,
+                            com.fasterxml.jackson.jaxrs*;version="[2,3)",
+                            org.apache.cxf*;version="[3,4)",
                             *
                         </Import-Package>
+                        <Private-Package>
+                            org.apache.karaf.util
+                        </Private-Package>
                     </instructions>
                 </configuration>
             </plugin>
diff --git a/rest/src/main/java/org/apache/karaf/cave/rest/Activator.java b/rest/src/main/java/org/apache/karaf/cave/rest/Activator.java
new file mode 100644
index 0000000..14270f6
--- /dev/null
+++ b/rest/src/main/java/org/apache/karaf/cave/rest/Activator.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.cave.rest;
+
+import org.apache.karaf.cave.deployer.api.Deployer;
+import org.apache.karaf.cave.server.api.CaveRepositoryService;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.util.tracker.annotation.RequireService;
+import org.apache.karaf.util.tracker.annotation.Services;
+import org.osgi.service.http.HttpService;
+
+@Services(
+        requires = {
+                @RequireService(HttpService.class),
+                @RequireService(CaveRepositoryService.class),
+                @RequireService(Deployer.class)
+        }
+)
+public class Activator extends BaseActivator {
+
+    private HttpService httpService;
+    private CaveRestServlet restServlet;
+
+    @Override
+    public void doStart() throws Exception {
+        httpService = getTrackedService(HttpService.class);
+        if (httpService == null) {
+            return;
+        }
+
+        CaveRepositoryService repositoryService = getTrackedService(CaveRepositoryService.class);
+        Deployer deployerService = getTrackedService(Deployer.class);
+
+        RepositoryRest repositoryRest = new RepositoryRest(repositoryService);
+        DeployerRest deployerRest = new DeployerRest(deployerService);
+        restServlet = new CaveRestServlet(repositoryRest, deployerRest);
+        httpService.registerServlet("/cave/rest", restServlet, null, null);
+    }
+
+    @Override
+    public void doStop() {
+        if (httpService != null) {
+            if (restServlet != null) {
+                httpService.unregister("/cave/rest");
+            }
+        }
+        if (restServlet != null) {
+            restServlet.destroy();
+        }
+        super.doStop();
+    }
+
+}
diff --git a/rest/src/main/java/org/apache/karaf/cave/rest/CaveRestServlet.java b/rest/src/main/java/org/apache/karaf/cave/rest/CaveRestServlet.java
new file mode 100644
index 0000000..6801cfe
--- /dev/null
+++ b/rest/src/main/java/org/apache/karaf/cave/rest/CaveRestServlet.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.cave.rest;
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+public class CaveRestServlet extends CXFNonSpringServlet {
+
+    private RepositoryRest repositoryRest;
+    private DeployerRest deployerRest;
+
+    public CaveRestServlet(RepositoryRest repositoryRest, DeployerRest deployerRest) {
+        this.repositoryRest = repositoryRest;
+        this.deployerRest = deployerRest;
+    }
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+
+        if (repositoryRest != null) {
+            JAXRSServerFactoryBean repositoryBean = new JAXRSServerFactoryBean();
+            repositoryBean.setAddress("/repository");
+            repositoryBean.setBus(getBus());
+            repositoryBean.setProvider(new JacksonJsonProvider());
+            repositoryBean.setServiceBean(repositoryRest);
+            repositoryBean.create();
+        }
+
+        if (deployerRest != null) {
+            JAXRSServerFactoryBean deployerBean = new JAXRSServerFactoryBean();
+            deployerBean.setAddress("/deployer");
+            deployerBean.setBus(getBus());
+            deployerBean.setProvider(new JacksonJsonProvider());
+            deployerBean.setServiceBean(deployerRest);
+            deployerBean.create();
+        }
+
+    }
+
+}
diff --git a/deployer/rest/src/main/java/org/apache/karaf/cave/deployer/rest/DeployerRest.java b/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
similarity index 92%
rename from deployer/rest/src/main/java/org/apache/karaf/cave/deployer/rest/DeployerRest.java
rename to rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
index 2b4d67b..04fa81f 100644
--- a/deployer/rest/src/main/java/org/apache/karaf/cave/deployer/rest/DeployerRest.java
+++ b/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
@@ -14,11 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.karaf.cave.deployer.rest;
-
-import org.apache.karaf.cave.deployer.api.*;
-
-import javax.ws.rs.*;
+package org.apache.karaf.cave.rest;
+
+import org.apache.karaf.cave.deployer.api.Bundle;
+import org.apache.karaf.cave.deployer.api.Config;
+import org.apache.karaf.cave.deployer.api.Connection;
+import org.apache.karaf.cave.deployer.api.Deployer;
+import org.apache.karaf.cave.deployer.api.Feature;
+import org.apache.karaf.cave.deployer.api.FeaturesRepository;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import java.util.List;
 import java.util.Map;
 
@@ -27,6 +39,30 @@
 
     private Deployer deployer;
 
+    public DeployerRest(Deployer deployer) {
+        this.deployer = deployer;
+    }
+
+    @Path("/connections")
+    @Produces("application/json")
+    @GET
+    public List<Connection> connections() throws Exception {
+        return deployer.connections();
+    }
+
+    @Path("/connections")
+    @Consumes("application/json")
+    @POST
+    public void registerConnection(Connection connection) throws Exception {
+        deployer.registerConnection(connection);
+    }
+
+    @Path("/connections/{name}")
+    @DELETE
+    public void deleteConnection(@PathParam("name") String name) throws Exception {
+        deployer.deleteConnection(name);
+    }
+
     public static class KarExplodeRequest {
 
         private String artifactUrl;
diff --git a/rest/src/main/java/org/apache/karaf/cave/rest/RepositoryRest.java b/rest/src/main/java/org/apache/karaf/cave/rest/RepositoryRest.java
new file mode 100644
index 0000000..ed4b3ea
--- /dev/null
+++ b/rest/src/main/java/org/apache/karaf/cave/rest/RepositoryRest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.cave.rest;
+
+import org.apache.karaf.cave.server.api.CaveRepository;
+import org.apache.karaf.cave.server.api.CaveRepositoryService;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Service to manipulate a Cave repository.
+ */
+@Path("/")
+public class RepositoryRest {
+
+    private final CaveRepositoryService service;
+
+    public RepositoryRest(CaveRepositoryService service) {
+        this.service = service;
+    }
+
+    class Repository {
+        private String name;
+        private String location;
+        private String realm;
+        private String downloadRole;
+        private String uploadRole;
+        private boolean scan;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public String getLocation() {
+            return location;
+        }
+
+        public void setLocation(String location) {
+            this.location = location;
+        }
+
+        public String getRealm() {
+            return realm;
+        }
+
+        public void setRealm(String realm) {
+            this.realm = realm;
+        }
+
+        public String getDownloadRole() {
+            return downloadRole;
+        }
+
+        public void setDownloadRole(String downloadRole) {
+            this.downloadRole = downloadRole;
+        }
+
+        public String getUploadRole() {
+            return uploadRole;
+        }
+
+        public void setUploadRole(String uploadRole) {
+            this.uploadRole = uploadRole;
+        }
+
+        public boolean isScan() {
+            return scan;
+        }
+
+        public void setScan(boolean scan) {
+            this.scan = scan;
+        }
+    }
+
+    @POST
+    @Path("/repositories")
+    @Consumes("application/json")
+    public void create(Repository repository) throws Exception {
+        service.create(repository.getName(),
+                repository.getLocation(),
+                repository.getRealm(),
+                repository.getDownloadRole(),
+                repository.getUploadRole(),
+                repository.isScan());
+    }
+
+    @POST
+    @Path("/repositories/{name}/uninstall")
+    public void uninstall(@PathParam(value = "name") String name) throws Exception {
+        service.uninstall(name);
+    }
+
+    @POST
+    @Path("/repositories/{name}/remove")
+    public void remove(@PathParam(value = "name") String name) throws Exception {
+        service.remove(name);
+    }
+
+    @DELETE
+    @Path("/repositories/{name}")
+    public void destroy(@PathParam(value = "name") String name) throws Exception {
+        service.destroy(name);
+    }
+
+    @POST
+    @Path("/repositories/{name}/install")
+    public void install(@PathParam(value = "name") String name) throws Exception {
+        service.install(name);
+    }
+
+    @GET
+    @Path("/repositories")
+    @Produces("application/json")
+    public List<Repository> getRepositories() {
+        CaveRepository[] repositories = service.getRepositories();
+        List<Repository> repos = new ArrayList<>();
+        for (int i = 0; i < repositories.length; i++) {
+            Repository repo = new Repository();
+            repo.setName(repositories[i].getName());
+            repo.setLocation(repositories[i].getLocation());
+            repo.setRealm(repositories[i].getRealm());
+            repo.setDownloadRole(repositories[i].getDownloadRole());
+            repo.setUploadRole(repositories[i].getUploadRole());
+            repos.add(repo);
+        }
+        return repos;
+    }
+
+    @GET
+    @Path("/repositories/{name}")
+    @Produces("application/json")
+    public Repository getRepository(@PathParam("name") String name) {
+        CaveRepository repository = service.getRepository(name);
+        if (repository != null) {
+            Repository repo = new Repository();
+            repo.setName(repository.getName());
+            repo.setLocation(repository.getLocation());
+            repo.setRealm(repository.getRealm());
+            repo.setDownloadRole(repository.getDownloadRole());
+            repo.setUploadRole(repository.getUploadRole());
+            return repo;
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/deployer/rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java b/rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java
similarity index 95%
rename from deployer/rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java
rename to rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java
index 59262a9..f4caf78 100644
--- a/deployer/rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java
+++ b/rest/src/test/java/org/apache/karaf/cave/deployer/rest/DeployerRestTest.java
@@ -18,12 +18,10 @@
 
 import org.apache.karaf.cave.deployer.api.Deployer;
 import org.apache.karaf.cave.deployer.service.impl.DeployerImpl;
+import org.apache.karaf.cave.rest.DeployerRest;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
-import java.util.Arrays;
-
 public class DeployerRestTest {
 
     private DeployerRest rest;
@@ -33,8 +31,7 @@ public void init() throws Exception {
         System.setProperty("java.protocol.handler.pkgs", "org.ops4j.pax.url");
         System.setProperty("java.io.tmpdir", "target");
         Deployer deployer = new DeployerImpl();
-        rest = new DeployerRest();
-        rest.setDeployer(deployer);
+        rest = new DeployerRest(deployer);
     }
 
     @Test
diff --git a/deployer/rest/src/test/resources/test.kar b/rest/src/test/resources/test.kar
similarity index 100%
rename from deployer/rest/src/test/resources/test.kar
rename to rest/src/test/resources/test.kar
diff --git a/server/pom.xml b/server/pom.xml
index 7bf8293..82f7736 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -39,7 +39,6 @@
         <module>management</module>
         <module>command</module>
         <module>http</module>
-        <module>rest</module>
         <module>maven</module>
     </modules>
 
diff --git a/server/rest/NOTICE b/server/rest/NOTICE
deleted file mode 100644
index 2bd5453..0000000
--- a/server/rest/NOTICE
+++ /dev/null
@@ -1,29 +0,0 @@
-Apache Karaf Cave
-Copyright 2010-2014 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.
-
-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
-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
diff --git a/server/rest/pom.xml b/server/rest/pom.xml
deleted file mode 100644
index 86ec48e..0000000
--- a/server/rest/pom.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?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.cave</groupId>
-        <artifactId>org.apache.karaf.cave.server</artifactId>
-        <version>4.1.1-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.apache.karaf.cave.server</groupId>
-    <artifactId>org.apache.karaf.cave.server.rest</artifactId>
-    <name>Apache Karaf :: Cave :: Server :: Rest</name>
-    <packaging>bundle</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>${servlet.spec.groupId}</groupId>
-            <artifactId>${servlet.spec.artifactId}</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.karaf.cave.server</groupId>
-            <artifactId>org.apache.karaf.cave.server.storage</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.cxf</groupId>
-            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.karaf</groupId>
-            <artifactId>org.apache.karaf.util</artifactId>
-        </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>
-                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
-                        <Private-Package>
-                            org.apache.karaf.util
-                        </Private-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Activator.java b/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Activator.java
deleted file mode 100644
index 735391a..0000000
--- a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Activator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.server.rest;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
-import org.apache.karaf.cave.server.api.CaveRepositoryService;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.apache.karaf.util.tracker.annotation.Managed;
-import org.apache.karaf.util.tracker.annotation.RequireService;
-import org.apache.karaf.util.tracker.annotation.Services;
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.http.HttpService;
-
-
-@Services(
-        requires = { @RequireService(CaveRepositoryService.class),
-                     @RequireService(HttpService.class) }
-)
-@Managed("org.apache.karaf.cave.server.rest")
-public class Activator extends BaseActivator implements ManagedService {
-
-    private HttpService httpService;
-    private String alias;
-    private CXFNonSpringJaxrsServlet servlet;
-
-    @Override
-    protected void doStart() throws Exception {
-        httpService = getTrackedService(HttpService.class);
-        if (httpService == null) {
-            return;
-        }
-
-        Service service = new Service(getTrackedService(CaveRepositoryService.class));
-
-        String alias = getString("cave.rest.alias", "/cave/rest");
-        Hashtable<String, String> config = new Hashtable<>();
-        if (getConfiguration() != null) {
-            for (Enumeration<String> e = getConfiguration().keys(); e.hasMoreElements();) {
-                String key = e.nextElement();
-                String val = getConfiguration().get(key).toString();
-                config.put(key, val);
-            }
-        }
-        this.alias = alias;
-        this.servlet = new CaveRestServlet(service);
-        this.httpService.registerServlet(this.alias, this.servlet, config, null);
-    }
-
-    @Override
-    protected void doStop() {
-        if (httpService != null) {
-            try {
-                httpService.unregister(alias);
-            } catch (Throwable t) {
-                logger.debug("Exception caught while stopping", t);
-            } finally {
-                httpService = null;
-            }
-        }
-        if (servlet != null) {
-            try {
-                servlet.destroy();
-            } catch (Throwable t) {
-                logger.debug("Exception caught while stopping", t);
-            } finally {
-                servlet = null;
-            }
-
-        }
-        super.doStop();
-    }
-
-}
diff --git a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/CaveRestServlet.java b/server/rest/src/main/java/org/apache/karaf/cave/server/rest/CaveRestServlet.java
deleted file mode 100644
index 74e505d..0000000
--- a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/CaveRestServlet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.server.rest;
-
-import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
-
-public class CaveRestServlet extends CXFNonSpringJaxrsServlet {
-
-    public CaveRestServlet(Object singletonService) {
-        super(singletonService);
-    }
-
-}
diff --git a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Repository.java b/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Repository.java
deleted file mode 100644
index aca0b5e..0000000
--- a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Repository.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.server.rest;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-import org.apache.karaf.cave.server.api.CaveRepository;
-import org.apache.karaf.util.XmlUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-@XmlRootElement(name = "cave-repository")
-@XmlAccessorType(XmlAccessType.NONE)
-@XmlType(name = "Repository", propOrder = {"name", "increment", "location", "resources"})
-public class Repository {
-
-    @XmlElement(name = "name")
-    private String name;
-    @XmlElement(name = "increment")
-    private long increment;
-    @XmlElement(name = "location")
-    private String location;
-    @XmlElement(name = "resources")
-    private List<Resource> resources;
-    
-    public Repository() {
-        // require for JABX IllegalAnnotationExceptions
-    }
-
-    public Repository(CaveRepository repository) {
-        this.name = repository.getName();
-        this.increment = repository.getIncrement();
-        this.location = repository.getLocation();
-
-        try {
-            Document doc = XmlUtils.parse(repository.getRepositoryXml().toExternalForm());
-
-            // get all resource elements
-            NodeList resourceList = doc.getElementsByTagName("resource");
-
-            if (resourceList.getLength() > 0) {
-                this.resources = new ArrayList<>();
-            }
-
-            // read resource
-            for (int vI = 0; vI < resourceList.getLength(); vI++) {
-
-                Element nodeResource = (Element) resourceList.item(vI);
-                Resource resource = new Resource();
-
-                NodeList capabilityList = nodeResource.getElementsByTagName("capability");
-
-                // read capability
-                for (int vInt = 0; vInt < capabilityList.getLength(); vInt++) {
-
-                    Element capability = (Element) capabilityList.item(vInt);
-
-                    if (capability.hasAttribute("namespace")) {
-
-                        Element attribute = (Element) capability.getFirstChild();
-
-                        while (attribute != null) {
-
-                            if (capability.getAttribute("namespace").equals("osgi.identity")) {
-
-                                switch (attribute.getAttribute("name")) {
-                                    case "osgi.identity":
-                                        resource.setIdentity(attribute.getAttribute("value"));
-                                        break;
-                                    case "type":
-                                        resource.setType(attribute.getAttribute("value"));
-                                        break;
-                                    case "version":
-                                        resource.setVersion(attribute.getAttribute("value"));
-                                        break;
-                                    default:
-                                        break;
-                                }
-
-                            } else if (capability.getAttribute("namespace")
-                                    .equals("osgi.content")) {
-                                switch (attribute.getAttribute("name")) {
-                                    case "url":
-                                        // name of the artefact, the baseURI of the HttpServlet
-                                        // for download is not available
-                                        resource.setArtefact(attribute.getAttribute("value"));
-                                        break;
-                                    default:
-                                        break;
-                                }
-                            }
-
-                            attribute = (Element) attribute.getNextSibling();
-                        }
-                    }
-                }
-
-                getResources().add(resource);
-            }
-
-        } catch (Exception exception) {
-            // do nothing
-        }
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String nameIn) {
-        name = nameIn;
-    }
-
-    public long getIncrement() {
-        return increment;
-    }
-
-    public void setIncrement(long incrementIn) {
-        increment = incrementIn;
-    }
-
-    public List<Resource> getResources() {
-        return resources;
-    }
-
-    public void setResources(List<Resource> resourcesIn) {
-        resources = resourcesIn;
-    }
-    
-    public String getLocation() {
-        return location;
-    }
-
-    public void setLocation(String locationIn) {
-        location = locationIn;
-    }
-
-}
diff --git a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Resource.java b/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Resource.java
deleted file mode 100644
index a26e193..0000000
--- a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Resource.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.server.rest;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "resource")
-@XmlAccessorType(XmlAccessType.NONE)
-@XmlType(name = "Resource", propOrder = {"identity", "type", "version", "artefact"})
-public class Resource {
-
-    @XmlElement(name = "identity")
-    private String identity;
-    @XmlElement(name = "type")
-    private String type;
-    @XmlElement(name = "version")
-    private String version;
-    @XmlElement(name = "artefact")
-    private String artefact;
-
-
-    public String getIdentity() {
-        return identity;
-    }
-
-    public void setIdentity(String pIdentity) {
-        identity = pIdentity;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String pType) {
-        type = pType;
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public void setVersion(String pVersion) {
-        version = pVersion;
-    }
-
-    public String getArtefact() {
-        return artefact;
-    }
-
-    public void setArtefact(String pArtefact) {
-        artefact = pArtefact;
-    }
-}
diff --git a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Service.java b/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Service.java
deleted file mode 100644
index bc659a2..0000000
--- a/server/rest/src/main/java/org/apache/karaf/cave/server/rest/Service.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.
- */
-package org.apache.karaf.cave.server.rest;
-
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-
-import org.apache.karaf.cave.server.api.CaveRepository;
-import org.apache.karaf.cave.server.api.CaveRepositoryService;
-
-/**
- * Service to manipulate a Cave repository.
- */
-@Path("/")
-public class Service {
-
-    private final CaveRepositoryService service;
-
-    public Service(CaveRepositoryService service) {
-        this.service = service;
-    }
-
-    /**
-     * Create a Cave repository.
-     *
-     * @param name the name of the repository
-     * @param scan if true, the repository is scanned at creation time, and the repository metadata are created.
-     * @return the Cave repository.
-     * @throws Exception in case of creation failure.
-     */
-    @POST
-    @Path("/repositories")
-    @Produces("application/json")
-    public Repository create(@QueryParam(value = "name") String name, @QueryParam(value = "scan") boolean scan) throws Exception {
-        return new Repository(service.create(name, scan));
-    }
-
-    /**
-     * Create a Cave repository.
-     *
-     * @param name the name of the repository.
-     * @param location the storage location of the repository.
-     * @param realm the JAAS realm
-     * @param downloadRole the users role allowed to download
-     * @param uploadRole the users role allowed to upload
-     * @param scan if true, the repository is scanned at creation time, and the repository metadata are created.
-     * @return the Cave repository.
-     * @throws Exception in case of creation failure.
-     */
-    @POST
-    @Path("/repositories")
-    @Produces("application/json")
-    public Repository create(@QueryParam(value = "name") String name,
-                             @QueryParam(value = "location") String location,
-                             @QueryParam(value = "realm") String realm,
-                             @QueryParam(value = "downloadRole") String downloadRole,
-                             @QueryParam(value = "uploadRole") String uploadRole,
-                             @QueryParam(value = "scan") boolean scan) throws Exception {
-        return new Repository(service.create(name, location, realm, downloadRole, uploadRole, scan));
-    }
-
-    /**
-     * Uninstall a Cave repository from the repository service.
-     *
-     * @param name the name of the repository.
-     * @throws Exception in case of uninstall failure.
-     */
-    @POST
-    @Path("/uninstall")
-    public void uninstall(@QueryParam(value = "name") String name) throws Exception {
-        service.uninstall(name);
-    }
-
-    /**
-     * Remove a Cave repository from the repositories registry.
-     *
-     * @param name the name of the repository.
-     * @throws Exception in case of remove failure.
-     */
-    @POST
-    @Path("/remove")
-    public void remove(@QueryParam(value = "name") String name) throws Exception {
-        service.remove(name);
-    }
-
-    /**
-     * Destroy a Cave repository, including the storage.
-     *
-     * @param name the name of the repository.
-     * @throws Exception incase of remove failure.
-     */
-    @DELETE
-    @Path("/repositories")
-    public void destroy(@QueryParam(value = "name") String name) throws Exception {
-        service.destroy(name);
-    }
-
-    /**
-     * Install a Cave repository into the repository service.
-     *
-     * @param name the name of the Cave repository.
-     * @throws Exception in case of registration failure.
-     */
-    @POST
-    @Path("/install")
-    public void install(@QueryParam(value = "name") String name) throws Exception {
-        service.install(name);
-    }
-
-    /**
-     * Get the list of all Cave repositories.
-     *
-     * @return the Cave repositories.
-     */
-    @GET
-    @Path("/repositories")
-    @Produces("application/json")
-    public Repository[] getRepositories() {
-        CaveRepository[] repositories = service.getRepositories();
-        Repository[] repos = new Repository[repositories.length];
-        for (int i = 0; i < repositories.length; i++) {
-            repos[i] = new Repository(repositories[i]);
-        }
-        
-        return repos;
-    }
-
-    /**
-     * Get a Cave repository identified by the given name.
-     *
-     * @param name the name of the Cave repository.
-     * @return the Cave repository
-     */
-    @GET
-    @Path("/repositories/{name}")
-    @Produces("application/json")
-    public Repository getRepository(@PathParam("name") String name) {
-        CaveRepository repository = service.getRepository(name);
-        if (repository != null) {
-            return new Repository(repository);
-        } else {
-            return null;
-        }
-    }
-
-}
diff --git a/server/storage/pom.xml b/server/storage/pom.xml
index 055429a..45d8669 100644
--- a/server/storage/pom.xml
+++ b/server/storage/pom.xml
@@ -91,6 +91,7 @@
                             !org.apache.felix.utils*,
                             !org.apache.felix.resolver,
                             !org.apache.felix.resolver.util,
+                            !org.apache.felix.resolver.reason,
                             org.apache.karaf.features;version="[2,5)",
                             *
                         </Import-Package>
@@ -98,6 +99,7 @@
                             org.apache.felix.utils*,
                             org.apache.felix.resolver,
                             org.apache.felix.resolver.util,
+                            org.apache.felix.resolver.reason,
                             org.apache.karaf.features.internal.model,
                             org.apache.karaf.features.internal.resolver,
                             org.apache.karaf.features.internal.repository,


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Change implementation of Cave Deployer REST to mimic Cave Server
> ----------------------------------------------------------------
>
>                 Key: KARAF-5783
>                 URL: https://issues.apache.org/jira/browse/KARAF-5783
>             Project: Karaf
>          Issue Type: Improvement
>          Components: cave-server
>            Reporter: Francois Papon
>            Assignee: Jean-Baptiste Onofré
>            Priority: Major
>             Fix For: cave-4.1.1
>
>
> Actually,  the Cave Server Rest bundle use a CXFNonSpringJaxrsServlet in order to publish the Rest endpoint. 
> We should use Blueprint as the Cave Deployer Rest bundle.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message