CAMEL-9873: Component should provide detail if a consumer/producer is native async supported
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e3f391b2 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e3f391b2 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e3f391b2 Branch: refs/heads/master Commit: e3f391b2727ebdd032b553d499e3b06002b7db95 Parents: 05b97d4 Author: Claus Ibsen <davscl...@apache.org> Authored: Mon Apr 18 09:12:57 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon Apr 18 10:02:26 2016 +0200 ---------------------------------------------------------------------- .../java/org/apache/camel/AsyncEndpoint.java | 24 ++++++++++++++ .../component/directvm/DirectVmEndpoint.java | 3 +- .../component/scheduler/SchedulerEndpoint.java | 3 +- .../camel/component/seda/SedaEndpoint.java | 3 +- .../camel/component/timer/TimerEndpoint.java | 3 +- .../tools/apt/AbstractAnnotationProcessor.java | 34 ++++++++++++++++++++ .../tools/apt/EndpointAnnotationProcessor.java | 9 ++++++ .../camel/tools/apt/model/ComponentModel.java | 9 ++++++ 8 files changed, 84 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/camel-core/src/main/java/org/apache/camel/AsyncEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/AsyncEndpoint.java b/camel-core/src/main/java/org/apache/camel/AsyncEndpoint.java new file mode 100644 index 0000000..811382d --- /dev/null +++ b/camel-core/src/main/java/org/apache/camel/AsyncEndpoint.java @@ -0,0 +1,24 @@ +/** + * 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; + +/** + * Marks the {@link Endpoint} as support asynchronous non-blocking routing in its consumer and producer. + */ +public interface AsyncEndpoint extends Endpoint { + +} http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/camel-core/src/main/java/org/apache/camel/component/directvm/DirectVmEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/directvm/DirectVmEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/directvm/DirectVmEndpoint.java index eeb3bdf..88dcf50 100644 --- a/camel-core/src/main/java/org/apache/camel/component/directvm/DirectVmEndpoint.java +++ b/camel-core/src/main/java/org/apache/camel/component/directvm/DirectVmEndpoint.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.directvm; +import org.apache.camel.AsyncEndpoint; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; @@ -33,7 +34,7 @@ import org.apache.camel.spi.UriPath; * This endpoint can be used to connect existing routes in the same JVM between different CamelContexts. */ @UriEndpoint(scheme = "direct-vm", title = "Direct VM", syntax = "direct-vm:name", consumerClass = DirectConsumer.class, label = "core,endpoint") -public class DirectVmEndpoint extends DefaultEndpoint { +public class DirectVmEndpoint extends DefaultEndpoint implements AsyncEndpoint { @UriPath(description = "Name of direct-vm endpoint") @Metadata(required = "true") private String name; http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/camel-core/src/main/java/org/apache/camel/component/scheduler/SchedulerEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/scheduler/SchedulerEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/scheduler/SchedulerEndpoint.java index 8f03af8..1430030 100644 --- a/camel-core/src/main/java/org/apache/camel/component/scheduler/SchedulerEndpoint.java +++ b/camel-core/src/main/java/org/apache/camel/component/scheduler/SchedulerEndpoint.java @@ -18,6 +18,7 @@ package org.apache.camel.component.scheduler; import java.util.concurrent.ScheduledExecutorService; +import org.apache.camel.AsyncEndpoint; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; @@ -34,7 +35,7 @@ import org.apache.camel.spi.UriPath; * Also this component uses JDK ScheduledExecutorService. Where as the timer uses a JDK Timer. */ @UriEndpoint(scheme = "scheduler", title = "Scheduler", syntax = "scheduler:name", consumerOnly = true, consumerClass = SchedulerConsumer.class, label = "core,scheduling") -public class SchedulerEndpoint extends ScheduledPollEndpoint { +public class SchedulerEndpoint extends ScheduledPollEndpoint implements AsyncEndpoint { @UriPath @Metadata(required = "true") private String name; http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java index 29c26bb..1f3fd3a 100644 --- a/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java +++ b/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java @@ -24,6 +24,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutorService; +import org.apache.camel.AsyncEndpoint; import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Exchange; @@ -52,7 +53,7 @@ import org.slf4j.LoggerFactory; */ @ManagedResource(description = "Managed SedaEndpoint") @UriEndpoint(scheme = "seda", title = "SEDA", syntax = "seda:name", consumerClass = SedaConsumer.class, label = "core,endpoint") -public class SedaEndpoint extends DefaultEndpoint implements BrowsableEndpoint, MultipleConsumersSupport { +public class SedaEndpoint extends DefaultEndpoint implements AsyncEndpoint, BrowsableEndpoint, MultipleConsumersSupport { private static final Logger LOG = LoggerFactory.getLogger(SedaEndpoint.class); private final Set<SedaProducer> producers = new CopyOnWriteArraySet<SedaProducer>(); private final Set<SedaConsumer> consumers = new CopyOnWriteArraySet<SedaConsumer>(); http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java index 9473bc7..e3c705d 100644 --- a/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java +++ b/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java @@ -19,6 +19,7 @@ package org.apache.camel.component.timer; import java.util.Date; import java.util.Timer; +import org.apache.camel.AsyncEndpoint; import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.MultipleConsumersSupport; @@ -40,7 +41,7 @@ import org.apache.camel.spi.UriPath; */ @ManagedResource(description = "Managed TimerEndpoint") @UriEndpoint(scheme = "timer", title = "Timer", syntax = "timer:timerName", consumerOnly = true, consumerClass = TimerConsumer.class, label = "core,scheduling") -public class TimerEndpoint extends DefaultEndpoint implements MultipleConsumersSupport { +public class TimerEndpoint extends DefaultEndpoint implements AsyncEndpoint, MultipleConsumersSupport { @UriPath @Metadata(required = "true") private String timerName; @UriParam(defaultValue = "1000") http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java index 9250196..8bf8334 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/AbstractAnnotationProcessor.java @@ -36,7 +36,9 @@ import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; @@ -280,6 +282,38 @@ public abstract class AbstractAnnotationProcessor extends AbstractProcessor { } } + protected boolean implementsInterface(RoundEnvironment roundEnv, TypeElement classElement, String interfaceClassName) { + while (true) { + // check if the class implements the interface + List<? extends TypeMirror> list = classElement.getInterfaces(); + if (list != null) { + for (TypeMirror type : list) { + if (type.getKind().compareTo(TypeKind.DECLARED) == 0) { + String name = type.toString(); + if (interfaceClassName.equals(name)) { + return true; + } + } + } + } + + // check super classes which may implement the interface + TypeElement baseTypeElement = null; + TypeMirror superclass = classElement.getSuperclass(); + if (superclass != null) { + String superClassName = canonicalClassName(superclass.toString()); + baseTypeElement = findTypeElement(roundEnv, superClassName); + } + if (baseTypeElement != null) { + classElement = baseTypeElement; + } else { + break; + } + } + + return false; + } + /** * Helper method to produce class output text file using the given handler */ http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java index f33dc44..a703a68 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java @@ -153,6 +153,13 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { } writer.println("<b>Description:</b> " + description + "<br/>"); writer.println("<b>Deprecated:</b>" + componentModel.isDeprecated() + "<br/>"); + if (componentModel.isConsumerOnly()) { + writer.println("<b>ConsumerOnly:</b>" + "true" + "<br/>"); + } + if (componentModel.isProducerOnly()) { + writer.println("<b>ProducerOnly:</b>" + "true" + "<br/>"); + } + writer.println("<b>Async:</b>" + componentModel.isAsync() + "<br/>"); writer.println("<b>Maven:</b> " + componentModel.getGroupId() + "/" + componentModel.getArtifactId() + "/" + componentModel.getVersionId() + "<br/>"); writeHtmlDocumentationAndFieldInjections(writer, roundEnv, componentModel, classElement, "", uriEndpoint.excludeProperties()); @@ -223,6 +230,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { buffer.append("\n \"description\": \"").append(componentModel.getDescription()).append("\","); buffer.append("\n \"label\": \"").append(getOrElse(componentModel.getLabel(), "")).append("\","); buffer.append("\n \"deprecated\": \"").append(componentModel.isDeprecated()).append("\","); + buffer.append("\n \"async\": \"").append(componentModel.isAsync()).append("\","); if (componentModel.isConsumerOnly()) { buffer.append("\n \"consumerOnly\": \"").append("true").append("\","); } else if (componentModel.isProducerOnly()) { @@ -457,6 +465,7 @@ public class EndpointAnnotationProcessor extends AbstractAnnotationProcessor { model.setConsumerOnly(uriEndpoint.consumerOnly()); model.setProducerOnly(uriEndpoint.producerOnly()); model.setLenientProperties(uriEndpoint.lenientProperties()); + model.setAsync(implementsInterface(roundEnv, endpointClassElement, "org.apache.camel.AsyncEndpoint")); String data = loadResource("META-INF/services/org/apache/camel/component", scheme); if (data != null) { http://git-wip-us.apache.org/repos/asf/camel/blob/e3f391b2/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java ---------------------------------------------------------------------- diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java index 7efdbb7..9bf8f75 100644 --- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java +++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/model/ComponentModel.java @@ -33,6 +33,7 @@ public final class ComponentModel { private boolean producerOnly; private boolean deprecated; private boolean lenientProperties; + private boolean async; public ComponentModel(String scheme) { this.scheme = scheme; @@ -153,4 +154,12 @@ public final class ComponentModel { public void setLenientProperties(boolean lenientProperties) { this.lenientProperties = lenientProperties; } + + public boolean isAsync() { + return async; + } + + public void setAsync(boolean async) { + this.async = async; + } }