Search in sources :

Example 1 with QuarkusClassLoader

use of io.quarkus.bootstrap.classloading.QuarkusClassLoader in project camel-quarkus by apache.

the class CSimpleProcessor method collectCSimpleExpressions.

@BuildStep
void collectCSimpleExpressions(CamelConfig config, List<CamelRoutesBuilderClassBuildItem> routesBuilderClasses, BuildProducer<CSimpleExpressionSourceBuildItem> csimpleExpressions) throws ClassNotFoundException {
    if (!routesBuilderClasses.isEmpty()) {
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (!(loader instanceof QuarkusClassLoader)) {
            throw new IllegalStateException(QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
        }
        final ExpressionCollector collector = new ExpressionCollector(loader);
        final CamelContext ctx = new DefaultCamelContext();
        for (CamelRoutesBuilderClassBuildItem routesBuilderClass : routesBuilderClasses) {
            final String className = routesBuilderClass.getDotName().toString();
            final Class<?> cl = loader.loadClass(className);
            if (!RouteBuilder.class.isAssignableFrom(cl)) {
                LOG.warnf("CSimple language expressions occurring in %s won't be compiled at build time", cl);
            } else {
                try {
                    final RouteBuilder rb = (RouteBuilder) cl.getDeclaredConstructor().newInstance();
                    rb.setCamelContext(ctx);
                    try {
                        rb.configure();
                        collector.collect("csimple", (script, isPredicate) -> csimpleExpressions.produce(new CSimpleExpressionSourceBuildItem(script, isPredicate, className)), rb.getRouteCollection(), rb.getRestCollection());
                    } catch (Exception e) {
                        switch(config.csimple.onBuildTimeAnalysisFailure) {
                            case fail:
                                throw new RuntimeException("Could not extract CSimple expressions from " + className + ". You may want to set quarkus.camel.csimple.on-build-time-analysis-failure to warn or ignore if you do not use CSimple language in your routes", e);
                            case warn:
                                LOG.warnf(e, "Could not extract CSimple language expressions from the route definition %s in class %s.", rb, cl);
                                break;
                            case ignore:
                                LOG.debugf(e, "Could not extract CSimple language expressions from the route definition %s in class %s", rb, cl);
                                break;
                            default:
                                throw new IllegalStateException("Unexpected " + FailureRemedy.class.getSimpleName() + ": " + config.csimple.onBuildTimeAnalysisFailure);
                        }
                    }
                } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException("Could not instantiate " + className, e);
                }
            }
        }
    }
}
Also used : DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) CamelContext(org.apache.camel.CamelContext) CamelRoutesBuilderClassBuildItem(org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem) RouteBuilder(org.apache.camel.builder.RouteBuilder) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) JAXBException(javax.xml.bind.JAXBException) InvocationTargetException(java.lang.reflect.InvocationTargetException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) FailureRemedy(org.apache.camel.quarkus.core.CamelConfig.FailureRemedy) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 2 with QuarkusClassLoader

use of io.quarkus.bootstrap.classloading.QuarkusClassLoader in project camel-quarkus by apache.

the class CamelRestOASFilter method exposeOpenAPI.

@BuildStep(onlyIf = ExposeOpenApiEnabled.class)
void exposeOpenAPI(List<CamelRoutesBuilderClassBuildItem> routesBuilderClasses, BuildProducer<AddToOpenAPIDefinitionBuildItem> openAPI, Capabilities capabilities) throws Exception {
    if (capabilities.isPresent(Capability.SMALLRYE_OPENAPI)) {
        RoutesConfigurer configurer = new RoutesConfigurer();
        List<RoutesBuilder> routes = new ArrayList<>();
        configurer.setRoutesBuilders(routes);
        configurer.setRoutesCollector(new DefaultRoutesCollector());
        configurer.setRoutesIncludePattern(CamelSupport.getOptionalConfigValue("camel.main.routes-include-pattern", String.class, null));
        configurer.setRoutesExcludePattern(CamelSupport.getOptionalConfigValue("camel.main.routes-exclude-pattern", String.class, null));
        final CamelContext ctx = new DefaultCamelContext();
        if (!routesBuilderClasses.isEmpty()) {
            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
            if (!(loader instanceof QuarkusClassLoader)) {
                throw new IllegalStateException(QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
            }
            for (CamelRoutesBuilderClassBuildItem routesBuilderClass : routesBuilderClasses) {
                final String className = routesBuilderClass.getDotName().toString();
                final Class<?> cl = loader.loadClass(className);
                if (RouteBuilder.class.isAssignableFrom(cl)) {
                    try {
                        final RouteBuilder rb = (RouteBuilder) cl.getDeclaredConstructor().newInstance();
                        routes.add(rb);
                    } catch (InstantiationException | IllegalAccessException e) {
                        throw new RuntimeException("Could not instantiate " + className, e);
                    }
                }
            }
        }
        try {
            configurer.configureRoutes(ctx);
        } catch (Exception e) {
            // ignore
            LOGGER.warn("config routes failed with " + e);
        }
        openAPI.produce(new AddToOpenAPIDefinitionBuildItem(new CamelRestOASFilter(ctx)));
    }
}
Also used : DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) CamelContext(org.apache.camel.CamelContext) CamelRoutesBuilderClassBuildItem(org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem) AddToOpenAPIDefinitionBuildItem(io.quarkus.smallrye.openapi.deployment.spi.AddToOpenAPIDefinitionBuildItem) RouteBuilder(org.apache.camel.builder.RouteBuilder) ArrayList(java.util.ArrayList) RoutesConfigurer(org.apache.camel.main.RoutesConfigurer) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) DefaultRoutesCollector(org.apache.camel.main.DefaultRoutesCollector) RoutesBuilder(org.apache.camel.RoutesBuilder) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 3 with QuarkusClassLoader

use of io.quarkus.bootstrap.classloading.QuarkusClassLoader in project camel-quarkus by apache.

the class CSimpleProcessor method compileCSimpleExpressions.

@BuildStep
void compileCSimpleExpressions(List<CSimpleExpressionSourceBuildItem> expressionSources, BuildProducer<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpression, BuildProducer<GeneratedClassBuildItem> generatedClasses) throws IOException {
    if (!expressionSources.isEmpty()) {
        final Set<String> imports = new TreeSet<>();
        final Map<String, String> aliases = new LinkedHashMap<>();
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (!(loader instanceof QuarkusClassLoader)) {
            throw new IllegalStateException(QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
        }
        final QuarkusClassLoader quarkusClassLoader = (QuarkusClassLoader) loader;
        readConfig(imports, aliases, loader);
        final CSimpleCodeGenerator generator = new CSimpleCodeGenerator();
        generator.setAliases(aliases);
        generator.setImports(imports);
        final Path projectDir = Paths.get(".").toAbsolutePath().normalize();
        final Path csimpleGeneratedSourceDir = projectDir.resolve("target/generated/csimple");
        Files.createDirectories(csimpleGeneratedSourceDir);
        final Set<File> filesToCompile = new LinkedHashSet<>();
        /* We do not want to compile the same source twice, so we store here what we have compiled already */
        final Map<Boolean, Set<String>> compiledExpressions = new HashMap<>();
        compiledExpressions.put(true, new HashSet<>());
        compiledExpressions.put(false, new HashSet<>());
        /* Generate Java classes for the language expressions */
        for (CSimpleExpressionSourceBuildItem expr : expressionSources) {
            final boolean predicate = expr.isPredicate();
            final String script = expr.getSourceCode();
            if (!compiledExpressions.get(predicate).contains(script)) {
                final CSimpleGeneratedCode code = predicate ? generator.generatePredicate(expr.getClassNameBase(), script) : generator.generateExpression(expr.getClassNameBase(), script);
                compiledCSimpleExpression.produce(new CompiledCSimpleExpressionBuildItem(code.getCode(), predicate, code.getFqn()));
                final Path javaCsimpleFile = csimpleGeneratedSourceDir.resolve(code.getFqn().replace('.', '/') + ".java");
                Files.createDirectories(javaCsimpleFile.getParent());
                Files.write(javaCsimpleFile, code.getCode().getBytes(StandardCharsets.UTF_8));
                filesToCompile.add(javaCsimpleFile.toFile());
                compiledExpressions.get(predicate).add(script);
            }
        }
        final Path csimpleClassesDir = projectDir.resolve("target/csimple-classes");
        Files.createDirectories(csimpleClassesDir);
        /* Compile the generated sources */
        try (JavaCompilationProvider compiler = new JavaCompilationProvider()) {
            final Context context = compilationContext(projectDir, csimpleClassesDir, quarkusClassLoader);
            compiler.compile(filesToCompile, context);
        }
        /* Register the compiled classes via Quarkus GeneratedClassBuildItem */
        try (Stream<Path> classFiles = Files.walk(csimpleClassesDir)) {
            classFiles.filter(Files::isRegularFile).filter(p -> p.getFileName().toString().endsWith(CLASS_EXT)).forEach(p -> {
                final Path relPath = csimpleClassesDir.relativize(p);
                String className = FileUtils.nixifyPath(relPath.toString());
                className = className.substring(0, className.length() - CLASS_EXT.length());
                try {
                    final GeneratedClassBuildItem item = new GeneratedClassBuildItem(true, className, Files.readAllBytes(p));
                    generatedClasses.produce(item);
                } catch (IOException e) {
                    throw new RuntimeException("Could not read " + p);
                }
            });
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExpressionNode(org.apache.camel.model.ExpressionNode) CamelContextBuildItem(org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem) Enumeration(java.util.Enumeration) URL(java.net.URL) Listener(javax.xml.bind.Marshaller.Listener) LanguageExpressionContentHandler(org.apache.camel.quarkus.core.deployment.LanguageExpressionContentHandler) RecorderContext(io.quarkus.deployment.recording.RecorderContext) Constants(org.apache.camel.model.Constants) FailureRemedy(org.apache.camel.quarkus.core.CamelConfig.FailureRemedy) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) FeatureBuildItem(io.quarkus.deployment.builditem.FeatureBuildItem) Map(java.util.Map) Context(io.quarkus.deployment.dev.CompilationProvider.Context) CSimpleLanguageRecorder(org.apache.camel.quarkus.component.csimple.CSimpleLanguageRecorder) NamedNode(org.apache.camel.NamedNode) Path(java.nio.file.Path) DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) Consume(io.quarkus.deployment.annotations.Consume) ExecutionTime(io.quarkus.deployment.annotations.ExecutionTime) Set(java.util.Set) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) Collectors(java.util.stream.Collectors) JAXBException(javax.xml.bind.JAXBException) StandardCharsets(java.nio.charset.StandardCharsets) InvocationTargetException(java.lang.reflect.InvocationTargetException) List(java.util.List) Stream(java.util.stream.Stream) RouteBuilder(org.apache.camel.builder.RouteBuilder) CSimpleCodeGenerator(org.apache.camel.language.csimple.CSimpleCodeGenerator) Builder(org.apache.camel.language.csimple.CSimpleLanguage.Builder) CompilationProvider(io.quarkus.deployment.dev.CompilationProvider) CamelRoutesBuilderClassBuildItem(org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem) CompiledCSimpleExpressionBuildItem(org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem) Record(io.quarkus.deployment.annotations.Record) Marshaller(javax.xml.bind.Marshaller) Logger(org.jboss.logging.Logger) HashMap(java.util.HashMap) Exchange(org.apache.camel.Exchange) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) BuildStep(io.quarkus.deployment.annotations.BuildStep) JavaCompilationProvider(io.quarkus.deployment.dev.JavaCompilationProvider) RuntimeValue(io.quarkus.runtime.RuntimeValue) BiConsumer(java.util.function.BiConsumer) LinkedHashSet(java.util.LinkedHashSet) JAXBContext(javax.xml.bind.JAXBContext) CSimpleHelper(org.apache.camel.language.csimple.CSimpleHelper) CamelContext(org.apache.camel.CamelContext) CSimpleLanguage(org.apache.camel.language.csimple.CSimpleLanguage) ClassPathElement(io.quarkus.bootstrap.classloading.ClassPathElement) FileUtils(org.apache.camel.quarkus.core.util.FileUtils) Files(java.nio.file.Files) CamelBeanBuildItem(org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem) PropertiesHelper(org.apache.camel.util.PropertiesHelper) IOException(java.io.IOException) InputStreamReader(java.io.InputStreamReader) File(java.io.File) CamelConfig(org.apache.camel.quarkus.core.CamelConfig) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) Paths(java.nio.file.Paths) CSimpleGeneratedCode(org.apache.camel.language.csimple.CSimpleGeneratedCode) BufferedReader(java.io.BufferedReader) Collections(java.util.Collections) CSimpleCodeGenerator(org.apache.camel.language.csimple.CSimpleCodeGenerator) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LinkedHashMap(java.util.LinkedHashMap) TreeSet(java.util.TreeSet) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) Files(java.nio.file.Files) Path(java.nio.file.Path) JavaCompilationProvider(io.quarkus.deployment.dev.JavaCompilationProvider) RecorderContext(io.quarkus.deployment.recording.RecorderContext) Context(io.quarkus.deployment.dev.CompilationProvider.Context) DefaultCamelContext(org.apache.camel.impl.DefaultCamelContext) JAXBContext(javax.xml.bind.JAXBContext) CamelContext(org.apache.camel.CamelContext) IOException(java.io.IOException) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) CSimpleGeneratedCode(org.apache.camel.language.csimple.CSimpleGeneratedCode) File(java.io.File) CompiledCSimpleExpressionBuildItem(org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Aggregations

QuarkusClassLoader (io.quarkus.bootstrap.classloading.QuarkusClassLoader)3 BuildStep (io.quarkus.deployment.annotations.BuildStep)3 CamelContext (org.apache.camel.CamelContext)3 RouteBuilder (org.apache.camel.builder.RouteBuilder)3 DefaultCamelContext (org.apache.camel.impl.DefaultCamelContext)3 CamelRoutesBuilderClassBuildItem (org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem)3 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ClassPathElement (io.quarkus.bootstrap.classloading.ClassPathElement)1 BuildProducer (io.quarkus.deployment.annotations.BuildProducer)1 Consume (io.quarkus.deployment.annotations.Consume)1 ExecutionTime (io.quarkus.deployment.annotations.ExecutionTime)1 Record (io.quarkus.deployment.annotations.Record)1 FeatureBuildItem (io.quarkus.deployment.builditem.FeatureBuildItem)1 GeneratedClassBuildItem (io.quarkus.deployment.builditem.GeneratedClassBuildItem)1 CompilationProvider (io.quarkus.deployment.dev.CompilationProvider)1 Context (io.quarkus.deployment.dev.CompilationProvider.Context)1 JavaCompilationProvider (io.quarkus.deployment.dev.JavaCompilationProvider)1 RecorderContext (io.quarkus.deployment.recording.RecorderContext)1 RuntimeValue (io.quarkus.runtime.RuntimeValue)1