001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.management.mbean; 018 019import java.util.Iterator; 020import java.util.List; 021import java.util.StringJoiner; 022 023import javax.management.openmbean.CompositeData; 024import javax.management.openmbean.CompositeDataSupport; 025import javax.management.openmbean.CompositeType; 026import javax.management.openmbean.TabularData; 027import javax.management.openmbean.TabularDataSupport; 028 029import org.apache.camel.CamelContext; 030import org.apache.camel.RuntimeCamelException; 031import org.apache.camel.api.management.ManagedResource; 032import org.apache.camel.api.management.mbean.CamelOpenMBeanTypes; 033import org.apache.camel.api.management.mbean.ManagedFailoverLoadBalancerMBean; 034import org.apache.camel.model.LoadBalanceDefinition; 035import org.apache.camel.model.ProcessorDefinition; 036import org.apache.camel.processor.loadbalancer.ExceptionFailureStatistics; 037import org.apache.camel.processor.loadbalancer.FailOverLoadBalancer; 038import org.apache.camel.util.ObjectHelper; 039 040@ManagedResource(description = "Managed Failover LoadBalancer") 041public class ManagedFailoverLoadBalancer extends ManagedProcessor implements ManagedFailoverLoadBalancerMBean { 042 private final FailOverLoadBalancer processor; 043 private String exceptions; 044 045 public ManagedFailoverLoadBalancer(CamelContext context, FailOverLoadBalancer processor, LoadBalanceDefinition definition) { 046 super(context, processor, definition); 047 this.processor = processor; 048 } 049 050 @Override 051 public LoadBalanceDefinition getDefinition() { 052 return (LoadBalanceDefinition) super.getDefinition(); 053 } 054 055 @Override 056 public void reset() { 057 super.reset(); 058 processor.reset(); 059 } 060 061 @Override 062 public Boolean getSupportExtendedInformation() { 063 return true; 064 } 065 066 @Override 067 public Integer getSize() { 068 return processor.getProcessors().size(); 069 } 070 071 @Override 072 public Boolean isRoundRobin() { 073 return processor.isRoundRobin(); 074 } 075 076 @Override 077 public Boolean isSticky() { 078 return processor.isSticky(); 079 } 080 081 @Override 082 public Integer getMaximumFailoverAttempts() { 083 return processor.getMaximumFailoverAttempts(); 084 } 085 086 @Override 087 public String getExceptions() { 088 if (exceptions != null) { 089 return exceptions; 090 } 091 092 List<Class<?>> classes = processor.getExceptions(); 093 if (classes == null || classes.isEmpty()) { 094 exceptions = ""; 095 } else { 096 StringJoiner exceptionsBuilder = new StringJoiner(","); 097 for (Class<?> clazz : classes) { 098 exceptionsBuilder.add(clazz.getCanonicalName()); 099 } 100 exceptions = exceptionsBuilder.toString(); 101 } 102 return exceptions; 103 } 104 105 @Override 106 public String getLastGoodProcessorId() { 107 int idx = processor.getLastGoodIndex(); 108 if (idx != -1) { 109 LoadBalanceDefinition def = getDefinition(); 110 ProcessorDefinition<?> output = def.getOutputs().get(idx); 111 if (output != null) { 112 return output.getId(); 113 } 114 } 115 return null; 116 } 117 118 @Override 119 public TabularData exceptionStatistics() { 120 try { 121 TabularData answer = new TabularDataSupport(CamelOpenMBeanTypes.loadbalancerExceptionsTabularType()); 122 123 ExceptionFailureStatistics statistics = processor.getExceptionFailureStatistics(); 124 125 Iterator<Class<?>> it = statistics.getExceptions(); 126 boolean empty = true; 127 while (it.hasNext()) { 128 empty = false; 129 Class<?> exception = it.next(); 130 String name = ObjectHelper.name(exception); 131 long counter = statistics.getFailureCounter(exception); 132 133 CompositeType ct = CamelOpenMBeanTypes.loadbalancerExceptionsCompositeType(); 134 CompositeData data = new CompositeDataSupport( 135 ct, 136 new String[] { "exception", "failures" }, 137 new Object[] { name, counter }); 138 answer.put(data); 139 } 140 if (empty) { 141 // use Exception as a single general 142 String name = ObjectHelper.name(Exception.class); 143 long counter = statistics.getFailureCounter(Exception.class); 144 145 CompositeType ct = CamelOpenMBeanTypes.loadbalancerExceptionsCompositeType(); 146 CompositeData data = new CompositeDataSupport( 147 ct, 148 new String[] { "exception", "failures" }, 149 new Object[] { name, counter }); 150 answer.put(data); 151 } 152 153 return answer; 154 } catch (Exception e) { 155 throw RuntimeCamelException.wrapRuntimeCamelException(e); 156 } 157 } 158 159}