This is an automated email from the ASF dual-hosted git repository.
orpiske 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 9cc2acf2445 CAMEL-18957: minor API cleanups and documentation
9cc2acf2445 is described below
commit 9cc2acf2445e2c746b96347f6b52752b14b003d8
Author: Otavio Rodolfo Piske <[email protected]>
AuthorDate: Thu Jan 26 18:18:33 2023 +0100
CAMEL-18957: minor API cleanups and documentation
---
.../camel/test/infra/core/AnnotationProcessor.java | 65 +++++++
.../infra/core/DefaultAnnotationProcessor.java | 162 ++++++++++++++++
.../infra/core/DefaultCamelContextExtension.java | 214 +--------------------
.../camel/test/infra/core/ExtensionUtils.java | 43 +++++
.../apache/camel/test/infra/core/MockUtils.java | 97 ++++++++++
5 files changed, 376 insertions(+), 205 deletions(-)
diff --git
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/AnnotationProcessor.java
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/AnnotationProcessor.java
new file mode 100644
index 00000000000..a1b9977a78c
--- /dev/null
+++
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/AnnotationProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * 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.test.infra.core;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.camel.CamelContext;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+/**
+ * A pluggable annotation processor
+ */
+public interface AnnotationProcessor {
+
+ /**
+ * Evaluates the given annotation in a test context to determine if it
provides a CamelContext
+ *
+ * @param extensionContext JUnit's extension context
+ * @param annotationClass the annotation class that may indicate that a
method within the test class provides a
+ * custom CamelContext
+ * @param target the target type of the CamelContext (usually
CamelContext.class)
+ * @return the provided CamelContext from the test class
or null if none exists
+ * @param <T> the type of the CamelContexts
+ */
+ <T> T setupContextProvider(
+ ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Class<T> target);
+
+ /**
+ * Evaluates the methods in the test instance, invoking them if the given
annotation is present. This can be used to
+ * invoke methods annotated with the fixture annotations (i.e.,
RouteFixture, etc).
+ *
+ * @param extensionContext JUnit's extension context
+ * @param annotationClass the annotation class that may indicate that a
method should be invoked
+ * @param instance the test instance
+ * @param context the CamelContext that will be passed to th
+ */
+ void evalMethod(ExtensionContext extensionContext, Class<? extends
Annotation> annotationClass, Object instance, CamelContext context);
+
+ /**
+ * Evaluates the fields in the test instance, handling them in accordance
with the given annotation (i.e., binding
+ * to the registry, adding endpoints, etc)
+ *
+ * @param extensionContext JUnit's extension context
+ * @param annotationClass the annotation class that may indicate that a
field needs to be evaluated
+ * @param instance the test instance
+ * @param context
+ */
+ void evalField(
+ ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Object instance, CamelContext context);
+}
diff --git
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultAnnotationProcessor.java
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultAnnotationProcessor.java
new file mode 100644
index 00000000000..91eda89731a
--- /dev/null
+++
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultAnnotationProcessor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.test.infra.core;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static
org.apache.camel.test.infra.core.ExtensionUtils.commonProviderMessage;
+import static
org.apache.camel.test.infra.core.ExtensionUtils.illegalAccessMessage;
+import static
org.apache.camel.test.infra.core.ExtensionUtils.invocationTargetMessage;
+
+/**
+ * The default implementation of the annotation processor
+ */
+public class DefaultAnnotationProcessor implements AnnotationProcessor {
+ private static final Logger LOG =
LoggerFactory.getLogger(DefaultAnnotationProcessor.class);
+
+ private final CamelContextExtension contextExtension;
+
+ public DefaultAnnotationProcessor(CamelContextExtension contextExtension) {
+ this.contextExtension = contextExtension;
+ }
+
+ @Override
+ public <T> T setupContextProvider(
+ ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Class<T> target) {
+ final Class<?> testClass = extensionContext.getTestClass().get();
+
+ final Optional<Method> providerMethodOpt =
Arrays.stream(testClass.getMethods())
+ .filter(m -> m.isAnnotationPresent(annotationClass))
+ .findFirst();
+
+ if (providerMethodOpt.isPresent()) {
+ Method providerMethod = providerMethodOpt.get();
+
+ final Object provided = doInvokeProvider(annotationClass,
providerMethod);
+ if (target.isInstance(provided)) {
+ return target.cast(provided);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void evalMethod(ExtensionContext extensionContext, Class<? extends
Annotation> annotationClass, Object instance, CamelContext context) {
+ final Class<?> testClass = extensionContext.getTestClass().get();
+
+ Arrays.stream(testClass.getMethods()).filter(m ->
m.isAnnotationPresent(annotationClass))
+ .forEach(m -> doInvokeFixture(annotationClass, m, instance,
context));
+ }
+
+ @Override
+ public void evalField(
+ ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Object instance, CamelContext context) {
+ final Class<?> testClass = extensionContext.getTestClass().get();
+
+ var superClass = testClass.getSuperclass();
+ while (superClass != null) {
+ Arrays.stream(superClass.getDeclaredFields()).filter(m ->
m.isAnnotationPresent(annotationClass))
+ .forEach(f ->
doInvokeFixture(f.getAnnotation(annotationClass), f, instance, context));
+
+ superClass = superClass.getSuperclass();
+ }
+
+ Arrays.stream(testClass.getDeclaredFields()).filter(f ->
f.isAnnotationPresent(annotationClass))
+ .forEach(f ->
doInvokeFixture(f.getAnnotation(annotationClass), f, instance, context));
+ }
+
+ private static Object doInvokeProvider(Class<? extends Annotation>
annotationClass, Method method) {
+ var methodName = method.getName();
+ LOG.trace("Checking instance method: {}", methodName);
+ if (method.getReturnType() == null) {
+ throw new RuntimeException(
+ commonProviderMessage(annotationClass,
method.getDeclaringClass()) + " provider does not return any value");
+ }
+
+ try {
+ return method.invoke(null);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(commonProviderMessage(annotationClass,
method.getDeclaringClass()), e);
+ }
+ }
+
+ private void doInvokeFixture(Class<? extends Annotation> annotationClass,
Method method, Object instance, CamelContext context) {
+ var methodName = method.getName();
+ LOG.trace("Checking instance method: {}", methodName);
+ try {
+ method.invoke(instance, context);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(illegalAccessMessage(annotationClass,
instance, methodName), e);
+ } catch (InvocationTargetException e) {
+ throw new
RuntimeException(invocationTargetMessage(annotationClass, instance,
methodName), e);
+ }
+ }
+
+ private void doInvokeFixture(Annotation annotation, Field field, Object
instance, CamelContext context) {
+ var fieldName = field.getName();
+ LOG.trace("Checking instance field: {}", fieldName);
+ try {
+ if (!Modifier.isPublic(field.getModifiers())) {
+ field.setAccessible(true);
+ }
+
+ if (annotation instanceof BindToRegistry r) {
+ String bindValue = r.value();
+
+ context.getRegistry().bind(bindValue, field.get(instance));
+
+ return;
+ }
+
+ if (annotation instanceof EndpointInject e) {
+ String uri = e.value();
+
+ if (field.getType() == MockEndpoint.class) {
+ final MockEndpoint mockEndpoint =
contextExtension.getMockEndpoint(uri);
+
+ assert mockEndpoint != null;
+
+ field.set(instance, mockEndpoint);
+ } else {
+ final Endpoint endpoint = context.getEndpoint(uri);
+
+ assert endpoint != null;
+ field.set(instance, endpoint);
+ }
+ }
+ } catch (IllegalAccessException e) {
+ throw new
RuntimeException(illegalAccessMessage(annotation.getClass(), instance,
fieldName), e);
+ }
+ }
+}
diff --git
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultCamelContextExtension.java
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultCamelContextExtension.java
index dce87ca9339..da84656dc6b 100644
---
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultCamelContextExtension.java
+++
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/DefaultCamelContextExtension.java
@@ -16,37 +16,26 @@
*/
package org.apache.camel.test.infra.core;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Optional;
-
import org.apache.camel.BindToRegistry;
import org.apache.camel.CamelContext;
import org.apache.camel.ConsumerTemplate;
-import org.apache.camel.Endpoint;
import org.apache.camel.EndpointInject;
import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.ProducerTemplate;
-import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.util.URISupport;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
/**
* A simple Camel context extension suitable for most of the simple use cases
in Camel and end-user applications.
*/
public class DefaultCamelContextExtension implements CamelContextExtension {
private static final Logger LOG =
LoggerFactory.getLogger(DefaultCamelContextExtension.class);
private final ContextLifeCycleManager lifeCycleManager;
+ private final AnnotationProcessor fixtureProcessor;
+
private CamelContext context;
private ProducerTemplate producerTemplate;
private ConsumerTemplate consumerTemplate;
@@ -65,36 +54,7 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
*/
public DefaultCamelContextExtension(ContextLifeCycleManager
lifeCycleManager) {
this.lifeCycleManager = lifeCycleManager;
- }
-
- /**
- * Resolves an endpoint and asserts that it is found.
- */
- public static <
- T extends Endpoint> T resolveMandatoryEndpoint(CamelContext
context, String endpointUri, Class<T> endpointType) {
- T endpoint = context.getEndpoint(endpointUri, endpointType);
-
- assertNotNull(endpoint, "No endpoint found for URI: " + endpointUri);
-
- return endpoint;
- }
-
- private static String commonProviderMessage(Class<? extends Annotation>
annotationClass, Class<?> clazz) {
- return "Unable to setup provider " + annotationClass.getSimpleName() +
" on " + clazz;
- }
-
- private static String commonFixtureMessage(Class<? extends Annotation>
annotationClass, Object instance) {
- return "Unable to setup fixture " + annotationClass.getSimpleName() +
" on " + instance.getClass().getName();
- }
-
- private static String invocationTargetMessage(
- Class<? extends Annotation> annotationClass, Object instance,
String methodName) {
- return commonFixtureMessage(annotationClass, instance) + " due to
invocation target exception to method: " + methodName;
- }
-
- private static String illegalAccessMessage(
- Class<? extends Annotation> annotationClass, Object instance,
String methodName) {
- return commonFixtureMessage(annotationClass, instance) + " due to
illegal access to method: " + methodName;
+ this.fixtureProcessor = new DefaultAnnotationProcessor(this);
}
protected CamelContext createCamelContext() {
@@ -108,7 +68,7 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception {
- context = setupContextProvider(extensionContext,
ContextProvider.class, CamelContext.class);
+ context = fixtureProcessor.setupContextProvider(extensionContext,
ContextProvider.class, CamelContext.class);
if (context == null) {
context = createCamelContext();
}
@@ -129,12 +89,12 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
LOG.info("********************************************************************************");
LOG.info("Testing: {} ({})", extensionContext.getDisplayName(),
o.getClass().getName());
- setupFixtureFields(extensionContext, EndpointInject.class, o);
- setupFixtureFields(extensionContext, BindToRegistry.class, o);
+ fixtureProcessor.evalField(extensionContext, EndpointInject.class, o,
context);
+ fixtureProcessor.evalField(extensionContext, BindToRegistry.class, o,
context);
if (!context.isStarted()) {
- setupFixture(extensionContext, ContextFixture.class, o);
- setupFixture(extensionContext, RouteFixture.class, o);
+ fixtureProcessor.evalMethod(extensionContext,
ContextFixture.class, o, context);
+ fixtureProcessor.evalMethod(extensionContext, RouteFixture.class,
o, context);
lifeCycleManager.beforeEach(context);
}
@@ -149,114 +109,6 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
LOG.info("********************************************************************************");
}
- private <T> T setupContextProvider(
- ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Class<T> target) {
- final Class<?> testClass = extensionContext.getTestClass().get();
-
- final Optional<Method> providerMethodOpt =
Arrays.stream(testClass.getMethods())
- .filter(m -> m.isAnnotationPresent(annotationClass))
- .findFirst();
-
- if (providerMethodOpt.isPresent()) {
- Method providerMethod = providerMethodOpt.get();
-
- final Object provided = doInvokeProvider(annotationClass,
providerMethod);
- if (target.isInstance(provided)) {
- return target.cast(provided);
- }
- }
-
- return null;
- }
-
- private void setupFixture(ExtensionContext extensionContext, Class<?
extends Annotation> annotationClass, Object instance) {
- final Class<?> testClass = extensionContext.getTestClass().get();
-
- Arrays.stream(testClass.getMethods()).filter(m ->
m.isAnnotationPresent(annotationClass))
- .forEach(m -> doInvokeFixture(annotationClass, instance, m));
- }
-
- private void setupFixtureFields(
- ExtensionContext extensionContext, Class<? extends Annotation>
annotationClass, Object instance) {
- final Class<?> testClass = extensionContext.getTestClass().get();
-
- var superClass = testClass.getSuperclass();
- while (superClass != null) {
- Arrays.stream(superClass.getDeclaredFields()).filter(m ->
m.isAnnotationPresent(annotationClass))
- .forEach(f ->
doInvokeFixture(f.getAnnotation(annotationClass), instance, f));
-
- superClass = superClass.getSuperclass();
- }
-
- Arrays.stream(testClass.getDeclaredFields()).filter(f ->
f.isAnnotationPresent(annotationClass))
- .forEach(f ->
doInvokeFixture(f.getAnnotation(annotationClass), instance, f));
- }
-
- private static Object doInvokeProvider(Class<? extends Annotation>
annotationClass, Method m) {
- var methodName = m.getName();
- LOG.trace("Checking instance method: {}", methodName);
- if (m.getReturnType() == null) {
- throw new RuntimeException(
- commonProviderMessage(annotationClass,
m.getDeclaringClass())
- + " provider does not return any
value");
- }
-
- try {
- return m.invoke(null);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new RuntimeException(commonProviderMessage(annotationClass,
m.getDeclaringClass()), e);
- }
- }
-
- private void doInvokeFixture(Class<? extends Annotation> annotationClass,
Object instance, Method m) {
- var methodName = m.getName();
- LOG.trace("Checking instance method: {}", methodName);
- try {
- m.invoke(instance, context);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(illegalAccessMessage(annotationClass,
instance, methodName), e);
- } catch (InvocationTargetException e) {
- throw new
RuntimeException(invocationTargetMessage(annotationClass, instance,
methodName), e);
- }
- }
-
- private void doInvokeFixture(Annotation annotation, Object instance, Field
f) {
- var fieldName = f.getName();
- LOG.trace("Checking instance field: {}", fieldName);
- try {
- if (!Modifier.isPublic(f.getModifiers())) {
- f.setAccessible(true);
- }
-
- if (annotation instanceof BindToRegistry r) {
- String bindValue = r.value();
-
- context.getRegistry().bind(bindValue, f.get(instance));
-
- return;
- }
-
- if (annotation instanceof EndpointInject e) {
- String uri = e.value();
-
- if (f.getType() == MockEndpoint.class) {
- final MockEndpoint mockEndpoint = getMockEndpoint(uri);
-
- assert mockEndpoint != null;
-
- f.set(instance, mockEndpoint);
- } else {
- final Endpoint endpoint = context.getEndpoint(uri);
-
- assert endpoint != null;
- f.set(instance, endpoint);
- }
- }
- } catch (IllegalAccessException e) {
- throw new
RuntimeException(illegalAccessMessage(annotation.getClass(), instance,
fieldName), e);
- }
- }
-
@Override
public CamelContext getContext() {
return context;
@@ -272,17 +124,6 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
return consumerTemplate;
}
- /**
- * Resolves a mandatory endpoint for the given URI and expected type or an
exception is thrown
- *
- * @param uri the Camel <a href="">URI</a> to use to create or
resolve an endpoint
- * @param endpointType the endpoint type (i.e., its class) to resolve
- * @return the endpoint
- */
- protected <T extends Endpoint> T resolveMandatoryEndpoint(String uri,
Class<T> endpointType) {
- return resolveMandatoryEndpoint(context, uri, endpointType);
- }
-
@Override
public MockEndpoint getMockEndpoint(String uri) {
MockEndpoint mock = getMockEndpoint(uri, true);
@@ -292,43 +133,6 @@ public class DefaultCamelContextExtension implements
CamelContextExtension {
@Override
public MockEndpoint getMockEndpoint(String uri, boolean create) throws
NoSuchEndpointException {
- // look for existing mock endpoints that have the same queue name, and
- // to
- // do that we need to normalize uri and strip out query parameters and
- // whatnot
- String n;
- try {
- n = URISupport.normalizeUri(uri);
- } catch (Exception e) {
- throw RuntimeCamelException.wrapRuntimeException(e);
- }
- // strip query
- int idx = n.indexOf('?');
- if (idx != -1) {
- n = n.substring(0, idx);
- }
- final String target = n;
-
- // lookup endpoints in registry and try to find it
- MockEndpoint found = (MockEndpoint)
context.getEndpointRegistry().values().stream()
- .filter(e -> e instanceof MockEndpoint).filter(e -> {
- String t = e.getEndpointUri();
- // strip query
- int idx2 = t.indexOf('?');
- if (idx2 != -1) {
- t = t.substring(0, idx2);
- }
- return t.equals(target);
- }).findFirst().orElse(null);
-
- if (found != null) {
- return found;
- }
-
- if (create) {
- return resolveMandatoryEndpoint(uri, MockEndpoint.class);
- } else {
- throw new NoSuchEndpointException(String.format("MockEndpoint %s
does not exist.", uri));
- }
+ return MockUtils.getMockEndpoint(context, uri, create);
}
}
diff --git
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/ExtensionUtils.java
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/ExtensionUtils.java
new file mode 100644
index 00000000000..e3efb87448d
--- /dev/null
+++
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/ExtensionUtils.java
@@ -0,0 +1,43 @@
+/*
+ * 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.test.infra.core;
+
+import java.lang.annotation.Annotation;
+
+final class ExtensionUtils {
+
+ private ExtensionUtils() {
+
+ }
+
+ private static String commonFixtureMessage(Class<? extends Annotation>
annotationClass, Object instance) {
+ return "Unable to setup fixture " + annotationClass.getSimpleName() +
" on " + instance.getClass().getName();
+ }
+
+ static String invocationTargetMessage(Class<? extends Annotation>
annotationClass, Object instance, String methodName) {
+ return commonFixtureMessage(annotationClass, instance) + " due to
invocation target exception to method: " + methodName;
+ }
+
+ static String illegalAccessMessage(Class<? extends Annotation>
annotationClass, Object instance, String methodName) {
+ return commonFixtureMessage(annotationClass, instance) + " due to
illegal access to method: " + methodName;
+ }
+
+ static String commonProviderMessage(Class<? extends Annotation>
annotationClass, Class<?> clazz) {
+ return "Unable to setup provider " + annotationClass.getSimpleName() +
" on " + clazz;
+ }
+}
diff --git
a/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/MockUtils.java
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/MockUtils.java
new file mode 100644
index 00000000000..33581c28a12
--- /dev/null
+++
b/test-infra/camel-test-infra-core/src/test/java/org/apache/camel/test/infra/core/MockUtils.java
@@ -0,0 +1,97 @@
+/*
+ * 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.test.infra.core;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.util.URISupport;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+final class MockUtils {
+ private MockUtils() {
+
+ }
+
+ /**
+ * Resolves an endpoint and asserts that it is found.
+ */
+ public static <
+ T extends Endpoint> T resolveMandatoryEndpoint(CamelContext
context, String endpointUri, Class<T> endpointType) {
+ T endpoint = context.getEndpoint(endpointUri, endpointType);
+
+ assertNotNull(endpoint, "No endpoint found for URI: " + endpointUri);
+
+ return endpoint;
+ }
+
+ /**
+ * Gets a mock endpoint for the given URI
+ *
+ * @param context the {@link CamelContext} to use
+ * @param uri the URI to use to create or resolve an
endpoint
+ * @param create whether to create the endpoint if it
does not
+ *
+ * @return the mock endpoint
+ * @throws NoSuchEndpointException if the endpoint does not exist and
create is false
+ */
+ public static MockEndpoint getMockEndpoint(CamelContext context, String
uri, boolean create)
+ throws NoSuchEndpointException {
+ // look for existing mock endpoints that have the same queue name, and
+ // to
+ // do that we need to normalize uri and strip out query parameters and
+ // whatnot
+ String n;
+ try {
+ n = URISupport.normalizeUri(uri);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeException(e);
+ }
+ // strip query
+ int idx = n.indexOf('?');
+ if (idx != -1) {
+ n = n.substring(0, idx);
+ }
+ final String target = n;
+
+ // lookup endpoints in registry and try to find it
+ MockEndpoint found = (MockEndpoint)
context.getEndpointRegistry().values().stream()
+ .filter(e -> e instanceof MockEndpoint).filter(e -> {
+ String t = e.getEndpointUri();
+ // strip query
+ int idx2 = t.indexOf('?');
+ if (idx2 != -1) {
+ t = t.substring(0, idx2);
+ }
+ return t.equals(target);
+ }).findFirst().orElse(null);
+
+ if (found != null) {
+ return found;
+ }
+
+ if (create) {
+ return resolveMandatoryEndpoint(context, uri, MockEndpoint.class);
+ } else {
+ throw new NoSuchEndpointException(String.format("MockEndpoint %s
does not exist.", uri));
+ }
+ }
+}