BUG-7473: add Karaf 4 features 02/49702/23
authorStephen Kitt <skitt@redhat.com>
Wed, 21 Dec 2016 14:27:21 +0000 (15:27 +0100)
committerRobert Varga <nite@hq.sk>
Mon, 23 Jan 2017 14:04:27 +0000 (14:04 +0000)
Instead of switching wholesale to Karaf 4 only, this patch adds
duplicate features for Karaf 4:

* feature-repo-parent is the new parent for Karaf 4 feature
  repositories (the Karaf 3 parent is now feature3-repo-parent, used
  only in odlparent);
* single-feature-parent is the new parent for Karaf 4 features (the
  Karaf 3 parent is now single-feature3-parent, used only in
  odlparent);
* features4-akka is the new odlparent Karaf 4 feature repository for
  Akka (dropping the old, backwards-compatible features);
* features4-odlparent is the new odlparent Karaf 4 feature repository
  for all other features (again, dropping the old,
  backwards-compatible features).

For the time being, we use Karaf 4.0.7 as the container (otherwise we
run into issues caused by
https://issues.apache.org/jira/browse/FELIX-5450 at least in
controller), and our own release of 4.0.9-SNAPSHOT, called 4.0.8-odl,
for the Karaf Maven plugin (we need upcoming 4.0.9 features when
generating our feature descriptors).

features-parent isn't duplicated for Karaf 4, downstreams are
encouraged to use at least feature-repo-parent instead.

This patch includes the following changes too:
* bundle uninstall failures are ignored in SingleFeatureTest;
* the deprecated features are reduced to delegates for their
  replacement features (e.g. odl-akka-scala simply pulls in
  odl-akka-scala-2.11);
* karaf4-parent only pulls in standard and war (these two features
  include all the other features that were explicitly listed);
* Pax Exam is upgraded to 4.9.2 (necessary to build with Karaf 4, but
  backwards-compatible with Karaf 3);
* Jacoco is upgraded to 0.7.7.201606060606 (as above);
* pax-url is upgraded to 2.5.1 (as above);
* the Protobuf tweaking for clustering is no longer necessary and is
  removed;
* bundles-test needs wrap as a pre-requisite, which requires wrapping
  it in a feature (odl-bundles-test) and using that in the Karaf 4
  SingleFeatureTest;
* karaf4-parent supports karaf.localFeature again.

Change-Id: I251aa7aefe6d3d7f93a73b5256bad6e596147c66
Signed-off-by: Stephen Kitt <skitt@redhat.com>
69 files changed:
bundles4-test/pom.xml [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleDiagInfos.java [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleServiceSummaryMatcher.java [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtil.java [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemState.java [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/TestBundleDiag.java [new file with mode: 0644]
bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java [new file with mode: 0644]
bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java [new file with mode: 0644]
feature-repo-parent/pom.xml
feature3-repo-parent/pom.xml [new file with mode: 0644]
features-test/pom.xml
features-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunNotifier.java
features/features-akka/pom.xml
features/features-akka/src/main/feature/feature.xml
features/features-odlparent/pom.xml
features/features-odlparent/src/main/feature/feature.xml
features/odl-akka-all/pom.xml
features/odl-akka-clustering-2.4/pom.xml
features/odl-akka-leveldb-0.7/pom.xml
features/odl-akka-persistence-2.4/pom.xml
features/odl-akka-persistence-2.4/src/main/feature/feature.xml [deleted file]
features/odl-akka-scala-2.11/pom.xml
features/odl-akka-system-2.4/pom.xml
features/odl-guava-18/pom.xml
features/odl-guava-21/pom.xml
features/odl-lmax-3/pom.xml
features/odl-netty-4/pom.xml
features/odl-triemap-0.2/pom.xml
features4-test/pom.xml [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Constants.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunNotifier.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunner.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerRepoTestRunner.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/SingleFeatureTest.java [new file with mode: 0644]
features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Util.java [new file with mode: 0644]
features4-test/src/main/resources/singlefeaturetest.properties [new file with mode: 0644]
features4/features4-akka/pom.xml [new file with mode: 0644]
features4/features4-odlparent/pom.xml [new file with mode: 0644]
features4/odl-akka-all/pom.xml [new file with mode: 0644]
features4/odl-akka-clustering-2.4/pom.xml [new file with mode: 0644]
features4/odl-akka-leveldb-0.7/pom.xml [new file with mode: 0644]
features4/odl-akka-persistence-2.4/pom.xml [new file with mode: 0644]
features4/odl-akka-scala-2.11/pom.xml [new file with mode: 0644]
features4/odl-akka-system-2.4/pom.xml [new file with mode: 0644]
features4/odl-bundles-test/pom.xml [new file with mode: 0644]
features4/odl-guava-18/pom.xml [new file with mode: 0644]
features4/odl-guava-21/pom.xml [new file with mode: 0644]
features4/odl-lmax-3/pom.xml [new file with mode: 0644]
features4/odl-netty-4/pom.xml [new file with mode: 0644]
features4/odl-triemap-0.2/pom.xml [new file with mode: 0644]
features4/pom.xml [new file with mode: 0644]
karaf/karaf-parent/pom.xml
karaf/karaf4-parent/pom.xml
karaf/opendaylight-karaf-empty/pom.xml
karaf/opendaylight-karaf-resources/pom.xml
karaf/opendaylight-karaf4-empty/pom.xml
karaf/opendaylight-karaf4-resources/pom.xml
karaf/opendaylight-karaf4-resources/src/main/resources/etc/custom.properties
karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.7.patch [new file with mode: 0644]
karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.9.patch [new file with mode: 0644]
karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv.bat.patch
karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv.patch
karaf/pom.xml
odlparent-artifacts/pom.xml
odlparent/pom.xml
pom.xml
single-feature-parent/pom.xml
single-feature3-parent/pom.xml [new file with mode: 0644]

diff --git a/bundles4-test/pom.xml b/bundles4-test/pom.xml
new file mode 100644 (file)
index 0000000..a245fe9
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>bundle-parent</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <relativePath>../bundle-parent</relativePath>
+  </parent>
+
+  <artifactId>bundles4-test</artifactId>
+  <packaging>bundle</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.bundle</groupId>
+      <artifactId>org.apache.karaf.bundle.core</artifactId>
+      <version>${karaf4.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <configuration>
+          <failOnError>true</failOnError>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!--
+    Maven Site Configuration
+
+    The following configuration is necessary for maven-site-plugin to
+    correctly identify the correct deployment path for OpenDaylight Maven
+    sites.
+  -->
+  <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+  <distributionManagement>
+    <site>
+      <id>opendaylight-site</id>
+      <url>${nexus.site.url}/${project.artifactId}/</url>
+    </site>
+  </distributionManagement>
+
+</project>
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleDiagInfos.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleDiagInfos.java
new file mode 100644 (file)
index 0000000..47f6f6e
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import static org.apache.karaf.bundle.core.BundleState.Active;
+import static org.apache.karaf.bundle.core.BundleState.Installed;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.karaf.bundle.core.BundleInfo;
+import org.apache.karaf.bundle.core.BundleService;
+import org.apache.karaf.bundle.core.BundleState;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * System readiness diagnostic summary information.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class BundleDiagInfos {
+
+    private final List<String> okBundleStateInfoTexts;
+    private final List<String> nokBundleStateInfoTexts;
+    private final List<String> whitelistedBundleStateInfoTexts;
+    private final Map<BundleState, Integer> bundleStatesCounters;
+
+    private static final Map<String, BundleState> WHITELISTED_BUNDLES = ImmutableMap.of(
+            "slf4j.log4j12", Installed );
+
+    public static BundleDiagInfos forContext(BundleContext bundleContext, BundleService bundleService) {
+        List<String> okBundleStateInfoTexts = new ArrayList<>();
+        List<String> nokBundleStateInfoTexts = new ArrayList<>();
+        List<String> whitelistedBundleStateInfoTexts = new ArrayList<>();
+        Map<BundleState, Integer> bundleStatesCounters = new EnumMap<>(BundleState.class);
+        for (BundleState bundleState : BundleState.values()) {
+            bundleStatesCounters.put(bundleState, 0);
+        }
+
+        for (Bundle bundle : bundleContext.getBundles()) {
+            String bundleSymbolicName = bundle.getSymbolicName();
+            BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
+            BundleState karafBundleState = karafBundleInfo.getState();
+
+            String bundleStateDiagText = "OSGi state = " + bundleStatetoText(bundle.getState())
+                + ", Karaf bundleState = " + karafBundleState;
+            String diagText = bundleService.getDiag(bundle);
+            if (!Strings.isNullOrEmpty(diagText)) {
+                bundleStateDiagText += ", due to: " + diagText;
+            }
+
+            if (WHITELISTED_BUNDLES.get(bundleSymbolicName) != null) {
+                if (WHITELISTED_BUNDLES.get(bundleSymbolicName).equals(karafBundleState)) {
+                    String msg = "WHITELISTED " + bundleSymbolicName + ": " + bundleStateDiagText;
+                    whitelistedBundleStateInfoTexts.add(msg);
+                    continue;
+                }
+            }
+
+            bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
+
+            // BundleState comparison as in Karaf's "diag" command,
+            // see https://github.com/apache/karaf/blob/master/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
+            // but we intentionally, got a little further than Karaf's "diag" command,
+            // and instead of only checking some states, we check what's really Active,
+            // but accept that some remain just Resolved:
+            if (karafBundleState != Active && !(karafBundleState == BundleState.Resolved)) {
+                String msg = "NOK " + bundleSymbolicName + ": " + bundleStateDiagText;
+                nokBundleStateInfoTexts.add(msg);
+            } else {
+                String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
+                okBundleStateInfoTexts.add(msg);
+            }
+        }
+
+        return new BundleDiagInfos(okBundleStateInfoTexts, nokBundleStateInfoTexts,
+                whitelistedBundleStateInfoTexts, bundleStatesCounters);
+    }
+
+    private static String bundleStatetoText(int state) {
+        switch (state) {
+            case Bundle.INSTALLED:
+                return "Installed";
+            case Bundle.RESOLVED:
+                return "Resolved";
+            case Bundle.STARTING:
+                return "Starting";
+            case Bundle.ACTIVE:
+                return "Active";
+            case Bundle.STOPPING:
+                return "Stopping";
+            case Bundle.UNINSTALLED:
+                return "Uninstalled";
+            default:
+                return state + "???";
+        }
+    }
+
+    private BundleDiagInfos(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
+            List<String> whitelistedBundleStateInfoTexts, Map<BundleState, Integer> bundleStatesCounters) {
+        this.okBundleStateInfoTexts = ImmutableList.copyOf(okBundleStateInfoTexts);
+        this.nokBundleStateInfoTexts = ImmutableList.copyOf(nokBundleStateInfoTexts);
+        this.whitelistedBundleStateInfoTexts = ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
+        this.bundleStatesCounters = ImmutableMap.copyOf(bundleStatesCounters);
+    }
+
+    public SystemState getSystemState() {
+        if (bundleStatesCounters.get(BundleState.Failure) > 0) {
+            return SystemState.Failure;
+        } else if (bundleStatesCounters.get(BundleState.Stopping) > 0) {
+            return SystemState.Stopping;
+        } else if (bundleStatesCounters.get(BundleState.Installed) == 0
+                // No, just Resolved is OK, so do not: && bundleStatesCounters.get(BundleState.Resolved) == 0
+                && bundleStatesCounters.get(BundleState.Unknown) == 0
+                && bundleStatesCounters.get(BundleState.GracePeriod) == 0
+                && bundleStatesCounters.get(BundleState.Waiting) == 0
+                && bundleStatesCounters.get(BundleState.Starting) == 0
+                // BundleState.Active *should* be ~= total # of bundles (minus Resolved, and whitelisted installed)
+                && bundleStatesCounters.get(BundleState.Stopping) == 0
+                && bundleStatesCounters.get(BundleState.Failure) == 0) {
+            return SystemState.Active;
+        } else {
+            return SystemState.Booting;
+        }
+    }
+
+    public String getFullDiagnosticText() {
+        StringBuilder sb = new StringBuilder(getSummaryText());
+        int failureNumber = 1;
+        for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
+            sb.append('\n');
+            sb.append(failureNumber++);
+            sb.append(". ");
+            sb.append(nokBundleStateInfoText);
+        }
+        return sb.toString();
+    }
+
+    public String getSummaryText() {
+        return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
+    }
+
+    public List<String> getNokBundleStateInfoTexts() {
+        return ImmutableList.copyOf(nokBundleStateInfoTexts);
+    }
+
+    public List<String> getOkBundleStateInfoTexts() {
+        return ImmutableList.copyOf(okBundleStateInfoTexts);
+    }
+
+    public List<String> getWhitelistedBundleStateInfoTexts() {
+        return ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
+    }
+
+    @Override
+    public String toString() {
+        return getFullDiagnosticText();
+    }
+}
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleServiceSummaryMatcher.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/BundleServiceSummaryMatcher.java
new file mode 100644 (file)
index 0000000..c1307e2
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import static org.opendaylight.odlparent.bundles4test.SystemState.Active;
+import static org.opendaylight.odlparent.bundles4test.SystemState.Failure;
+import static org.opendaylight.odlparent.bundles4test.SystemState.Stopping;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+
+/**
+ * Hamcrest Matcher for {@link BundleDiagInfos}.
+ *
+ * @author Michael Vorburger.ch
+ */
+class BundleServiceSummaryMatcher extends BaseMatcher<BundleDiagInfos> {
+
+    @Override
+    public boolean matches(Object item) {
+        SystemState systemState = ((BundleDiagInfos) item).getSystemState();
+        return systemState.equals(Active) || systemState.equals(Stopping) || systemState.equals(Failure);
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText("system either ready with all bundles Active, "
+                + "or Stopping or Failure (but not still booting in GracePeriod, Waiting, Starting, Unknown;"
+                + "but just Resolved and some exceptional Installed is OK)");
+    }
+}
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtil.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtil.java
new file mode 100644 (file)
index 0000000..41f9c2c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Utilities for OSGi's {@link ServiceReference}.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class ServiceReferenceUtil {
+
+    public Map<String, Object> getProperties(ServiceReference<?> serviceRef) {
+        String[] propertyKeys = serviceRef.getPropertyKeys();
+        Map<String, Object> properties = new HashMap<>(propertyKeys.length);
+        for (String propertyKey : propertyKeys) {
+            Object propertyValue = serviceRef.getProperty(propertyKey);
+            if (propertyValue.getClass().isArray()) {
+                propertyValue = Arrays.asList((Object[]) propertyValue);
+            }
+            properties.put(propertyKey, propertyValue);
+        }
+        return properties;
+    }
+
+    public List<String> getUsingBundleSymbolicNames(ServiceReference<?> serviceRef) {
+        if (serviceRef.getUsingBundles() == null) {
+            return Collections.emptyList();
+        } else {
+            return Arrays.asList(serviceRef.getUsingBundles()).stream()
+                .map(bundle -> bundle.getSymbolicName()).collect(Collectors.toList());
+        }
+    }
+
+}
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemState.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/SystemState.java
new file mode 100644 (file)
index 0000000..47a3314
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import org.apache.karaf.bundle.core.BundleState;
+
+/**
+ * Karaf OSGi System State.
+ *
+ * @see BundleState
+ *
+ * @author Michael Vorburger.ch
+ */
+public enum SystemState {
+
+    Booting,
+
+    Active,
+
+    Stopping,
+
+    Failure
+
+}
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/TestBundleDiag.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/TestBundleDiag.java
new file mode 100644 (file)
index 0000000..d1b87d9
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.TimeUnit;
+import org.apache.karaf.bundle.core.BundleService;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionTimeoutException;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility to verify bundle diagnostic state from OSGi integration tests.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class TestBundleDiag {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TestBundleDiag.class);
+
+    private final BundleContext bundleContext;
+    private final BundleService bundleService;
+
+    public TestBundleDiag(BundleContext bundleContext, BundleService bundleService) {
+        this.bundleContext = bundleContext;
+        this.bundleService = bundleService;
+    }
+
+    /**
+     * Does the equivalent of the "diag" CLI command, and fails the test if anything incl. bundle wiring is NOK.
+     *
+     * <p>The implementation is based on Karaf's BundleService, and not the BundleStateService,
+     * because each Karaf supported DI system (such as Blueprint and Declarative Services, see String constants
+     * in BundleStateService), will have a separate BundleStateService.  The BundleService however will
+     * contain the combined status of all BundleStateServices.
+     *
+     * @author Michael Vorburger, based on guidance from Christian Schneider
+     */
+    public void checkBundleDiagInfos(long timeout, TimeUnit timeoutUnit) {
+        try {
+            Awaitility.await("checkBundleDiagInfos")
+                .pollDelay(0, MILLISECONDS)
+                .pollInterval(1, SECONDS)
+                .atMost(timeout, timeoutUnit)
+                    .conditionEvaluationListener(
+                        condition -> LOG.info("{} (elapsed time {}s, remaining time {}s)",
+                            ((BundleDiagInfos) condition.getValue()).getSummaryText(),
+                            condition.getElapsedTimeInMS() / 1000, condition.getRemainingTimeInMS() / 1000 ))
+                    .until(() -> getBundleDiagInfos(), new BundleServiceSummaryMatcher());
+
+            // If we're here then either BundleServiceSummaryMatcher quit because of Active, Failure or Stopping..
+            BundleDiagInfos bundleInfos = getBundleDiagInfos();
+            SystemState systemState = bundleInfos.getSystemState();
+            if (systemState.equals(SystemState.Failure) || systemState.equals(SystemState.Stopping)) {
+                LOG.error("diag failure; BundleService reports bundle(s) which failed or are already stopping"
+                        + " (details in following INFO and ERROR log messages...)");
+                logBundleDiagInfos(bundleInfos);
+                fail(bundleInfos.getFullDiagnosticText());
+
+            } else {
+                // Inform the developer of the green SystemState.Active
+                LOG.info(bundleInfos.getFullDiagnosticText());
+            }
+
+        } catch (ConditionTimeoutException e) {
+            // If this happens then it got stuck waiting in SystemState.Booting,
+            // typically due to bundles still in BundleState GracePeriod or Waiting
+            LOG.error("diag failure; BundleService reports bundle(s) which are still not active"
+                    + " (details in following INFO and ERROR log messages...)");
+            BundleDiagInfos bundleInfos = getBundleDiagInfos();
+            logBundleDiagInfos(bundleInfos);
+            throw e; // fail the test!
+        }
+    }
+
+    private void logBundleDiagInfos(BundleDiagInfos bundleInfos) {
+        try {
+            logOSGiServices();
+        } catch (IllegalStateException e) {
+            LOG.warn("logOSGiServices() failed (never mind); too late during shutdown already?", e);
+        }
+        for (String okBundleStateInfo : bundleInfos.getOkBundleStateInfoTexts()) {
+            LOG.info(okBundleStateInfo);
+        }
+        for (String whitelistedBundleStateInfo : bundleInfos.getWhitelistedBundleStateInfoTexts()) {
+            LOG.warn(whitelistedBundleStateInfo);
+        }
+        for (String nokBundleStateInfo : bundleInfos.getNokBundleStateInfoTexts()) {
+            LOG.error(nokBundleStateInfo);
+        }
+    }
+
+    private BundleDiagInfos getBundleDiagInfos() {
+        return BundleDiagInfos.forContext(bundleContext, bundleService);
+    }
+
+    private void logOSGiServices() {
+        ServiceReferenceUtil util = new ServiceReferenceUtil();
+        LOG.info("Now going to log all known services, to help diagnose root cause of "
+                + "diag failure BundleService reported bundle(s) which are not active");
+        try {
+            for (ServiceReference<?> serviceRef : bundleContext.getAllServiceReferences(null, null)) {
+                LOG.info("{} defines OSGi Service {} used by {}", serviceRef.getBundle().getSymbolicName(),
+                        util.getProperties(serviceRef), util.getUsingBundleSymbolicNames(serviceRef));
+            }
+        } catch (InvalidSyntaxException e) {
+            LOG.error("logOSGiServices() failed due to InvalidSyntaxException", e);
+        }
+    }
+
+}
diff --git a/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java b/bundles4-test/src/main/java/org/opendaylight/odlparent/bundles4test/package-info.java
new file mode 100644 (file)
index 0000000..3629e2b
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.opendaylight.odlparent.bundles4test;
diff --git a/bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java b/bundles4-test/src/test/java/org/opendaylight/odlparent/bundles4test/ServiceReferenceUtilTest.java
new file mode 100644 (file)
index 0000000..c3892ef
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.bundles4test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.Arrays;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Unit test for ServiceReferenceUtil.
+ *
+ * @author Michael Vorburger.ch
+ */
+public class ServiceReferenceUtilTest {
+
+    @Test
+    public void testGetUsingBundleSymbolicNames() {
+        assertThat(new ServiceReferenceUtil().getUsingBundleSymbolicNames(getServiceReference())).isEmpty();
+    }
+
+    @Test
+    public void testGetProperties() {
+        assertThat(new ServiceReferenceUtil().getProperties(getServiceReference())).containsExactly(
+                "property1", "value1",
+                "property2", Arrays.asList(new String[] { "value2.1", "value2.2" }));
+    }
+
+    private ServiceReference<?> getServiceReference() {
+        return new ServiceReference<Object>() {
+
+            @Override
+            public Object getProperty(String key) {
+                if ("property1".equals(key)) {
+                    return "value1";
+                } else if ("property2".equals(key)) {
+                    return new String[] { "value2.1", "value2.2" };
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public String[] getPropertyKeys() {
+                return new String[] { "property1", "property2"};
+            }
+
+            @Override
+            public Bundle getBundle() {
+                return null;
+            }
+
+            @Override
+            public Bundle[] getUsingBundles() {
+                return null;
+            }
+
+            @Override
+            public boolean isAssignableTo(Bundle bundle, String className) {
+                return false;
+            }
+
+            @Override
+            public int compareTo(Object reference) {
+                return 0;
+            }
+        };
+    }
+
+}
index 86eff2e15d3a256801a8efd7d76277fb68e53742..12dc904ced1bef24ba367aabd1a2b6c0cd42e65c 100644 (file)
@@ -37,6 +37,7 @@
     <name>ODL :: odlparent :: ${project.artifactId}</name>
 
     <properties>
+        <karaf.version>${karaf4.version}</karaf.version>
         <skip.karaf.featureTest>false</skip.karaf.featureTest>
     </properties>
 
@@ -44,7 +45,7 @@
         <!-- Test the generated features.xml -->
         <dependency>
             <groupId>org.opendaylight.odlparent</groupId>
-            <artifactId>features-test</artifactId>
+            <artifactId>features4-test</artifactId>
             <version>1.8.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
@@ -69,7 +70,7 @@
                 <configuration>
                     <skip>${skip.karaf.featureTest}</skip>
                     <dependenciesToScan>
-                        <dependency>org.opendaylight.odlparent:features-test</dependency>
+                        <dependency>org.opendaylight.odlparent:features4-test</dependency>
                     </dependenciesToScan>
                     <additionalClasspathElements>
                         <additionalClasspathElement>${project.build.directory}/feature</additionalClasspathElement>
@@ -87,6 +88,7 @@
             <plugin>
                 <groupId>org.apache.karaf.tooling</groupId>
                 <artifactId>karaf-maven-plugin</artifactId>
+                <version>${karaf4.plugin.version}</version>
                 <extensions>true</extensions>
                 <configuration>
                     <aggregateFeatures>true</aggregateFeatures>
diff --git a/feature3-repo-parent/pom.xml b/feature3-repo-parent/pom.xml
new file mode 100644 (file)
index 0000000..ae6da0d
--- /dev/null
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!--
+         Base parent POM for building, packaging and testing Karaf feature repositories.
+         Karaf features are generated based on the POM dependencies; they can be supplemented by a base
+         feature.xml file in src/main/feature.
+
+         Users should do the following:
+
+         - specify this as their parent
+         - make sure the packaging is set to feature
+         - specify features to be provided in the repository by depending on them in the project <dependencies/>
+    -->
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>odlparent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../odlparent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>feature3-repo-parent</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <properties>
+        <skip.karaf.featureTest>false</skip.karaf.featureTest>
+    </properties>
+
+    <dependencies>
+        <!-- Test the generated features.xml -->
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>features-test</artifactId>
+            <version>1.8.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- Force SLF4J to test scope -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!-- This generates the META-INF/maven/dependencies.properties file
+                     which is required by the versionAsInProject() used in SingleFeatureTest -->
+                <groupId>org.apache.servicemix.tooling</groupId>
+                <artifactId>depends-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven.surefire.version}</version>
+                <configuration>
+                    <skip>${skip.karaf.featureTest}</skip>
+                    <dependenciesToScan>
+                        <dependency>org.opendaylight.odlparent:features-test</dependency>
+                    </dependenciesToScan>
+                    <additionalClasspathElements>
+                        <additionalClasspathElement>${project.build.directory}/feature</additionalClasspathElement>
+                    </additionalClasspathElements>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <version>${karaf.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <aggregateFeatures>true</aggregateFeatures>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
index 0d6653835b984c82e78274f894455b7bd6429464..a9aa2c1fcf5ec6c3c014104ef73deaa9c3b372d0 100644 (file)
         </dependency>
         <dependency>
             <groupId>org.apache.karaf.features</groupId>
-            <artifactId>org.apache.karaf.features.core</artifactId>
+            <artifactId>standard</artifactId>
             <version>${karaf.version}</version>
-            <scope>compile</scope>
+            <classifier>features</classifier>
+            <type>xml</type>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
index 7d969f38bed66ee7a5d7323000aa261625f88d7d..3166f330a35caa63b943e118b221595bf8147f14 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.odlparent.featuretest;
 
 import com.google.common.base.Preconditions;
 import java.net.URL;
+import java.rmi.NoSuchObjectException;
 import org.junit.runner.Description;
 import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
@@ -85,7 +86,9 @@ public class PerFeatureRunNotifier extends RunNotifier {
 
     @Override
     public void fireTestFailure(final Failure failure) {
-        delegate.fireTestFailure(convertFailure(failure));
+        if (!(failure.getException() instanceof NoSuchObjectException)) {
+            delegate.fireTestFailure(convertFailure(failure));
+        }
     }
 
     @Override
index 6b176a4ffcd9fef31bf035ffc753f83af632cebe..1d0ed2a59b4ef2d210c1158ff9a8d4ba7c1ae03d 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>feature-repo-parent</artifactId>
+        <artifactId>feature3-repo-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../feature-repo-parent</relativePath>
+        <relativePath>../../feature3-repo-parent</relativePath>
     </parent>
 
     <artifactId>features-akka</artifactId>
index afd0a2003602a13864e22c187aec5f17ff77a70c..9c3d5917324f1c0ef2246fbe65105ae022300b2c 100644 (file)
          unversioned features, in terms of the feasability of handling upgrades
          later.) -->
     <feature name="odl-akka-scala" description="Scala Runtime for OpenDaylight" version="${scala.version}">
-        <bundle>mvn:org.scala-lang/scala-library/${scala.version}.${scala.micro.version}</bundle>
-        <bundle>mvn:org.scala-lang/scala-reflect/${scala.version}.${scala.micro.version}</bundle>
-        <bundle>mvn:org.scala-lang.modules/scala-java8-compat_${scala.version}/0.8.0</bundle>
-        <bundle>mvn:org.scala-lang.modules/scala-parser-combinators_${scala.version}/1.0.4</bundle>
+        <feature version="${project.version}">odl-akka-scala-${scala.version}</feature>
     </feature>
     <feature name="odl-akka-system" description="Akka Actor Framework System Bundles" version="${akka.version}">
-        <feature version="${scala.version}">odl-akka-scala</feature>
-        <bundle>mvn:com.typesafe/config/1.3.0</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-actor_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-slf4j_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-osgi_${scala.version}/${akka.version}</bundle>
+        <feature version="${project.version}">odl-akka-system-2.4</feature>
     </feature>
     <feature name="odl-akka-clustering" description="Akka Clustering" version="${akka.version}">
-        <feature version="${akka.version}">odl-akka-system</feature>
-        <bundle>wrap:mvn:org.uncommons.maths/uncommons-maths/1.2.2a</bundle>
-        <bundle>mvn:com.google.protobuf/protobuf-java/2.5.0</bundle>
-        <bundle>mvn:com.typesafe/ssl-config-akka_${scala.version}/0.2.1</bundle>
-        <bundle>mvn:com.typesafe/ssl-config-core_${scala.version}/0.2.1</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-cluster_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-distributed-data-experimental_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-protobuf_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-remote_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-stream_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:org.agrona/Agrona/0.9.1</bundle>
-        <bundle>mvn:io.aeron/aeron-client/1.0.5</bundle>
-        <bundle>mvn:io.aeron/aeron-driver/1.0.5</bundle>
-        <bundle>mvn:io.netty/netty/3.10.6.Final</bundle>
-        <bundle>mvn:org.reactivestreams/reactive-streams/1.0.0</bundle>
-        <bundle>wrap:mvn:org.lmdbjava/lmdbjava/0.0.4</bundle>
+        <feature version="${project.version}">odl-akka-clustering-2.4</feature>
     </feature>
     <feature name='odl-akka-leveldb' description='LevelDB' version='${leveldb.version}'>
-        <bundle>wrap:mvn:org.iq80.leveldb/leveldb/${leveldb.version}</bundle>
-        <bundle>mvn:org.fusesource.leveldbjni/leveldbjni-all/1.8-odl</bundle>
+        <feature version="${project.version}">odl-akka-leveldb-0.7</feature>
     </feature>
     <feature name='odl-akka-persistence' description='Akka Persistence' version="${akka.version}">
-        <feature version='${leveldb.version}'>odl-akka-leveldb</feature>
-        <feature version="${akka.version}">odl-akka-system</feature>
-        <bundle>mvn:com.typesafe.akka/akka-protobuf_${scala.version}/${akka.version}</bundle>
-        <bundle>mvn:com.typesafe.akka/akka-persistence_${scala.version}/${akka.version}</bundle>
-        <bundle>wrap:mvn:com.google.protobuf/protobuf-java/2.5.0$overwrite=merge&amp;DynamicImport-Package=org.opendaylight.controller.protobuff.messages.*;org.opendaylight.controller.cluster.raft.protobuff.client.messages.*</bundle>
+        <feature version="${project.version}">odl-akka-persistence-2.4</feature>
     </feature>
 </features>
index b9a21a9641bba28bd31654743c8dea4c6dd90ea9..e6ce69f5f7280d8fee9e4f7ca29fc21cec0ad268 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>feature-repo-parent</artifactId>
+        <artifactId>feature3-repo-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../feature-repo-parent</relativePath>
+        <relativePath>../../feature3-repo-parent</relativePath>
     </parent>
 
     <artifactId>features-odlparent</artifactId>
index bed858178feb00e4b14b7bd8f4c28ef9bd9bfa8f..8b56f74ce03b2e18590ea50a13b75d419dd68b9c 100644 (file)
          later.) -->
     <!-- See also the links defined for our Maven site in the root POM (maven-javadoc-plugin) -->
     <feature name="odl-netty" description="OpenDaylight :: Netty" version="4.0.37.Final">
-        <bundle>mvn:io.netty/netty-buffer/4.0.37.Final</bundle>
-        <bundle>mvn:io.netty/netty-common/4.0.37.Final</bundle>
-        <bundle>mvn:io.netty/netty-transport/4.0.37.Final</bundle>
-        <bundle>mvn:io.netty/netty-codec/4.0.37.Final</bundle>
-        <bundle>mvn:io.netty/netty-codec-http/4.0.37.Final</bundle>
-        <bundle>mvn:io.netty/netty-handler/4.0.37.Final</bundle>
-        <!-- Here we need to include all available native epoll implementations; we can't limit ourselves to the build
-        platform and we can't require the build platform to have an implementation (e.g. OS X) -->
-        <bundle>mvn:io.netty/netty-transport-native-epoll/4.0.37.Final/jar/linux-x86_64</bundle>
+        <feature version="${project.version}">odl-netty-4</feature>
     </feature>
     <feature name="odl-guava" description="OpenDaylight :: Guava" version="18.0">
-        <bundle>mvn:com.google.guava/guava/18.0</bundle>
+        <feature version="${project.version}">odl-guava-18</feature>
     </feature>
     <feature name="odl-guava" description="OpenDaylight :: Guava" version="19.0">
         <bundle>mvn:com.google.guava/guava/19.0</bundle>
     </feature>
     <feature name="odl-lmax" description="OpenDaylight :: LMAX Disruptor" version="3.3.4">
-        <bundle>mvn:com.lmax/disruptor/3.3.4</bundle>
+        <feature version="${project.version}">odl-lmax-3</feature>
     </feature>
     <feature name="odl-triemap" description="OpenDaylight :: Concurrent Trie HashMap" version="0.2.23">
-        <bundle>mvn:com.github.romix/java-concurrent-hash-trie-map/0.2.23</bundle>
+        <feature version="${project.version}">odl-triemap-0.2</feature>
     </feature>
 </features>
index 797addf37746576e52fbf2f075d4b303eddfa5e6..47b9eb83158696db47faee5f6db9a0c920afd999 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index f70f2c62b5d2b0a53b18894d34df7cd137f4858a..595374b426391c82b5ea07af94f79af3fd4b7397 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+ Copyright © 2016, 2017 Red Hat, Inc. and others.  All rights reserved.
 
  This program and the accompanying materials are made available under the
  terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index fb9d0361560465dc7d44a6b1182b759f1945aea8..5df68cea4ef1302d381231ab47d40808a07df989 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index 1be754fd9901fffcad98668f0edc20bc18f60c6a..74e133122ff6d98dec88bbef8dc727d84585bb47 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
             <groupId>com.typesafe.akka</groupId>
             <artifactId>akka-persistence_${scala.version}</artifactId>
         </dependency>
-        <!-- karaf-maven-plugin doesn't merge this with the feature.xml file yet -->
-        <!--dependency>
+        <dependency>
             <groupId>com.google.protobuf</groupId>
             <artifactId>protobuf-java</artifactId>
-        </dependency-->
+        </dependency>
     </dependencies>
 
     <!--
diff --git a/features/odl-akka-persistence-2.4/src/main/feature/feature.xml b/features/odl-akka-persistence-2.4/src/main/feature/feature.xml
deleted file mode 100644 (file)
index 7525956..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
- Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.1" name="odl-akka-persistence-2.4">
-    <feature name="odl-akka-persistence-2.4">
-        <!-- TODO Handle the version here -->
-        <bundle>wrap:mvn:com.google.protobuf/protobuf-java/2.5.0$overwrite=merge&amp;DynamicImport-Package=org.opendaylight.controller.protobuff.messages.*;org.opendaylight.controller.cluster.raft.protobuff.client.messages.*</bundle>
-    </feature>
-</features>
index 25421138ef3e9bbebcbfb91de5e6fe7f53de0984..dc101050f4437fc9e67651c2deb4d34406b9378b 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index f9be9899e0a88257160418b220b517a1bb842db3..9ef031829434719ab83b184381342d0e111ec52b 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index 4d0a1c452e6ba90b50336669d818927a90793e89..8b57fe2b446bdd27f89d950b09190afbe68c0228 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index f27634203ec5d06e78c83c63887051b72ba66263..b8140afc758ab77cc2fb2236b5918d015c0d43d9 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index 10a8e135d320c64c87e728ab32daafdea4ef2f34..67442a5e2d25ec64c20e5b87efcbf175069bb652 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index a4aece1d219f404900c1e818664d9d1a622c48ce..1174381419a97fefae7222c7d7c542bb48fc684d 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
index 15e32ac11ea09b19bdff10104988cad979719710..3be317690c7dd6c3754a99fd8186760edebf5d97 100644 (file)
@@ -13,9 +13,9 @@
 
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>single-feature-parent</artifactId>
+        <artifactId>single-feature3-parent</artifactId>
         <version>1.8.0-SNAPSHOT</version>
-        <relativePath>../../single-feature-parent</relativePath>
+        <relativePath>../../single-feature3-parent</relativePath>
     </parent>
 
     <groupId>org.opendaylight.odlparent</groupId>
diff --git a/features4-test/pom.xml b/features4-test/pom.xml
new file mode 100644 (file)
index 0000000..cd2409b
--- /dev/null
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright © 2014, 2017 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>bundle-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../bundle-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>features4-test</artifactId>
+    <packaging>bundle</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <dependencies>
+        <!-- Dependencies for pax exam karaf container -->
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-karaf</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-aether</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.wagon</groupId>
+            <artifactId>wagon-http</artifactId>
+            <version>2.10</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.features</groupId>
+            <artifactId>standard</artifactId>
+            <version>${karaf4.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.deployer</groupId>
+            <artifactId>org.apache.karaf.deployer.blueprint</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.deployer</groupId>
+            <artifactId>org.apache.karaf.deployer.features</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.deployer</groupId>
+            <artifactId>org.apache.karaf.deployer.spring</artifactId>
+            <version>${karaf4.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-wrap</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bundles-test</artifactId>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>apache-karaf</artifactId>
+            <version>${karaf4.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>check-license</id>
+                        <configuration>
+                            <excludes>
+                                <!-- Skip Apache Licensed files -->
+                                org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+  <!--
+    Maven Site Configuration
+
+    The following configuration is necessary for maven-site-plugin to
+    correctly identify the correct deployment path for OpenDaylight Maven
+    sites.
+  -->
+  <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+  <distributionManagement>
+    <site>
+      <id>opendaylight-site</id>
+      <url>${nexus.site.url}/${project.artifactId}/</url>
+    </site>
+  </distributionManagement>
+</project>
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Constants.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Constants.java
new file mode 100644 (file)
index 0000000..f3ad104
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.odlparent.featuretest;
+
+public final class Constants {
+
+    private Constants() {
+        // Noop constructor
+    }
+
+    /*
+     * Named of System Properties we need to set in PerFeatureRunner and read in SingleFeatureTest
+     */
+    public static final String ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP = "org.opendaylight.featuretest.uri";
+    public static final String ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP =
+            "org.opendaylight.featuretest.featurename";
+    public static final String ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP =
+            "org.opendaylight.featuretest.featureversion";
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java
new file mode 100644 (file)
index 0000000..2cb2211
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * The NOTICE file referred to in the license statement below is available
+ * as Karaf-NOTICE at the root of this project.
+ */
+/*
+ * 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.opendaylight.odlparent.featuretest;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+import org.apache.karaf.deployer.blueprint.BlueprintURLHandler;
+import org.apache.karaf.deployer.features.FeatureURLHandler;
+import org.apache.karaf.deployer.spring.SpringURLHandler;
+
+public class CustomBundleUrlStreamHandlerFactory implements URLStreamHandlerFactory {
+
+    private static final String MVN_URI_PREFIX = "mvn";
+    private static final String WRAP_URI_PREFIX = "wrap";
+    private static final String FEATURE_URI_PREFIX = "feature";
+    private static final String SPRING_URI_PREFIX = "spring";
+    private static final String BLUEPRINT_URI_PREFIX = "blueprint";
+
+    @Override
+    public URLStreamHandler createURLStreamHandler(String protocol) {
+        switch (protocol) {
+            case MVN_URI_PREFIX:
+                return new org.ops4j.pax.url.mvn.Handler();
+            case WRAP_URI_PREFIX:
+                return new org.ops4j.pax.url.wrap.Handler();
+            case FEATURE_URI_PREFIX:
+                return new FeatureURLHandler();
+            case SPRING_URI_PREFIX:
+                return new SpringURLHandler();
+            case BLUEPRINT_URI_PREFIX:
+                return new BlueprintURLHandler();
+            default:
+                return null;
+        }
+    }
+
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunNotifier.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunNotifier.java
new file mode 100644 (file)
index 0000000..3166f33
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.odlparent.featuretest;
+
+import com.google.common.base.Preconditions;
+import java.net.URL;
+import java.rmi.NoSuchObjectException;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+public class PerFeatureRunNotifier extends RunNotifier {
+
+    private final RunNotifier delegate;
+    private final URL repoUrl;
+    private final String featureName;
+    private final String featureVersion;
+
+    /**
+     * Create a delegating notifier.
+     *
+     * @param repoUrl The repository URL.
+     * @param featureName The feature name.
+     * @param featureVersion The feature version.
+     * @param delegate The notification delegate.
+     */
+    public PerFeatureRunNotifier(
+            final URL repoUrl, final String featureName, final String featureVersion, final RunNotifier delegate) {
+        this.repoUrl = Preconditions.checkNotNull(repoUrl);
+        this.featureName = Preconditions.checkNotNull(featureName);
+        this.featureVersion = Preconditions.checkNotNull(featureVersion);
+        this.delegate = Preconditions.checkNotNull(delegate);
+    }
+
+    private Failure convertFailure(final Failure failure) {
+        return new Failure(Util.convertDescription(repoUrl, featureName, featureVersion, failure.getDescription()),
+                failure.getException());
+    }
+
+    @Override
+    public void addListener(final RunListener listener) {
+        delegate.addListener(listener);
+    }
+
+    @Override
+    public void removeListener(final RunListener listener) {
+        delegate.removeListener(listener);
+    }
+
+    /**
+     * Calculates the hash code (delegated).
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    @Override
+    public void fireTestRunStarted(final Description description) {
+        delegate.fireTestRunStarted(Util.convertDescription(repoUrl, featureName, featureVersion, description));
+    }
+
+    @Override
+    public void fireTestRunFinished(final Result result) {
+        delegate.fireTestRunFinished(result);
+    }
+
+    @Override
+    public void fireTestStarted(final Description description) {
+        delegate.fireTestStarted(Util.convertDescription(repoUrl, featureName, featureVersion, description));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        return delegate.equals(obj);
+    }
+
+    @Override
+    public void fireTestFailure(final Failure failure) {
+        if (!(failure.getException() instanceof NoSuchObjectException)) {
+            delegate.fireTestFailure(convertFailure(failure));
+        }
+    }
+
+    @Override
+    public void fireTestAssumptionFailed(final Failure failure) {
+        delegate.fireTestAssumptionFailed(convertFailure(failure));
+    }
+
+    @Override
+    public void fireTestIgnored(final Description description) {
+        delegate.fireTestIgnored(Util.convertDescription(repoUrl, featureName, featureVersion, description));
+    }
+
+    @Override
+    public void fireTestFinished(final Description description) {
+        delegate.fireTestFinished(Util.convertDescription(repoUrl, featureName, featureVersion, description));
+    }
+
+    /**
+     * Please stop.
+     * @see org.junit.runner.notification.RunNotifier#pleaseStop()
+     */
+    @Override
+    public void pleaseStop() {
+        delegate.pleaseStop();
+    }
+
+    @Override
+    public void addFirstListener(final RunListener listener) {
+        delegate.addFirstListener(listener);
+    }
+
+    /**
+     * Value of the delegate as a String.
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunner.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerFeatureRunner.java
new file mode 100644 (file)
index 0000000..f14a401
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.odlparent.featuretest;
+
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP;
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP;
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP;
+
+import com.google.common.base.Preconditions;
+import java.net.URL;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InitializationError;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PerFeatureRunner extends Runner implements Filterable, Sortable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PerFeatureRunner.class);
+
+    private final String featureVersion;
+    private final String featureName;
+    private final PaxExam delegate;
+    private final URL repoUrl;
+
+    /**
+     * Create a runner.
+     *
+     * @param repoUrl        The repository URL.
+     * @param featureName    The feature name.
+     * @param featureVersion The feature version.
+     * @param testClass      The test class.
+     * @throws InitializationError if an error occurs.
+     */
+    public PerFeatureRunner(
+            final URL repoUrl, final String featureName, final String featureVersion, final Class<?> testClass)
+            throws InitializationError {
+        this.repoUrl = Preconditions.checkNotNull(repoUrl);
+        this.featureName = Preconditions.checkNotNull(featureName);
+        this.featureVersion = Preconditions.checkNotNull(featureVersion);
+
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP, repoUrl.toString());
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP, featureName);
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP, featureVersion);
+        this.delegate = new PaxExam(Preconditions.checkNotNull(testClass));
+    }
+
+    @Override
+    public Description getDescription() {
+        return Util.convertDescription(repoUrl, featureName, featureVersion, delegate.getDescription());
+    }
+
+    @Override
+    public void run(final RunNotifier notifier) {
+        LOG.info("About to run test for feature: {} {}", featureName, featureVersion);
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP, repoUrl.toString());
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP, featureName);
+        System.setProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP, featureVersion);
+        delegate.run(new PerFeatureRunNotifier(repoUrl, featureName, featureVersion, notifier));
+    }
+
+    @Override
+    public int testCount() {
+        return delegate.testCount();
+    }
+
+    @Override
+    public void filter(final Filter filter) throws NoTestsRemainException {
+        delegate.filter(filter);
+    }
+
+    @Override
+    public void sort(final Sorter sorter) {
+        delegate.sort(sorter);
+    }
+
+    /**
+     * Delegated implementation of {@link #toString()}.
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+
+    /**
+     * Returns the repository URL.
+     *
+     * @return The repository URL.
+     */
+    public URL getRepoUrl() {
+        return repoUrl;
+    }
+
+    /**
+     * Returns the feature name.
+     *
+     * @return The feature name.
+     */
+    public String getFeatureName() {
+        return featureName;
+    }
+
+    /**
+     * Returns the feature version.
+     *
+     * @return The feature version.
+     */
+    public String getFeatureVersion() {
+        return featureVersion;
+    }
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerRepoTestRunner.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/PerRepoTestRunner.java
new file mode 100644 (file)
index 0000000..eea226a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.odlparent.featuretest;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.JAXBException;
+import org.apache.karaf.features.internal.model.Feature;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
+import org.junit.runner.Description;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PerRepoTestRunner extends ParentRunner<PerFeatureRunner> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PerRepoTestRunner.class);
+
+    private static final String REPO_RECURSE = "repo.recurse";
+    private static final String[] FEATURES_FILENAMES = new String[] { "features.xml", "feature.xml" };
+
+    private static boolean isURLStreamHandlerFactorySet = false;
+    // Do NOT static { URL.setURLStreamHandlerFactory(new CustomBundleUrlStreamHandlerFactory()); }
+    // This is VERY BAD practice, because it leads to VERY HARD TO TRACK errors in case ANYTHING
+    // goes wrong in this.  For example, we had a case where (following an upgrade of PAX Exam)
+    // a dependency was missing.  This appeared as a confusing error because the root cause
+    // of static initialization errors is typically lost in Java; so best is NOT to use it!
+    // ("NoClassDefFoundError: Could not initialize class ...PerRepoTestRunner")
+
+    private final List<PerFeatureRunner> children = new ArrayList<>();
+
+    /**
+     * Create a runner.
+     *
+     * @param testClass The test class.
+     * @throws InitializationError if an error occurs.
+     */
+    public PerRepoTestRunner(final Class<?> testClass) throws InitializationError {
+        super(testClass);
+        setURLStreamHandlerFactory();
+        try {
+            for (String filename : FEATURES_FILENAMES) {
+                final URL repoUrl = getClass().getClassLoader().getResource(filename);
+                if (repoUrl != null) {
+                    final boolean recursive = Boolean.getBoolean(REPO_RECURSE);
+                    LOG.info("Creating test runners for repoUrl {} recursive {}", repoUrl, recursive);
+                    children.addAll(runnersFromRepoUrl(repoUrl, testClass, recursive));
+                } else {
+                    LOG.error("getClass().getClassLoader().getResource(\"{}\") returned null", filename);
+                }
+            }
+        } catch (final IOException | JAXBException e) {
+            throw new InitializationError(e);
+        }
+    }
+
+    // We have to exceptionally suppress IllegalCatch just because URL.setURLStreamHandlerFactory stupidly throws Error
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    // see doc on isURLStreamHandlerFactorySet for why we do NOT want to do this in a static block
+    private static synchronized void setURLStreamHandlerFactory() {
+        if (!isURLStreamHandlerFactorySet) {
+            try {
+                URL.setURLStreamHandlerFactory(new CustomBundleUrlStreamHandlerFactory());
+                isURLStreamHandlerFactorySet = true;
+            } catch (Error e) {
+                LOG.warn("Failed to setURLStreamHandlerFactory to CustomBundleUrlStreamHandlerFactory "
+                        + "(depending on which is already set, this may or may not actually be a problem"
+                        + "; e.g. Karaf 4 already registers the neccessary handlers, so OK to ignore)", e);
+            }
+        }
+    }
+
+    protected List<PerFeatureRunner> runnersFromRepoUrl(
+            final URL repoUrl, final Class<?> testClass, final boolean recursive)
+            throws JAXBException, IOException, InitializationError {
+        if (recursive) {
+            return recursiveRunnersFromRepoUrl(repoUrl, testClass);
+        } else {
+            return runnersFromRepoUrl(repoUrl, testClass);
+        }
+    }
+
+    protected List<PerFeatureRunner> runnersFromRepoUrl(final URL repoUrl, final Class<?> testClass)
+            throws JAXBException, IOException, InitializationError {
+        final List<PerFeatureRunner> runners = new ArrayList<>();
+        final Features features = getFeatures(repoUrl);
+        runners.addAll(runnersFromFeatures(repoUrl, features, testClass));
+        return runners;
+    }
+
+    protected List<PerFeatureRunner> recursiveRunnersFromRepoUrl(final URL repoUrl, final Class<?> testClass)
+            throws JAXBException, IOException, InitializationError {
+        final List<PerFeatureRunner> runners = new ArrayList<>();
+        final Features features = getFeatures(repoUrl);
+        runners.addAll(runnersFromRepoUrl(repoUrl, testClass));
+        for (final String repoString : features.getRepository()) {
+            final URL subRepoUrl = new URL(repoString);
+            runners.addAll(recursiveRunnersFromRepoUrl(subRepoUrl, testClass));
+        }
+        return runners;
+    }
+
+    protected List<PerFeatureRunner> runnersFromFeatures(
+            final URL repoUrl, final Features features, final Class<?> testClass) throws InitializationError {
+        final List<PerFeatureRunner> runners = new ArrayList<>();
+        final List<Feature> featureList = features.getFeature();
+        for (final Feature f : featureList) {
+            runners.add(new PerFeatureRunner(repoUrl, f.getName(), f.getVersion(), testClass));
+        }
+        return runners;
+    }
+
+    protected Features getFeatures(final URL repoUrl) throws JAXBException, IOException {
+        return JaxbUtil.unmarshal(repoUrl.toExternalForm(), false);
+    }
+
+    @Override
+    protected List<PerFeatureRunner> getChildren() {
+        return children;
+    }
+
+    @Override
+    protected Description describeChild(final PerFeatureRunner child) {
+        return child.getDescription();
+    }
+
+    @Override
+    @SuppressWarnings("checkstyle:RegexpSinglelineJava")
+    protected void runChild(final PerFeatureRunner child, final RunNotifier notifier) {
+        LOG.info("[LOG] About to run test: {}", child.getDescription());
+        System.out.println("[sys.out] About to run test: " + child.getDescription());
+        child.run(notifier);
+    }
+
+    /* (non-Javadoc)
+     * @see org.junit.runner.Runner#testCount()
+     */
+    @Override
+    public int testCount() {
+        return super.testCount() * children.size();
+    }
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/SingleFeatureTest.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/SingleFeatureTest.java
new file mode 100644 (file)
index 0000000..c291062
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Copyright © 2014, 2017 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.odlparent.featuretest;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP;
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP;
+import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
+import static org.ops4j.pax.exam.CoreOptions.systemPackages;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
+
+import com.google.common.collect.ImmutableList;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Properties;
+import javax.inject.Inject;
+import org.apache.karaf.bundle.core.BundleService;
+import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.Repository;
+import org.eclipse.jdt.annotation.NonNull;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.odlparent.bundles4test.TestBundleDiag;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
+import org.ops4j.pax.exam.options.MavenUrlReference;
+import org.ops4j.pax.exam.options.extra.VMOption;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(PerRepoTestRunner.class)
+public class SingleFeatureTest {
+
+    private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
+    private static final String ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY = "org.ops4j.pax.url.mvn.localRepository";
+    private static final String ORG_OPS4J_PAX_URL_MVN_REPOSITORIES = "org.ops4j.pax.url.mvn.repositories";
+    private static final String ETC_ORG_OPS4J_PAX_URL_MVN_CFG = "etc/org.ops4j.pax.url.mvn.cfg";
+    private static final String ETC_ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
+
+    private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
+    private static final String PROFILE_PROP = "karaf.featureTest.profile";
+    private static final String BUNDLES_DIAG_SKIP_PROP = "sft.diag.skip";
+    private static final String BUNDLES_DIAG_TIMEOUT_PROP = "sft.diag.timeout";
+
+    private static final String LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST =
+            "log4j.logger.org.opendaylight.odlparent.featuretest";
+    private static final Logger LOG = LoggerFactory.getLogger(SingleFeatureTest.class);
+
+    /*
+     * File name to add our logging config property too.
+     */
+    private static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
+
+    /*
+     * Default values for karaf distro type, groupId, and artifactId
+     */
+    private static final String KARAF_DISTRO_TYPE = "zip";
+    private static final String KARAF_DISTRO_ARTIFACTID = "apache-karaf";
+    private static final String KARAF_DISTRO_GROUPID = "org.apache.karaf";
+
+    /*
+     * Property names to override defaults for karaf distro artifactId, groupId, version, and type
+     */
+    private static final String KARAF_DISTRO_VERSION_PROP = "karaf.distro.version";
+    private static final String KARAF_DISTRO_TYPE_PROP = "karaf.distro.type";
+    private static final String KARAF_DISTRO_ARTIFACTID_PROP = "karaf.distro.artifactId";
+    private static final String KARAF_DISTRO_GROUPID_PROP = "karaf.distro.groupId";
+
+    /**
+     * Property file used to store the Karaf distribution version.
+     */
+    private static final String PROPERTIES_FILENAME = "singlefeaturetest.properties";
+
+    /**
+     * <p>List of Karaf 3.0.4 default maven repositories with snapshot repositories excluded.</p>
+     * <p>Unfortunately this must be hard-coded since declarative model which uses Options,
+     * does not allow us to read value, parse it (properties has allways
+     * problems with lists) and construct replacement string which does
+     * not contains snapshots.</p>
+     * <p>When updating Karaf, check this against org.ops4j.pax.url.mvn.cfg in the Karaf distribution.</p>
+     */
+    private static final String EXTERNAL_DEFAULT_REPOSITORIES = "http://repo1.maven.org/maven2@id=central, "
+            + "http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, "
+            + "http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, "
+            + "http://zodiac.springsource.com/maven/bundles/release@id=gemini ";
+
+    @Inject @NonNull
+    private BundleContext bundleContext;
+
+    @Inject @NonNull
+    private FeaturesService featuresService;
+
+    @Inject @NonNull
+    private BundleService bundleService; // NOT BundleStateService, see checkBundleStatesDiag()
+
+    private String karafVersion;
+    private String karafDistroVersion;
+
+    /**
+     * Returns the required configuration.
+     *
+     * @return The Pax Exam configuration.
+     * @throws IOException if an error occurs.
+     */
+    @Configuration
+    public Option[] config() throws IOException {
+        MavenUrlReference bundleTestRepo = maven()
+                .groupId("org.opendaylight.odlparent")
+                .artifactId("odl-bundles-test")
+                .classifier("features")
+                .type("xml")
+                .versionAsInProject();
+
+        return new Option[] {
+            // TODO: Find a way to inherit memory limits from Maven options.
+            new VMOption("-Xmx2g"),
+            // inspired by org.apache.commons.lang.SystemUtils
+            when(System.getProperty("os.name").toLowerCase().startsWith("linux")).useOptions(
+                // This prevents low entropy issues on Linux to affect Java random numbers
+                // which can block crypto such as the SSH server in netconf
+                // see https://bugs.opendaylight.org/show_bug.cgi?id=6790
+                new VMOption("-Djava.security.egd=file:/dev/./urandom")
+            ),
+            when(Boolean.getBoolean(PROFILE_PROP)).useOptions(
+                new VMOption("-XX:+UnlockCommercialFeatures"),
+                new VMOption("-XX:+FlightRecorder"),
+                new VMOption("-XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath="
+                               + getNewJFRFile())
+            ),
+            getKarafDistroOption(),
+            when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
+            configureConsole().ignoreLocalConsole(),
+            logLevel(LogLevel.WARN),
+            mvnLocalRepoOption(),
+            features(bundleTestRepo, "odl-bundles-test"),
+            editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG, LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,
+                    LogLevel.INFO.name()),
+            editConfigurationFilePut(ETC_ORG_OPS4J_PAX_LOGGING_CFG, "log4j.rootLogger", "INFO, stdout, osgi:*"),
+             /*
+              *
+              * Disables external snapshot repositories.
+              *
+              * Pax URL and Karaf by default always search for new version of snapshots
+              * in all snapshots repository, even if that snapshots does not belong to that
+              * repository and maven is invoked even with -nsu (no snapshot update)
+              * or offline mode.
+              *
+              * This is also true for OpenDaylight snapshot artefacts - pax url tries
+              * to resolve them from third-party repositories, even if they are not present
+              * there - this increases time which takes for features to install.
+              *
+              * For more complex projects this actually means several HTTP GETs for each
+              * snapshot bundle referenced, even if the bundle is already present
+              * in local maven repository.
+              *
+              * In order to speed-up installation and remove unnecessary network traffic,
+              * which fails for obvious reasons, external snapshot repositories are
+              * removed.
+              *
+              *
+              */
+            disableExternalSnapshotRepositories(),
+            propagateSystemProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP),
+            propagateSystemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP),
+            propagateSystemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP),
+            propagateSystemProperty(BUNDLES_DIAG_SKIP_PROP),
+            propagateSystemProperty(BUNDLES_DIAG_TIMEOUT_PROP),
+            // Needed for Agrona/aeron.io
+            systemPackages("com.sun.media.sound", "sun.nio.ch"),
+        };
+    }
+
+    private String getNewJFRFile() throws IOException {
+        return File.createTempFile("SingleFeatureTest-Karaf-JavaFlightRecorder", ".jfr").getAbsolutePath();
+    }
+
+    private String getKarafVersion() {
+        if (karafVersion == null) {
+            // We use a properties file to retrieve ${karaf.version}, instead of .versionAsInProject()
+            // This avoids forcing all users to depend on Karaf in their POMs
+            Properties singleFeatureTestProps = new Properties();
+            try (InputStream singleFeatureTestInputStream = Thread.currentThread().getContextClassLoader()
+                    .getResourceAsStream(PROPERTIES_FILENAME)) {
+                singleFeatureTestProps.load(singleFeatureTestInputStream);
+            } catch (IOException e) {
+                LOG.error("Unable to load {} to determine the Karaf version", PROPERTIES_FILENAME, e);
+            }
+            karafVersion = singleFeatureTestProps.getProperty(KARAF_DISTRO_VERSION_PROP);
+
+            LOG.info("Retrieved karafVersion {} from properties file {}", karafVersion, PROPERTIES_FILENAME);
+        } else {
+            LOG.info("Retrieved karafVersion {} from system property {}", karafVersion, KARAF_DISTRO_VERSION_PROP);
+        }
+
+        return karafVersion;
+    }
+
+    private String getKarafDistroVersion() {
+        if (karafDistroVersion == null) {
+            karafDistroVersion = System.getProperty(KARAF_DISTRO_VERSION_PROP);
+            if (karafDistroVersion == null) {
+                karafDistroVersion = getKarafVersion();
+            } else {
+                LOG.info("Retrieved karafDistroVersion {} from system property {}", karafVersion,
+                        KARAF_DISTRO_VERSION_PROP);
+            }
+        }
+
+        return karafDistroVersion;
+    }
+
+    /**
+     * Disables snapshot repositories, which are enabled by default in karaf distribution.
+     *
+     * @return Edit Configuration option which removes external snapshot repositories.
+     */
+    private static Option disableExternalSnapshotRepositories() {
+        return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_REPOSITORIES,
+                EXTERNAL_DEFAULT_REPOSITORIES);
+    }
+
+    protected Option mvnLocalRepoOption() {
+        String mvnRepoLocal = System.getProperty(MAVEN_REPO_LOCAL, "");
+        LOG.info("mvnLocalRepo \"{}\"", mvnRepoLocal);
+        return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,
+                mvnRepoLocal);
+    }
+
+    protected Option getKarafDistroOption() {
+        String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP, KARAF_DISTRO_GROUPID);
+        String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP, KARAF_DISTRO_ARTIFACTID);
+        String type = System.getProperty(KARAF_DISTRO_TYPE_PROP, KARAF_DISTRO_TYPE);
+        LOG.info("Using karaf distro {} {} {} {}", groupId, artifactId, getKarafDistroVersion(), type);
+        return karafDistributionConfiguration()
+                .frameworkUrl(
+                        maven()
+                                .groupId(groupId)
+                                .artifactId(artifactId)
+                                .type(type)
+                                .version(getKarafDistroVersion()))
+                .name("OpenDaylight")
+                .unpackDirectory(new File("target/pax"))
+                .useDeployFolder(false);
+    }
+
+    private static URI getRepoUri() throws URISyntaxException {
+        return new URI(getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP));
+    }
+
+    private static String getFeatureName() {
+        return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP);
+    }
+
+    public String getFeatureVersion() {
+        return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP);
+    }
+
+    private static String getProperty(final String propName) {
+        String prop = System.getProperty(propName);
+        Assert.assertTrue("Missing property :" + propName, prop != null);
+        return prop;
+    }
+
+    private void checkRepository(final URI repoUri) throws Exception {
+        Repository repo = null;
+        for (Repository r : featuresService.listRepositories()) {
+            if (r.getURI().equals(repoUri)) {
+                repo = r;
+                break;
+            }
+        }
+        Assert.assertNotNull("Repository not found: " + repoUri, repo);
+    }
+
+    /**
+     * Sets the repository up.
+     *
+     * @throws Exception if an error occurs.
+     */
+    @Before
+    public void installRepo() throws Exception {
+        final URI repoUri = getRepoUri();
+        LOG.info("Attempting to add repository {}", repoUri);
+        featuresService.addRepository(repoUri);
+        checkRepository(repoUri);
+        LOG.info("Successfully loaded repository {}", repoUri);
+    }
+
+    // Give it 10 minutes max as we've seen feature install hang on jenkins.
+    @Test(timeout = 600000)
+    public void installFeature() throws Exception {
+        LOG.info("Attempting to install feature {} {}", getFeatureName(), getFeatureVersion());
+        featuresService.installFeature(getFeatureName(), getFeatureVersion());
+        Feature feature = featuresService.getFeature(getFeatureName(), getFeatureVersion());
+        Assert.assertNotNull(
+                "Attempt to get feature " + getFeatureName() + " " + getFeatureVersion() + "resulted in null", feature);
+        Assert.assertTrue("Failed to install Feature: " + getFeatureName() + " " + getFeatureVersion(),
+                featuresService.isInstalled(feature));
+        LOG.info("Successfull installed feature {} {}", getFeatureName(), getFeatureVersion());
+
+        if (!Boolean.getBoolean(BUNDLES_DIAG_SKIP_PROP)
+                && !BLACKLISTED_BROKEN_FEATURES.contains(getFeatureName())) {
+            Integer timeOutInSeconds = Integer.getInteger(BUNDLES_DIAG_TIMEOUT_PROP, 5 * 60);
+            new TestBundleDiag(bundleContext, bundleService).checkBundleDiagInfos(timeOutInSeconds, SECONDS);
+        } else {
+            LOG.warn("SKIPPING TestBundleDiag because system property {} is true or feature is blacklisted: {}",
+                    BUNDLES_DIAG_SKIP_PROP, getFeatureName());
+        }
+    }
+
+    // TODO remove this when all issues linked to parent https://bugs.opendaylight.org/show_bug.cgi?id=7582 are resolved
+    private static final List<String> BLACKLISTED_BROKEN_FEATURES = ImmutableList.of(
+            // integration/distribution/features-test due to DOMRpcService
+            // see https://bugs.opendaylight.org/show_bug.cgi?id=7595
+            "odl-integration-all",
+            // controller/features/mdsal/ due to IllegalStateException: ./configuration/initial/akka.conf is missing
+            // see https://bugs.opendaylight.org/show_bug.cgi?id=7583
+            "odl-mdsal-broker-local",
+            "odl-mdsal-clustering-commons",
+            "odl-mdsal-distributed-datastore",
+            "odl-mdsal-remoterpc-connector",
+            // aaa/features/authn due to Cassandra expected to be up on
+            // see https://bugs.opendaylight.org/show_bug.cgi?id=7584
+            "odl-aaa-authn-cassandra-cluster",
+            // 1/17 in groupbasedpolicy/features due to NOK org.opendaylight.groupbasedpolicy
+            // Caused by: org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException
+            // see https://bugs.opendaylight.org/show_bug.cgi?id=7587
+            "odl-groupbasedpolicy-ne-location-provider",
+            // 1/11 in tsdr/features due to (strange) ClassNotFoundException: odlparent.bundlestest
+            //   .TestBundleDiag (works for all other features; class loading issue in that feature?)
+            // see https://bugs.opendaylight.org/show_bug.cgi?id=7588
+            "odl-hbaseclient",
+            // 1/9 in unimgr/features due missing mdsal, similar to issue to odl-integration-all?
+            // TODO retry after https://bugs.opendaylight.org/show_bug.cgi?id=7595 is fixed
+            "odl-unimgr-netvirt"
+    );
+}
diff --git a/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Util.java b/features4-test/src/main/java/org/opendaylight/odlparent/featuretest/Util.java
new file mode 100644 (file)
index 0000000..fd97fa1
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.odlparent.featuretest;
+
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.Collection;
+
+import org.junit.runner.Description;
+
+public final class Util {
+
+    private Util() {
+        // Noop constructor
+    }
+
+    /**
+     * <p>Convert a Description to a Description that includes information about repoUrl, featureName, and
+     * featureVersion</p>
+     * <p>This is done so that when a test fails, we can get information about which repoUrl, featureName, and
+     * featureVersion can come back with the Failure.</p>
+     *
+     * @param repoUrl URL of the repository.
+     * @param featureName the name of the feature.
+     * @param featureVersion the version of the feature.
+     * @param description original description of the feature.
+     * @return the final description of the feature with the information of repoUrl, featureName, and featureVersion
+     *     included.
+     */
+    public static Description convertDescription(
+            final URL repoUrl, final String featureName,
+            final String featureVersion, final Description description) {
+        String delegateDisplayName = description.getDisplayName();
+        delegateDisplayName =
+                delegateDisplayName + "[repoUrl: " + repoUrl + ", Feature: " + featureName + " " + featureVersion + "]";
+        Collection<Annotation> annotations = description.getAnnotations();
+        Annotation[] annotationArray = annotations.toArray(new Annotation[annotations.size()]);
+        return Description.createSuiteDescription(delegateDisplayName, annotationArray);
+    }
+}
diff --git a/features4-test/src/main/resources/singlefeaturetest.properties b/features4-test/src/main/resources/singlefeaturetest.properties
new file mode 100644 (file)
index 0000000..ca72774
--- /dev/null
@@ -0,0 +1 @@
+karaf.distro.version=${karaf4.version}
diff --git a/features4/features4-akka/pom.xml b/features4/features4-akka/pom.xml
new file mode 100644 (file)
index 0000000..8367651
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>feature-repo-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../feature-repo-parent</relativePath>
+    </parent>
+
+    <artifactId>features4-akka</artifactId>
+    <packaging>feature</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-all</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-scala-${scala.version}</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-system-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-clustering-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-leveldb-0.7</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-persistence-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
diff --git a/features4/features4-odlparent/pom.xml b/features4/features4-odlparent/pom.xml
new file mode 100644 (file)
index 0000000..225757e
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>feature-repo-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../feature-repo-parent</relativePath>
+    </parent>
+
+    <artifactId>features4-odlparent</artifactId>
+    <packaging>feature</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-netty-4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-guava-18</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-guava-21</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-lmax-3</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>odl4-triemap-0.2</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
diff --git a/features4/odl-akka-all/pom.xml b/features4/odl-akka-all/pom.xml
new file mode 100644 (file)
index 0000000..8e44d87
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-all</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: Akka :: All (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-scala-2.11</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-system-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-clustering-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-leveldb-0.7</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-persistence-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-akka-clustering-2.4/pom.xml b/features4/odl-akka-clustering-2.4/pom.xml
new file mode 100644 (file)
index 0000000..20ec33f
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016, 2017 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-clustering-2.4</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>Akka Clustering (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-system-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>org.uncommons.maths</groupId>
+            <artifactId>uncommons-maths</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>jfree</groupId>
+                    <artifactId>jcommon</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>jfree</groupId>
+                    <artifactId>jfreechart</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-protobuf_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty</artifactId>
+            <version>3.10.5.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-remote_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-cluster_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-distributed-data-experimental_${scala.version}</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-akka-leveldb-0.7/pom.xml b/features4/odl-akka-leveldb-0.7/pom.xml
new file mode 100644 (file)
index 0000000..5c5bcce
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-leveldb-0.7</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>LevelDB (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.iq80.leveldb</groupId>
+            <artifactId>leveldb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.fusesource.leveldbjni</groupId>
+            <artifactId>leveldbjni-all</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-akka-persistence-2.4/pom.xml b/features4/odl-akka-persistence-2.4/pom.xml
new file mode 100644 (file)
index 0000000..4068328
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-persistence-2.4</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>Akka Persistence (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-leveldb-0.7</artifactId>
+            <version>1.8.0-SNAPSHOT</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-system-2.4</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-protobuf_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-persistence_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-akka-scala-2.11/pom.xml b/features4/odl-akka-scala-2.11/pom.xml
new file mode 100644 (file)
index 0000000..bdd33d3
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-scala-2.11</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>Scala Runtime for OpenDaylight (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-reflect</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.scala-lang.modules</groupId>
+            <artifactId>scala-java8-compat_${scala.version}</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-akka-system-2.4/pom.xml b/features4/odl-akka-system-2.4/pom.xml
new file mode 100644 (file)
index 0000000..9307538
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-akka-system-2.4</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>Akka Actor Framework System Bundles (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl4-akka-scala-${scala.version}</artifactId>
+            <version>${project.version}</version>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe</groupId>
+            <artifactId>config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-actor_${scala.version}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-slf4j_${scala.version}</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-osgi_${scala.version}</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-bundles-test/pom.xml b/features4/odl-bundles-test/pom.xml
new file mode 100644 (file)
index 0000000..1690e84
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2017 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl-bundles-test</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bundles4-test</artifactId>
+            <version>1.8.0-SNAPSHOT</version>
+        </dependency>
+        <!-- We need to force these to compile scope -->
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/features4/odl-guava-18/pom.xml b/features4/odl-guava-18/pom.xml
new file mode 100644 (file)
index 0000000..4cf4254
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-guava-18</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: Guava 18 (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>18.0</version>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-guava-21/pom.xml b/features4/odl-guava-21/pom.xml
new file mode 100644 (file)
index 0000000..e50f416
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-guava-21</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: Guava 21 (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>21.0</version>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
diff --git a/features4/odl-lmax-3/pom.xml b/features4/odl-lmax-3/pom.xml
new file mode 100644 (file)
index 0000000..6836644
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-lmax-3</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: LMAX Disruptor (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.lmax</groupId>
+            <artifactId>disruptor</artifactId>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file
diff --git a/features4/odl-netty-4/pom.xml b/features4/odl-netty-4/pom.xml
new file mode 100644 (file)
index 0000000..dfbcd20
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-netty-4</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: Netty (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-buffer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-codec-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-handler</artifactId>
+        </dependency>
+        <!-- Here we need to depend on all available native epoll implementations; we can't limit ourselves to the build
+        platform and we can't require the build platform to have an implementation (e.g. OS X) -->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport-native-epoll</artifactId>
+            <classifier>linux-x86_64</classifier>
+        </dependency>
+    </dependencies>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
diff --git a/features4/odl-triemap-0.2/pom.xml b/features4/odl-triemap-0.2/pom.xml
new file mode 100644 (file)
index 0000000..1981f12
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../../single-feature-parent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odl4-triemap-0.2</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: Concurrent Trie HashMap (for Karaf 4)</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.github.romix</groupId>
+            <artifactId>java-concurrent-hash-trie-map</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/features4/pom.xml b/features4/pom.xml
new file mode 100644 (file)
index 0000000..f14962f
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016, 2017 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>odlparent-lite</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../odlparent-lite</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>features4-aggregator</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <modules>
+        <!-- Akka features -->
+        <module>features4-akka</module>
+        <module>odl-akka-all</module>
+        <module>odl-akka-clustering-2.4</module>
+        <module>odl-akka-leveldb-0.7</module>
+        <module>odl-akka-persistence-2.4</module>
+        <module>odl-akka-scala-2.11</module>
+        <module>odl-akka-system-2.4</module>
+
+        <!-- General features -->
+        <module>features4-odlparent</module>
+        <module>odl-guava-18</module>
+        <module>odl-guava-21</module>
+        <module>odl-lmax-3</module>
+        <module>odl-netty-4</module>
+        <module>odl-triemap-0.2</module>
+
+        <!-- Test features -->
+        <module>odl-bundles-test</module>
+    </modules>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-install-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
index 79aeb253672023581ea04d5de22fba37f9f86854..f9e2ecb728fa5c53c62b2f811076703898d418ab 100644 (file)
@@ -17,6 +17,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
   <artifactId>karaf-parent</artifactId>
   <packaging>pom</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
 
   <properties>
     <branding.version>1.8.0-SNAPSHOT</branding.version>
index 851272f75076932c1bd75007366cc0254256f03a..e47279a22817c7a189c7d6be095740f1a4351356 100644 (file)
     <artifactId>karaf4-parent</artifactId>
     <version>1.8.0-SNAPSHOT</version>
     <packaging>pom</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <properties>
+        <!-- Projects can override this to add their own boot feature -->
+        <karaf.localFeature>standard</karaf.localFeature>
+    </properties>
 
     <dependencyManagement>
         <dependencies>
             <plugin>
                 <groupId>org.apache.karaf.tooling</groupId>
                 <artifactId>karaf-maven-plugin</artifactId>
-                <version>${karaf4.version}</version>
+                <version>${karaf4.plugin.version}</version>
                 <executions>
                     <execution>
                         <id>process-resources</id>
                         <feature>wrapper</feature>
                     </installedFeatures>
                     <bootFeatures>
-                        <feature>framework</feature>
-                        <feature>jaas</feature>
-                        <feature>shell</feature>
-                        <feature>feature</feature>
-                        <feature>ssh</feature>
-                        <feature>management</feature>
-                        <feature>bundle</feature>
-                        <feature>config</feature>
-                        <feature>deployer</feature>
-                        <feature>diagnostic</feature>
-                        <feature>instance</feature>
-                        <feature>kar</feature>
-                        <feature>log</feature>
-                        <feature>package</feature>
-                        <feature>service</feature>
-                        <feature>system</feature>
+                        <feature>standard</feature>
+                        <feature>war</feature>
                         <!-- We load wrap as a workaround to handle old features without the wrap prerequisite -->
                         <!-- TODO Remove this once all the downstream features are fixed -->
                         <feature>wrap</feature>
+                        <!-- Local feature if any -->
+                        <feature>${karaf.localFeature}</feature>
                     </bootFeatures>
                     <javase>1.8</javase>
                 </configuration>
index 2f553168448972beccf42bd889e938efc0f0bf70..ea2f5cf0c4d0c1df7a0f8f49482b348ef19c6042 100644 (file)
@@ -8,8 +8,8 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>opendaylight-karaf-empty</artifactId>
-  <name>${project.artifactId}</name>
   <packaging>pom</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
   <prerequisites>
     <maven>3.1.1</maven>
   </prerequisites>
index 667c24ce5475b13a2be4a1f3d563e241bbd7ae34..26c7c629fd877010bf03d734f487b56b9b7173b5 100644 (file)
@@ -18,6 +18,7 @@
   <artifactId>opendaylight-karaf-resources</artifactId>
   <description>Resources for opendaylight-karaf</description>
   <packaging>jar</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
   <properties>
     <!-- These are used in the instance script and need to be kept in sync with Karaf's definitions -->
     <aries.blueprint.api.version>1.0.1</aries.blueprint.api.version>
index f4863fdddc4848efd978441b31cfe6935ddfda0f..f0938c995563c2d6054338f50f2cf50953168746 100644 (file)
@@ -22,5 +22,6 @@
     <artifactId>opendaylight-karaf4-empty</artifactId>
     <version>1.8.0-SNAPSHOT</version>
     <packaging>pom</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
 
 </project>
\ No newline at end of file
index 680359a8c1c214641f66333b49f5519537b27899..e5dfca424264e2b5432ced6901cac1249c874e8a 100644 (file)
@@ -18,6 +18,7 @@
   <artifactId>opendaylight-karaf4-resources</artifactId>
   <description>Resources for opendaylight-karaf</description>
   <packaging>jar</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
   <build>
     <resources>
       <resource>
index e2bb24e34bb906d6bbae81ddfeb6db63d86d593b..de0e8f39c2166f3cda232307b6207ab46198e6c0 100644 (file)
@@ -92,8 +92,8 @@ java.util.logging.config.file=configuration/tomcat-logging.properties
 hosttracker.keyscheme=IP
 
 # LISP Flow Mapping configuration
-# Map-Register messages overwrite existing RLOC sets in EID-to-RLOC mappings (default: true)
-lisp.mappingOverwrite = true
+# Enable merging RLOC sets received from different xTR-IDs for the same EID (default: false)
+lisp.mappingMerge = false
 # Enable the Solicit-Map-Request (SMR) mechanism (default: true)
 lisp.smr = true
 # Choose policy for Explicit Locator Path (ELP) handling
diff --git a/karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.7.patch b/karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.7.patch
new file mode 100644 (file)
index 0000000..6746a77
--- /dev/null
@@ -0,0 +1,10 @@
+--- bin/setenv 2016-10-27 16:23:51.966147872 +0200
++++ bin/setenv 2016-10-03 13:48:22.841563465 +0200
+@@ -48,4 +48,6 @@
+ # export KARAF_OPTS # Additional available Karaf options
+ # export KARAF_DEBUG # Enable debug mode
+ # export KARAF_REDIRECT # Enable/set the std/err redirection when using bin/start
+-
++if [ "x$JAVA_MAX_MEM" = "x" ]; then
++    export JAVA_MAX_MEM="2048m"
++fi
diff --git a/karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.9.patch b/karaf/opendaylight-karaf4-resources/src/main/resources/patches/karaf-setenv-4.0.9.patch
new file mode 100644 (file)
index 0000000..8b6361a
--- /dev/null
@@ -0,0 +1,9 @@
+--- bin/setenv 2016-10-27 16:23:51.966147872 +0200
++++ bin/setenv 2016-10-03 13:48:22.841563465 +0200
+@@ -49,3 +49,6 @@
+ # export KARAF_DEBUG # Enable debug mode
+ # export KARAF_REDIRECT # Enable/set the std/err redirection when using bin/start
+ # export KARAF_NOROOT # Prevent execution as root if set to true
++if [ "x$JAVA_MAX_MEM" = "x" ]; then
++    export JAVA_MAX_MEM="2048m"
++fi
index 2266a7f57a706093b8bf2c9dd98f894c73a4de39..bb19e47c0dad42d96fdb00765193c4ba11ab26ca 100644 (file)
@@ -1,9 +1,8 @@
 --- bin/setenv.bat     2016-10-27 16:23:51.966147872 +0200
 +++ bin/setenv.bat     2016-10-03 13:48:22.841563465 +0200
-@@ -62,4 +62,5 @@
+@@ -62,4 +62,4 @@
  rem SET KARAF_OPTS
  rem Enable debug mode
  rem SET KARAF_DEBUG
 -
-+IF "%JAVA_MAX_PERM_MEM%"=="" SET JAVA_MAX_PERM_MEM=512m
 +IF "%JAVA_MAX_MEM%"=="" SET JAVA_MAX_MEM=2048m
index 5d40b1af0bc17d7261a9c7f20184eeab0df66534..6746a77dd7d6441cc2487c0ab64419ad891b8ada 100644 (file)
@@ -1,13 +1,10 @@
 --- bin/setenv 2016-10-27 16:23:51.966147872 +0200
 +++ bin/setenv 2016-10-03 13:48:22.841563465 +0200
-@@ -48,4 +48,9 @@
+@@ -48,4 +48,6 @@
  # export KARAF_OPTS # Additional available Karaf options
  # export KARAF_DEBUG # Enable debug mode
  # export KARAF_REDIRECT # Enable/set the std/err redirection when using bin/start
 -
-+if [ "x$JAVA_MAX_PERM_MEM" = "x" ]; then
-+    export JAVA_MAX_PERM_MEM="512m"
-+fi
 +if [ "x$JAVA_MAX_MEM" = "x" ]; then
 +    export JAVA_MAX_MEM="2048m"
 +fi
index c8bd1380553bd12a1536bb9602439ce37f4b13b6..cc304ffcf02ce3d227671d413af25f4e0ce19b8d 100644 (file)
@@ -17,6 +17,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </parent>
   <artifactId>karaf-aggregator</artifactId>
   <packaging>pom</packaging>
+  <name>ODL :: odlparent :: ${project.artifactId}</name>
   <modules>
     <module>karaf-branding</module>
     <module>opendaylight-karaf-resources</module>
index 167deb8dcc25296adbb2b0c2a80be63d792eaf3a..d4de7f2c3eecf7d2ce6c23777497cb5c9371a1bf 100644 (file)
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>features-akka</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
             <dependency>
                 <groupId>org.opendaylight.odlparent</groupId>
                 <artifactId>odl-akka-all</artifactId>
                 <classifier>features</classifier>
                 <type>xml</type>
             </dependency>
+
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>features4-odlparent</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>features4-akka</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-all</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-clustering-2.4</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-leveldb-0.7</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-persistence-2.4</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-scala-2.11</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-akka-system-2.4</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-guava-18</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-guava-21</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-lmax-3</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-netty-4</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>odl4-triemap-0.2</artifactId>
+                <version>1.8.0-SNAPSHOT</version>
+                <classifier>features</classifier>
+                <type>xml</type>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
index cb4f9c215ccdeeaa346ba23e61e5071fbde1bc01..17bc7841b29b488099a0bac86135cb825e0f1979 100644 (file)
     <!-- Used in affinity, controller, nemo, opendove, snmp4sdn -->
     <enunciate.version>1.31</enunciate.version>
     <!-- Used in affinity, coretutorials, netide -->
-    <exam.version>4.4.0</exam.version>
+    <exam.version>4.9.2</exam.version>
     <!-- Used in affinity, controller, neutron, of-config; see also snmp4sdn -->
     <!-- Later versions break tests in downstream projects -->
     <failsafe.version>2.18.1</failsafe.version>
-    <!--
-        Regression in jacoco-plugin 0.7.5 prevents us from upgrading to it
-        http://jira.xwiki.org/browse/XCOMMONS-821
-
-        Additionally we need to stay on jacoco 0.7.2.201409121644. Future
-        versions appear to have issues picking up code coverage for projects
-        that use PowerMock.
-        https://github.com/jayway/powermock/issues/564
-    -->
     <!-- Used in controller, netvirt, neutron, of-config, ovsdb, persistence, snmp4sdn, vtn; see also usc -->
-    <jacoco.version>0.7.2.201409121644</jacoco.version>
+    <jacoco.version>0.7.7.201606060606</jacoco.version>
     <!-- Used in aaa, controller, coretutorials, integration/distribution, l2switch, lacp, lispflowmapping, netide,
          nic, openflowplugin, ovsdb, persistence, sfc, snbi, snmp4sdn?, sxp, topoprocessing, unimgr, vtn -->
     <karaf.version>3.0.8</karaf.version>
     <karaf4.version>4.0.7</karaf4.version>
+    <karaf4.plugin.version>4.0.8-odl</karaf4.plugin.version>
     <!-- Used in lispflowmapping, snmp4sdn, vtn -->
     <projectinfo>2.8.1</projectinfo>
     <!-- Used in of-config; see also snmp4sdn -->
       <dependency>
         <groupId>org.ops4j.pax.url</groupId>
         <artifactId>pax-url-aether</artifactId>
-        <version>2.4.7</version>
+        <version>2.5.1</version>
         <scope>test</scope>
       </dependency>
       <dependency>
         <groupId>org.ops4j.pax.url</groupId>
         <artifactId>pax-url-wrap</artifactId>
-        <version>2.4.7</version>
+        <version>2.5.1</version>
       </dependency>
       <dependency>
         <groupId>org.springframework.osgi</groupId>
diff --git a/pom.xml b/pom.xml
index a8ee24306874a751db80d2317ca66c6aabbb44d5..c70bb16ccf38097ec82f8e35f8bff481a370c317 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,9 @@
         <module>findbugs</module>
         <module>license</module>
         <module>bundles-test</module>
+        <module>bundles4-test</module>
         <module>features-test</module>
+        <module>features4-test</module>
 
         <!-- Karaf integration -->
         <module>karaf</module>
         <!-- Parent POMs -->
         <module>bundle-parent</module>
         <module>features-parent</module>
+        <module>single-feature3-parent</module>
         <module>single-feature-parent</module>
+        <module>feature3-repo-parent</module>
         <module>feature-repo-parent</module>
         <module>odlparent</module>
         <module>odlparent-lite</module>
 
         <!-- Features -->
         <module>features</module>
+        <module>features4</module>
 
         <!-- Artifacts -->
         <module>odlparent-artifacts</module>
index 579c949fa2012ecabceb8f50ab5922bca0dc3de0..0f5661f3b168d609d011fb83526d5ddef8ddbc43 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+ Copyright © 2016, 2017 Red Hat, Inc. and others.  All rights reserved.
 
  This program and the accompanying materials are made available under the
  terms of the Eclipse Public License v1.0 which accompanies this distribution,
     <packaging>pom</packaging>
     <name>ODL :: odlparent :: ${project.artifactId}</name>
 
+    <properties>
+        <karaf.version>${karaf4.version}</karaf.version>
+    </properties>
+
     <build>
         <plugins>
+            <plugin>
+                <!-- This generates the META-INF/maven/dependencies.properties file
+                     which is required by the versionAsInProject() used in SingleFeatureTest -->
+                <groupId>org.apache.servicemix.tooling</groupId>
+                <artifactId>depends-maven-plugin</artifactId>
+            </plugin>
             <plugin>
                 <groupId>org.apache.karaf.tooling</groupId>
                 <artifactId>karaf-maven-plugin</artifactId>
-                <version>3.0.8</version>
+                <version>${karaf4.plugin.version}</version>
                 <extensions>true</extensions>
                 <configuration>
+                    <simplifyBundleDependencies>true</simplifyBundleDependencies>
                     <excludedArtifactIds>
                         <excludedArtifactId>slf4j-api</excludedArtifactId>
                     </excludedArtifactIds>
@@ -70,7 +81,7 @@
                 <!-- Test the generated features.xml -->
                 <dependency>
                     <groupId>org.opendaylight.odlparent</groupId>
-                    <artifactId>features-test</artifactId>
+                    <artifactId>features4-test</artifactId>
                     <version>1.8.0-SNAPSHOT</version>
                     <scope>test</scope>
                 </dependency>
@@ -88,7 +99,7 @@
                         <version>${maven.surefire.version}</version>
                         <configuration>
                             <dependenciesToScan>
-                                <dependency>org.opendaylight.odlparent:features-test</dependency>
+                                <dependency>org.opendaylight.odlparent:features4-test</dependency>
                             </dependenciesToScan>
                             <additionalClasspathElements>
                                 <additionalClasspathElement>${project.build.directory}/feature</additionalClasspathElement>
diff --git a/single-feature3-parent/pom.xml b/single-feature3-parent/pom.xml
new file mode 100644 (file)
index 0000000..00cf0b2
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2016 Red Hat, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!--
+         Base parent POM for building and packaging single Karaf features.
+         Karaf features are generated based on the POM dependencies; they can be supplemented by a base
+         feature.xml file in src/main/feature.
+
+         By default, such single features aren't tested for loadability; they're supposed to be aggregated
+         in a feature repository (see feature-repo-parent), which is tested using SingleFeatureTest. The
+         sft profile can be used to enforce SingleFeatureTest on single features too.
+
+         Single features which aren't part of a repository can not be considered part of a project's API.
+         In any case, refer to each project's declared features to determine their API and future
+         availability.
+
+         Users should do the following:
+
+         - specify this as their parent
+         - make sure the packaging is set to feature
+         - setup projects <dependencies/> as needed for their features
+    -->
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>odlparent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../odlparent</relativePath>
+    </parent>
+
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>single-feature3-parent</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <version>${karaf.version}</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <excludedArtifactIds>
+                        <excludedArtifactId>slf4j-api</excludedArtifactId>
+                    </excludedArtifactIds>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--
+        Maven Site Configuration
+
+        The following configuration is necessary for maven-site-plugin to
+        correctly identify the correct deployment path for OpenDaylight Maven
+        sites.
+    -->
+    <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+    <distributionManagement>
+        <site>
+            <id>opendaylight-site</id>
+            <url>${nexus.site.url}/${project.artifactId}/</url>
+        </site>
+    </distributionManagement>
+
+</project>
\ No newline at end of file