This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 0940f345ab6 CAMEL-18204: camel-jbang - Export to quarkus should use
quarkus catalog to know if the JARs are an extension or not to generate correct
pom.xml
0940f345ab6 is described below
commit 0940f345ab67cd4a2a93a4abb652f17f37632af4
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Jun 21 12:31:18 2022 +0200
CAMEL-18204: camel-jbang - Export to quarkus should use quarkus catalog to
know if the JARs are an extension or not to generate correct pom.xml
---
.../dsl/jbang/core/commands/ExportQuarkus.java | 110 ++++++++++++++++++++-
.../camel/dsl/jbang/core/common/XmlHelper.java | 58 +++++++++++
.../camel/main/download/DependencyDownloader.java | 22 ++++-
.../main/download/MavenDependencyDownloader.java | 36 ++++++-
4 files changed, 221 insertions(+), 5 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
index 8146be4ebb1..e9badb96529 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
@@ -22,7 +22,22 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Set;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.RuntimeProvider;
+import org.apache.camel.dsl.jbang.core.common.XmlHelper;
+import org.apache.camel.main.KameletMain;
+import org.apache.camel.main.download.MavenArtifact;
+import org.apache.camel.main.download.MavenDependencyDownloader;
import org.apache.camel.main.download.MavenGav;
+import org.apache.camel.tooling.model.ArtifactModel;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.OrderedProperties;
@@ -30,6 +45,12 @@ import org.apache.commons.io.FileUtils;
class ExportQuarkus extends Export {
+ private static final String DEFAULT_CAMEL_CATALOG =
"org.apache.camel.catalog.DefaultCamelCatalog";
+ private static final String QUARKUS_CATALOG_PROVIDER =
"org.apache.camel.catalog.quarkus.QuarkusRuntimeProvider";
+
+ private String camelVersion = null;
+ private String camelQuarkusVersion = null;
+
public ExportQuarkus(CamelJBangMain main) {
super(main);
}
@@ -129,11 +150,17 @@ class ExportQuarkus extends Export {
String context = IOHelper.loadText(is);
IOHelper.close(is);
+ CamelCatalog catalog = loadQuarkusCatalog();
+ if (camelVersion == null) {
+ camelVersion = catalog.getCatalogVersion();
+ }
+
context = context.replaceFirst("\\{\\{ \\.GroupId }}", ids[0]);
context = context.replaceFirst("\\{\\{ \\.ArtifactId }}", ids[1]);
context = context.replaceFirst("\\{\\{ \\.Version }}", ids[2]);
context = context.replaceAll("\\{\\{ \\.QuarkusVersion }}",
quarkusVersion);
context = context.replaceFirst("\\{\\{ \\.JavaVersion }}",
javaVersion);
+ context = context.replaceFirst("\\{\\{ \\.CamelVersion }}",
camelVersion);
OrderedProperties prop = new OrderedProperties();
prop.load(new FileInputStream(settings));
@@ -162,9 +189,17 @@ class ExportQuarkus extends Export {
String v = gav.getVersion();
// transform to camel-quarkus extension GAV
if ("org.apache.camel".equals(gid)) {
- gid = "org.apache.camel.quarkus";
- aid = aid.replace("camel-", "camel-quarkus-");
- v = null;
+ String qaid = aid.replace("camel-", "camel-quarkus-");
+ ArtifactModel<?> am =
catalog.modelFromMavenGAV("org.apache.camel.quarkus", qaid, null);
+ if (am != null) {
+ // use quarkus extension
+ gid = am.getGroupId();
+ aid = am.getArtifactId();
+ v = null; // uses BOM so version should not be included
+ } else {
+ // there is no quarkus extension so use plain camel
+ v = camelVersion;
+ }
}
sb.append(" <dependency>\n");
sb.append("
<groupId>").append(gid).append("</groupId>\n");
@@ -191,4 +226,73 @@ class ExportQuarkus extends Export {
return answer;
}
+ private CamelCatalog loadQuarkusCatalog() {
+ CamelCatalog answer = new DefaultCamelCatalog(true);
+
+ // use kamelet-main to dynamic download dependency via maven
+ KameletMain main = new KameletMain();
+ try {
+ main.start();
+
+ // shrinkwrap does not return POM file as result (they are
hardcoded to be filtered out)
+ // so after this we download a JAR and then use its File location
to compute the file for the downloaded POM
+ MavenDependencyDownloader downloader =
main.getCamelContext().hasService(MavenDependencyDownloader.class);
+ downloader.downloadArtifact("io.quarkus.platform",
"quarkus-camel-bom:pom", quarkusVersion);
+ MavenArtifact ma = downloader.downloadArtifact("io.quarkus",
"quarkus-core", quarkusVersion);
+ if (ma != null && ma.getFile() != null) {
+ String name = ma.getFile().getAbsolutePath();
+ name = name.replace("io/quarkus/quarkus-core",
"io/quarkus/platform/quarkus-camel-bom");
+ name = name.replace("quarkus-core", "quarkus-camel-bom");
+ name = name.replace(".jar", ".pom");
+ File file = new File(name);
+ if (file.exists()) {
+ DocumentBuilderFactory dbf =
XmlHelper.createDocumentBuilderFactory();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document dom = db.parse(file);
+
+ // grab what exact camelVersion and camelQuarkusVersion we
are using
+ NodeList nl = dom.getElementsByTagName("dependency");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Element node = (Element) nl.item(i);
+ String g =
node.getElementsByTagName("groupId").item(0).getTextContent();
+ String a =
node.getElementsByTagName("artifactId").item(0).getTextContent();
+ if ("org.apache.camel".equals(g) &&
"camel-core-engine".equals(a)) {
+ camelVersion =
node.getElementsByTagName("version").item(0).getTextContent();
+ } else if ("org.apache.camel.quarkus".equals(g) &&
"camel-quarkus-catalog".equals(a)) {
+ camelQuarkusVersion =
node.getElementsByTagName("version").item(0).getTextContent();
+ }
+ }
+ }
+ }
+
+ if (camelQuarkusVersion != null) {
+ // download camel-quarkus-catalog we use to know if we have an
extension or not
+ downloader.downloadDependency("org.apache.camel.quarkus",
"camel-quarkus-catalog", camelQuarkusVersion);
+
+ Class<RuntimeProvider> clazz =
main.getCamelContext().getClassResolver().resolveClass(QUARKUS_CATALOG_PROVIDER,
+ RuntimeProvider.class);
+ if (clazz != null) {
+ RuntimeProvider provider =
main.getCamelContext().getInjector().newInstance(clazz);
+ if (provider != null) {
+ // re-create answer with the classloader that loaded
spring-boot to be able to load resources in this catalog
+ Class<CamelCatalog> clazz2
+ =
main.getCamelContext().getClassResolver().resolveClass(DEFAULT_CAMEL_CATALOG,
+ CamelCatalog.class);
+ answer =
main.getCamelContext().getInjector().newInstance(clazz2);
+ answer.setRuntimeProvider(provider);
+ // use classloader that loaded spring-boot provider to
ensure we can load its resources
+
answer.getVersionManager().setClassLoader(main.getCamelContext().getApplicationContextClassLoader());
+ answer.enableCache();
+ }
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ main.stop();
+ }
+
+ return answer;
+ }
+
}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
new file mode 100644
index 00000000000..afc58f99cd9
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dsl.jbang.core.common;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.camel.util.ObjectHelper;
+
+public final class XmlHelper {
+
+ private XmlHelper() {
+ }
+
+ public static DocumentBuilderFactory createDocumentBuilderFactory() {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setIgnoringElementContentWhitespace(true);
+ factory.setIgnoringComments(true);
+ try {
+ // Set secure processing
+ factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
Boolean.TRUE);
+ } catch (ParserConfigurationException e) {
+ }
+ try {
+ // Disable the external-general-entities by default
+
factory.setFeature("http://xml.org/sax/features/external-general-entities",
false);
+ } catch (ParserConfigurationException e) {
+ }
+ // setup the SecurityManager by default if it's apache xerces
+ try {
+ Class<?> smClass =
ObjectHelper.loadClass("org.apache.xerces.util.SecurityManager");
+ if (smClass != null) {
+ Object sm = smClass.getDeclaredConstructor().newInstance();
+ // Here we just use the default setting of the SeurityManager
+
factory.setAttribute("http://apache.org/xml/properties/security-manager", sm);
+ }
+ } catch (Exception e) {
+ }
+ return factory;
+ }
+
+}
diff --git
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
index 5823a85dbf0..153ac0d3050 100644
---
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
+++
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
@@ -46,7 +46,7 @@ public interface DependencyDownloader extends
CamelContextAware, StaticService {
void setFresh(boolean fresh);
/**
- * Downloads the dependency
+ * Downloads the dependency incl transitive dependencies
*
* @param groupId maven group id
* @param artifactId maven artifact id
@@ -54,6 +54,26 @@ public interface DependencyDownloader extends
CamelContextAware, StaticService {
*/
void downloadDependency(String groupId, String artifactId, String version);
+ /**
+ * Downloads the dependency
+ *
+ * @param groupId maven group id
+ * @param artifactId maven artifact id
+ * @param version maven version
+ * @param transitively whether to include transitive dependencies
+ */
+ void downloadDependency(String groupId, String artifactId, String version,
boolean transitively);
+
+ /**
+ * Downloads a single maven artifact (no transitive dependencies)
+ *
+ * @param groupId maven group id
+ * @param artifactId maven artifact id
+ * @param version maven version
+ * @return the artifact, or null if none found
+ */
+ MavenArtifact downloadArtifact(String groupId, String artifactId, String
version);
+
/**
* Checks whether the dependency is already on the classpath
*
diff --git
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
index 1e11eae6ddb..cb1c5261743 100644
---
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
+++
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
@@ -89,6 +89,11 @@ public class MavenDependencyDownloader extends
ServiceSupport implements Depende
@Override
public void downloadDependency(String groupId, String artifactId, String
version) {
+ downloadDependency(groupId, artifactId, version, true);
+ }
+
+ @Override
+ public void downloadDependency(String groupId, String artifactId, String
version, boolean transitively) {
// trigger listener
if (downloadListener != null) {
downloadListener.onDownloadDependency(groupId, artifactId,
version);
@@ -132,7 +137,7 @@ public class MavenDependencyDownloader extends
ServiceSupport implements Depende
}
List<MavenArtifact> artifacts
- =
MavenDependencyResolver.resolveDependenciesViaAether(deps, mavenRepos, false,
fresh, true);
+ =
MavenDependencyResolver.resolveDependenciesViaAether(deps, mavenRepos, false,
fresh, transitively);
LOG.debug("Resolved {} -> [{}]", gav, artifacts);
DependencyDownloaderClassLoader classLoader
@@ -149,6 +154,35 @@ public class MavenDependencyDownloader extends
ServiceSupport implements Depende
}, gav);
}
+ @Override
+ public MavenArtifact downloadArtifact(String groupId, String artifactId,
String version) {
+ String gav = groupId + ":" + artifactId + ":" + version;
+ LOG.debug("DownloadingArtifact: {}", gav);
+ List<String> deps = List.of(gav);
+ List<String> mavenRepos = new ArrayList<>();
+
+ // add maven central first
+ mavenRepos.add(MAVEN_CENTRAL_REPO);
+ // and custom repos
+ if (repos != null) {
+
mavenRepos.addAll(Arrays.stream(repos.split(",")).collect(Collectors.toList()));
+ }
+ // include Apache snapshot to make it easy to use upcoming releases
+ if ("org.apache.camel".equals(groupId) &&
version.contains("SNAPSHOT")) {
+ mavenRepos.add(APACHE_SNAPSHOT_REPO);
+ }
+
+ List<MavenArtifact> artifacts
+ = MavenDependencyResolver.resolveDependenciesViaAether(deps,
mavenRepos, false, fresh, false);
+ LOG.debug("Resolved {} -> [{}]", gav, artifacts);
+
+ if (artifacts.size() == 1) {
+ return artifacts.get(0);
+ }
+
+ return null;
+ }
+
public boolean alreadyOnClasspath(String groupId, String artifactId,
String version) {
return alreadyOnClasspath(groupId, artifactId, version, true);
}