This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 186e8a28f5dfd43136496eebcd42b905b2f1744d
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sat Jul 6 09:56:29 2019 +0200

    CAMEL-13730: Add NotifyBuilderMatcher in SPI so we can have mock endpoints 
back with notify builder as predicates.
---
 .../apache/camel/component/mock/MockEndpoint.java  |  27 +++-
 .../org/apache/camel/spi/NotifyBuilderMatcher.java |  46 ++++++
 .../org/apache/camel/builder/NotifyBuilder.java    | 166 +++++++++++++++++++++
 3 files changed, 238 insertions(+), 1 deletion(-)

diff --git 
a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
 
b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
index 12e4827..3ee6959 100644
--- 
a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
+++ 
b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
@@ -43,8 +43,10 @@ import org.apache.camel.Message;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.RuntimeExchangeException;
 import org.apache.camel.spi.BrowsableEndpoint;
 import org.apache.camel.spi.InterceptSendToEndpoint;
+import org.apache.camel.spi.NotifyBuilderMatcher;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -88,7 +90,7 @@ import org.apache.camel.util.StopWatch;
  * number of values provided in the bodies/headers.
  */
 @UriEndpoint(firstVersion = "1.0.0", scheme = "mock", title = "Mock", syntax = 
"mock:name", producerOnly = true, label = "core,testing", lenientProperties = 
true)
-public class MockEndpoint extends DefaultEndpoint implements BrowsableEndpoint 
{
+public class MockEndpoint extends DefaultEndpoint implements 
BrowsableEndpoint, NotifyBuilderMatcher {
 
     // must be volatile so changes is visible between the thread which 
performs the assertions
     // and the threads which process the exchanges when routing messages in 
Camel
@@ -1085,6 +1087,29 @@ public class MockEndpoint extends DefaultEndpoint 
implements BrowsableEndpoint {
         return getReceivedExchange(index);
     }
 
+    @Override
+    public void notifyBuilderOnExchange(Exchange exchange) {
+        onExchange(exchange);
+    }
+
+    @Override
+    public void notifyBuilderReset() {
+        reset();
+    }
+
+    @Override
+    public boolean notifyBuilderMatches() {
+        if (latch != null) {
+            try {
+                return latch.await(0, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                throw RuntimeExchangeException.wrapRuntimeException(e);
+            }
+        } else {
+            return true;
+        }
+    }
+
     // Properties
     // 
-------------------------------------------------------------------------
 
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/NotifyBuilderMatcher.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/NotifyBuilderMatcher.java
new file mode 100644
index 0000000..a951545
--- /dev/null
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/NotifyBuilderMatcher.java
@@ -0,0 +1,46 @@
+/*
+ * 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.spi;
+
+import org.apache.camel.Exchange;
+
+/**
+ * Allows to be used in combination with <tt>NotifyBuilder</tt> as external 
predicate implementations to compute
+ * if the exchange matches.
+ * <p/>
+ * This is used by the mock endpoint, for example.
+ */
+public interface NotifyBuilderMatcher {
+
+    /**
+     * When an exchange was received
+     *
+     * @param exchange the exchange
+     */
+    void notifyBuilderOnExchange(Exchange exchange);
+
+    /**
+     * Whether the predicate matches
+     */
+    boolean notifyBuilderMatches();
+
+    /**
+     * Reset state
+     */
+    void notifyBuilderReset();
+    
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/NotifyBuilder.java 
b/core/camel-core/src/main/java/org/apache/camel/builder/NotifyBuilder.java
index 1fba0ff..c569a79 100644
--- a/core/camel-core/src/main/java/org/apache/camel/builder/NotifyBuilder.java
+++ b/core/camel-core/src/main/java/org/apache/camel/builder/NotifyBuilder.java
@@ -37,6 +37,7 @@ import org.apache.camel.spi.CamelEvent.ExchangeCompletedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeCreatedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeFailedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeSentEvent;
+import org.apache.camel.spi.NotifyBuilderMatcher;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.spi.UnitOfWork;
 import org.apache.camel.support.EndpointHelper;
@@ -975,6 +976,171 @@ public class NotifyBuilder {
     }
 
     /**
+     * Sets a condition when the provided mock is satisfied based on {@link 
Exchange}
+     * being sent to it when they are <b>done</b>.
+     * <p/>
+     * The idea is that you can use mock endpoints (or other matchers) for 
setting fine grained expectations
+     * and then use that together with this builder. The mock provided does 
<b>NOT</b>
+     * have to already exist in the route. You can just create a new pseudo 
mock
+     * and this builder will send the done {@link Exchange} to it. So its like
+     * adding the mock to the end of your route(s).
+     *
+     * @param matcher the matcher such as mock endpoint
+     * @return the builder
+     */
+    public NotifyBuilder whenDoneSatisfied(final NotifyBuilderMatcher matcher) 
{
+        return doWhenSatisfied(matcher, false);
+    }
+
+    /**
+     * Sets a condition when the provided mock endpoint (or other matchers) is 
satisfied based on {@link Exchange}
+     * being sent to it when they are <b>received</b>.
+     * <p/>
+     * The idea is that you can use mock endpoints (or other matchers) for 
setting fine grained expectations
+     * and then use that together with this builder. The mock provided does 
<b>NOT</b>
+     * have to already exist in the route. You can just create a new pseudo 
mock
+     * and this builder will send the done {@link Exchange} to it. So its like
+     * adding the mock to the end of your route(s).
+     *
+     * @param matcher the matcher such as mock endpoint
+     * @return the builder
+     */
+    public NotifyBuilder whenReceivedSatisfied(final NotifyBuilderMatcher 
matcher) {
+        return doWhenSatisfied(matcher, true);
+    }
+
+    private NotifyBuilder doWhenSatisfied(final NotifyBuilderMatcher matcher, 
final boolean received) {
+        stack.add(new EventPredicateSupport() {
+
+            @Override
+            public boolean onExchangeCreated(Exchange exchange) {
+                if (received) {
+                    matcher.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            @Override
+            public boolean onExchangeFailed(Exchange exchange) {
+                if (!received) {
+                    matcher.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            @Override
+            public boolean onExchangeCompleted(Exchange exchange) {
+                if (!received) {
+                    matcher.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            public boolean matches() {
+                return matcher.notifyBuilderMatches();
+            }
+
+            @Override
+            public void reset() {
+                matcher.notifyBuilderReset();
+            }
+
+            @Override
+            public String toString() {
+                if (received) {
+                    return "whenReceivedSatisfied(" + matcher + ")";
+                } else {
+                    return "whenDoneSatisfied(" + matcher + ")";
+                }
+            }
+        });
+        return this;
+    }
+
+    /**
+     * Sets a condition when the provided mock (or other matchers) is 
<b>not</b> satisfied based on {@link Exchange}
+     * being sent to it when they are <b>received</b>.
+     * <p/>
+     * The idea is that you can use  mock endpoints (or other matchers) for 
setting fine grained expectations
+     * and then use that together with this builder. The mock provided does 
<b>NOT</b>
+     * have to already exist in the route. You can just create a new pseudo 
mock
+     * and this builder will send the done {@link Exchange} to it. So its like
+     * adding the mock to the end of your route(s).
+     *
+     * @param matcher the matcher such as mock endpoint
+     * @return the builder
+     */
+    @Deprecated
+    public NotifyBuilder whenReceivedNotSatisfied(final NotifyBuilderMatcher 
matcher) {
+        return doWhenNotSatisfied(matcher, true);
+    }
+
+    /**
+     * Sets a condition when the provided mock (or other matchers) is 
<b>not</b> satisfied based on {@link Exchange}
+     * being sent to it when they are <b>done</b>.
+     * <p/>
+     * The idea is that you can use  mock endpoints (or other matchers) for 
setting fine grained expectations
+     * and then use that together with this builder. The mock provided does 
<b>NOT</b>
+     * have to already exist in the route. You can just create a new pseudo 
mock
+     * and this builder will send the done {@link Exchange} to it. So its like
+     * adding the mock to the end of your route(s).
+     *
+     * @param matcher the matcher such as mock endpoint
+     * @return the builder
+     */
+    public NotifyBuilder whenDoneNotSatisfied(final NotifyBuilderMatcher 
matcher) {
+        return doWhenNotSatisfied(matcher, false);
+    }
+
+    private NotifyBuilder doWhenNotSatisfied(final NotifyBuilderMatcher mock, 
final boolean received) {
+        stack.add(new EventPredicateSupport() {
+
+            @Override
+            public boolean onExchangeCreated(Exchange exchange) {
+                if (received) {
+                    mock.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            @Override
+            public boolean onExchangeFailed(Exchange exchange) {
+                if (!received) {
+                    mock.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            @Override
+            public boolean onExchangeCompleted(Exchange exchange) {
+                if (!received) {
+                    mock.notifyBuilderOnExchange(exchange);
+                }
+                return true;
+            }
+
+            public boolean matches() {
+                return !mock.notifyBuilderMatches();
+            }
+
+            @Override
+            public void reset() {
+                mock.notifyBuilderReset();
+            }
+
+            @Override
+            public String toString() {
+                if (received) {
+                    return "whenReceivedNotSatisfied(" + mock + ")";
+                } else {
+                    return "whenDoneNotSatisfied(" + mock + ")";
+                }
+            }
+        });
+        return this;
+    }
+
+    /**
      * Prepares to append an additional expression using the <i>and</i> 
operator.
      *
      * @return the builder

Reply via email to