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.Collection;
020import java.util.Collections;
021import java.util.Optional;
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.mbean.CamelOpenMBeanTypes;
032import org.apache.camel.api.management.mbean.ManagedCamelHealthMBean;
033import org.apache.camel.health.HealthCheck;
034import org.apache.camel.health.HealthCheckHelper;
035import org.apache.camel.health.HealthCheckRegistry;
036import org.apache.camel.health.HealthCheckRepository;
037import org.apache.camel.spi.ManagementStrategy;
038
039public class ManagedCamelHealth implements ManagedCamelHealthMBean {
040    private final CamelContext context;
041    private final HealthCheckRegistry healthCheckRegistry;
042
043    public ManagedCamelHealth(CamelContext context, HealthCheckRegistry healthCheckRegistry) {
044        this.context = context;
045        this.healthCheckRegistry = healthCheckRegistry;
046    }
047
048    public void init(ManagementStrategy strategy) {
049        // do nothing
050    }
051
052    public CamelContext getContext() {
053        return context;
054    }
055
056    @Override
057    public boolean isEnabled() {
058        return healthCheckRegistry.isEnabled();
059    }
060
061    @Override
062    public boolean isHealthy() {
063        for (HealthCheck.Result result : HealthCheckHelper.invoke(context)) {
064            if (result.getState() == HealthCheck.State.DOWN) {
065                return false;
066            }
067        }
068
069        return true;
070    }
071
072    @Override
073    public boolean isHealthyReadiness() {
074        for (HealthCheck.Result result : HealthCheckHelper.invokeReadiness(context)) {
075            if (result.getState() == HealthCheck.State.DOWN) {
076                return false;
077            }
078        }
079
080        return true;
081    }
082
083    @Override
084    public boolean isHealthyLiveness() {
085        for (HealthCheck.Result result : HealthCheckHelper.invokeLiveness(context)) {
086            if (result.getState() == HealthCheck.State.DOWN) {
087                return false;
088            }
089        }
090
091        return true;
092    }
093
094    @Override
095    public Collection<String> getHealthChecksIDs() {
096        return healthCheckRegistry.getCheckIDs();
097    }
098
099    @Override
100    public TabularData details() {
101        try {
102            final TabularData answer = new TabularDataSupport(CamelOpenMBeanTypes.camelHealthDetailsTabularType());
103            final CompositeType type = CamelOpenMBeanTypes.camelHealthDetailsCompositeType();
104
105            for (HealthCheck.Result result: HealthCheckHelper.invoke(context)) {
106                CompositeData data = new CompositeDataSupport(
107                    type,
108                    new String[] {
109                        "id",
110                        "group",
111                        "state",
112                        "enabled",
113                        "readiness",
114                        "liveness",
115                        "interval",
116                        "failureThreshold"
117                    },
118                    new Object[] {
119                        result.getCheck().getId(),
120                        result.getCheck().getGroup(),
121                        result.getState().name(),
122                        result.getCheck().getConfiguration().isEnabled(),
123                        result.getCheck().isReadiness(),
124                        result.getCheck().isLiveness(),
125                        result.getCheck().getConfiguration().getInterval(),
126                        result.getCheck().getConfiguration().getFailureThreshold()
127                    }
128                );
129
130                answer.put(data);
131            }
132
133            return answer;
134        } catch (Exception e) {
135            throw RuntimeCamelException.wrapRuntimeCamelException(e);
136        }
137    }
138
139    @Override
140    public String invoke(String id) {
141        Optional<HealthCheck.Result> result = HealthCheckHelper.invoke(context, id, Collections.emptyMap());
142
143        return result.map(r -> r.getState().name()).orElse(HealthCheck.State.UNKNOWN.name());
144    }
145
146    @Override
147    public void enableById(String id) {
148        Optional<HealthCheck> hc = healthCheckRegistry.getCheck(id);
149        if (hc.isPresent()) {
150            hc.get().getConfiguration().setEnabled(true);
151        } else {
152            Optional<HealthCheckRepository> hcr = healthCheckRegistry.getRepository(id);
153            hcr.ifPresent(repository -> repository.setEnabled(true));
154        }
155    }
156
157    @Override
158    public void disableById(String id) {
159        Optional<HealthCheck> hc = healthCheckRegistry.getCheck(id);
160        if (hc.isPresent()) {
161            hc.get().getConfiguration().setEnabled(false);
162        } else {
163            Optional<HealthCheckRepository> hcr = healthCheckRegistry.getRepository(id);
164            hcr.ifPresent(repository -> repository.setEnabled(false));
165        }
166    }
167}