You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2014/09/01 20:13:11 UTC
git commit: CAMEL-7452: Made bean component cache by default,
and fixed setting cache=false will create a new instance of the bean
on-demand. As before we really always created a singleton bean instance.
Repository: camel
Updated Branches:
refs/heads/master 43e66e47d -> d2defc15e
CAMEL-7452: Made bean component cache by default, and fixed setting cache=false will create a new instance of the bean on-demand. As before we really always created a singleton bean instance.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d2defc15
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d2defc15
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d2defc15
Branch: refs/heads/master
Commit: d2defc15e84f34b148bd88cfcb9f1400feb82228
Parents: 43e66e4
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Sep 1 16:56:24 2014 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Sep 1 20:12:49 2014 +0200
----------------------------------------------------------------------
.../camel/component/bean/BeanProcessor.java | 3 +-
.../bean/ConstantStaticTypeBeanHolder.java | 47 +++++++++++++
.../component/bean/ConstantTypeBeanHolder.java | 17 ++++-
.../camel/component/bean/RegistryBean.java | 48 +++++---------
.../org/apache/camel/model/BeanDefinition.java | 55 +++++++++++-----
.../apache/camel/model/ProcessorDefinition.java | 22 +++++++
.../camel/component/bean/BeanNoCacheTest.java | 69 ++++++++++++++++++++
.../component/bean/BeanRefNoCacheTest.java | 69 ++++++++++++++++++++
.../camel/component/bean/NewInstanceTest.java | 2 +-
.../component/bean/PredicateAsBeanTest.java | 3 -
10 files changed, 284 insertions(+), 51 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
index dc91566..80dd138 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
@@ -90,7 +90,8 @@ public class BeanProcessor extends ServiceSupport implements AsyncProcessor {
// do we have a custom adapter for this POJO to a Processor
// but only do this if allowed
if (allowProcessor(explicitMethodName, beanInfo)) {
- Processor processor = getProcessor();
+ // see if there is a processor for the given bean
+ Processor processor = exchange.getContext().getTypeConverter().convertTo(Processor.class, exchange, bean);
if (processor != null) {
LOG.trace("Using a custom adapter as bean invocation: {}", processor);
try {
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/component/bean/ConstantStaticTypeBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantStaticTypeBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantStaticTypeBeanHolder.java
new file mode 100644
index 0000000..f052a54
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantStaticTypeBeanHolder.java
@@ -0,0 +1,47 @@
+/**
+ * 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.component.bean;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A constant (singleton) bean implementation of {@link BeanTypeHolder}
+ *
+ * @version
+ */
+public class ConstantStaticTypeBeanHolder extends ConstantTypeBeanHolder {
+
+ public ConstantStaticTypeBeanHolder(Class<?> type, BeanInfo beanInfo) {
+ super(type, beanInfo);
+ }
+
+ public ConstantStaticTypeBeanHolder(Class<?> type, CamelContext context) {
+ super(type, context);
+ }
+
+ public ConstantStaticTypeBeanHolder(Class<?> type, CamelContext context, ParameterMappingStrategy parameterMappingStrategy) {
+ super(type, context, parameterMappingStrategy);
+ }
+
+ @Override
+ public Object getBean() {
+ // we cannot create a bean as there is no default constructor
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
index 515272b..800b88c 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
@@ -45,13 +45,28 @@ public class ConstantTypeBeanHolder implements BeanTypeHolder {
this(type, new BeanInfo(context, type, parameterMappingStrategy));
}
+ /**
+ * Creates a cached and constant {@link org.apache.camel.component.bean.BeanHolder} from this holder.
+ *
+ * @return a new {@link org.apache.camel.component.bean.BeanHolder} that has cached the lookup of the bean.
+ */
+ public ConstantBeanHolder createCacheHolder() throws Exception {
+ Object bean = getBean();
+ return new ConstantBeanHolder(bean, beanInfo);
+ }
+
@Override
public String toString() {
return type.toString();
}
public Object getBean() {
- return null;
+ // create a new bean
+ if (ObjectHelper.hasDefaultPublicNoArgConstructor(type)) {
+ return getBeanInfo().getCamelContext().getInjector().newInstance(type);
+ } else {
+ return null;
+ }
}
public Processor getProcessor() {
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
index 0c6e774..72d1c2a 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
@@ -28,13 +28,11 @@ import org.apache.camel.util.CamelContextHelper;
* @version
*/
public class RegistryBean implements BeanHolder {
- private final Object lock = new Object();
private final CamelContext context;
private final String name;
private final Registry registry;
- private volatile Processor processor;
private volatile BeanInfo beanInfo;
- private volatile Object bean;
+ private volatile Class<?> clazz;
private ParameterMappingStrategy parameterMappingStrategy;
public RegistryBean(CamelContext context, String name) {
@@ -54,6 +52,11 @@ public class RegistryBean implements BeanHolder {
return "bean: " + name;
}
+ /**
+ * Creates a cached and constant {@link org.apache.camel.component.bean.BeanHolder} from this holder.
+ *
+ * @return a new {@link org.apache.camel.component.bean.BeanHolder} that has cached the lookup of the bean.
+ */
public ConstantBeanHolder createCacheHolder() throws Exception {
Object bean = getBean();
BeanInfo info = createBeanInfo(bean);
@@ -70,52 +73,37 @@ public class RegistryBean implements BeanHolder {
// bean is a class so create an instance of it
value = context.getInjector().newInstance((Class<?>)value);
}
- bean = value;
return value;
}
// okay bean is not in registry, so try to resolve if its a class name and create a shared instance
- synchronized (lock) {
- if (bean != null) {
- return bean;
- }
+ if (clazz == null) {
+ clazz = context.getClassResolver().resolveClass(name);
+ }
- // maybe its a class
- bean = context.getClassResolver().resolveClass(name);
- if (bean == null) {
- // no its not a class then we cannot find the bean
- throw new NoSuchBeanException(name);
- }
- // could be a class then create an instance of it
- if (bean instanceof Class) {
- // bean is a class so create an instance of it
- bean = context.getInjector().newInstance((Class<?>)bean);
- }
+ if (clazz == null) {
+ // no its not a class then we cannot find the bean
+ throw new NoSuchBeanException(name);
}
- return bean;
+ // bean is a class so create an instance of it
+ return context.getInjector().newInstance(clazz);
}
public Processor getProcessor() {
- if (processor == null && bean != null) {
- processor = CamelContextHelper.convertTo(context, Processor.class, bean);
- }
- return processor;
+ return null;
}
public BeanInfo getBeanInfo() {
- if (beanInfo == null && bean != null) {
+ if (beanInfo == null) {
+ Object bean = getBean();
this.beanInfo = createBeanInfo(bean);
}
return beanInfo;
}
public BeanInfo getBeanInfo(Object bean) {
- if (this.bean == bean) {
- return getBeanInfo();
- } else {
- return createBeanInfo(bean);
- }
+ return createBeanInfo(bean);
}
public String getName() {
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
index 182f661..a8789bf 100644
--- a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
@@ -27,6 +27,7 @@ import org.apache.camel.component.bean.BeanHolder;
import org.apache.camel.component.bean.BeanInfo;
import org.apache.camel.component.bean.BeanProcessor;
import org.apache.camel.component.bean.ConstantBeanHolder;
+import org.apache.camel.component.bean.ConstantStaticTypeBeanHolder;
import org.apache.camel.component.bean.ConstantTypeBeanHolder;
import org.apache.camel.component.bean.MethodNotFoundException;
import org.apache.camel.component.bean.RegistryBean;
@@ -222,14 +223,16 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
BeanHolder beanHolder;
if (ObjectHelper.isNotEmpty(ref)) {
- if (cache != null && cache) {
+ // lets cache by default
+ if (isCacheBean()) {
// cache the registry lookup which avoids repeat lookup in the registry
beanHolder = new RegistryBean(routeContext.getCamelContext(), ref).createCacheHolder();
+ // bean holder will check if the bean exists
+ bean = beanHolder.getBean();
} else {
+ // we do not cache so we invoke on-demand
beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
}
- // bean holder will check if the bean exists
- bean = beanHolder.getBean();
answer = new BeanProcessor(beanHolder);
} else {
if (bean == null) {
@@ -250,7 +253,7 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
}
// create a bean if there is a default public no-arg constructor
- if (ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
+ if (isCacheBean() && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
bean = CamelContextHelper.newInstance(routeContext.getCamelContext(), clazz);
ObjectHelper.notNull(bean, "bean", this);
}
@@ -264,7 +267,21 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
}
// the holder should either be bean or type based
- beanHolder = bean != null ? new ConstantBeanHolder(bean, routeContext.getCamelContext()) : new ConstantTypeBeanHolder(clazz, routeContext.getCamelContext());
+ if (bean != null) {
+ beanHolder = new ConstantBeanHolder(bean, routeContext.getCamelContext());
+ } else {
+ if (isCacheBean() && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
+ // we can only cache if we can create an instance of the bean, and for that we need a public constructor
+ beanHolder = new ConstantTypeBeanHolder(clazz, routeContext.getCamelContext()).createCacheHolder();
+ } else {
+ if (ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
+ beanHolder = new ConstantTypeBeanHolder(clazz, routeContext.getCamelContext());
+ } else {
+ // this is only for invoking static methods on the bean
+ beanHolder = new ConstantStaticTypeBeanHolder(clazz, routeContext.getCamelContext());
+ }
+ }
+ }
answer = new BeanProcessor(beanHolder);
}
@@ -278,16 +295,20 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
answer.setMethod(method);
// check there is a method with the given name, and leverage BeanInfo for that
- BeanInfo beanInfo = beanHolder.getBeanInfo();
- if (bean != null) {
- // there is a bean instance, so check for any methods
- if (!beanInfo.hasMethod(method)) {
- throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
- }
- } else if (clazz != null) {
- // there is no bean instance, so check for static methods only
- if (!beanInfo.hasStaticMethod(method)) {
- throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, clazz, method, true));
+ // which we only do if we are caching the bean as otherwise we will create a bean instance for this check
+ // which we only want to do if we cache the bean
+ if (isCacheBean()) {
+ BeanInfo beanInfo = beanHolder.getBeanInfo();
+ if (bean != null) {
+ // there is a bean instance, so check for any methods
+ if (!beanInfo.hasMethod(method)) {
+ throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
+ }
+ } else if (clazz != null) {
+ // there is no bean instance, so check for static methods only
+ if (!beanInfo.hasStaticMethod(method)) {
+ throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, clazz, method, true));
+ }
}
}
}
@@ -295,4 +316,8 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
return answer;
}
+ private boolean isCacheBean() {
+ return cache == null || cache;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index af44b18..534e976 100644
--- a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -2534,6 +2534,28 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
* <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
* Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
*
+ * @param beanType the bean class, Camel will instantiate an object at runtime
+ * @param method the method name to invoke on the bean (can be used to avoid ambiguity)
+ * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds
+ * the multi parameter
+ * @param cache if enabled, Camel will cache the result of the first Registry look-up.
+ * Cache can be enabled if the bean in the Registry is defined as a singleton scope.
+ * @return the builder
+ */
+ public Type bean(Class<?> beanType, String method, boolean multiParameterArray, boolean cache) {
+ BeanDefinition answer = new BeanDefinition();
+ answer.setBeanType(beanType);
+ answer.setMethod(method);
+ answer.setMultiParameterArray(multiParameterArray);
+ answer.setCache(cache);
+ addOutput(answer);
+ return (Type) this;
+ }
+
+ /**
+ * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
+ * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
+ *
* @param ref reference to a bean to lookup in the registry
* @return the builder
*/
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoCacheTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoCacheTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoCacheTest.java
new file mode 100644
index 0000000..11a3f0d
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/BeanNoCacheTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.component.bean;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version
+ */
+public class BeanNoCacheTest extends ContextTestSupport {
+
+ private static final AtomicInteger counter = new AtomicInteger();
+
+ public void testBeanRefNoCache() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived("Hello1", "Bye2", "Camel3");
+
+ template.sendBody("direct:start", "Hello");
+ template.sendBody("direct:start", "Bye");
+ template.sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .bean(MyCoolBean.class, "doSomething", false, false)
+ .to("mock:result");
+ }
+ };
+ }
+
+ public static class MyCoolBean {
+
+ private final int count;
+
+ public MyCoolBean() {
+ count = counter.incrementAndGet();
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String doSomething(String s) {
+ return s + count;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNoCacheTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNoCacheTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNoCacheTest.java
new file mode 100644
index 0000000..bff02a7
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNoCacheTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.component.bean;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version
+ */
+public class BeanRefNoCacheTest extends ContextTestSupport {
+
+ private static final AtomicInteger counter = new AtomicInteger();
+
+ public void testBeanRefNoCache() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived("Hello1", "Bye2", "Camel3");
+
+ template.sendBody("direct:start", "Hello");
+ template.sendBody("direct:start", "Bye");
+ template.sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .beanRef(MyCoolBean.class.getName(), "doSomething", false)
+ .to("mock:result");
+ }
+ };
+ }
+
+ public static class MyCoolBean {
+
+ private final int count;
+
+ public MyCoolBean() {
+ count = counter.incrementAndGet();
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String doSomething(String s) {
+ return s + count;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/test/java/org/apache/camel/component/bean/NewInstanceTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/NewInstanceTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/NewInstanceTest.java
index f8e4400..188c066 100644
--- a/camel-core/src/test/java/org/apache/camel/component/bean/NewInstanceTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/NewInstanceTest.java
@@ -60,7 +60,7 @@ public class NewInstanceTest extends ContextTestSupport {
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() {
- from("direct:start").beanRef("myBean").to("mock:result");
+ from("direct:start").beanRef("myBean", false).to("mock:result");
}
};
}
http://git-wip-us.apache.org/repos/asf/camel/blob/d2defc15/camel-core/src/test/java/org/apache/camel/component/bean/PredicateAsBeanTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/PredicateAsBeanTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/PredicateAsBeanTest.java
index 6e67226..df050da 100644
--- a/camel-core/src/test/java/org/apache/camel/component/bean/PredicateAsBeanTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/PredicateAsBeanTest.java
@@ -66,8 +66,5 @@ public class PredicateAsBeanTest extends ContextTestSupport {
return (null != body) && (body.equals("Wobble"));
}
- public void assertMatches(String text, Exchange exchange) throws AssertionError {
- LOG.info("assertMatches(text, exchange) called with: " + text + ", " + exchange);
- }
}
}