You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2022/08/13 13:34:27 UTC

[sling-maven-plugin] branch bugfix/fix-mount-goals created (now 6d03945)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch bugfix/fix-mount-goals
in repository https://gitbox.apache.org/repos/asf/sling-maven-plugin.git


      at 6d03945  SLING-11522 fix mount goals

This branch includes the following new commits:

     new 6d03945  SLING-11522 fix mount goals

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-maven-plugin] 01/01: SLING-11522 fix mount goals

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch bugfix/fix-mount-goals
in repository https://gitbox.apache.org/repos/asf/sling-maven-plugin.git

commit 6d0394556b11d89b5edc99a6d3edae3df21ee858
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sat Aug 13 15:34:22 2022 +0200

    SLING-11522 fix mount goals
    
    add ITs for mount and validate goals
    improve logging
---
 src/it/fs-mount-test/invoker.properties            |  17 +++
 src/it/fs-mount-test/pom.xml                       | 115 +++++++++++++++++++++
 .../src/main/webapp/app-root/example.txt           |  19 ++++
 src/it/fs-mount-test/verify.groovy                 |  22 ++++
 src/it/validate-test/invoker.properties            |  18 ++++
 src/it/validate-test/pom.xml                       |  73 +++++++++++++
 .../validate-test/src/main/resources/invalid.json  |   3 +
 src/it/validate-test/verify.groovy                 |  22 ++++
 .../bundlesupport/AbstractBundleInstallMojo.java   |   4 +-
 .../bundlesupport/AbstractBundleRequestMojo.java   |  26 ++++-
 .../maven/bundlesupport/BundlePrerequisite.java    |   7 +-
 .../maven/bundlesupport/BundleUninstallMojo.java   |   2 +-
 .../sling/maven/bundlesupport/FsMountMojo.java     |  27 ++++-
 .../sling/maven/bundlesupport/FsUnMountMojo.java   |   6 +-
 .../ResponseCodeEnforcingResponseHandler.java      |  85 +++++++++++++++
 .../deploy/method/WebDavPutDeployMethod.java       |  29 ------
 .../fsresource/FileVaultXmlMounter.java            |  24 +++--
 .../bundlesupport/fsresource/FsMountHelper.java    |  89 ++++++++++------
 .../fsresource/FsResourceConfiguration.java        |  31 ++++--
 .../fsresource/SlingInitialContentMounter.java     |  30 +++---
 20 files changed, 540 insertions(+), 109 deletions(-)

diff --git a/src/it/fs-mount-test/invoker.properties b/src/it/fs-mount-test/invoker.properties
new file mode 100644
index 0000000..84e0a98
--- /dev/null
+++ b/src/it/fs-mount-test/invoker.properties
@@ -0,0 +1,17 @@
+# 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.
+invoker.goals=install -Dsling.urlSuffix=/system/console
\ No newline at end of file
diff --git a/src/it/fs-mount-test/pom.xml b/src/it/fs-mount-test/pom.xml
new file mode 100644
index 0000000..f8c59dd
--- /dev/null
+++ b/src/it/fs-mount-test/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<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/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>example-pom</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <build>
+        <resources>
+            <!-- copy webapp resources to SLING-INF/app-root -->
+            <resource>
+                <directory>src/main/webapp</directory>
+                <targetPath>SLING-INF</targetPath>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>3.3.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.10.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.22.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-install-plugin</artifactId>
+                    <version>3.0.1</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.3.0</version>
+                <executions>
+                    <execution>
+                        <id>copy</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>io.wcm</groupId>
+                                    <artifactId>io.wcm.caconfig.editor</artifactId>
+                                    <version>1.8.0</version>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <destFileName>ca-config-editor.jar</destFileName>
+                                </artifactItem>
+                            </artifactItems>
+                            <!-- other configurations here -->
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>@project.groupId@</groupId>
+                <artifactId>@project.artifactId@</artifactId>
+                <version>@project.version@</version>
+                <executions>
+                    <execution>
+                        <id>fsmount</id>
+                        <goals>
+                            <goal>fsmount</goal>
+                        </goals>
+                        <phase>install</phase>
+                    </execution>
+                    <execution>
+                        <id>fsunmount</id>
+                        <goals>
+                            <goal>fsunmount</goal>
+                        </goals>
+                        <phase>install</phase>
+                    </execution>
+                </executions>
+                <configuration>
+                    <!-- try a bundle with Sling Initial content -->
+                    <bundleFileName>${project.build.directory}/ca-config-editor.jar</bundleFileName>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/src/it/fs-mount-test/src/main/webapp/app-root/example.txt b/src/it/fs-mount-test/src/main/webapp/app-root/example.txt
new file mode 100644
index 0000000..99ca447
--- /dev/null
+++ b/src/it/fs-mount-test/src/main/webapp/app-root/example.txt
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+Dummy file
\ No newline at end of file
diff --git a/src/it/fs-mount-test/verify.groovy b/src/it/fs-mount-test/verify.groovy
new file mode 100644
index 0000000..e488cd4
--- /dev/null
+++ b/src/it/fs-mount-test/verify.groovy
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+String buildLog = new File(basedir, 'build.log').text
+
+assert buildLog.contains('[INFO] Added new configuration for resource path /apps/wcm-io/caconfig/editor to server')
+assert buildLog.contains('[INFO] Removed configuration for resource path /apps/wcm-io/caconfig/editor')
diff --git a/src/it/validate-test/invoker.properties b/src/it/validate-test/invoker.properties
new file mode 100644
index 0000000..abd4d0a
--- /dev/null
+++ b/src/it/validate-test/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+invoker.goals=install
+invoker.buildResult=failure
\ No newline at end of file
diff --git a/src/it/validate-test/pom.xml b/src/it/validate-test/pom.xml
new file mode 100644
index 0000000..6bc4be2
--- /dev/null
+++ b/src/it/validate-test/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<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/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>example-pom</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>3.3.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.10.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.22.1</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-install-plugin</artifactId>
+                    <version>3.0.1</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        
+        <plugins>
+            <plugin>
+                <groupId>@project.groupId@</groupId>
+                <artifactId>@project.artifactId@</artifactId>
+                <version>@project.version@</version>
+                <executions>
+                    <execution>
+                        <id>validate</id>
+                        <goals>
+                            <goal>validate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <!-- try a bundle with Sling Initial content -->
+                    <bundleFileName>${project.build.directory}/ca-config-editor.jar</bundleFileName>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/src/it/validate-test/src/main/resources/invalid.json b/src/it/validate-test/src/main/resources/invalid.json
new file mode 100644
index 0000000..3bd37ee
--- /dev/null
+++ b/src/it/validate-test/src/main/resources/invalid.json
@@ -0,0 +1,3 @@
+{
+  some test: "test"
+}
\ No newline at end of file
diff --git a/src/it/validate-test/verify.groovy b/src/it/validate-test/verify.groovy
new file mode 100644
index 0000000..c145f94
--- /dev/null
+++ b/src/it/validate-test/verify.groovy
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+String buildLog = new File(basedir, 'build.log').text
+
+assert buildLog.contains('invalid.json [2:4]: Invalid JSON: Unexpected character \'s\' (Codepoint: 115). Reason is [[Expected structural character or digit or \'t\' or \'n\' or \'f\' or \'-\']]')
+assert buildLog.contains('validate (validate) on project example-pom: Validated 1 file(s), found 1 failures. -> [Help 1]')
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleInstallMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleInstallMojo.java
index e6c3bb2..385bd67 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleInstallMojo.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleInstallMojo.java
@@ -160,8 +160,8 @@ abstract class AbstractBundleInstallMojo extends AbstractBundleRequestMojo {
         }
     }
     
-    protected void configure(CloseableHttpClient httpClient, final URI targetURL, final File file) throws MojoExecutionException {
-        new SlingInitialContentMounter(getLog(), httpClient, project).mount(targetURL, file);
+    protected void configure(CloseableHttpClient httpClient, final URI consoleTargetURL, final File file) throws MojoExecutionException {
+        new SlingInitialContentMounter(getLog(), httpClient, getRequestConfigBuilder(), project).mount(consoleTargetURL, file);
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleRequestMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleRequestMojo.java
index 8203640..9517807 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleRequestMojo.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/AbstractBundleRequestMojo.java
@@ -92,6 +92,23 @@ abstract class AbstractBundleRequestMojo extends AbstractMojo {
     @Parameter(property = "sling.failOnError", defaultValue = "true", required = true)
     protected boolean failOnError;
 
+    /**
+     * HTTP connection timeout (in seconds). Determines the timeout until a new connection is fully established.
+     * This may also include transport security negotiation exchanges
+     * such as {@code SSL} or {@code TLS} protocol negotiation).
+     * @since 3.0.0
+     */
+    @Parameter(property = "sling.httpConnectTimeoutSec", defaultValue = "10")
+    private int httpConnectTimeoutSec;
+
+    /**
+     * HTTP response timeout (in seconds). Determines the timeout until arrival of a response from the opposite
+     * endpoint.
+     * @since 3.0.0
+     */
+    @Parameter(property = "sling.httpResponseTimeoutSec", defaultValue = "60")
+    private int httpResponseTimeoutSec;
+
     /**
      * Returns the symbolic name of the given bundle. If the
      * <code>jarFile</code> does not contain a manifest with a
@@ -191,14 +208,17 @@ abstract class AbstractBundleRequestMojo extends AbstractMojo {
         // restrict to the Sling URL only
         final HttpHost target = new HttpHost(getTargetURL().getScheme(), getTargetURL().getHost(), getTargetURL().getPort());
 
-        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(Timeout.ofSeconds(5)).build();
-        
         return HttpClients.custom()
-                .setDefaultRequestConfig(requestConfig)
+                .setDefaultRequestConfig(getRequestConfigBuilder().build())
                 .addRequestInterceptorFirst(new PreemptiveBasicAuthInterceptor(basicAuth, target, getLog()))
                 .build();
     }
 
+    protected RequestConfig.Builder getRequestConfigBuilder() {
+        return RequestConfig.custom()
+            .setConnectTimeout(Timeout.ofSeconds(httpConnectTimeoutSec))
+            .setResponseTimeout(Timeout.ofSeconds(httpResponseTimeoutSec));
+    }
 
     private static final class PreemptiveBasicAuthInterceptor implements HttpRequestInterceptor {
 
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/BundlePrerequisite.java b/src/main/java/org/apache/sling/maven/bundlesupport/BundlePrerequisite.java
index a6afbef..a976ab2 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/BundlePrerequisite.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/BundlePrerequisite.java
@@ -129,7 +129,12 @@ public final class BundlePrerequisite {
                 return this.version;
             }
         }
-        
+
+        @Override
+        public String toString() {
+            return "Bundle [groupId=" + groupId + ", artifactId=" + artifactId + ", version=" + version + ", symbolicName=" + symbolicName
+                    + "]";
+        }
     }
 
 }
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/BundleUninstallMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/BundleUninstallMojo.java
index 3d17b05..2721437 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/BundleUninstallMojo.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/BundleUninstallMojo.java
@@ -114,7 +114,7 @@ public class BundleUninstallMojo extends AbstractBundleInstallMojo {
 
     @Override
     protected void configure(CloseableHttpClient httpClient, final URI targetURL, final File file) throws MojoExecutionException {
-        new SlingInitialContentMounter(getLog(), httpClient, project).unmount(targetURL);
+        new SlingInitialContentMounter(getLog(), httpClient, getRequestConfigBuilder(), project).unmount(targetURL);
     }
     
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/FsMountMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/FsMountMojo.java
index a2dcac7..6109f1c 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/FsMountMojo.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/FsMountMojo.java
@@ -22,15 +22,18 @@ import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import javax.json.JsonArray;
 import javax.json.JsonException;
 import javax.json.JsonObject;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hc.client5.http.HttpResponseException;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpStatus;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
@@ -50,6 +53,8 @@ import org.apache.sling.maven.bundlesupport.fsresource.SlingInitialContentMounte
 /**
  * Create OSGi configurations for the
  * <a href="https://sling.apache.org/documentation/bundles/accessing-filesystem-resources-extensions-fsresource.html">Apache Sling File System Resource Provider</a>.
+ * In case a bundle file is provided via {@link AbstractFsMountMojo#bundleFileName} the configuration for its <a href="https://sling.apache.org/documentation/bundles/content-loading-jcr-contentloader.html#initial-content-loading">initial content</a> is created.
+ * Otherwise it tries to detect a FileVault XML layout within {@link AbstractFsMountMojo#fileVaultJcrRootFile} or the project's base directory and potentially creates a configuration for each path in the package's {@code filter.xml}. 
  * @since 2.2.0
  */
 @Mojo(name = "fsmount", requiresProject = true)
@@ -164,12 +169,12 @@ public class FsMountMojo extends AbstractFsMountMojo {
 
     @Override
     protected void configureSlingInitialContent(CloseableHttpClient httpClient, final URI targetUrl, final File bundleFile) throws MojoExecutionException {
-        new SlingInitialContentMounter(getLog(), getHttpClient(), project).mount(targetUrl, bundleFile);
+        new SlingInitialContentMounter(getLog(), getHttpClient(), getRequestConfigBuilder(), project).mount(targetUrl, bundleFile);
     }
 
     @Override
     protected void configureFileVaultXml(CloseableHttpClient httpClient, URI targetUrl, File jcrRootFile, File filterXmlFile) throws MojoExecutionException {
-        new FileVaultXmlMounter(getLog(), httpClient, project).mount(targetUrl, jcrRootFile, filterXmlFile);
+        new FileVaultXmlMounter(getLog(), httpClient, getRequestConfigBuilder(), project).mount(targetUrl, jcrRootFile, filterXmlFile);
     }
 
     @Override
@@ -198,6 +203,8 @@ public class FsMountMojo extends AbstractFsMountMojo {
                     deployBundle(httpClient, bundle, targetUrl);
                 }
                 break;
+            } else {
+                throw new MojoExecutionException("Target server does not meet prerequisites for this goal. Haven't found the necessary bundles: " + bundlePrerequisite.getPreconditions().stream().map(BundlePrerequisite.Bundle::toString).collect(Collectors.joining(", ")));
             }
         }
     }
@@ -208,7 +215,10 @@ public class FsMountMojo extends AbstractFsMountMojo {
                 getLog().debug("Bundle " + bundle.getSymbolicName() + " " + bundle.getOsgiVersion() + " (or higher) already installed.");
                 return;
             }
-            
+        } catch(IOException e) {
+            throw new MojoExecutionException("Error getting installation status of " + bundle + " via " + targetUrl + ": " + e.getMessage(), e);
+        }
+        try {
             getLog().info("Installing Bundle " + bundle.getSymbolicName() + " " + bundle.getOsgiVersion() + " to "
                         + targetUrl + " via " + deploymentMethod);
             
@@ -255,11 +265,12 @@ public class FsMountMojo extends AbstractFsMountMojo {
      * @throws MojoExecutionException
      */
     private String getBundleInstalledVersion(CloseableHttpClient httpClient, final String bundleSymbolicName, final URI targetUrl) throws IOException {
-        final URI getUrl = targetUrl.resolve( "/bundles/" + bundleSymbolicName + ".json");
+        final URI getUrl = targetUrl.resolve( "/system/console/bundles/" + bundleSymbolicName + ".json");
+        getLog().debug("Get bundle data via request to " + getUrl);
         final HttpGet get = new HttpGet(getUrl);
 
-        final String jsonText = httpClient.execute(get, new BasicHttpClientResponseHandler());
         try {
+            final String jsonText = httpClient.execute(get, new BasicHttpClientResponseHandler());
             JsonObject response = JsonSupport.parseObject(jsonText);
             JsonArray data = response.getJsonArray("data");
             if (!data.isEmpty()) {
@@ -270,6 +281,12 @@ public class FsMountMojo extends AbstractFsMountMojo {
         } catch (JsonException ex) {
             throw new IOException("Reading bundle data from " + getUrl
                     + " failed, cause: " + ex.getMessage(), ex);
+        } catch (HttpResponseException e) {
+            // accept 404 response
+            if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+                return null;
+            }
+            throw e;
         }
         // no version detected, bundle is not installed
         return null;
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/FsUnMountMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/FsUnMountMojo.java
index 962887d..2d5aae5 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/FsUnMountMojo.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/FsUnMountMojo.java
@@ -29,6 +29,8 @@ import org.apache.sling.maven.bundlesupport.fsresource.SlingInitialContentMounte
 /**
  * Remove OSGi configurations for the 
  * <a href="https://sling.apache.org/documentation/bundles/accessing-filesystem-resources-extensions-fsresource.html">Apache Sling File System Resource Provider</a>.
+ * In case a bundle file is provided via {@link AbstractFsMountMojo#bundleFileName} the configuration for its <a href="https://sling.apache.org/documentation/bundles/content-loading-jcr-contentloader.html#initial-content-loading">initial content</a> is removed.
+ * Otherwise it tries to detect a FileVault XML layout within {@link AbstractFsMountMojo#fileVaultJcrRootFile} or the project's base directory and potentially removes the configurations for each path in the package's {@code filter.xml}. 
  * @since 2.2.0
  */
 @Mojo(name = "fsunmount", requiresProject = true)
@@ -36,12 +38,12 @@ public class FsUnMountMojo extends AbstractFsMountMojo {
 
     @Override
     protected void configureSlingInitialContent(CloseableHttpClient httpClient, final URI targetUrl, final File bundleFile) throws MojoExecutionException {
-        new SlingInitialContentMounter(getLog(), httpClient, project).unmount(targetUrl);
+        new SlingInitialContentMounter(getLog(), httpClient, getRequestConfigBuilder(), project).unmount(targetUrl);
     }
 
     @Override
     protected void configureFileVaultXml(CloseableHttpClient httpClient, URI targetUrl, File jcrRootFile, File filterXmlFile) throws MojoExecutionException {
-        new FileVaultXmlMounter(getLog(), httpClient, project).unmount(targetUrl, jcrRootFile, filterXmlFile);
+        new FileVaultXmlMounter(getLog(), httpClient, getRequestConfigBuilder(), project).unmount(targetUrl, jcrRootFile, filterXmlFile);
     }
 
     @Override
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/ResponseCodeEnforcingResponseHandler.java b/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/ResponseCodeEnforcingResponseHandler.java
new file mode 100644
index 0000000..2f56f26
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/ResponseCodeEnforcingResponseHandler.java
@@ -0,0 +1,85 @@
+/*
+ * 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.sling.maven.bundlesupport.deploy.method;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpResponseException;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+
+/**
+ * Throws {@link HttpResponseException} for all response codes except for the accepted ones.
+ * In addition optionally checks for a certain content type and content of the response.
+ * Returns the response code if all checks pass.
+ *
+ */
+public final class ResponseCodeEnforcingResponseHandler implements HttpClientResponseHandler<Integer> {
+
+    private final List<Integer> allowedCodes;
+    private final String expectedContentType; // may be null
+    private final Predicate<String> responseStringPredicate; // may be null
+
+    public ResponseCodeEnforcingResponseHandler(Integer... allowedCodes) {
+        this(null, allowedCodes);
+    }
+
+    public ResponseCodeEnforcingResponseHandler(String expectedContentType, Integer... allowedCodes) {
+        this(expectedContentType, null, allowedCodes);
+    }
+
+    public ResponseCodeEnforcingResponseHandler(String expectedContentType, Predicate<String> responseStringPredicate, Integer... allowedCodes) {
+        this.expectedContentType = expectedContentType;
+        this.responseStringPredicate = responseStringPredicate;
+        this.allowedCodes = Arrays.asList(allowedCodes);
+    }
+
+    @Override
+    public Integer handleResponse(ClassicHttpResponse response) throws HttpException, IOException {
+        final HttpEntity entity = response.getEntity();
+        try {
+            if (responseStringPredicate != null) {
+                String responseContent = EntityUtils.toString(entity);
+                if (!responseStringPredicate.test(responseContent)) {
+                    throw new ClientProtocolException("Unexpected response content returned: " + responseContent);
+                }
+            }
+            if (!allowedCodes.contains(response.getCode())) {
+                throw new HttpResponseException(response.getCode(), "Unexpected response code " + response.getCode() + ": " + response.getReasonPhrase());
+            }
+            String actualContentType = Optional.ofNullable(response.getHeader(HttpHeaders.CONTENT_TYPE)).map(Header::getValue).orElse(null);
+            if (expectedContentType != null && expectedContentType.equals(actualContentType)) {
+                throw new ClientProtocolException("Unexpected content type returned, expected " + expectedContentType + " but was " + actualContentType);
+            }
+        } finally {
+            EntityUtils.consume(entity);
+        }
+        return response.getCode();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/WebDavPutDeployMethod.java b/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/WebDavPutDeployMethod.java
index 0e96a94..de3877a 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/WebDavPutDeployMethod.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/deploy/method/WebDavPutDeployMethod.java
@@ -21,7 +21,6 @@ package org.apache.sling.maven.bundlesupport.deploy.method;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.util.Arrays;
 import java.util.List;
 
 import org.apache.hc.client5.http.HttpResponseException;
@@ -29,13 +28,8 @@ import org.apache.hc.client5.http.classic.methods.HttpDelete;
 import org.apache.hc.client5.http.classic.methods.HttpHead;
 import org.apache.hc.client5.http.classic.methods.HttpPut;
 import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.FileEntity;
 import org.apache.sling.maven.bundlesupport.deploy.DeployContext;
 import org.apache.sling.maven.bundlesupport.deploy.DeployMethod;
@@ -83,29 +77,6 @@ public class WebDavPutDeployMethod implements DeployMethod {
         // this never returns a body
     }
 
-    /**
-     * Throws {@link HttpResponseException} for all response codes except for the accepted ones.
-     * Returns the response code otherwise.
-     *
-     */
-    private static final class ResponseCodeEnforcingResponseHandler implements HttpClientResponseHandler<Integer> {
-
-        private final List<Integer> allowedCodes;
-        public ResponseCodeEnforcingResponseHandler(Integer... allowedCodes) {
-            this.allowedCodes = Arrays.asList(allowedCodes);
-        }
-
-        @Override
-        public Integer handleResponse(ClassicHttpResponse response) throws HttpException, IOException {
-            final HttpEntity entity = response.getEntity();
-            EntityUtils.consume(entity);
-            if (!allowedCodes.contains(response.getCode())) {
-                throw new HttpResponseException(response.getCode(), "Unexpected response code " + response.getCode() + ": " + response.getReasonPhrase());
-            }
-            return null;
-        }
-    }
-
     private void performMkCol(URI uri, DeployContext context) throws IOException {
         WebDavMkCol mkCol = new WebDavMkCol(uri);
         String response = context.getHttpClient().execute(mkCol, new BasicHttpClientResponseHandler());
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FileVaultXmlMounter.java b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FileVaultXmlMounter.java
index e1c5cd3..1c32f56 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FileVaultXmlMounter.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FileVaultXmlMounter.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
 import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
@@ -42,19 +43,19 @@ public final class FileVaultXmlMounter {
     private final Log log;
     private final FsMountHelper helper;
 
-    public FileVaultXmlMounter(Log log, CloseableHttpClient httpClient, MavenProject project) {
+    public FileVaultXmlMounter(Log log, CloseableHttpClient httpClient, RequestConfig.Builder requestConfigBuilder, MavenProject project) {
         this.log = log;
-        this.helper = new FsMountHelper(log, httpClient, project);
+        this.helper = new FsMountHelper(log, httpClient, requestConfigBuilder, project);
     }
 
     /**
      * Add configurations to a running OSGi instance for FileVault XML
-     * @param targetUrl The web console base url
+     * @param consoleTargetUrl The web console base url
      * @param jcrRootFile jcr_root directory
      * @param filterXmlFile FileVault Filter XML file
      * @throws MojoExecutionException Exception
      */
-    public void mount(final URI targetUrl, final File jcrRootFile, final File filterXmlFile) throws MojoExecutionException {
+    public void mount(final URI consoleTargetUrl, final File jcrRootFile, final File filterXmlFile) throws MojoExecutionException {
         log.info("Trying to configure file system provider...");
 
         // create config for each path defined in filter
@@ -63,29 +64,30 @@ public final class FileVaultXmlMounter {
         for (PathFilterSet filterSet : workspaceFilter.getFilterSets()) {
             cfgs.add(new FsResourceConfiguration()
                     .fsMode(FsMode.FILEVAULT_XML)
-                    .contentRootDir(jcrRootFile.getAbsolutePath())
-                    .providerRootPath(filterSet.getRoot())
+                    .fsRootPath(jcrRootFile.getAbsoluteFile())
+                    .resourceRootPath(filterSet.getRoot())
                     .fileVaultFilterXml(filterXmlFile.getAbsolutePath()));
+            log.info("Created new configuration for resource path " + filterSet.getRoot());
         }
      
         if (!cfgs.isEmpty()) {
-            helper.addConfigurations(targetUrl, cfgs);
+            helper.addConfigurations(consoleTargetUrl, cfgs);
         }
     }
     
     /**
      * Remove configurations to a running OSGi instance for FileVault XML
-     * @param targetUrl The web console base url
+     * @param consoleTargetUrl The web console base url
      * @param jcrRootFile jcr_root directory
      * @param filterXmlFile FileVault Filter XML file
      * @throws MojoExecutionException Exception
      */
-    public void unmount(final URI targetUrl, final File jcrRootFile, final File filterXmlFile) throws MojoExecutionException {
+    public void unmount(final URI consoleTargetUrl, final File jcrRootFile, final File filterXmlFile) throws MojoExecutionException {
         log.info("Removing file system provider configurations...");
 
         // remove all current configs for this project
-        final Map<String,FsResourceConfiguration> oldConfigs = helper.getCurrentConfigurations(targetUrl);
-        helper.removeConfigurations(targetUrl, oldConfigs);
+        final Map<String,FsResourceConfiguration> oldConfigs = helper.getCurrentConfigurations(consoleTargetUrl);
+        helper.removeConfigurations(consoleTargetUrl, oldConfigs);
     }
         
     private WorkspaceFilter getWorkspaceFilter(final File filterXmlFile) throws MojoExecutionException {
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsMountHelper.java b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsMountHelper.java
index d9412b8..bb88efa 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsMountHelper.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsMountHelper.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.maven.bundlesupport.fsresource;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
@@ -26,18 +27,23 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
+import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonException;
 import javax.json.JsonObject;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hc.client5.http.HttpResponseException;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
-import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.NameValuePair;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
@@ -46,6 +52,7 @@ import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 import org.apache.sling.maven.bundlesupport.JsonSupport;
+import org.apache.sling.maven.bundlesupport.deploy.method.ResponseCodeEnforcingResponseHandler;
 
 /**
  * Manages OSGi configurations for File System Resource Provider.
@@ -66,11 +73,13 @@ final class FsMountHelper {
         
     private final Log log;
     private final CloseableHttpClient httpClient;
+    private final RequestConfig.Builder requestConfigBuilder;
     private final MavenProject project;
 
-    public FsMountHelper(Log log, CloseableHttpClient httpClient, MavenProject project) {
+    public FsMountHelper(Log log, CloseableHttpClient httpClient, RequestConfig.Builder requestConfigBuilder, MavenProject project) {
         this.log = log;
         this.httpClient = httpClient;
+        this.requestConfigBuilder = requestConfigBuilder;
         this.project = project;
     }
     
@@ -81,7 +90,7 @@ final class FsMountHelper {
         final Map<String,FsResourceConfiguration> oldConfigs = getCurrentConfigurations(targetUrl);
 
         for (FsResourceConfiguration cfg : cfgs) {
-            log.info("Mapping " + cfg.getContentRootDir() + " to " + cfg.getProviderRootPath());
+            log.debug("Found mapping " + cfg.getFsRootPath() + " to " + cfg.getResourceRootPath());
             
             // check if this is already configured
             boolean found = false;
@@ -89,23 +98,24 @@ final class FsMountHelper {
             while ( !found && entryIterator.hasNext() ) {
                 final Map.Entry<String,FsResourceConfiguration> current = entryIterator.next();
                 final FsResourceConfiguration oldcfg = current.getValue();
-                log.debug("Comparing " + oldcfg.getContentRootDir() + " with " + oldcfg);
-                if (StringUtils.equals(oldcfg.getContentRootDir(), oldcfg.getContentRootDir())) {
+                log.debug("Comparing " + oldcfg.getFsRootPath() + " with " + oldcfg);
+                if (Objects.equals(oldcfg.getFsRootPath(), cfg.getFsRootPath())) {
                     if (cfg.equals(oldcfg)) {
-                        log.debug("Using existing configuration for " + cfg.getContentRootDir() + " and " + cfg.getProviderRootPath());
+                        log.info("Using existing configuration for " + cfg.getFsRootPath() + " mounted at " + cfg.getResourceRootPath());
                         found = true;
                     }
                     else {
                         // remove old config
-                        log.debug("Removing old configuration for " + oldcfg);
+                        log.info("Removing old configuration for " + oldcfg);
                         removeConfiguration(targetUrl, current.getKey());
                     }
                     entryIterator.remove();
                 }
             }
             if ( !found ) {
-                log.debug("Adding new configuration for " + cfg.getContentRootDir() + " and " + cfg.getProviderRootPath());
+                log.debug("Adding new configuration for " + cfg.getFsRootPath() + " mounted at " + cfg.getResourceRootPath());
                 addConfiguration(targetUrl, cfg);
+                log.info("Added new configuration for resource path "+ cfg.getResourceRootPath() + " to server");
             }
         }
         
@@ -116,13 +126,19 @@ final class FsMountHelper {
     /**
      * Add a new configuration for the file system provider
      */
-    private void addConfiguration(final URI targetUrl, FsResourceConfiguration cfg) throws MojoExecutionException {
-        final URI postUrl = targetUrl.resolve("/configMgr/" + FS_FACTORY);
+    private void addConfiguration(final URI consoleTargetUrl, FsResourceConfiguration cfg) throws MojoExecutionException {
+        final URI postUrl = consoleTargetUrl.resolve("configMgr/" + FS_FACTORY);
         final HttpPost post = new HttpPost(postUrl);
         List<NameValuePair> params = new ArrayList<>();
         params.add(new BasicNameValuePair("apply", "true"));
         params.add(new BasicNameValuePair("factoryPid", FS_FACTORY));
-        params.add(new BasicNameValuePair("pid", "[Temporary PID replaced by real PID upon save]"));
+        /*
+         * The pid parameter is mandatory but is replaced with another value upon save() for factories
+         * For that it must have the magic value from
+         * https://github.com/apache/felix-dev/blob/6603d69977f4cea8b9b9dd2faf5d320906b43368/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationUtil.java#L36
+         * This value is also used for performing a redirect and is no valid URI, therefore disable redirect handling
+         */
+        params.add(new BasicNameValuePair("pid", "[Temporary PID replaced by real PID upon save]")); // this is replaced with a generated one, upon save, still this is used for the redirect
         Map<String,String> props = toMap(cfg);
         for (Map.Entry<String,String> entry : props.entrySet()) {
             params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
@@ -130,9 +146,14 @@ final class FsMountHelper {
         params.add(new BasicNameValuePair("propertylist", StringUtils.join(props.keySet(), ",")));
         post.setEntity(new UrlEncodedFormEntity(params));
         
+        // do not follow redirects
+        RequestConfig requestConfig = requestConfigBuilder.setRedirectsEnabled(false).build();
+        HttpClientContext httpContext = HttpClientContext.create();
+        httpContext.setRequestConfig(requestConfig);
         try {
-            String response = httpClient.execute(post, new BasicHttpClientResponseHandler());
-            log.debug("Configuration created: " + response);
+            // accept also 302
+            httpClient.execute(post, httpContext, new ResponseCodeEnforcingResponseHandler(HttpStatus.SC_MOVED_TEMPORARILY));
+            log.debug("New configuration created POST to " + postUrl);
         }
         catch (IOException ex) {
             throw new MojoExecutionException("Configuration on " + postUrl + " failed, cause: " + ex.getMessage(), ex);
@@ -144,13 +165,13 @@ final class FsMountHelper {
         if (cfg.getFsMode() != null) {
             props.put(PROPERTY_FSMODE, cfg.getFsMode().name());
         }
-        if (cfg.getContentRootDir() != null) {
-            props.put(PROPERTY_PATH, cfg.getContentRootDir());
+        if (cfg.getFsRootPath() != null) {
+            props.put(PROPERTY_PATH, cfg.getFsRootPath().toString());
         }
-        if (cfg.getProviderRootPath() != null) {
+        if (cfg.getResourceRootPath() != null) {
             // save property value to both "provider.roots" and "provider.root" because the name has changed between fsresource 1.x and 2.x
-            props.put(PROPERTY_ROOT, cfg.getProviderRootPath());
-            props.put(PROPERTY_ROOTS, cfg.getProviderRootPath());
+            props.put(PROPERTY_ROOT, cfg.getResourceRootPath());
+            props.put(PROPERTY_ROOTS, cfg.getResourceRootPath());
         }
         if (cfg.getInitialContentImportOptions() != null) {
             props.put(PROPERTY_INITIAL_CONTENT_IMPORT_OPTIONS, cfg.getInitialContentImportOptions());
@@ -169,14 +190,15 @@ final class FsMountHelper {
             log.debug("Removing configuration for " + current.getValue());
             // remove old config
             removeConfiguration(targetUrl, current.getKey());
+            log.info("Removed configuration for resource path " + current.getValue().getResourceRootPath() + " (PID: " + current.getKey() + ") from server");
         }
     }
 
     /**
      * Remove configuration.
      */
-    private void removeConfiguration(final URI targetUrl, final String pid) throws MojoExecutionException {
-        final URI postUrl = targetUrl.resolve("/configMgr/" + pid);
+    private void removeConfiguration(final URI consoleTargetUrl, final String pid) throws MojoExecutionException {
+        final URI postUrl = consoleTargetUrl.resolve("configMgr/" + pid);
         final HttpPost post = new HttpPost(postUrl);
         List<NameValuePair> params = new ArrayList<>();
         params.add(new BasicNameValuePair("apply", "true"));
@@ -184,9 +206,11 @@ final class FsMountHelper {
         post.setEntity(new UrlEncodedFormEntity(params));
        
         try {
-            String response = httpClient.execute(post, new BasicHttpClientResponseHandler());
-            // we get a moved temporarily back from the configMgr plugin
-            log.debug("Configuration removed: " + response);
+            JsonObject expectedJsonResponse = Json.createObjectBuilder().add("status", true).build();
+            // https://github.com/apache/felix-dev/blob/6603d69977f4cea8b9b9dd2faf5d320906b43368/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java#L145
+            httpClient.execute(post, new ResponseCodeEnforcingResponseHandler("application/json", 
+                    response ->  JsonSupport.parseObject(response).equals(expectedJsonResponse),
+                    HttpStatus.SC_OK));
         }
         catch (IOException ex) {
             throw new MojoExecutionException("Removing configuration at " + postUrl
@@ -196,19 +220,19 @@ final class FsMountHelper {
 
     /**
      * Return all file provider configs for this project
-     * @param targetUrl The targetUrl of the webconsole
+     * @param consoleTargetUrl The web console base url
      * @return A map (may be empty) with the pids as keys and the configurations as values
      * @throws MojoExecutionException
      */
-    public Map<String,FsResourceConfiguration> getCurrentConfigurations(final URI targetUrl) throws MojoExecutionException {
-        log.debug("Getting current file provider configurations.");
+    public Map<String,FsResourceConfiguration> getCurrentConfigurations(final URI consoleTargetUrl) throws MojoExecutionException {
         final Map<String,FsResourceConfiguration> result = new HashMap<>();
-        final URI getUrl = targetUrl.resolve("/configMgr/(service.factoryPid=" + FS_FACTORY + ").json");
+        final URI getUrl = consoleTargetUrl.resolve("configMgr/(service.factoryPid=" + FS_FACTORY + ").json");
+        log.debug("Getting current file provider configurations via GET from " + getUrl);
         final HttpGet get = new HttpGet(getUrl);
 
         try (CloseableHttpResponse response = httpClient.execute(get)) {
             final int status = response.getCode();
-            if ( status == 200 ) {
+            if ( status == HttpStatus.SC_OK ) {
                 String contentType = response.getHeader(HEADER_CONTENT_TYPE).getValue();
                 int pos = contentType.indexOf(';');
                 if ( pos != -1 ) {
@@ -238,18 +262,23 @@ final class FsMountHelper {
                         if (path != null && path.startsWith(this.project.getBasedir().getAbsolutePath()) && root != null) {
                             FsResourceConfiguration cfg = new FsResourceConfiguration()
                                     .fsMode(fsmode)
-                                    .providerRootPath(path)
-                                    .contentRootDir(root)
+                                    .resourceRootPath(root)
+                                    .fsRootPath(new File(path))
                                     .initialContentImportOptions(initialContentImportOptions)
                                     .fileVaultFilterXml(fileVaultFilterXml);
                             log.debug("Found configuration with pid: " + pid + ", " + cfg);
                             result.put(pid, cfg);
                         }
                     }
+                    if (array.isEmpty()) {
+                        log.info("Found no existing configurations for factory PID " + FS_FACTORY);
+                    }
                 } catch (JsonException ex) {
                     throw new MojoExecutionException("Reading configuration from " + getUrl
                             + " failed, cause: " + ex.getMessage(), ex);
                 }
+            } else {
+                throw new HttpResponseException(response.getCode(), "Unexpected status code " + response.getCode() + ": " + response.getReasonPhrase());
             }
         }
         catch (IOException | ProtocolException ex) {
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsResourceConfiguration.java b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsResourceConfiguration.java
index 3a81408..2202c6c 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsResourceConfiguration.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/FsResourceConfiguration.java
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.maven.bundlesupport.fsresource;
 
+import java.io.File;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
@@ -27,8 +29,8 @@ import org.apache.commons.lang3.builder.ToStringStyle;
 class FsResourceConfiguration {
 
     private FsMode fsMode;
-    private String providerRootPath;
-    private String contentRootDir;
+    private String resourceRootPath; // absolute resource path
+    private File fsRootPath; // absolute filesystem path
     private String initialContentImportOptions;
     private String fileVaultFilterXml;
 
@@ -49,25 +51,29 @@ class FsResourceConfiguration {
         return this;
     }
 
-    public String getProviderRootPath() {
-        return providerRootPath;
+    public String getResourceRootPath() {
+        return resourceRootPath;
     }
-    public FsResourceConfiguration providerRootPath(String value) {
-        this.providerRootPath = value;
+    public FsResourceConfiguration resourceRootPath(String value) {
+        this.resourceRootPath = value;
         return this;
     }
 
-    public String getContentRootDir() {
-        return contentRootDir;
+    public File getFsRootPath() {
+        return fsRootPath;
     }
-    public FsResourceConfiguration contentRootDir(String value) {
-        this.contentRootDir = value;
+    public FsResourceConfiguration fsRootPath(File value) {
+        if (!value.isAbsolute()) {
+            throw new IllegalArgumentException("The given filesystem path must be absolute");
+        }
+        this.fsRootPath = value;
         return this;
     }
 
     public String getInitialContentImportOptions() {
         return initialContentImportOptions;
     }
+
     public FsResourceConfiguration initialContentImportOptions(String value) {
         this.initialContentImportOptions = value;
         return this;
@@ -76,19 +82,22 @@ class FsResourceConfiguration {
     public String getStringVaultFilterXml() {
         return fileVaultFilterXml;
     }
+
     public FsResourceConfiguration fileVaultFilterXml(String value) {
         this.fileVaultFilterXml = value;
         return this;
     }
-    
+
     @Override
     public int hashCode() {
         return HashCodeBuilder.reflectionHashCode(this);
     }
+
     @Override
     public boolean equals(Object obj) {
         return EqualsBuilder.reflectionEquals(this, obj);
     }
+
     @Override
     public String toString() {
         return ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/SlingInitialContentMounter.java b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/SlingInitialContentMounter.java
index fb340a4..1e6d6d3 100644
--- a/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/SlingInitialContentMounter.java
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/fsresource/SlingInitialContentMounter.java
@@ -29,6 +29,7 @@ import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -49,19 +50,19 @@ public final class SlingInitialContentMounter {
     private final MavenProject project;
     private final FsMountHelper helper;
 
-    public SlingInitialContentMounter(Log log, CloseableHttpClient httpClient, MavenProject project) {
+    public SlingInitialContentMounter(Log log, CloseableHttpClient httpClient, RequestConfig.Builder requestConfigBuilder, MavenProject project) {
         this.log = log;
         this.project = project;
-        this.helper = new FsMountHelper(log, httpClient, project);
+        this.helper = new FsMountHelper(log, httpClient, requestConfigBuilder, project);
     }
 
     /**
      * Add configurations to a running OSGi instance for initial content.
-     * @param targetUrl The web console base url
+     * @param consoleTargetUrl The web console base url
      * @param bundleFile The artifact (bundle)
      * @throws MojoExecutionException Exception
      */
-    public void mount(final URI targetUrl, final File bundleFile) throws MojoExecutionException {
+    public void mount(final URI consoleTargetUrl, final File bundleFile) throws MojoExecutionException {
         // first, let's get the manifest and see if initial content is configured
         ManifestHeader header = null;
         try {
@@ -82,7 +83,7 @@ public final class SlingInitialContentMounter {
 
         log.info("Trying to configure file system provider...");
         // quick check if resources are configured
-        final List resources = project.getResources();
+        final List<Resource> resources = project.getResources();
         if ( resources == null || resources.size() == 0 ) {
             throw new MojoExecutionException("No resources configured for this project.");
         }
@@ -107,7 +108,7 @@ public final class SlingInitialContentMounter {
             // search the path in the resources (usually this should be the first resource
             // entry but this might be reconfigured
             File dir = null;
-            final Iterator i = resources.iterator();
+            final Iterator<Resource> i = resources.iterator();
             while ( dir == null && i.hasNext() ) {
                 final Resource rsrc = (Resource)i.next();
                 String child = path;
@@ -116,6 +117,7 @@ public final class SlingInitialContentMounter {
                 if ( targetPath != null && !targetPath.endsWith("/") ) {
                     targetPath = targetPath + "/";
                 }
+                log.debug("Checking if project resource '" + rsrc.getDirectory() + "' with target path '" + targetPath + "' is a potential mount point for " + path + " ..." );
                 if ( targetPath != null && path != null && path.startsWith(targetPath) ) {
                     child = child.substring(targetPath.length());
                 }
@@ -145,30 +147,30 @@ public final class SlingInitialContentMounter {
                 }
                 importOptions.append("ignoreImportProviders:=\"" + ignoreImportProvidersValue + "\"");
             }
-            
             cfgs.add(new FsResourceConfiguration()
                     .fsMode(FsMode.INITIAL_CONTENT)
-                    .contentRootDir(dir.getAbsolutePath())
-                    .providerRootPath(installPath)
+                    .fsRootPath(dir.getAbsoluteFile())
+                    .resourceRootPath(installPath)
                     .initialContentImportOptions(importOptions.toString()));
+            log.info("Created new configuration for resource path " + installPath);
         }
 
         if (!cfgs.isEmpty()) {
-            helper.addConfigurations(targetUrl, cfgs);
+            helper.addConfigurations(consoleTargetUrl, cfgs);
         }
     }
 
     /**
      * Remove configurations from a running OSGi instance for initial content.
-     * @param targetUrl The web console base url (up to the parent resource of the affected bundle)
+     * @param consoleTargetUrl The web console base url
      * @throws MojoExecutionException Exception
      */
-    public void unmount(final URI targetUrl) throws MojoExecutionException {
+    public void unmount(final URI consoleTargetUrl) throws MojoExecutionException {
         log.info("Removing file system provider configurations...");
 
         // remove all current configs for this project
-        final Map<String,FsResourceConfiguration> oldConfigs = helper.getCurrentConfigurations(targetUrl);
-        helper.removeConfigurations(targetUrl, oldConfigs);
+        final Map<String,FsResourceConfiguration> oldConfigs = helper.getCurrentConfigurations(consoleTargetUrl);
+        helper.removeConfigurations(consoleTargetUrl, oldConfigs);
     }
     
     /**