| /* |
| * 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.cassandra.net; |
| |
| import java.net.UnknownHostException; |
| import java.util.function.Predicate; |
| |
| import org.apache.cassandra.locator.InetAddressAndPort; |
| |
| /** |
| * Starting point for mocking {@link MessagingService} interactions. Outgoing messages can be |
| * intercepted by first creating a {@link MatcherResponse} by calling {@link MockMessagingService#when(Matcher)}. |
| * Alternatively {@link Matcher}s can be created by using helper methods such as {@link #to(InetAddressAndPort)}, |
| * {@link #verb(Verb)} or {@link #payload(Predicate)} and may also be |
| * nested using {@link MockMessagingService#all(Matcher[])} or {@link MockMessagingService#any(Matcher[])}. |
| * After each test, {@link MockMessagingService#cleanup()} must be called for free listeners registered |
| * in {@link MessagingService}. |
| */ |
| public class MockMessagingService |
| { |
| |
| private MockMessagingService() |
| { |
| } |
| |
| /** |
| * Creates a MatcherResponse based on specified matcher. |
| */ |
| public static MatcherResponse when(Matcher matcher) |
| { |
| return new MatcherResponse(matcher); |
| } |
| |
| /** |
| * Unsubscribes any handlers. |
| * This should be called after each test. |
| */ |
| public static void cleanup() |
| { |
| MessagingService.instance().outboundSink.clear(); |
| MessagingService.instance().inboundSink.clear(); |
| } |
| |
| /** |
| * Creates a matcher that will indicate if the target address of the outgoing message equals the |
| * provided address. |
| */ |
| public static Matcher<InetAddressAndPort> to(String address) |
| { |
| try |
| { |
| return to(InetAddressAndPort.getByName(address)); |
| } |
| catch (UnknownHostException e) |
| { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Creates a matcher that will indicate if the target address of the outgoing message equals the |
| * provided address. |
| */ |
| public static Matcher<InetAddressAndPort> to(InetAddressAndPort address) |
| { |
| return (in, to) -> to == address || to.equals(address); |
| } |
| |
| /** |
| * Creates a matcher that will indicate if the target address of the outgoing message matches the provided predicate. |
| */ |
| public static Matcher<InetAddressAndPort> to(Predicate<InetAddressAndPort> predicate) |
| { |
| return (in, to) -> predicate.test(to); |
| } |
| |
| /** |
| * Creates a matcher that will indicate if the verb of the outgoing message equals the |
| * provided value. |
| */ |
| public static Matcher<Verb> verb(Verb verb) |
| { |
| return (in, to) -> in.verb() == verb; |
| } |
| |
| /** |
| * Creates a matcher based on the result of the provided predicate called with the outgoing message. |
| */ |
| public static <T> Matcher<T> message(Predicate<Message<T>> fn) |
| { |
| return (msg, to) -> fn.test(msg); |
| } |
| |
| /** |
| * Creates a matcher based on the result of the provided predicate called with the outgoing message's payload. |
| */ |
| public static <T> Matcher<T> payload(Predicate<T> fn) |
| { |
| return (msg, to) -> fn.test(msg.payload); |
| } |
| |
| /** |
| * Inverts boolean result of wrapped matcher. |
| */ |
| public static <T> Matcher<T> not(Matcher<T> matcher) |
| { |
| return (o, to) -> !matcher.matches(o, to); |
| } |
| |
| /** |
| * Indicates true in case all provided matchers returned true. |
| */ |
| public static <T> Matcher<?> all(Matcher<?>... matchers) |
| { |
| return (Message<T> out, InetAddressAndPort to) -> { |
| for (Matcher matcher : matchers) |
| { |
| if (!matcher.matches(out, to)) |
| return false; |
| } |
| return true; |
| }; |
| } |
| |
| /** |
| * Indicates true in case at least a single provided matcher returned true. |
| */ |
| public static <T> Matcher<?> any(Matcher<?>... matchers) |
| { |
| return (Message<T> out, InetAddressAndPort to) -> { |
| for (Matcher matcher : matchers) |
| { |
| if (matcher.matches(out, to)) |
| return true; |
| } |
| return false; |
| }; |
| } |
| } |