This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karaf.git
The following commit(s) were added to refs/heads/main by this push:
new b523e94cf Ref #287: Add camel-karaf-feature-maven-plugin (#317)
b523e94cf is described below
commit b523e94cfe0c2fe3f23de1e199f4a384b7fbd598
Author: Stefan Tataru <[email protected]>
AuthorDate: Tue Jun 4 15:48:47 2024 +0200
Ref #287: Add camel-karaf-feature-maven-plugin (#317)
Maven Plugin that modifies `karaf/features/target/feature/camel-features.xm`
`ensure-wrap-bundle-version` - will add the **Bundle-Version** header to
the bundles that are using the **wrap** protocol and do not already have the
header declared. It will also check the existing Bundle-Version declarations
and make sure that they are OSGI compliant.
---------
Co-authored-by: Nicolas Filotto <[email protected]>
---
features/pom.xml | 15 ++
features/src/main/feature/camel-features.xml | 2 +-
pom.xml | 2 +
tooling/camel-karaf-feature-maven-plugin/pom.xml | 104 ++++++++
.../feature/maven/EnsureWrapBundleVersionMojo.java | 270 +++++++++++++++++++++
.../maven/EnsureWrapBundleVersionMojoTest.java | 143 +++++++++++
tooling/pom.xml | 35 +++
7 files changed, 570 insertions(+), 1 deletion(-)
diff --git a/features/pom.xml b/features/pom.xml
index 7866f42d6..892315938 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -63,6 +63,21 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.camel.karaf</groupId>
+ <artifactId>camel-karaf-feature-maven-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>ensure-wrap-bundle-version</goal>
+ </goals>
+ <configuration>
+
<featuresFilePath>file:${project.build.directory}/feature/camel-features.xml</featuresFilePath>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
diff --git a/features/src/main/feature/camel-features.xml
b/features/src/main/feature/camel-features.xml
index 52d31f837..cbd4828d2 100644
--- a/features/src/main/feature/camel-features.xml
+++ b/features/src/main/feature/camel-features.xml
@@ -17,7 +17,7 @@
limitations under the License.
-->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.5.0"
name="camel-${project.version}">
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.6.0"
name="camel-${project.version}">
<!-- TODO: specs will be provided by Apache Karaf 4.5.x spec features
repository. However, in order to have Camel 4.x working on Karaf 4.4.x, we
define spec features here -->
<feature name="jakarta-activation" version="${jakarta-activation-version}">
diff --git a/pom.xml b/pom.xml
index e6c2a9deb..ea0aa6f16 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,7 @@
<!-- <module>archetypes</module> -->
<!-- <module>bom</module> -->
<module>tests</module>
+ <module>tooling</module>
</modules>
<scm>
@@ -548,6 +549,7 @@
<osgi.service.event.version>1.4.1</osgi.service.event.version>
<osgi.service.component.version>1.5.1</osgi.service.component.version>
<slf4j.version>2.0.13</slf4j.version>
+ <servicemix-specs-version>10</servicemix-specs-version>
<camel.osgi.version.clean>4.6</camel.osgi.version.clean>
<camel.osgi.next.version.clean>4.7</camel.osgi.next.version.clean>
diff --git a/tooling/camel-karaf-feature-maven-plugin/pom.xml
b/tooling/camel-karaf-feature-maven-plugin/pom.xml
new file mode 100644
index 000000000..6a039ecdd
--- /dev/null
+++ b/tooling/camel-karaf-feature-maven-plugin/pom.xml
@@ -0,0 +1,104 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.karaf</groupId>
+ <artifactId>tooling</artifactId>
+ <version>4.6.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-karaf-feature-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Apache Camel :: Karaf :: Tooling :: Feature Maven Plugin</name>
+
+ <properties>
+ <felix.utils.version>1.11.8</felix.utils.version>
+ <maven.version>3.9.7</maven.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <version>${felix.utils.version}</version>
+ </dependency>
+
+ <!-- maven plugin -->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ </dependency>
+
+ <!-- tests -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>${junit-jupiter-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>${junit-jupiter-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- maven plugin -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-descriptor</id>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- tests -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git
a/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojo.java
b/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojo.java
new file mode 100644
index 000000000..ef06fe20d
--- /dev/null
+++
b/tooling/camel-karaf-feature-maven-plugin/src/main/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojo.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.karaf.feature.maven;
+
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.utils.version.VersionCleaner;
+import org.apache.karaf.features.internal.model.Bundle;
+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.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.osgi.framework.Version;
+
+@Mojo(name = "ensure-wrap-bundle-version", defaultPhase =
LifecyclePhase.PROCESS_RESOURCES)
+public class EnsureWrapBundleVersionMojo extends AbstractMojo {
+
+ private static final String FILE_PROTOCOL = "file:";
+
+ private static final String WRAP_PROTOCOL = "wrap:mvn:";
+ private static final List<String> HEADERS_AFTER_BUNDLE_VEIRSION =
Arrays.asList(
+ //"Bundle-Version",
+ "DynamicImport-Package",
+ "Export-Package",
+ "Export-Service",
+ "Fragment-Host",
+ "Import-Package",
+ "Import-Service",
+ "Provide-Capability",
+ "Require-Bundle",
+ "Require-Capability");
+
+ private static final String DEFAULT_HEADER = "<?xml version=\"1.0\"
encoding=\"UTF-8\" standalone=\"yes\"?>";
+ private static final String LICENCE_HEADER = """
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->""";
+
+ static final String BUNDLE_VERSION = "Bundle-Version";
+
+ @Parameter(property = "featuresFilePath", required = true)
+ private String featuresFilePath;
+
+ public String getFeaturesFilePath() {
+ return featuresFilePath;
+ }
+
+ public void setFeaturesFilePath(String featuresFilePath) {
+ this.featuresFilePath = featuresFilePath;
+ }
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ Features featuresData = JaxbUtil.unmarshal(getFeaturesFilePath(),
false);
+ processFeatures(featuresData.getFeature());
+
+ marshal(featuresData);
+ }
+
+ private void marshal(Features featuresData) throws MojoExecutionException {
+ try (StringWriter writer = new StringWriter()) {
+ JaxbUtil.marshal(featuresData, writer);
+
+ String result = writer.toString().replace(DEFAULT_HEADER,
LICENCE_HEADER);
+
+ Path path =
Paths.get(getFeaturesFilePath().replaceFirst(FILE_PROTOCOL, ""));
+ Files.writeString(path, result);
+
+ getLog().info("File '%s' was successfully modified and
saved".formatted(getFeaturesFilePath()));
+ } catch (Exception e) {
+ getLog().error("File '%s' was successfully modified but an error
occurred while saving it"
+ .formatted(getFeaturesFilePath()), e);
+ throw new MojoExecutionException(e);
+ }
+ }
+
+ private void processFeatures(List<Feature> features) {
+ for (Feature feature : features) {
+ processFeature(feature);
+ }
+ }
+
+ private void processFeature(Feature feature) {
+ for (Bundle bundle : feature.getBundle()) {
+ String location = bundle.getLocation();
+ if (location != null && location.startsWith(WRAP_PROTOCOL)) {
+ try {
+ bundle.setLocation(processLocation(location));
+ } catch (Exception e) {
+ getLog().error("Could not process the Bundle location
'%s': %s".formatted(location, e.getMessage()), e);
+ }
+ }
+ }
+ }
+
+ String processLocation(String location) throws Exception {
+ int versionStartIndex = getVersionStartIndex(location);
+ int versionEndIndex = getVersionEndIndex(location, versionStartIndex);
+
+ String rawVersion = getVersion(location, versionStartIndex,
versionEndIndex);
+ String version = getValidVersion(location, rawVersion);
+
+ String bundleVersionHeader = "%s=%s".formatted(BUNDLE_VERSION,
version);
+
+ if (location.contains(bundleVersionHeader)) {
+ return location;
+ } else if (location.contains(BUNDLE_VERSION)) {
+ return updateExistingVersion(location, bundleVersionHeader);
+ }
+
+ String wrapProtocolOptions = location.substring(versionEndIndex + 1,
location.length());
+ StringBuilder sb = new StringBuilder(location);
+
+ // insert before existing headers header
+ for (String header : HEADERS_AFTER_BUNDLE_VEIRSION) {
+ // add Bundle-Version before
+ if (location.contains(header)) {
+ int versionHeaderStartIndex = location.indexOf(header);
+ if (wrapProtocolOptions.contains("$")) {
+ // "amp;" is automatically added
+ return sb.insert(versionHeaderStartIndex,
"%s&".formatted(bundleVersionHeader)).toString();
+ } else {
+ // "amp;" is automatically added
+ return sb.insert(versionHeaderStartIndex,
"$%s&".formatted(bundleVersionHeader)).toString();
+ }
+ }
+ }
+
+ // insert at the end
+ if (wrapProtocolOptions.contains("$")) {
+ // "amp;" is automatically added
+ return sb.insert(location.length(),
"&%s".formatted(bundleVersionHeader)).toString();
+ } else {
+ return sb.insert(location.length(),
"$%s".formatted(bundleVersionHeader)).toString();
+ }
+ }
+
+ /**
+ * @return artifact version first char index, inclusive
+ */
+ int getVersionStartIndex(String location) {
+ boolean artifactIdFound = false;
+ for (int i = 0; i < location.length(); i++) {
+ if ('/' == location.charAt(i)) {
+ if (!artifactIdFound) {
+ artifactIdFound = true;
+ } else {
+ return i + 1;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ int getVersionEndIndex(String location) {
+ return getVersionEndIndex(location, getVersionStartIndex(location));
+ }
+
+ /**
+ * @return artifact version last char index, inclusive
+ */
+ int getVersionEndIndex(String location, int versionStartIndex) {
+ // start at + 1 to ignore the potential $ coming from version
placeholder
+ for (int i = versionStartIndex + 1; i < location.length(); i++) {
+ if ('$' == location.charAt(i)) {
+ return i - 1;
+ }
+ }
+
+ return location.length() - 1;
+ }
+
+ String getVersion(String Location) {
+ return getVersion(Location, getVersionStartIndex(Location),
getVersionEndIndex(Location));
+ }
+
+ String getVersion(String location, int versionStartIndex, int
versionEndIndex) {
+ return location.substring(versionStartIndex, versionEndIndex + 1);
+ }
+
+ String getValidVersion(String location, String version) throws Exception {
+ if (version.charAt(0) == '$') {
+ throw new Exception("Maven version placeholder '%s' wasn't
resolved".formatted(version));
+ }
+
+ String cleanVersion = VersionCleaner.clean(version);
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(
+ "Bundle location '%s' will be set with Bundle-Version
'%s', the output of VersionCleaner.clean(%s)"
+ .formatted(location, cleanVersion, version));
+ }
+
+ // test if clean version will work in Karaf, just in case
+ try {
+ new Version(cleanVersion);
+ return cleanVersion;
+ } catch (Exception newException) {
+ throw new Exception("Version '%s' is not OSGi
compliant".formatted(cleanVersion), newException);
+ }
+ }
+
+ String updateExistingVersion(String location, String bundleVersioHeader)
throws Exception {
+ int versionHeaderStartIndex = location.indexOf(BUNDLE_VERSION);
+ int versionHeaderEndIndex = getBundleVersionHeaderEndIndex(location,
versionHeaderStartIndex);
+
+ // BUNDLE_VERSION.length() + 1 will include '='
+ String currentVersion = location.substring(versionHeaderStartIndex +
BUNDLE_VERSION.length() + 1,
+ versionHeaderEndIndex + 1);
+ if (currentVersion.charAt(0) == '$' ||
!currentVersion.equals(getValidVersion(location, currentVersion))) {
+ String currentBundleVersionHeader =
location.substring(versionHeaderStartIndex, versionHeaderEndIndex + 1);
+
+ return location.replace(currentBundleVersionHeader,
bundleVersioHeader);
+ }
+
+ return location;
+ }
+
+ /**
+ * @return wrap protocol Bundle-Version header last char index, inclusive
+ */
+ int getBundleVersionHeaderEndIndex(String location, int
versionHeaderStartIndex) {
+ for (int i = versionHeaderStartIndex; i < location.length(); i++) {
+ if (location.charAt(i) == '&' || location.charAt(i) == ';') {
+ return i - 1;
+ }
+ }
+
+ return location.length() - 1;
+ }
+}
\ No newline at end of file
diff --git
a/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojoTest.java
b/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojoTest.java
new file mode 100644
index 000000000..974750717
--- /dev/null
+++
b/tooling/camel-karaf-feature-maven-plugin/src/test/java/org/apache/camel/karaf/feature/maven/EnsureWrapBundleVersionMojoTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.karaf.feature.maven;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class EnsureWrapBundleVersionMojoTest {
+
+ private final EnsureWrapBundleVersionMojo ensureVersionMojo = new
EnsureWrapBundleVersionMojo();
+
+ @Test
+ void modifyLocationTest() throws Exception {
+ // add bundle version at the end as first wrap protocol option
+ String location = "wrap:mvn:org.apache.olingo/odata-server-core/5.0.0";
+ String expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=5.0.0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+
+ // add bundle version at the end but not as first wrap protocol option
+ location =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge";
+ expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Version=5.0.0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+
+ // add bundle version before existing wrap protocol header that should
be declared after
+ location =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Export-Package=org.apache.olingo.*;version=5.0.0";
+ expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Bundle-Version=5.0.0&Export-Package=org.apache.olingo.*;version=5.0.0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+
+ // original version won't work in Karaf
+ location =
"wrap:mvn:com.google.apis/google-api-services-storage/v1-rev20240209-2.0.0";
+ expected =
"wrap:mvn:com.google.apis/google-api-services-storage/v1-rev20240209-2.0.0$Bundle-Version=0.0.0.v1-rev20240209-2_0_0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+
+ // bundle version header is present but it won't work in Karaf
+ location =
"wrap:mvn:com.google.apis/google-api-services-storage/v1-rev20240209-2.0.0$Bundle-Version=v1-rev20240209-2.0.0";
+ expected =
"wrap:mvn:com.google.apis/google-api-services-storage/v1-rev20240209-2.0.0$Bundle-Version=0.0.0.v1-rev20240209-2_0_0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+
+ // bundle version header is present and points to the wrong value but
it will
+ // work in Karaf
+ location = "mvn:commons-io/commons-io/2.15.1$Bundle-Version=2.15.0";
+ expected = "mvn:commons-io/commons-io/2.15.1$Bundle-Version=2.15.0";
+ assertEquals(expected, ensureVersionMojo.processLocation(location));
+ }
+
+ @Test
+ void getVersionStartIndexTest() {
+ assertEquals(51,
+
ensureVersionMojo.getVersionStartIndex("wrap:mvn:org.apache.httpcomponents.core5/httpcore5/5.2.1"));
+ assertEquals(51, ensureVersionMojo.getVersionStartIndex(
+
"wrap:mvn:org.eclipse.californium/element-connector/3.11.0$overwrite=merge&Import-Package=net.i2p.crypto.eddsa;resolution:=optional"));
+ }
+
+ @Test
+ void getVersionEndIndexTest() {
+ assertEquals(55,
+
ensureVersionMojo.getVersionEndIndex("wrap:mvn:org.apache.httpcomponents.core5/httpcore5/5.2.1"));
+ assertEquals(56, ensureVersionMojo.getVersionEndIndex(
+
"wrap:mvn:org.eclipse.californium/element-connector/3.11.0$overwrite=merge&Import-Package=net.i2p.crypto.eddsa;resolution:=optional"));
+ }
+
+ @Test
+ void getVersionTest() {
+ assertEquals("${google-oauth-client-version}",
ensureVersionMojo.getVersion(
+
"wrap:mvn:com.google.oauth-client/google-oauth-client-jetty/${google-oauth-client-version}$overwrite=merge&Import-Package=com.sun.net.httpserver;resolution:=optional,*"));
+
+ assertEquals("8.44.0.Final",
ensureVersionMojo.getVersion("wrap:mvn:org.kie/kie-api/8.44.0.Final"));
+
+ assertEquals("5.0.0", ensureVersionMojo.getVersion(
+
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$overwrite=merge&Export-Package=org.apache.olingo.*;version=5.0.0"));
+
+ assertEquals("${grpc-version}",
+
ensureVersionMojo.getVersion("wrap:mvn:io.grpc/grpc-core/${grpc-version}$${spi-provider}"));
+
+ assertEquals("1.63.0",
ensureVersionMojo.getVersion("wrap:mvn:io.grpc/grpc-googleapis/1.63.0$SPI-Provider=*"));
+ }
+
+ @Test
+ void getValidVersionTest() throws Exception {
+ // raw version is already valid
+ assertEquals("1.2.3", ensureVersionMojo.getValidVersion("", "1.2.3"));
+ assertEquals("1.0.0", ensureVersionMojo.getValidVersion("", "1.0"));
+
+ // raw version is invalid
+ assertEquals("0.0.0.SRU2023-10_1_4",
ensureVersionMojo.getValidVersion("", "SRU2023-10.1.4"));
+ assertEquals("1.23.1.alpha", ensureVersionMojo.getValidVersion("",
"1.23.1-alpha"));
+ assertEquals("0.0.0.v3-rev20240123-2_0_0",
ensureVersionMojo.getValidVersion("", "v3-rev20240123-2.0.0"));
+ assertEquals("1.1.0.4c", ensureVersionMojo.getValidVersion("",
"1.1.4c"));
+ }
+
+ @Test
+ void updateExistingVersionTest() throws Exception {
+ String bundleVersionHeader = "Bundle-Version=9.9.9";
+
+ // no update test
+ String location =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=4.4.4";
+ String expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=4.4.4";
+ String result = ensureVersionMojo.updateExistingVersion(location,
bundleVersionHeader);
+ assertEquals(expected, result);
+
+ location =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=${unresolved-placeholder-version}";
+ expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=9.9.9";
+ result = ensureVersionMojo.updateExistingVersion(location,
bundleVersionHeader);
+ assertEquals(expected, result);
+
+ location =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=invalid_4.4.4";
+ expected =
"wrap:mvn:org.apache.olingo/odata-server-core/5.0.0$Bundle-Version=9.9.9";
+ result = ensureVersionMojo.updateExistingVersion(location,
bundleVersionHeader);
+ assertEquals(expected, result);
+
+ location =
"wrap:mvn:org.eclipse.californium/element-connector/${californium-version}$overwrite=merge&Bundle-Version=invalid_4.4.4&Import-Package=net.i2p.crypto.eddsa;resolution:=optional";
+ expected =
"wrap:mvn:org.eclipse.californium/element-connector/${californium-version}$overwrite=merge&Bundle-Version=9.9.9&Import-Package=net.i2p.crypto.eddsa;resolution:=optional";
+ result = ensureVersionMojo.updateExistingVersion(location,
bundleVersionHeader);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ void getBundleVersionHeaderEndIndexTest() {
+ String location =
"wrap:mvn:org.apache.qpid/qpid-jms-client/${qpid-jms-client-version}$Bundle-Version=${qpid-jms-client-version}&Import-Package=net.i2p.crypto.eddsa;resolution:=optional";
+ int versionHeaderStartIndex =
location.indexOf(EnsureWrapBundleVersionMojo.BUNDLE_VERSION);
+ assertEquals(108,
ensureVersionMojo.getBundleVersionHeaderEndIndex(location,
versionHeaderStartIndex));
+
+ location =
"wrap:mvn:org.apache.qpid/qpid-jms-client/${qpid-jms-client-version}$Bundle-Version=${qpid-jms-client-version}";
+ versionHeaderStartIndex =
location.indexOf(EnsureWrapBundleVersionMojo.BUNDLE_VERSION);
+ assertEquals(108,
ensureVersionMojo.getBundleVersionHeaderEndIndex(location,
versionHeaderStartIndex));
+ }
+}
\ No newline at end of file
diff --git a/tooling/pom.xml b/tooling/pom.xml
new file mode 100644
index 000000000..aa47d0d65
--- /dev/null
+++ b/tooling/pom.xml
@@ -0,0 +1,35 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel.karaf</groupId>
+ <artifactId>camel-karaf</artifactId>
+ <version>4.6.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>tooling</artifactId>
+ <packaging>pom</packaging>
+ <name>Apache Camel :: Karaf :: Tooling</name>
+
+ <modules>
+ <module>camel-karaf-feature-maven-plugin</module>
+ </modules>
+
+</project>
\ No newline at end of file