| /* |
| * 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.geode.admin.internal; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.logging.log4j.Logger; |
| |
| import org.apache.geode.admin.GemFireHealth; |
| import org.apache.geode.admin.GemFireHealthConfig; |
| import org.apache.geode.distributed.internal.ClusterDistributionManager; |
| import org.apache.geode.internal.Assert; |
| import org.apache.geode.logging.internal.log4j.api.LogService; |
| |
| /** |
| * Evaluates the health of various GemFire components in the VM according to a |
| * {@link GemFireHealthConfig}. |
| * |
| * <P> |
| * |
| * Note that evaluators never reside in the administration VM, they only in member VMs. They are not |
| * <code>Serializable</code> and aren't meant to be. |
| * |
| * @see MemberHealthEvaluator |
| * @see CacheHealthEvaluator |
| * |
| * |
| * @since GemFire 3.5 |
| */ |
| public class GemFireHealthEvaluator { |
| |
| private static final Logger logger = LogService.getLogger(); |
| |
| /** Determines how the health of GemFire is determined */ |
| private GemFireHealthConfig config; |
| |
| /** Evaluates the health of this member of the distributed system */ |
| private MemberHealthEvaluator memberHealth; |
| |
| /** Evaluates the health of the Cache hosted in this VM */ |
| private CacheHealthEvaluator cacheHealth; |
| |
| /** |
| * The most recent <code>OKAY_HEALTH</code> diagnoses of the GemFire system |
| */ |
| private List<String> okayDiagnoses; |
| |
| /** |
| * The most recent <code>POOR_HEALTH</code> diagnoses of the GemFire system |
| */ |
| private List<String> poorDiagnoses; |
| |
| /////////////////////// Constructors /////////////////////// |
| |
| /** |
| * Creates a new <code>GemFireHealthEvaluator</code> |
| * |
| * @param config The configuration that determines whether or GemFire is healthy |
| * @param dm The distribution manager |
| */ |
| public GemFireHealthEvaluator(GemFireHealthConfig config, ClusterDistributionManager dm) { |
| if (config == null) { |
| throw new NullPointerException( |
| "Null GemFireHealthConfig"); |
| } |
| |
| this.config = config; |
| this.memberHealth = new MemberHealthEvaluator(config, dm); |
| this.cacheHealth = new CacheHealthEvaluator(config, dm); |
| this.okayDiagnoses = new ArrayList<>(); |
| this.poorDiagnoses = new ArrayList<>(); |
| } |
| |
| ////////////////////// Instance Methods ////////////////////// |
| |
| /** |
| * Evaluates the health of the GemFire components in this VM. |
| * |
| * @return The aggregate health code (such as {@link GemFireHealth#OKAY_HEALTH}) of the GemFire |
| * components. |
| */ |
| public GemFireHealth.Health evaluate() { |
| List status = new ArrayList(); |
| this.memberHealth.evaluate(status); |
| this.cacheHealth.evaluate(status); |
| |
| GemFireHealth.Health overallHealth = GemFireHealth.GOOD_HEALTH; |
| this.okayDiagnoses.clear(); |
| this.poorDiagnoses.clear(); |
| |
| for (Iterator iter = status.iterator(); iter.hasNext();) { |
| AbstractHealthEvaluator.HealthStatus health = |
| (AbstractHealthEvaluator.HealthStatus) iter.next(); |
| if (overallHealth == GemFireHealth.GOOD_HEALTH) { |
| if ((health.getHealthCode() != GemFireHealth.GOOD_HEALTH)) { |
| overallHealth = health.getHealthCode(); |
| } |
| |
| } else if (overallHealth == GemFireHealth.OKAY_HEALTH) { |
| if (health.getHealthCode() == GemFireHealth.POOR_HEALTH) { |
| overallHealth = GemFireHealth.POOR_HEALTH; |
| } |
| } |
| |
| GemFireHealth.Health healthCode = health.getHealthCode(); |
| if (healthCode == GemFireHealth.OKAY_HEALTH) { |
| this.okayDiagnoses.add(health.getDiagnosis()); |
| |
| } else if (healthCode == GemFireHealth.POOR_HEALTH) { |
| this.poorDiagnoses.add(health.getDiagnosis()); |
| } |
| } |
| |
| if (logger.isDebugEnabled()) { |
| logger.debug("Evaluated health to be {}", overallHealth); |
| } |
| return overallHealth; |
| } |
| |
| /** |
| * Returns detailed information explaining the current health status. Each array element is a |
| * different cause for the current status. An empty array will be returned if the current status |
| * is {@link GemFireHealth#GOOD_HEALTH}. |
| */ |
| public String[] getDiagnosis(GemFireHealth.Health healthCode) { |
| if (healthCode == GemFireHealth.GOOD_HEALTH) { |
| return new String[0]; |
| |
| } else if (healthCode == GemFireHealth.OKAY_HEALTH) { |
| String[] array = new String[this.okayDiagnoses.size()]; |
| this.okayDiagnoses.toArray(array); |
| return array; |
| |
| } else { |
| Assert.assertTrue(healthCode == GemFireHealth.POOR_HEALTH); |
| String[] array = new String[this.poorDiagnoses.size()]; |
| this.poorDiagnoses.toArray(array); |
| return array; |
| } |
| } |
| |
| /** |
| * Resets the state of this evaluator |
| */ |
| public void reset() { |
| this.okayDiagnoses.clear(); |
| this.poorDiagnoses.clear(); |
| } |
| |
| /** |
| * Returns the heath evaluation interval, in seconds. |
| * |
| * @see GemFireHealthConfig#getHealthEvaluationInterval |
| */ |
| public int getEvaluationInterval() { |
| return this.config.getHealthEvaluationInterval(); |
| } |
| |
| /** |
| * Closes this evaluator and releases all of its resources |
| */ |
| public void close() { |
| this.memberHealth.close(); |
| this.cacheHealth.close(); |
| } |
| |
| } |