You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2021/04/27 13:22:10 UTC

[camel-quarkus] 04/05: Make AtlasMap work on Quarkus 2.0.0

This is an automated email from the ASF dual-hosted git repository.

ppalaga pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git

commit 1782e9c58989dab30a3c16c9890b0246c397bc84
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Tue Apr 27 00:05:57 2021 +0200

    Make AtlasMap work on Quarkus 2.0.0
---
 .../atlasmap/deployment/AtlasmapProcessor.java     | 20 +++++
 .../component/atlasmap/AtlasmapRecorder.java       | 90 ++++++++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/extensions/atlasmap/deployment/src/main/java/org/apache/camel/quarkus/component/atlasmap/deployment/AtlasmapProcessor.java b/extensions/atlasmap/deployment/src/main/java/org/apache/camel/quarkus/component/atlasmap/deployment/AtlasmapProcessor.java
index 4eee6bf..0e35d58 100644
--- a/extensions/atlasmap/deployment/src/main/java/org/apache/camel/quarkus/component/atlasmap/deployment/AtlasmapProcessor.java
+++ b/extensions/atlasmap/deployment/src/main/java/org/apache/camel/quarkus/component/atlasmap/deployment/AtlasmapProcessor.java
@@ -180,11 +180,20 @@ import io.atlasmap.xml.v2.XmlNamespace;
 import io.atlasmap.xml.v2.XmlNamespaces;
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
+import io.quarkus.deployment.recording.RecorderContext;
 import io.quarkus.deployment.util.ServiceUtil;
+import io.quarkus.runtime.RuntimeValue;
+import org.apache.camel.component.atlasmap.AtlasMapComponent;
+import org.apache.camel.quarkus.component.atlasmap.AtlasmapRecorder;
+import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem;
 
 class AtlasmapProcessor {
 
@@ -382,4 +391,15 @@ class AtlasmapProcessor {
                 });
     }
 
+    @Record(ExecutionTime.STATIC_INIT)
+    @BuildStep
+    CamelBeanBuildItem configureComponent(
+            RecorderContext recorderContext,
+            AtlasmapRecorder recorder,
+            CamelContextBuildItem camelContext,
+            List<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpressions) {
+
+        final RuntimeValue<?> atlasmapComponent = recorder.createAtlasmapComponent();
+        return new CamelBeanBuildItem("atlasmap", AtlasMapComponent.class.getName(), atlasmapComponent);
+    }
 }
diff --git a/extensions/atlasmap/runtime/src/main/java/org/apache/camel/quarkus/component/atlasmap/AtlasmapRecorder.java b/extensions/atlasmap/runtime/src/main/java/org/apache/camel/quarkus/component/atlasmap/AtlasmapRecorder.java
new file mode 100644
index 0000000..146484c
--- /dev/null
+++ b/extensions/atlasmap/runtime/src/main/java/org/apache/camel/quarkus/component/atlasmap/AtlasmapRecorder.java
@@ -0,0 +1,90 @@
+package org.apache.camel.quarkus.component.atlasmap;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import io.atlasmap.core.DefaultAtlasContextFactory;
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.component.atlasmap.AtlasMapComponent;
+import org.jboss.logging.Logger;
+
+@Recorder
+public class AtlasmapRecorder {
+
+    public RuntimeValue<AtlasMapComponent> createAtlasmapComponent() {
+        /*
+         * TODO simplify once https://github.com/atlasmap/atlasmap/issues/2704 is solved
+         * Currently there is no way to directly create a DefaultAtlasContextFactory with a custom compound class loader
+         */
+        final DefaultAtlasContextFactory cf = DefaultAtlasContextFactory.getInstance();
+        cf.destroy();
+        final CamelQuarkusCompoundClassLoader compoundClassLoader = new CamelQuarkusCompoundClassLoader();
+        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        compoundClassLoader.addAlternativeLoader(tccl);
+        cf.init(compoundClassLoader);
+
+        final AtlasMapComponent component = new AtlasMapComponent();
+        component.setAtlasContextFactory(cf);
+        return new RuntimeValue<AtlasMapComponent>(component);
+    }
+
+    /**
+     * TODO: remove once https://github.com/atlasmap/atlasmap/pull/2703 is fixed in an AtlasMap version we use
+     */
+    static class CamelQuarkusCompoundClassLoader extends io.atlasmap.core.CompoundClassLoader {
+        private static final Logger LOG = Logger.getLogger(CamelQuarkusCompoundClassLoader.class);
+
+        private Set<ClassLoader> delegates = new LinkedHashSet<>();
+
+        @Override
+        public Class<?> loadClass(String name) throws ClassNotFoundException {
+            for (ClassLoader cl : delegates) {
+                try {
+                    return cl.loadClass(name);
+                } catch (Throwable t) {
+                    LOG.debugf(t, "Class '%s' was not found with ClassLoader '%s'", name, cl);
+                }
+            }
+            throw new ClassNotFoundException(name);
+        }
+
+        @Override
+        public URL getResource(String name) {
+            for (ClassLoader cl : delegates) {
+                URL url = cl.getResource(name);
+                if (url != null) {
+                    return url;
+                }
+                LOG.debugf("Resource '%s' was not found with ClassLoader '%s'", name, cl);
+            }
+            return null;
+        }
+
+        @Override
+        public Enumeration<URL> getResources(String name) {
+            List<URL> answer = new LinkedList<>();
+            for (ClassLoader cl : delegates) {
+                try {
+                    Enumeration<URL> urls = cl.getResources(name);
+                    while (urls != null && urls.hasMoreElements()) {
+                        answer.add(urls.nextElement());
+                    }
+                } catch (Exception e) {
+                    LOG.debugf(e, "I/O error while looking for a resource '%s' with ClassLoader '%s'", name, cl);
+                }
+            }
+            return Collections.enumeration(answer);
+        }
+
+        @Override
+        public synchronized void addAlternativeLoader(ClassLoader cl) {
+            delegates.add(cl);
+        }
+    }
+}