Skip to content

Commit

Permalink
Introduce CamelRoutesBuilderClassBuildItem to query for RoutesBuilder
Browse files Browse the repository at this point in the history
classes just once.
  • Loading branch information
ppalaga committed Nov 12, 2019
1 parent 5971258 commit 53252e8
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 32 deletions.
Expand Up @@ -20,8 +20,11 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
Expand All @@ -42,6 +45,8 @@
import org.apache.camel.CamelContext;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.impl.converter.BaseTypeConverterRegistry;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.quarkus.core.CamelMain;
import org.apache.camel.quarkus.core.CamelMainProducers;
import org.apache.camel.quarkus.core.CamelMainRecorder;
Expand All @@ -55,7 +60,9 @@
import org.apache.camel.spi.Registry;
import org.apache.camel.spi.TypeConverterLoader;
import org.apache.camel.spi.TypeConverterRegistry;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -250,16 +257,39 @@ CamelRuntimeRegistryBuildItem bindRuntimeBeansToRegistry(
* disabled by setting quarkus.camel.disable-main = true
*/
public static class Main {

@BuildStep
public List<CamelRoutesBuilderClassBuildItem> discoverRoutesBuilderClassNames(
CombinedIndexBuildItem combinedIndex) {
final IndexView index = combinedIndex.getIndex();
Set<ClassInfo> allKnownImplementors = new HashSet<>();
allKnownImplementors.addAll(
index.getAllKnownImplementors(DotName.createSimple(RoutesBuilder.class.getName())));
allKnownImplementors.addAll(
index.getAllKnownSubclasses(DotName.createSimple(RouteBuilder.class.getName())));
allKnownImplementors.addAll(
index.getAllKnownSubclasses(DotName.createSimple(AdviceWithRouteBuilder.class.getName())));

return allKnownImplementors
.stream()
// public and non-abstract
.filter(ci -> ((ci.flags() & (Modifier.ABSTRACT | Modifier.PUBLIC)) == Modifier.PUBLIC))
.map(ClassInfo::name)
.map(CamelRoutesBuilderClassBuildItem::new)
.collect(Collectors.toList());
}

@Record(ExecutionTime.STATIC_INIT)
@BuildStep(onlyIf = Flags.MainEnabled.class)
public List<CamelBeanBuildItem> collectRoutes(
CombinedIndexBuildItem combinedIndex,
List<CamelRoutesBuilderClassBuildItem> camelRoutesBuilders,
CamelMainRecorder recorder,
RecorderContext recorderContext) {
return CamelSupport.getRouteBuilderClasses(combinedIndex.getIndex())
.map(className -> {
return camelRoutesBuilders.stream()
.map(CamelRoutesBuilderClassBuildItem::getDotName)
.map(dotName -> {
try {
return Class.forName(className);
return Class.forName(dotName.toString());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Expand Down
@@ -0,0 +1,41 @@
/*
* 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.quarkus.core.deployment;

import io.quarkus.builder.item.MultiBuildItem;
import org.apache.camel.RoutesBuilder;
import org.jboss.jandex.DotName;

/**
* A {@link MultiBuildItem} holding class names of all {@link RoutesBuilder} implementations.
* <p>
* The class names are gathered from Jandex by {@code camel-quarkus-core}. Extensions are free to add
* {@link CamelRoutesBuilderClassBuildItem}s programmatically.
*/
public final class CamelRoutesBuilderClassBuildItem extends MultiBuildItem {

private final DotName dotName;

public CamelRoutesBuilderClassBuildItem(DotName dotName) {
this.dotName = dotName;
}

public DotName getDotName() {
return dotName;
};

}
Expand Up @@ -24,21 +24,14 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Stream;

import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.quarkus.core.CamelServiceInfo;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;

public final class CamelSupport {
public static final String CAMEL_SERVICE_BASE_PATH = "META-INF/services/org/apache/camel";
Expand Down Expand Up @@ -71,22 +64,6 @@ public static Stream<Path> resources(ApplicationArchivesBuildItem archives, Stri
.filter(Files::isRegularFile);
}

public static Stream<String> getRouteBuilderClasses(IndexView view) {
Set<ClassInfo> allKnownImplementors = new HashSet<>();
allKnownImplementors.addAll(
view.getAllKnownImplementors(DotName.createSimple(RoutesBuilder.class.getName())));
allKnownImplementors.addAll(
view.getAllKnownSubclasses(DotName.createSimple(RouteBuilder.class.getName())));
allKnownImplementors.addAll(
view.getAllKnownSubclasses(DotName.createSimple(AdviceWithRouteBuilder.class.getName())));

return allKnownImplementors
.stream()
.filter(CamelSupport::isConcrete)
.filter(CamelSupport::isPublic)
.map(ClassInfo::toString);
}

public static Stream<CamelServiceInfo> services(ApplicationArchivesBuildItem applicationArchivesBuildItem) {
return CamelSupport.resources(applicationArchivesBuildItem, CamelSupport.CAMEL_SERVICE_BASE_PATH)
.map(CamelSupport::services)
Expand Down
Expand Up @@ -17,6 +17,7 @@
package org.apache.camel.quarkus.core.deployment;

import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
Expand Down Expand Up @@ -176,17 +177,15 @@ protected void addReflectiveMethod(MethodInfo mi) {
public static class Main {
@BuildStep(onlyIf = Flags.MainEnabled.class)
void process(
CombinedIndexBuildItem combinedIndex,
List<CamelRoutesBuilderClassBuildItem> camelRoutesBuilders,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {

IndexView view = combinedIndex.getIndex();

//
// Register routes as reflection aware as camel-main main use reflection
// to bind beans to the registry
//
CamelSupport.getRouteBuilderClasses(view).forEach(name -> {
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, name));
camelRoutesBuilders.forEach(dotName -> {
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, dotName.toString()));
});

reflectiveClass.produce(new ReflectiveClassBuildItem(
Expand Down

0 comments on commit 53252e8

Please sign in to comment.