Rework BouncyCastle/OSGi integration 60/79160/6
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 2 Jan 2019 17:30:05 +0000 (18:30 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 4 Jan 2019 12:37:55 +0000 (13:37 +0100)
We are packaging BC jars twice, once in lib/boot for the purposes
of having the provider set by karaf's Main class and second time
to expose them to OSGi world via startup.properties as normal bundles.

This is required because the boot classpath is not exposed directly
into OSGi world and thus bundles linking to BC would not be able
to find correct exports.

An alternative would be to specify all the packages through
org.osgi.framework.system.packages.extra, but that has the downside
of being static and requiring maintentance.

This patch takes the route of Framework Extension Bundles, where
it provides two fragment bundles, which attach to system.bundle,
which itself has access to the boot class loader -- hence they
can themselves contain appropriate Export-Package instructions.

We generate these instructions from upstream bundles by unpacking
their manifest and retaining only Export-Package instruction (via a
simplistic maven plugin) and feeding this as input into
maven-bundle-plugin.

JIRA: ODLPARENT-185
Change-Id: I5cbfc9a499aa117581004585f4fa5283f65a5a38
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
filter-manifest-plugin/pom.xml [new file with mode: 0644]
filter-manifest-plugin/src/main/java/org/opendaylight/odlparent/filter/manifest/plugin/FilterManifestMojo.java [new file with mode: 0644]
karaf/bcpkix-framework-ext/pom.xml [new file with mode: 0644]
karaf/bcprov-framework-ext/pom.xml [new file with mode: 0644]
karaf/karaf4-parent/pom.xml
karaf/opendaylight-karaf-resources/pom.xml
karaf/pom.xml
odlparent-artifacts/pom.xml
pom.xml

diff --git a/filter-manifest-plugin/pom.xml b/filter-manifest-plugin/pom.xml
new file mode 100644 (file)
index 0000000..acb8c30
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2019 Pantheon Technologies, s.r.o. 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>
+        <artifactId>odlparent</artifactId>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <version>4.0.8-SNAPSHOT</version>
+        <relativePath>../odlparent</relativePath>
+    </parent>
+    <artifactId>filter-manifest-plugin</artifactId>
+    <packaging>maven-plugin</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+    <description>
+        Simple plugin for extracting a set of attributes from a source
+        MANIFEST.MF into an output. This is useful in situations where you
+        need to create a bundle based on some other bundle.
+    </description>
+
+    <prerequisites>
+        <maven>3.3.9</maven>
+    </prerequisites>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>3.3.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.3</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>mojo-descriptor</id>
+                        <goals>
+                            <goal>descriptor</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.github.spotbugs</groupId>
+                <artifactId>spotbugs-maven-plugin</artifactId>
+                <configuration>
+                    <failOnError>true</failOnError>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/filter-manifest-plugin/src/main/java/org/opendaylight/odlparent/filter/manifest/plugin/FilterManifestMojo.java b/filter-manifest-plugin/src/main/java/org/opendaylight/odlparent/filter/manifest/plugin/FilterManifestMojo.java
new file mode 100644 (file)
index 0000000..88a3b77
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019 Pantheon Technologies, s.r.o. 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.filter.manifest.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.Manifest;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Mojo processing filtering an input Manifest file into an output, retaining only selected entries.
+ */
+@Mojo(name = "filter-manifest")
+public class FilterManifestMojo extends AbstractMojo {
+    private static final Logger LOG = LoggerFactory.getLogger(FilterManifestMojo.class);
+
+    /**
+     * Input {@code MANIFEST.MF} file.
+     */
+    @Parameter(required = true)
+    private File inputFile;
+
+    /**
+     * Output {@code MANIFEST.MF} file.
+     */
+    @Parameter(required = true)
+    private File outputFile;
+
+    /**
+     * List of main attributes that should be copied from input to output. All other attributes (aside from version)
+     * and entries are ignored. If an attribute is specified here and it does not exist in input, plugin execution will
+     * fail.
+     */
+    @Parameter(required = true)
+    private List<String> retainedAttributes;
+
+    @Override
+    public void execute() throws MojoExecutionException {
+        LOG.debug("Filtering {} to {} retaining {}", inputFile, outputFile, retainedAttributes);
+
+        final Manifest input;
+        try (InputStream is = Files.newInputStream(inputFile.toPath())) {
+            input = new Manifest(is);
+        } catch (IOException e) {
+            throw new MojoExecutionException("Failed to read input " + inputFile, e);
+        }
+
+        // Keep only the entries we are instructed to keep
+        final Attributes inputAttrs = input.getMainAttributes();
+        LOG.debug("Input manifest has attributes {}", inputAttrs.keySet());
+
+        final Manifest output = new Manifest();
+        final Attributes outputAttrs = output.getMainAttributes();
+        // We need to always emit version
+        outputAttrs.putValue(Name.MANIFEST_VERSION.toString(), inputAttrs.getValue(Name.MANIFEST_VERSION));
+
+        for (String attr : retainedAttributes) {
+            final String value = inputAttrs.getValue(attr);
+            if (value == null) {
+                throw new MojoExecutionException("Attribute " + attr + " is not present in " + inputFile);
+            }
+
+            LOG.debug("Propagating attribute {} value {}", attr, value);
+            outputAttrs.putValue(attr, value);
+        }
+        LOG.debug("Output manifest has attributes {}", outputAttrs.keySet());
+
+        try (OutputStream os = Files.newOutputStream(outputFile.toPath())) {
+            output.write(os);
+        } catch (IOException e) {
+            throw new MojoExecutionException("Failed to write output " + outputFile, e);
+        }
+    }
+}
diff --git a/karaf/bcpkix-framework-ext/pom.xml b/karaf/bcpkix-framework-ext/pom.xml
new file mode 100644 (file)
index 0000000..e1d4211
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright © 2019 Pantheon Technologies, s.r.o. 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>4.0.8-SNAPSHOT</version>
+        <relativePath>../../bundle-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>bcpkix-framework-ext</artifactId>
+    <packaging>bundle</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>unpack-dependencies</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>unpack-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <includes>**/MANIFEST.MF</includes>
+                            <includeArtifactIds>bcpkix-jdk15on</includeArtifactIds>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>filter-manifest-plugin</artifactId>
+                <version>${project.version}</version>
+                <executions>
+                    <execution>
+                        <id>filter-manifest</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>filter-manifest</goal>
+                        </goals>
+                        <configuration>
+                            <inputFile>${project.build.directory}/dependency/META-INF/MANIFEST.MF</inputFile>
+                            <outputFile>${project.build.directory}/MANIFEST.MF</outputFile>
+                            <retainedAttributes>
+                                <retainedAttribute>Export-Package</retainedAttribute>
+                            </retainedAttributes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <_include>${project.build.directory}/MANIFEST.MF</_include>
+                        <Fragment-Host>system.bundle;extension:=framework</Fragment-Host>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/karaf/bcprov-framework-ext/pom.xml b/karaf/bcprov-framework-ext/pom.xml
new file mode 100644 (file)
index 0000000..5b8acad
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright © 2019 Pantheon Technologies, s.r.o. 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>4.0.8-SNAPSHOT</version>
+        <relativePath>../../bundle-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>bcprov-framework-ext</artifactId>
+    <packaging>bundle</packaging>
+    <name>ODL :: odlparent :: ${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-ext-jdk15on</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>unpack-dependencies</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>unpack-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <includes>**/MANIFEST.MF</includes>
+                            <includeArtifactIds>bcprov-ext-jdk15on</includeArtifactIds>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>filter-manifest-plugin</artifactId>
+                <version>${project.version}</version>
+                <executions>
+                    <execution>
+                        <id>filter-manifest</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>filter-manifest</goal>
+                        </goals>
+                        <configuration>
+                            <inputFile>${project.build.directory}/dependency/META-INF/MANIFEST.MF</inputFile>
+                            <outputFile>${project.build.directory}/MANIFEST.MF</outputFile>
+                            <retainedAttributes>
+                                <retainedAttribute>Export-Package</retainedAttribute>
+                            </retainedAttributes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <_include>${project.build.directory}/MANIFEST.MF</_include>
+                        <Fragment-Host>system.bundle;extension:=framework</Fragment-Host>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
index 4f7f56fdb21750d3edadb50c43fbfc0a316e91c9..37d7f7498b6d9b5144db22e10ec04082e0bc03e8 100644 (file)
             <!-- for https://bugs.opendaylight.org/show_bug.cgi?id=4290 -->
             <artifactId>org.osgi.service.event</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcpkix-jdk15on</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcprov-ext-jdk15on</artifactId>
-        </dependency>
 
         <!-- Optional dependency of karaf.config.core -->
         <dependency>
             <groupId>org.opendaylight.odlparent</groupId>
             <artifactId>opendaylight-karaf-resources</artifactId>
         </dependency>
+
+        <!-- BouncyCastle Framework Extension Bundles -->
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bcpkix-framework-ext</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlparent</groupId>
+            <artifactId>bcprov-framework-ext</artifactId>
+            <scope>runtime</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 1607e6804c7d980b2f7e55134b7cbfc2705ad9b8..e63983c533770f85d293b435a4622f5ce57d8897 100644 (file)
@@ -41,6 +41,7 @@
       <scope>runtime</scope>
     </dependency>
   </dependencies>
+
   <build>
     <resources>
       <resource>
 # The following are added by opendaylight-karaf-resources
 mvn\:org.osgi/org.osgi.service.event/1.3.1 = 7
 mvn\:org.apache.felix/org.apache.felix.metatype/1.2.2 = 8
-mvn\:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version} = 14
-mvn\:org.bouncycastle/bcprov-ext-jdk15on/${bouncycastle.version} = 14
+mvn\:org.opendaylight.odlparent/bcprov-framework-ext/${project.version} = 14
+mvn\:org.opendaylight.odlparent/bcpkix-framework-ext/${project.version} = 14
 mvn\:org.apache.aries.blueprint/org.apache.aries.blueprint.core.compatibility/1.0.0 = 14
                 </echo>
                 <copy file="${project.build.directory}/assembly/etc/startup.properties"
index 643fa1a4adb70cfa39eb3fea75a855357898a8df..778e1f10fc032edfa1d747ffedce2c9ab0d92a63 100644 (file)
@@ -26,6 +26,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     </properties>
 
     <modules>
+        <module>bcpkix-framework-ext</module>
+        <module>bcprov-framework-ext</module>
         <module>karaf-branding</module>
         <module>karaf4-parent</module>
         <module>opendaylight-karaf-resources</module>
index b21a4d2fd1c902d3ee09e9120ac7003b3bae2d98..6a91a3e013c46f86f72d91f28fceb304e0a21076 100644 (file)
                 <type>zip</type>
             </dependency>
 
+            <!-- BouncyCastle/Karaf/OSGi glue -->
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>bcpkix-framework-ext</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.odlparent</groupId>
+                <artifactId>bcprov-framework-ext</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.opendaylight.odlparent</groupId>
                 <artifactId>features-odlparent</artifactId>
diff --git a/pom.xml b/pom.xml
index e3ff4f0cc76e912c1c2491ed252f03c6de952fc9..71392c59896471b3e755b8027d5bccd322df2ff0 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,9 @@
         <module>odlparent</module>
         <module>odlparent-lite</module>
 
+        <!-- Manifest filtering plugin -->
+        <module>filter-manifest-plugin</module>
+
         <!-- Features -->
         <module>features</module>