/** * 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.management; import java.util.Set; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.ObjectName; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.ServiceStatus; import org.apache.camel.api.management.mbean.ManagedThrottlingExceptionRoutePolicyMBean; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.ThrottlingExceptionHalfOpenHandler; import org.apache.camel.impl.ThrottlingExceptionRoutePolicy; import org.junit.Test; public class ManagedThrottlingExceptionRoutePolicyTest extends ManagementTestSupport { @Test public void testRoutes() throws Exception { // JMX tests dont work well on AIX CI servers (hangs them) if (isPlatform("aix")) { return; } MBeanServer mbeanServer = getMBeanServer(); // get the Camel route Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=routes,*"), null); assertEquals(1, set.size()); ObjectName on = set.iterator().next(); boolean registered = mbeanServer.isRegistered(on); assertEquals("Should be registered", true, registered); // check the starting endpoint uri String uri = (String) mbeanServer.getAttribute(on, "EndpointUri"); assertEquals("direct://start", uri); // should be started String state = (String) mbeanServer.getAttribute(on, "State"); assertEquals(ServiceStatus.Started.name(), state); // should have ThrottlingExceptionRoutePolicy route policy String policy = (String) mbeanServer.getAttribute(on, "RoutePolicyList"); assertNotNull(policy); assertTrue(policy.startsWith("ThrottlingExceptionRoutePolicy")); // get the RoutePolicy String mbeanName = String.format("org.apache.camel:context=camel-1,name=%s,type=services", policy); set = mbeanServer.queryNames(new ObjectName(mbeanName), null); assertEquals(1, set.size()); on = set.iterator().next(); assertTrue(mbeanServer.isRegistered(on)); // the route has no failures String myType = (String) mbeanServer.getAttribute(on, "ServiceType"); assertEquals("ThrottlingExceptionRoutePolicy", myType); ManagedThrottlingExceptionRoutePolicyMBean proxy = JMX.newMBeanProxy(mbeanServer, on, ManagedThrottlingExceptionRoutePolicyMBean.class); assertNotNull(proxy); // state should be closed w/ no failures String myState = proxy.currentState(); assertEquals("State closed, failures 0", myState); // the route has no failures Integer val = proxy.getCurrentFailures(); assertEquals(0, val.intValue()); // the route has no failures Long lastFail = proxy.getLastFailure(); assertEquals(0L, lastFail.longValue()); // the route is closed Long openAt = proxy.getOpenAt(); assertEquals(0L, openAt.longValue()); // the route has a handler String handlerClass = proxy.getHalfOpenHandlerName(); assertEquals("DummyHandler", handlerClass); // values set during construction of class Integer threshold = proxy.getFailureThreshold(); assertEquals(10, threshold.intValue()); Long window = proxy.getFailureWindow(); assertEquals(1000L, window.longValue()); Long halfOpenAfter = proxy.getHalfOpenAfter(); assertEquals(5000L, halfOpenAfter.longValue()); // change value proxy.setHalfOpenAfter(10000L); halfOpenAfter = proxy.getHalfOpenAfter(); assertEquals(10000L, halfOpenAfter.longValue()); try { getMockEndpoint("mock:result").expectedMessageCount(0); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); } catch (Exception e) { // expected } // state should be closed w/ no failures myState = proxy.currentState(); assertTrue(myState.contains("State closed, failures 1, last failure")); // the route has 1 failure val = proxy.getCurrentFailures(); assertEquals(1, val.intValue()); Thread.sleep(200); // the route has 1 failure X mills ago lastFail = proxy.getLastFailure(); assertTrue(lastFail.longValue() > 0); } @Override protected RouteBuilder createRouteBuilder() throws Exception { ThrottlingExceptionRoutePolicy policy = new ThrottlingExceptionRoutePolicy(10, 1000, 5000, null); policy.setHalfOpenHandler(new DummyHandler()); return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").routeId("testRoute") .routePolicy(policy) .to("log:foo") .process(new BoomProcess()) .to("mock:result"); } }; } class BoomProcess implements Processor { @Override public void process(Exchange exchange) throws Exception { // need to sleep a little to cause last failure to be slow Thread.sleep(50); throw new RuntimeException("boom!"); } } class DummyHandler implements ThrottlingExceptionHalfOpenHandler { @Override public boolean isReadyToBeClosed() { return false; } } }