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
043    private String exceptions;
044
045    public ManagedFailoverLoadBalancer(CamelContext context, FailOverLoadBalancer processor, LoadBalanceDefinition definition) {
046        super(context, processor, definition);
047    }
048
049    @Override
050    public FailOverLoadBalancer getProcessor() {
051        return (FailOverLoadBalancer) super.getProcessor();
052    }
053
054    @Override
055    public LoadBalanceDefinition getDefinition() {
056        return (LoadBalanceDefinition) super.getDefinition();
057    }
058
059    @Override
060    public void reset() {
061        super.reset();
062        getProcessor().reset();
063    }
064
065    @Override
066    public Boolean getSupportExtendedInformation() {
067        return true;
068    }
069
070    @Override
071    public Integer getSize() {
072        return getProcessor().getProcessors().size();
073    }
074
075    @Override
076    public Boolean isRoundRobin() {
077        return getProcessor().isRoundRobin();
078    }
079
080    @Override
081    public Boolean isSticky() {
082        return getProcessor().isSticky();
083    }
084
085    @Override
086    public Integer getMaximumFailoverAttempts() {
087        return getProcessor().getMaximumFailoverAttempts();
088    }
089
090    @Override
091    public String getExceptions() {
092        if (exceptions != null) {
093            return exceptions;
094        }
095
096        List<Class<?>> classes = getProcessor().getExceptions();
097        if (classes == null || classes.isEmpty()) {
098            exceptions = "";
099        } else {
100            StringJoiner exceptionsBuilder = new StringJoiner(",");
101            for (Class<?> clazz : classes) {
102                exceptionsBuilder.add(clazz.getCanonicalName());
103            }
104            exceptions = exceptionsBuilder.toString();
105        }
106        return exceptions;
107    }
108
109    @Override
110    public String getLastGoodProcessorId() {
111        int idx = getProcessor().getLastGoodIndex();
112        if (idx != -1) {
113            LoadBalanceDefinition def = getDefinition();
114            ProcessorDefinition<?> output = def.getOutputs().get(idx);
115            if (output != null) {
116                return output.getId();
117            }
118        }
119        return null;
120    }
121
122    @Override
123    public TabularData extendedInformation() {
124        try {
125            TabularData answer = new TabularDataSupport(CamelOpenMBeanTypes.loadbalancerExceptionsTabularType());
126
127            ExceptionFailureStatistics statistics = getProcessor().getExceptionFailureStatistics();
128
129            Iterator<Class<?>> it = statistics.getExceptions();
130            boolean empty = true;
131            while (it.hasNext()) {
132                empty = false;
133                Class<?> exception = it.next();
134                String name = ObjectHelper.name(exception);
135                long counter = statistics.getFailureCounter(exception);
136
137                CompositeType ct = CamelOpenMBeanTypes.loadbalancerExceptionsCompositeType();
138                CompositeData data = new CompositeDataSupport(
139                        ct,
140                        new String[] { "exception", "failures" },
141                        new Object[] { name, counter });
142                answer.put(data);
143            }
144            if (empty) {
145                // use Exception as a single general
146                String name = ObjectHelper.name(Exception.class);
147                long counter = statistics.getFailureCounter(Exception.class);
148
149                CompositeType ct = CamelOpenMBeanTypes.loadbalancerExceptionsCompositeType();
150                CompositeData data = new CompositeDataSupport(
151                        ct,
152                        new String[] { "exception", "failures" },
153                        new Object[] { name, counter });
154                answer.put(data);
155            }
156
157            return answer;
158        } catch (Exception e) {
159            throw RuntimeCamelException.wrapRuntimeCamelException(e);
160        }
161    }
162
163}