content: /*
   * 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.springboot.example;
  
  import org.apache.camel.CamelContext;
  import org.apache.camel.ProducerTemplate;
  import org.apache.camel.component.mock.MockEndpoint;
  import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.test.context.SpringBootTest;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  
  @CamelSpringBootTest
  @SpringBootTest(classes = Application.class)
  public class LoadBalancerEIPTest {
  
  	@Autowired
  	private CamelContext camelContext;
  
  	private ProducerTemplate producerTemplate;
  
  	@BeforeEach
  	public void setUp() {
  		producerTemplate = camelContext.createProducerTemplate();
  	}
  
  	@Test
  	public void testLoadBalancer() throws InterruptedException {
  		MockEndpoint mockA = camelContext.getEndpoint("mock:a", MockEndpoint.class);
  		MockEndpoint mockB = camelContext.getEndpoint("mock:b", MockEndpoint.class);
  
  		mockA.expectedBodiesReceived("A", "C");
  		mockB.expectedBodiesReceived("B", "D");
  
  		producerTemplate.sendBody("direct:loadbalancer-round-robin", "A");
  		producerTemplate.sendBody("direct:loadbalancer-round-robin", "B");
  		producerTemplate.sendBody("direct:loadbalancer-round-robin", "C");
  		producerTemplate.sendBody("direct:loadbalancer-round-robin", "D");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  
  	@Test
  	public void testRandomLoadBalancer() {
  		MockEndpoint mockC = camelContext.getEndpoint("mock:c", MockEndpoint.class);
  		MockEndpoint mockD = camelContext.getEndpoint("mock:d", MockEndpoint.class);
  
  		for (int i = 0 ; i < 10 ; i++){
  			producerTemplate.sendBody("direct:loadbalancer-random", i);
  		}
  
  		assertEquals(10, mockC.getReceivedCounter() + mockD.getReceivedCounter());
  	}
  
  	@Test
  	public void testStickyLoadBalancer() throws InterruptedException {
  		MockEndpoint mockE = camelContext.getEndpoint("mock:e", MockEndpoint.class);
  		MockEndpoint mockF = camelContext.getEndpoint("mock:f", MockEndpoint.class);
  
  		mockE.expectedBodiesReceived("A", "E");
  		mockF.expectedBodiesReceived("B", "C", "D");
  
  		producerTemplate.sendBodyAndHeader("direct:loadbalancer-sticky", "A", "correlation-key",  "vowel");
  		producerTemplate.sendBodyAndHeader("direct:loadbalancer-sticky", "B", "correlation-key",  "consonant");
  		producerTemplate.sendBodyAndHeader("direct:loadbalancer-sticky", "C", "correlation-key",  "consonant");
  		producerTemplate.sendBodyAndHeader("direct:loadbalancer-sticky", "D", "correlation-key",  "consonant");
  		producerTemplate.sendBodyAndHeader("direct:loadbalancer-sticky", "E", "correlation-key",  "vowel");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  	@Test
  	public void testTopicLoadBalancer() throws Exception {
  		MockEndpoint mockJ = camelContext.getEndpoint("mock:j", MockEndpoint.class);
  		MockEndpoint mockK = camelContext.getEndpoint("mock:k", MockEndpoint.class);
  
  		mockJ.expectedBodiesReceived("A", "B", "C", "D", "E");
  		mockK.expectedBodiesReceived("A", "B", "C", "D", "E");
  
  		producerTemplate.sendBody("direct:loadbalancer-topic", "A");
  		producerTemplate.sendBody("direct:loadbalancer-topic", "B");
  		producerTemplate.sendBody("direct:loadbalancer-topic", "C");
  		producerTemplate.sendBody("direct:loadbalancer-topic", "D");
  		producerTemplate.sendBody("direct:loadbalancer-topic", "E");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  	@Test
  	public void testFailoverLoadBalancer() throws Exception {
  		MockEndpoint mockL = camelContext.getEndpoint("mock:l", MockEndpoint.class);
  		MockEndpoint mockM = camelContext.getEndpoint("mock:m", MockEndpoint.class);
  
  		mockL.expectedBodiesReceived("A", "B", "C", "D");
  		mockM.expectedBodiesReceived("E");
  
  		producerTemplate.sendBody("direct:loadbalancer-failover", "A");
  		producerTemplate.sendBody("direct:loadbalancer-failover", "B");
  		producerTemplate.sendBody("direct:loadbalancer-failover", "C");
  		producerTemplate.sendBody("direct:loadbalancer-failover", "E");
  		producerTemplate.sendBody("direct:loadbalancer-failover", "D");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  	@Test
  	public void testFailoverRoundRobinLoadBalancer() throws Exception {
  		MockEndpoint mockN = camelContext.getEndpoint("mock:n", MockEndpoint.class);
  		MockEndpoint mockO = camelContext.getEndpoint("mock:o", MockEndpoint.class);
  		MockEndpoint mockP = camelContext.getEndpoint("mock:p", MockEndpoint.class);
  		MockEndpoint mockQ = camelContext.getEndpoint("mock:q", MockEndpoint.class);
  
  		mockN.expectedMessageCount(0);
  		mockO.expectedMessageCount(0);
  		mockP.expectedBodiesReceived("A", "C");
  		mockQ.expectedBodiesReceived("B", "D", "E");
  
  		producerTemplate.sendBody("direct:loadbalancer-failover-round-robin-no-error-handler", "A");
  		producerTemplate.sendBody("direct:loadbalancer-failover-round-robin-no-error-handler", "B");
  		producerTemplate.sendBody("direct:loadbalancer-failover-round-robin-no-error-handler", "C");
  		producerTemplate.sendBody("direct:loadbalancer-failover-round-robin-no-error-handler", "D");
  		producerTemplate.sendBody("direct:loadbalancer-failover-round-robin-no-error-handler", "E");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  	@Test
  	public void testWeightedRoundRobinLoadBalancer() throws Exception {
  		MockEndpoint mockW = camelContext.getEndpoint("mock:w", MockEndpoint.class);
  		MockEndpoint mockX  = camelContext.getEndpoint("mock:x", MockEndpoint.class);
  
  		mockW.expectedBodiesReceived("A", "C", "D", "F", "G", "J", "K");
  		mockX.expectedBodiesReceived("B", "E", "H");
  
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "A"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "B"); // X
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "C"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "D"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "E"); // X
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "F"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "G"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "H"); // X
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "J"); // W
  		producerTemplate.sendBody("direct:loadbalancer-weighted-round-robin", "K"); // W
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  	@Test
  	public void testCustomLoadBalancer() throws InterruptedException {
  		MockEndpoint mockG = camelContext.getEndpoint("mock:g", MockEndpoint.class);
  		MockEndpoint mockH = camelContext.getEndpoint("mock:h", MockEndpoint.class);
  
  		mockG.expectedBodiesReceived("A", "E");
  		mockH.expectedBodiesReceived("B", "C", "D");
  
  		producerTemplate.sendBody("direct:loadbalancer-custom", "A");
  		producerTemplate.sendBody("direct:loadbalancer-custom", "B");
  		producerTemplate.sendBody("direct:loadbalancer-custom", "C");
  		producerTemplate.sendBody("direct:loadbalancer-custom", "D");
  		producerTemplate.sendBody("direct:loadbalancer-custom", "E");
  
  		MockEndpoint.assertIsSatisfied(camelContext);
  	}
  
  }
  