You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gg...@apache.org on 2016/11/04 16:57:52 UTC

[1/2] karaf git commit: [KARAF-4773] AbstractRetryableDownloadTask is smarter with pax-url-aether 2.5.0

Repository: karaf
Updated Branches:
  refs/heads/master bc22e0b3b -> dd7b5bdd4


[KARAF-4773] AbstractRetryableDownloadTask is smarter with pax-url-aether 2.5.0


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/e4f9ead5
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/e4f9ead5
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/e4f9ead5

Branch: refs/heads/master
Commit: e4f9ead54c348d206ddedb3fd54444ec9fbf1cb8
Parents: bc22e0b
Author: Grzegorz Grzybek <gr...@gmail.com>
Authored: Fri Nov 4 17:00:57 2016 +0100
Committer: Grzegorz Grzybek <gr...@gmail.com>
Committed: Fri Nov 4 17:00:57 2016 +0100

----------------------------------------------------------------------
 .../resources/etc/org.ops4j.pax.logging.cfg     |   4 +
 .../impl/AbstractRetryableDownloadTask.java     |  40 ++-
 .../download/impl/MavenDownloadTask.java        |  28 +-
 .../download/impl/SimpleDownloadTask.java       |   9 +-
 itests/pom.xml                                  |   8 +
 .../java/org/apache/karaf/itests/MavenTest.java | 257 +++++++++++++++++++
 .../src/test/resources/etc/maven-settings.xml   |  36 +++
 .../resources/etc/org.ops4j.pax.logging.cfg     |   4 +
 .../resources/etc/org.ops4j.pax.url.mvn.cfg     | 138 ++++++++++
 .../assembly/CustomSimpleDownloadTask.java      |   3 +-
 10 files changed, 518 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.logging.cfg
----------------------------------------------------------------------
diff --git a/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.logging.cfg b/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.logging.cfg
index 41f8f7e..b88a4e2 100644
--- a/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.logging.cfg
+++ b/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.logging.cfg
@@ -82,3 +82,7 @@ log4j2.appender.osgi.type = PaxOsgi
 log4j2.appender.osgi.name = PaxOsgi
 log4j2.appender.osgi.filter = *
 
+# help with identification of maven-related problems with pax-url-aether
+#log4j.logger.shaded.org.eclipse.aether = TRACE
+#log4j.logger.shaded.org.apache.http.headers = DEBUG
+#log4j.logger.org.ops4j.pax.url.mvn = TRACE

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/AbstractRetryableDownloadTask.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/AbstractRetryableDownloadTask.java b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/AbstractRetryableDownloadTask.java
index d324b23..b2d10d8 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/AbstractRetryableDownloadTask.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/AbstractRetryableDownloadTask.java
@@ -32,6 +32,8 @@ public abstract class AbstractRetryableDownloadTask extends AbstractDownloadTask
     private int scheduleMaxRun = 9;
     private int scheduleNbRun = 0;
 
+    private Exception previousException = null;
+
     public AbstractRetryableDownloadTask(ScheduledExecutorService executorService, String url) {
         super(executorService, url);
     }
@@ -55,12 +57,20 @@ public abstract class AbstractRetryableDownloadTask extends AbstractDownloadTask
     public void run() {
         try {
             try {
-                File file = download();
+                File file = download(previousException);
                 setFile(file);
             } catch (IOException e) {
-                if (++scheduleNbRun < scheduleMaxRun) {
+                Retry retry = isRetryable(e);
+                int retryCount = scheduleMaxRun;
+                if (retry == Retry.QUICK_RETRY) {
+                    retryCount = retryCount / 2; // arbitrary number...
+                } else if (retry == Retry.NO_RETRY) {
+                    retryCount = 0;
+                }
+                if (++scheduleNbRun < retryCount) {
+                    previousException = e;
                     long delay = (long)(scheduleDelay * 3 / 2 + Math.random() * scheduleDelay / 2);
-                    LOGGER.debug("Error downloading " + url + ": " + e.getMessage() + ". Retrying in approx " + delay + " ms.");
+                    LOGGER.debug("Error downloading " + url + ": " + e.getMessage() + ". " + retry + " in approx " + delay + " ms.");
                     executorService.schedule(this, delay, TimeUnit.MILLISECONDS);
                     scheduleDelay *= 2;
                 } else {
@@ -72,6 +82,28 @@ public abstract class AbstractRetryableDownloadTask extends AbstractDownloadTask
         }
     }
 
-    protected abstract File download() throws Exception;
+    protected Retry isRetryable(IOException e) {
+        return Retry.DEFAULT_RETRY;
+    }
+
+    /**
+     * Abstract download operation that may use <em>previous exception</em> as hint for optimized retry
+     * @param previousException
+     * @return
+     * @throws Exception
+     */
+    protected abstract File download(Exception previousException) throws Exception;
+
+    /**
+     * What kind of retry may be attempted
+     */
+    protected enum Retry {
+        /** Each retry would lead to the same result */
+        NO_RETRY,
+        /** It's ok to retry 2, 3 times, but no more */
+        QUICK_RETRY,
+        /** Retry with high expectation of success at some point */
+        DEFAULT_RETRY
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/MavenDownloadTask.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/MavenDownloadTask.java b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/MavenDownloadTask.java
index 0959e77..70a4594 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/MavenDownloadTask.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/MavenDownloadTask.java
@@ -17,6 +17,7 @@
 package org.apache.karaf.features.internal.download.impl;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.concurrent.ScheduledExecutorService;
 
 import org.ops4j.pax.url.mvn.MavenResolver;
@@ -30,8 +31,31 @@ public class MavenDownloadTask extends AbstractRetryableDownloadTask {
         this.resolver = resolver;
     }
 
-    protected File download() throws Exception {
-        return resolver.resolve(url);
+    @Override
+    protected File download(Exception previousException) throws Exception {
+        return resolver.resolve(url, previousException);
+    }
+
+    /**
+     * Maven artifact may be looked up in several repositories. Only if exception for <strong>each</strong>
+     * repository is not retryable, we won't retry.
+     * @param e
+     * @return
+     */
+    @Override
+    protected Retry isRetryable(IOException e) {
+        // convert pax-url-aether "retry" to features.core "retry" concept
+        switch (resolver.isRetryableException(e)) {
+            case NEVER:
+                return Retry.NO_RETRY;
+            case LOW:
+            case HIGH:
+                // no need to repeat many times
+                return Retry.QUICK_RETRY;
+            case UNKNOWN:
+            default:
+                return Retry.DEFAULT_RETRY;
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/SimpleDownloadTask.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/SimpleDownloadTask.java b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/SimpleDownloadTask.java
index be9090e..6e8c079 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/SimpleDownloadTask.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/download/impl/SimpleDownloadTask.java
@@ -46,7 +46,7 @@ public class SimpleDownloadTask extends AbstractRetryableDownloadTask {
     }
 
     @Override
-    protected File download() throws Exception {
+    protected File download(Exception previousExceptionNotUsed) throws Exception {
         LOG.trace("Downloading [" + url + "]");
 
         if (url.startsWith(BLUEPRINT_PREFIX) || url.startsWith(SPRING_PREFIX)) {
@@ -114,4 +114,11 @@ public class SimpleDownloadTask extends AbstractRetryableDownloadTask {
         }
         return tmpFile;
     }
+
+    @Override
+    protected Retry isRetryable(IOException e) {
+        // TODO: check http errors, etc.
+        return super.isRetryable(e);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/itests/pom.xml
----------------------------------------------------------------------
diff --git a/itests/pom.xml b/itests/pom.xml
index 490b7d0..f94364b 100644
--- a/itests/pom.xml
+++ b/itests/pom.xml
@@ -35,6 +35,7 @@
 
     <properties>
         <appendedResourcesDirectory>${basedir}/../etc/appended-resources</appendedResourcesDirectory>
+        <jetty.version>9.3.12.v20160915</jetty.version>
     </properties>
 
     <dependencies>
@@ -146,6 +147,13 @@
             <version>16.0.1</version>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/itests/src/test/java/org/apache/karaf/itests/MavenTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/MavenTest.java b/itests/src/test/java/org/apache/karaf/itests/MavenTest.java
new file mode 100644
index 0000000..3f2ed53
--- /dev/null
+++ b/itests/src/test/java/org/apache/karaf/itests/MavenTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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.itests;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.jetty.server.NetworkConnector;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.ProbeBuilder;
+import org.ops4j.pax.exam.TestProbeBuilder;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.url.mvn.MavenResolver;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.karaf.itests.KarafTestSupport.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.*;
+import static org.ops4j.pax.exam.CoreOptions.*;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class MavenTest /*extends KarafTestSupport*/ {
+
+    public static Logger LOG = LoggerFactory.getLogger(MavenTest.class);
+
+    private static Server server;
+    private static int port;
+
+    private static ExecutorService pool = Executors.newFixedThreadPool(1);
+
+    private static AtomicBoolean requestAtPort3333Done = new AtomicBoolean(false);
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    // don't extend, because we don't want @Rule Retry
+    private static KarafTestSupport karafTestSupport = new KarafTestSupport();
+
+    /**
+     * This server will act as HTTP proxy. @Test methods will change maven settings, where proxy is configured
+     * and update <code>org.ops4j.pax.ul.mvn</code> PID, which will republish {@link MavenResolver} service.
+     * @throws Exception
+     */
+    @BeforeClass
+    public static void startJetty() throws Exception {
+        server = new Server(0);
+        server.setHandler(new AbstractHandler() {
+            @Override
+            public void handle(String target, Request baseRequest, HttpServletRequest request,
+                               HttpServletResponse response) throws IOException, ServletException {
+                try {
+                    int port = baseRequest.getServerPort();
+                    if (port == 3333 && request.getRequestURI().endsWith(".jar")) {
+                        if (!requestAtPort3333Done.get()) {
+                            requestAtPort3333Done.set(true);
+                            // explicit timeout at first attempt - higher than the one set by Aether
+                            Thread.sleep(4000);
+                        }
+                        response.setStatus(HttpServletResponse.SC_OK);
+                        response.getOutputStream().write(0x42);
+                    } else {
+                        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+                    }
+                } catch (Exception ignored) {
+                } finally {
+                    baseRequest.setHandled(true);
+                }
+            }
+        });
+        server.start();
+        port = ((NetworkConnector) server.getConnectors()[0]).getLocalPort();
+    }
+
+    @AfterClass
+    public static void stopJetty() throws Exception {
+        server.stop();
+        pool.shutdown();
+    }
+
+    @ProbeBuilder
+    public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
+        probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*,org.apache.felix.service.*;status=provisional");
+        return probe;
+    }
+
+    private int getAvailablePort(int min, int max) {
+        for (int i = min; i <= max; i++) {
+            try {
+                ServerSocket socket = new ServerSocket(i);
+                return socket.getLocalPort();
+            } catch (Exception ignored) {
+            }
+        }
+        throw new IllegalStateException("Can't find available network ports");
+    }
+
+    @Configuration
+    public Option[] config() {
+        MavenArtifactUrlReference karafUrl = maven().groupId("org.apache.karaf").artifactId("apache-karaf").versionAsInProject().type("tar.gz");
+
+        String httpPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_HTTP_PORT), Integer.parseInt(MAX_HTTP_PORT)));
+        String rmiRegistryPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_RMI_REG_PORT), Integer.parseInt(MAX_RMI_REG_PORT)));
+        String rmiServerPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_RMI_SERVER_PORT), Integer.parseInt(MAX_RMI_SERVER_PORT)));
+        String sshPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_SSH_PORT), Integer.parseInt(MAX_SSH_PORT)));
+
+        Option[] baseOptions = new Option[] {
+                karafDistributionConfiguration().frameworkUrl(karafUrl).name("Apache Karaf").unpackDirectory(new File("target/exam")),
+                // enable JMX RBAC security, thanks to the KarafMBeanServerBuilder
+                configureSecurity().disableKarafMBeanServerBuilder(),
+                keepRuntimeFolder(),
+                logLevel(LogLevelOption.LogLevel.INFO),
+                replaceConfigurationFile("etc/org.ops4j.pax.logging.cfg", new File("src/test/resources/etc/org.ops4j.pax.logging.cfg")),
+                editConfigurationFilePut("etc/org.apache.karaf.features.cfg", "updateSnapshots", "none"),
+                editConfigurationFilePut("etc/org.ops4j.pax.web.cfg", "org.osgi.service.http.port", httpPort),
+                editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort),
+                editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort),
+                editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort),
+        };
+        List<Option> options = new LinkedList<>(Arrays.asList(baseOptions));
+
+        // Prepare default pax-url-aether configuration
+        options.addAll(Arrays.asList(
+//                new TimeoutOption(3600000),
+//                KarafDistributionOption.debugConfiguration("8889", false),
+                bundle("mvn:commons-io/commons-io/2.5"),
+                mavenBundle(maven().groupId("javax.servlet").artifactId("javax.servlet-api").versionAsInProject()).noStart(),
+                mavenBundle(maven().groupId("org.eclipse.jetty").artifactId("jetty-server").versionAsInProject()).noStart(),
+                mavenBundle(maven().groupId("org.eclipse.jetty").artifactId("jetty-http").versionAsInProject()).noStart(),
+                mavenBundle(maven().groupId("org.eclipse.jetty").artifactId("jetty-util").versionAsInProject()).noStart(),
+                mavenBundle(maven().groupId("org.eclipse.jetty").artifactId("jetty-io").versionAsInProject()).noStart(),
+                replaceConfigurationFile("etc/maven-settings.xml", new File("src/test/resources/etc/maven-settings.xml")),
+                replaceConfigurationFile("etc/org.ops4j.pax.url.mvn.cfg", new File("src/test/resources/etc/org.ops4j.pax.url.mvn.cfg"))
+        ));
+
+        return options.toArray(new Option[options.size()]);
+    }
+
+    @Test
+    public void smartRetriesTest() throws Exception {
+        karafTestSupport.bundleContext = bundleContext;
+        final ConfigurationAdmin cm = karafTestSupport.getOsgiService(ConfigurationAdmin.class, 3000);
+
+        updateSettings();
+
+        awaitMavenResolver(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    org.osgi.service.cm.Configuration config = cm.getConfiguration("org.ops4j.pax.url.mvn", null);
+                    Dictionary<String, Object> props = config.getProperties();
+                    props.put("org.ops4j.pax.url.mvn.globalChecksumPolicy", "ignore");
+                    props.put("org.ops4j.pax.url.mvn.socket.readTimeout", "2000");
+                    props.put("org.ops4j.pax.url.mvn.connection.retryCount", "0");
+                    props.put("org.ops4j.pax.url.mvn.repositories", "http://localhost:1111/repository@id=r1," +
+                            "http://localhost:2222/repository@id=r2," +
+                            "http://localhost:3333/repository@id=r3");
+                    config.update(props);
+                } catch (Exception e) {
+                    fail(e.getMessage());
+                }
+            }
+        });
+
+        // grab modified resolver
+        MavenResolver resolver = karafTestSupport.getOsgiService(MavenResolver.class, 15000);
+        try {
+            resolver.resolve("mvn:commons-universalis/commons-universalis/42");
+            fail("Should fail at first attempt");
+        } catch (IOException e) {
+            File f = resolver.resolve("mvn:commons-universalis/commons-universalis/42", e);
+            byte[] commonsUniversalis = FileUtils.readFileToByteArray(f);
+            assertThat(commonsUniversalis.length, equalTo(1));
+            assertThat(commonsUniversalis[0], equalTo((byte) 0x42));
+        }
+    }
+
+    private void updateSettings() throws IOException {
+        File settingsFile = new File(System.getProperty("karaf.home"), "etc/maven-settings.xml");
+        String settings = FileUtils.readFileToString(settingsFile);
+        settings = settings.replace("@@port@@", Integer.toString(port));
+        FileUtils.write(settingsFile, settings);
+    }
+
+    /**
+     * Invoke config admin task and await reregistration of {@link MavenResolver} service
+     */
+    private void awaitMavenResolver(Runnable task) throws Exception {
+        CountDownLatch latch = new CountDownLatch(2);
+        ServiceListener listener = new ServiceListener() {
+            @Override
+            public void serviceChanged(ServiceEvent event) {
+                if (event.getType() == ServiceEvent.UNREGISTERING || event.getType() == ServiceEvent.REGISTERED) {
+                    latch.countDown();
+                }
+            }
+        };
+        bundleContext.addServiceListener(listener, "(objectClass=org.ops4j.pax.url.mvn.MavenResolver)");
+        try {
+            task.run();
+            assertTrue(latch.await(5, TimeUnit.SECONDS));
+        } finally {
+            bundleContext.removeServiceListener(listener);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/itests/src/test/resources/etc/maven-settings.xml
----------------------------------------------------------------------
diff --git a/itests/src/test/resources/etc/maven-settings.xml b/itests/src/test/resources/etc/maven-settings.xml
new file mode 100644
index 0000000..6c760db
--- /dev/null
+++ b/itests/src/test/resources/etc/maven-settings.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+    <proxies>
+        <proxy>
+            <active>true</active>
+            <host>localhost</host>
+            <port>@@port@@</port>
+            <protocol>http</protocol>
+        </proxy>
+    </proxies>
+
+    <servers />
+    <mirrors />
+    <profiles />
+
+</settings>

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/itests/src/test/resources/etc/org.ops4j.pax.logging.cfg
----------------------------------------------------------------------
diff --git a/itests/src/test/resources/etc/org.ops4j.pax.logging.cfg b/itests/src/test/resources/etc/org.ops4j.pax.logging.cfg
index 97a33f9..dcd97d5 100644
--- a/itests/src/test/resources/etc/org.ops4j.pax.logging.cfg
+++ b/itests/src/test/resources/etc/org.ops4j.pax.logging.cfg
@@ -60,3 +60,7 @@ log4j2.appender.osgi.type = PaxOsgi
 log4j2.appender.osgi.name = PaxOsgi
 log4j2.appender.osgi.filter = *
 
+# help with identification of maven-related problems with pax-url-aether
+#log4j.logger.shaded.org.eclipse.aether = TRACE
+#log4j.logger.shaded.org.apache.http.headers = DEBUG
+#log4j.logger.org.ops4j.pax.url.mvn = TRACE

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
----------------------------------------------------------------------
diff --git a/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg b/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
new file mode 100644
index 0000000..6876301
--- /dev/null
+++ b/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
@@ -0,0 +1,138 @@
+################################################################################
+#
+#    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.
+#
+################################################################################
+
+#
+# see: https://ops4j1.jira.com/wiki/display/paxurl/Aether+Configuration
+#
+
+#
+# Path to the local Maven settings file.
+# The repositories defined in this file will be automatically added to the list
+# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property
+# below is not set.
+# The following locations are checked for the existence of the settings.xml file
+#   * 1. looks for the specified url
+#   * 2. if not found looks for ${user.home}/.m2/settings.xml
+#   * 3. if not found looks for ${maven.home}/conf/settings.xml
+#   * 4. if not found looks for ${M2_HOME}/conf/settings.xml
+#
+# Properties prefixed with "org.ops4j.pax.url.mvn." have
+# higher priority except <proxies> element. HTTP proxies should be configured in
+# settings file
+org.ops4j.pax.url.mvn.settings = ${karaf.etc}/maven-settings.xml
+
+#
+# Path to the local Maven repository which is used to avoid downloading
+# artifacts when they already exist locally.
+# The value of this property will be extracted from the settings.xml file
+# above, or defaulted to:
+#     System.getProperty( "user.home" ) + "/.m2/repository"
+# leaving this option commented makes the system dependent on external
+# configuration, which is not always desired
+# "localRepository" is the target location for artifacts downloaded from
+# "remote repositories", it's not searched for already available artifacts,
+# unless added explicitly to "defaultRepositories"
+# by default internal local repository is used to have behavior independent
+# of the content of ~/.m2/repository
+org.ops4j.pax.url.mvn.localRepository = ${karaf.data}/repository
+
+#
+# Default this to false. It's just weird to use undocumented repos
+# "false" means that http://repo1.maven.org/maven2@id=central won't be
+# implicitly used as remote repository
+#
+org.ops4j.pax.url.mvn.useFallbackRepositories = false
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# list of repositories searched in the first place, should contain
+# ${runtime.home}/${karaf.default.repository}.
+# if "org.ops4j.pax.url.mvn.localRepository" is defined and it's not
+# ~/.m2/repository, it's recommended (at least for dev purposes) to add
+# it to defaultRepositories
+# each of these repositories is checked by aether as "local repository". if
+# artifact isn't found, "repositories" are searched next
+#
+# Those repositories will be checked before iterating through the
+#    below list of repositories and even before the local repository
+# A repository url can be appended with zero or more of the following flags:
+#    @snapshots  : the repository contains snaphots
+#    @noreleases : the repository does not contain any released artifacts
+#
+# The following property value will add the system folder as a repo.
+#
+#org.ops4j.pax.url.mvn.defaultRepositories = \
+#    file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
+#    file:\${user.home}/.m2/repository@snapshots@id=local, \
+#    file:${karaf.data}/kar@id=kar.repository@multi@snapshots, \
+#    file:${karaf.base}/${karaf.default.repository}@id=child.system.repository@snapshots
+org.ops4j.pax.url.mvn.defaultRepositories = \
+    file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
+    file:${user.home}/.m2/repository@snapshots@id=local
+
+#
+# if "defaultLocalRepoAsRemote" is set do *any* value, localRepository will be
+# added to the list of remote repositories being searched for artifacts
+#
+#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote = true
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# list of repositories searched after resolution fails for "defaultRepositories"
+# These are true remote repositories accessed using maven/aether/wagon
+# mechanisms. If any repository contains required artifact, it is then written
+# to "localRepository"
+#
+# if this list is _prepended_ with '+' sign, all repositories from active
+# profiles defined in effective settings.xml file will be _appended_ to this
+# list
+# A repository url can be appended with zero or more of the following flags:
+#    @snapshots  : the repository contains snapshots
+#    @noreleases : the repository does not contain any released artifacts
+#    @id=repository.id : the id for the repository, just like in the
+#        settings.xml this is optional but recommended
+#
+org.ops4j.pax.url.mvn.repositories = \
+    http://repo1.maven.org/maven2@id=central
+
+org.ops4j.pax.url.mvn.globalUpdatePolicy = daily
+org.ops4j.pax.url.mvn.globalChecksumPolicy = warn
+
+#
+# socket and connection configuration
+#
+# default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout
+# are not specified
+org.ops4j.pax.url.mvn.timeout = 5000
+# timeout in ms when establishing http connection during artifact resolution
+org.ops4j.pax.url.mvn.socket.connectionTimeout = 5000
+# timeout in ms when reading data after connecting to remote repository
+org.ops4j.pax.url.mvn.socket.readTimeout = 30000
+# SO_KEEPALIVE option for sockets, defaults to false
+org.ops4j.pax.url.mvn.socket.keepAlive = false
+# SO_LINGER option for sockets, defaults to -1
+org.ops4j.pax.url.mvn.socket.linger = -1
+# SO_REUSEADDR option for sockets, defaults to false
+org.ops4j.pax.url.mvn.socket.reuseAddress = false
+# TCP_NODELAY option for sockets, defaults to true
+org.ops4j.pax.url.mvn.socket.tcpNoDelay = true
+# Configure buffer size for HTTP connections (output and input buffers), defaults to 8192 bytes
+org.ops4j.pax.url.mvn.connection.bufferSize = 8192
+# Number of connection retries after failure is detected in http client. httpclient uses default value "3"
+org.ops4j.pax.url.mvn.connection.retryCount = 3

http://git-wip-us.apache.org/repos/asf/karaf/blob/e4f9ead5/profile/src/main/java/org/apache/karaf/profile/assembly/CustomSimpleDownloadTask.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/CustomSimpleDownloadTask.java b/profile/src/main/java/org/apache/karaf/profile/assembly/CustomSimpleDownloadTask.java
index 0eb9946..15b0fbf 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/CustomSimpleDownloadTask.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/CustomSimpleDownloadTask.java
@@ -23,7 +23,6 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
@@ -54,7 +53,7 @@ public class CustomSimpleDownloadTask extends AbstractRetryableDownloadTask {
     }
 
     @Override
-    protected File download() throws Exception {
+    protected File download(Exception previousExceptionNotUsed) throws Exception {
         URL url = createUrl(getUrl());
         Path path = Files.createTempFile("download-", null);
         try (InputStream is = url.openStream()) {


[2/2] karaf git commit: [KARAF-4795] Add new configuration options from pax-url-aether 2.5.0 (timeouts)

Posted by gg...@apache.org.
[KARAF-4795] Add new configuration options from pax-url-aether 2.5.0 (timeouts)


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/dd7b5bdd
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/dd7b5bdd
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/dd7b5bdd

Branch: refs/heads/master
Commit: dd7b5bdd4a9724d17cf3df94d4850c2513915f7e
Parents: e4f9ead
Author: Grzegorz Grzybek <gr...@gmail.com>
Authored: Mon Oct 17 10:46:14 2016 +0200
Committer: Grzegorz Grzybek <gr...@gmail.com>
Committed: Fri Nov 4 17:05:39 2016 +0100

----------------------------------------------------------------------
 .../resources/etc/org.ops4j.pax.url.mvn.cfg     | 76 ++++++++++++++++----
 .../resources/etc/org.ops4j.pax.url.mvn.cfg     | 22 +++---
 2 files changed, 76 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/dd7b5bdd/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.url.mvn.cfg
----------------------------------------------------------------------
diff --git a/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.url.mvn.cfg b/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.url.mvn.cfg
index bc2c34d..6fe0368 100644
--- a/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.url.mvn.cfg
+++ b/assemblies/features/base/src/main/resources/resources/etc/org.ops4j.pax.url.mvn.cfg
@@ -18,6 +18,9 @@
 ################################################################################
 
 #
+# see: https://ops4j1.jira.com/wiki/display/paxurl/Aether+Configuration
+#
+
 # If set to true, the following property will not allow any certificate to be used
 # when accessing Maven repositories through SSL
 #
@@ -34,6 +37,9 @@
 #   * 3. if not found looks for ${maven.home}/conf/settings.xml
 #   * 4. if not found looks for ${M2_HOME}/conf/settings.xml
 #
+# Properties prefixed with "org.ops4j.pax.url.mvn." have
+# higher priority except <proxies> element. HTTP proxies should be configured in
+# settings file
 #org.ops4j.pax.url.mvn.settings=
 
 #
@@ -42,22 +48,29 @@
 # The value of this property will be extracted from the settings.xml file
 # above, or defaulted to:
 #     System.getProperty( "user.home" ) + "/.m2/repository"
-#
+# leaving this option commented makes the system dependent on external
+# configuration, which is not always desired
+# "localRepository" is the target location for artifacts downloaded from
+# "remote repositories"
 #org.ops4j.pax.url.mvn.localRepository=
 
 #
 # Default this to false. It's just weird to use undocumented repos
+# "false" means that http://repo1.maven.org/maven2@id=central won't be
+# implicitly used as remote repository
 #
 org.ops4j.pax.url.mvn.useFallbackRepositories=false
 
 #
-# Uncomment if you don't wanna use the proxy settings
-# from the Maven conf/settings.xml file
-#
-# org.ops4j.pax.url.mvn.proxySupport=false
-
-#
 # Comma separated list of repositories scanned when resolving an artifact.
+# list of repositories searched in the first place, should contain
+# ${runtime.home}/${karaf.default.repository}.
+# if "org.ops4j.pax.url.mvn.localRepository" is defined and it's not
+# ~/.m2/repository, it's recommended (at least for dev purposes) to add
+# ~/.m2/repository to defaultRepositories
+# each of these repositories is checked by aether as "local repository". if
+# artifact isn't found, "repositories" are searched next
+#
 # Those repositories will be checked before iterating through the
 #    below list of repositories and even before the local repository
 # A repository url can be appended with zero or more of the following flags:
@@ -71,11 +84,22 @@ org.ops4j.pax.url.mvn.defaultRepositories=\
     file:${karaf.data}/kar@id=kar.repository@multi@snapshots, \
     file:${karaf.base}/${karaf.default.repository}@id=child.system.repository@snapshots
 
-# Use the default local repo (e.g.~/.m2/repository) as a "remote" repo
-#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false
+#
+# if "defaultLocalRepoAsRemote" is set do *any* value, localRepository will be
+# added to the list of remote repositories being searched for artifacts
+#
+#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote = true
 
 #
 # Comma separated list of repositories scanned when resolving an artifact.
+# list of repositories searched after resolution fails for "defaultRepositories"
+# These are true remote repositories accessed using maven/aether/wagon
+# mechanisms. If any repository contains required artifact, it is then written
+# to "localRepository"
+#
+# if this list is _prepended_ with '+' sign, all repositories from active
+# profiles defined in effective settings.xml file will be _appended_ to this
+# list
 # The default list includes the following repositories:
 #    http://repo1.maven.org/maven2@id=central
 #    http://repository.springsource.com/maven/bundles/release@id=spring.ebr
@@ -84,12 +108,11 @@ org.ops4j.pax.url.mvn.defaultRepositories=\
 #    http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases
 #    https://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@noreleases
 #    https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases
-# To add repositories to the default ones, prepend '+' to the list of repositories
-# to add.
 # A repository url can be appended with zero or more of the following flags:
 #    @snapshots  : the repository contains snapshots
 #    @noreleases : the repository does not contain any released artifacts
-#    @id=repository.id : the id for the repository, just like in the settings.xml this is optional but recommended
+#    @id=repository.id : the id for the repository, just like in the
+#        settings.xml this is optional but recommended
 #
 org.ops4j.pax.url.mvn.repositories= \
     http://repo1.maven.org/maven2@id=central, \
@@ -100,3 +123,32 @@ org.ops4j.pax.url.mvn.repositories= \
     https://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@noreleases, \
     https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases, \
     http://repository.springsource.com/maven/bundles/external@id=spring-ebr-repository@snapshots@noreleases
+
+#
+# Global policies override repository-specific settings (@checksum=..., @update=..., @releasesUpdate=..., ...)
+#
+#org.ops4j.pax.url.mvn.globalUpdatePolicy = daily
+#org.ops4j.pax.url.mvn.globalChecksumPolicy = warn
+
+#
+# socket and connection configuration (pax-url-aether 2.5.0)
+#
+# default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout
+# are not specified
+org.ops4j.pax.url.mvn.timeout = 5000
+# timeout in ms when establishing http connection during artifact resolution
+org.ops4j.pax.url.mvn.socket.connectionTimeout = 5000
+# timeout in ms when reading data after connecting to remote repository
+org.ops4j.pax.url.mvn.socket.readTimeout = 30000
+# SO_KEEPALIVE option for sockets, defaults to false
+org.ops4j.pax.url.mvn.socket.keepAlive = false
+# SO_LINGER option for sockets, defaults to -1
+org.ops4j.pax.url.mvn.socket.linger = -1
+# SO_REUSEADDR option for sockets, defaults to false
+org.ops4j.pax.url.mvn.socket.reuseAddress = false
+# TCP_NODELAY option for sockets, defaults to true
+org.ops4j.pax.url.mvn.socket.tcpNoDelay = true
+# Configure buffer size for HTTP connections (output and input buffers), defaults to 8192 bytes
+org.ops4j.pax.url.mvn.connection.bufferSize = 8192
+# Number of connection retries after failure is detected in http client. httpclient uses default value "3"
+org.ops4j.pax.url.mvn.connection.retryCount = 3

http://git-wip-us.apache.org/repos/asf/karaf/blob/dd7b5bdd/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
----------------------------------------------------------------------
diff --git a/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg b/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
index 6876301..9e1b187 100644
--- a/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
+++ b/itests/src/test/resources/etc/org.ops4j.pax.url.mvn.cfg
@@ -35,7 +35,7 @@
 # Properties prefixed with "org.ops4j.pax.url.mvn." have
 # higher priority except <proxies> element. HTTP proxies should be configured in
 # settings file
-org.ops4j.pax.url.mvn.settings = ${karaf.etc}/maven-settings.xml
+org.ops4j.pax.url.mvn.settings=${karaf.etc}/maven-settings.xml
 
 #
 # Path to the local Maven repository which is used to avoid downloading
@@ -46,18 +46,17 @@ org.ops4j.pax.url.mvn.settings = ${karaf.etc}/maven-settings.xml
 # leaving this option commented makes the system dependent on external
 # configuration, which is not always desired
 # "localRepository" is the target location for artifacts downloaded from
-# "remote repositories", it's not searched for already available artifacts,
-# unless added explicitly to "defaultRepositories"
+# "remote repositories"
 # by default internal local repository is used to have behavior independent
 # of the content of ~/.m2/repository
-org.ops4j.pax.url.mvn.localRepository = ${karaf.data}/repository
+org.ops4j.pax.url.mvn.localRepository=${karaf.data}/repository
 
 #
 # Default this to false. It's just weird to use undocumented repos
 # "false" means that http://repo1.maven.org/maven2@id=central won't be
 # implicitly used as remote repository
 #
-org.ops4j.pax.url.mvn.useFallbackRepositories = false
+org.ops4j.pax.url.mvn.useFallbackRepositories=false
 
 #
 # Comma separated list of repositories scanned when resolving an artifact.
@@ -65,7 +64,7 @@ org.ops4j.pax.url.mvn.useFallbackRepositories = false
 # ${runtime.home}/${karaf.default.repository}.
 # if "org.ops4j.pax.url.mvn.localRepository" is defined and it's not
 # ~/.m2/repository, it's recommended (at least for dev purposes) to add
-# it to defaultRepositories
+# ~/.m2/repository to defaultRepositories
 # each of these repositories is checked by aether as "local repository". if
 # artifact isn't found, "repositories" are searched next
 #
@@ -77,12 +76,12 @@ org.ops4j.pax.url.mvn.useFallbackRepositories = false
 #
 # The following property value will add the system folder as a repo.
 #
-#org.ops4j.pax.url.mvn.defaultRepositories = \
+#org.ops4j.pax.url.mvn.defaultRepositories=\
 #    file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
 #    file:\${user.home}/.m2/repository@snapshots@id=local, \
 #    file:${karaf.data}/kar@id=kar.repository@multi@snapshots, \
 #    file:${karaf.base}/${karaf.default.repository}@id=child.system.repository@snapshots
-org.ops4j.pax.url.mvn.defaultRepositories = \
+org.ops4j.pax.url.mvn.defaultRepositories=\
     file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots, \
     file:${user.home}/.m2/repository@snapshots@id=local
 
@@ -108,14 +107,17 @@ org.ops4j.pax.url.mvn.defaultRepositories = \
 #    @id=repository.id : the id for the repository, just like in the
 #        settings.xml this is optional but recommended
 #
-org.ops4j.pax.url.mvn.repositories = \
+org.ops4j.pax.url.mvn.repositories= \
     http://repo1.maven.org/maven2@id=central
 
+#
+# Global policies override repository-specific settings (@checksum=..., @update=..., @releasesUpdate=..., ...)
+#
 org.ops4j.pax.url.mvn.globalUpdatePolicy = daily
 org.ops4j.pax.url.mvn.globalChecksumPolicy = warn
 
 #
-# socket and connection configuration
+# socket and connection configuration (pax-url-aether 2.5.0)
 #
 # default value for connection and read timeouts, when socket.readTimeout and socket.connectionTimeout
 # are not specified