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.List;
020
021import org.apache.camel.CamelContext;
022import org.apache.camel.ManagementStatisticsLevel;
023import org.apache.camel.Route;
024import org.apache.camel.ServiceStatus;
025import org.apache.camel.TimerListener;
026import org.apache.camel.api.management.ManagedResource;
027import org.apache.camel.api.management.mbean.ManagedRouteGroupMBean;
028import org.apache.camel.spi.ManagementStrategy;
029import org.apache.camel.util.TimeUtils;
030
031@ManagedResource(description = "Managed Route Group")
032public class ManagedRouteGroup extends ManagedPerformanceCounter implements TimerListener, ManagedRouteGroupMBean {
033
034    public static final String VALUE_UNKNOWN = "Unknown";
035
036    protected final String group;
037    protected final CamelContext context;
038    private final LoadTriplet load = new LoadTriplet();
039    private final LoadThroughput thp = new LoadThroughput();
040    private final String jmxDomain;
041
042    public ManagedRouteGroup(CamelContext context, String group) {
043        this.context = context;
044        this.group = group;
045        this.jmxDomain = context.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName();
046    }
047
048    @Override
049    public void init(ManagementStrategy strategy) {
050        super.init(strategy);
051        boolean enabled
052                = context.getManagementStrategy().getManagementAgent().getStatisticsLevel() != ManagementStatisticsLevel.Off;
053        setStatisticsEnabled(enabled);
054    }
055
056    public CamelContext getContext() {
057        return context;
058    }
059
060    @Override
061    public String getRouteGroup() {
062        return group;
063    }
064
065    @Override
066    public int getGroupSize() {
067        return context.getRoutesByGroup(group).size();
068    }
069
070    @Override
071    public String[] getGroupIds() {
072        List<String> list = context.getRoutesByGroup(group).stream().map(Route::getRouteId).toList();
073        return list.toArray(new String[0]);
074    }
075
076    @Override
077    public String getState() {
078        String answer = null;
079        for (Route route : context.getRoutesByGroup(group)) {
080            ServiceStatus status = context.getRouteController().getRouteStatus(route.getId());
081            if (status != null) {
082                if (answer == null) {
083                    answer = status.name();
084                } else if (!status.name().equals(answer)) {
085                    answer = VALUE_UNKNOWN;
086                }
087            }
088        }
089        return answer;
090    }
091
092    @Override
093    public String getUptime() {
094        long delta = getUptimeMillis();
095        if (delta == 0) {
096            return "";
097        }
098        return TimeUtils.printDuration(delta);
099    }
100
101    @Override
102    public long getUptimeMillis() {
103        long answer = -1;
104        for (Route route : context.getRoutesByGroup(group)) {
105            answer = Math.max(answer, route.getUptimeMillis());
106        }
107        return answer;
108    }
109
110    @Override
111    public String getCamelId() {
112        return context.getName();
113    }
114
115    @Override
116    public String getCamelManagementName() {
117        return context.getManagementName();
118    }
119
120    @Override
121    public String getLoad01() {
122        double load1 = load.getLoad1();
123        if (Double.isNaN(load1)) {
124            // empty string if load statistics is disabled
125            return "";
126        } else {
127            return String.format("%.2f", load1);
128        }
129    }
130
131    @Override
132    public String getLoad05() {
133        double load5 = load.getLoad5();
134        if (Double.isNaN(load5)) {
135            // empty string if load statistics is disabled
136            return "";
137        } else {
138            return String.format("%.2f", load5);
139        }
140    }
141
142    @Override
143    public String getLoad15() {
144        double load15 = load.getLoad15();
145        if (Double.isNaN(load15)) {
146            // empty string if load statistics is disabled
147            return "";
148        } else {
149            return String.format("%.2f", load15);
150        }
151    }
152
153    @Override
154    public String getThroughput() {
155        double d = thp.getThroughput();
156        if (Double.isNaN(d)) {
157            // empty string if load statistics is disabled
158            return "";
159        } else {
160            return String.format("%.2f", d);
161        }
162    }
163
164    @Override
165    public void onTimer() {
166        load.update(getInflightExchanges());
167        thp.update(getExchangesTotal());
168    }
169
170    private Integer getInflightExchanges() {
171        return (int) super.getExchangesInflight();
172    }
173
174    @Override
175    public void start() throws Exception {
176        context.getRouteController().startRouteGroup(group);
177    }
178
179    @Override
180    public void stop() throws Exception {
181        context.getRouteController().stopRouteGroup(group);
182    }
183
184}