View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe.beans.stats.listeners;
12  
13  import java.util.HashMap;
14  
15  import psiprobe.Utils;
16  import psiprobe.tools.SizeExpression;
17  
18  /**
19   * The listener interface for receiving threshold events. The class that is interested in processing
20   * a threshold event implements this interface, and the object created with that class is registered
21   * with a component using the component's {@code addThresholdListener} method. When the threshold
22   * event occurs, that object's appropriate method is invoked.
23   */
24  public abstract class AbstractThresholdListener extends AbstractStatsCollectionListener {
25  
26    /** The Constant DEFAULT_THRESHOLD. */
27    public static final long DEFAULT_THRESHOLD = Long.MAX_VALUE;
28  
29    /** The Constant DEFAULT_VALUE. */
30    public static final long DEFAULT_VALUE = Long.MIN_VALUE;
31  
32    /** The previous values. */
33    private final HashMap<String, Long> previousValues = new HashMap<>();
34  
35    /** The series disabled. */
36    private final HashMap<String, Boolean> seriesDisabled = new HashMap<>();
37  
38    /**
39     * Crossed above threshold.
40     *
41     * @param sce the sce
42     */
43    protected abstract void crossedAboveThreshold(StatsCollectionEvent sce);
44  
45    /**
46     * Crossed below threshold.
47     *
48     * @param sce the sce
49     */
50    protected abstract void crossedBelowThreshold(StatsCollectionEvent sce);
51  
52    /**
53     * Remained above threshold.
54     *
55     * @param sce the sce
56     */
57    protected abstract void remainedAboveThreshold(StatsCollectionEvent sce);
58  
59    /**
60     * Remained below threshold.
61     *
62     * @param sce the sce
63     */
64    protected abstract void remainedBelowThreshold(StatsCollectionEvent sce);
65  
66    @Override
67    public void statsCollected(StatsCollectionEvent sce) {
68      String name = sce.getName();
69      if (isSeriesDisabled(name)) {
70        return;
71      }
72      long value = sce.getValue();
73      if (isValueAboveThreshold(sce)) {
74        if (isPreviousValueAboveThreshold(sce)) {
75          remainedAboveThreshold(sce);
76        } else {
77          crossedAboveThreshold(sce);
78        }
79      } else if (isPreviousValueAboveThreshold(sce)) {
80        crossedBelowThreshold(sce);
81      } else {
82        remainedBelowThreshold(sce);
83      }
84      setPreviousValue(name, value);
85    }
86  
87    @Override
88    public void reset() {
89      previousValues.clear();
90      super.reset();
91    }
92  
93    /**
94     * Checks if is previous value above threshold.
95     *
96     * @param sce the sce
97     *
98     * @return true, if is previous value above threshold
99     */
100   protected boolean isPreviousValueAboveThreshold(StatsCollectionEvent sce) {
101     String name = sce.getName();
102     long threshold = getThreshold(name);
103     long previousValue = getPreviousValue(name);
104     return previousValue != DEFAULT_VALUE && previousValue > threshold;
105   }
106 
107   /**
108    * Checks if is value above threshold.
109    *
110    * @param sce the sce
111    *
112    * @return true, if is value above threshold
113    */
114   protected boolean isValueAboveThreshold(StatsCollectionEvent sce) {
115     String name = sce.getName();
116     long value = sce.getValue();
117     long threshold = getThreshold(name);
118     return value > threshold;
119   }
120 
121   /**
122    * Gets the threshold.
123    *
124    * @param name the name
125    *
126    * @return the threshold
127    */
128   protected long getThreshold(String name) {
129     if (isSeriesDisabled(name)) {
130       return DEFAULT_THRESHOLD;
131     }
132     String threshold = getPropertyValue(name, "threshold");
133     if (threshold == null && !isSeriesDisabled(name)) {
134       if (logger.isInfoEnabled()) {
135         logger.info(
136             "Required property '{}' is not defined or inherited.  Disabling listener for '{}' series",
137             getPropertyKey(name, "threshold"), name);
138       }
139       setSeriesDisabled(name, true);
140       return DEFAULT_THRESHOLD;
141     }
142     try {
143       return SizeExpression.parse(threshold);
144     } catch (NumberFormatException ex) {
145       logger.trace("", ex);
146       return DEFAULT_THRESHOLD;
147     }
148   }
149 
150   /**
151    * Gets the previous value.
152    *
153    * @param name the name
154    *
155    * @return the previous value
156    */
157   protected long getPreviousValue(String name) {
158     Long value = previousValues.get(name);
159     return Utils.toLong(value, DEFAULT_VALUE);
160   }
161 
162   /**
163    * Sets the previous value.
164    *
165    * @param name the name
166    * @param previousValue the previous value
167    */
168   protected void setPreviousValue(String name, long previousValue) {
169     Long value = previousValue;
170     previousValues.put(name, value);
171   }
172 
173   /**
174    * Checks if is series disabled.
175    *
176    * @param name the name
177    *
178    * @return true, if is series disabled
179    */
180   protected boolean isSeriesDisabled(String name) {
181     Boolean disabled = seriesDisabled.get(name);
182     if (disabled == null) {
183       disabled = Boolean.FALSE;
184     }
185     return disabled;
186   }
187 
188   /**
189    * Sets the series disabled.
190    *
191    * @param name the name
192    * @param disabled the disabled
193    */
194   protected void setSeriesDisabled(String name, boolean disabled) {
195     seriesDisabled.put(name, disabled);
196   }
197 
198 }