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       logger.info(
135           "Required property '{}' is not defined or inherited.  Disabling listener for '{}' series",
136           getPropertyKey(name, "threshold"), name);
137       setSeriesDisabled(name, true);
138       return DEFAULT_THRESHOLD;
139     }
140     try {
141       return SizeExpression.parse(threshold);
142     } catch (NumberFormatException ex) {
143       logger.trace("", ex);
144       return DEFAULT_THRESHOLD;
145     }
146   }
147 
148   /**
149    * Gets the previous value.
150    *
151    * @param name the name
152    *
153    * @return the previous value
154    */
155   protected long getPreviousValue(String name) {
156     Long value = previousValues.get(name);
157     return Utils.toLong(value, DEFAULT_VALUE);
158   }
159 
160   /**
161    * Sets the previous value.
162    *
163    * @param name the name
164    * @param previousValue the previous value
165    */
166   protected void setPreviousValue(String name, long previousValue) {
167     Long value = previousValue;
168     previousValues.put(name, value);
169   }
170 
171   /**
172    * Checks if is series disabled.
173    *
174    * @param name the name
175    *
176    * @return true, if is series disabled
177    */
178   protected boolean isSeriesDisabled(String name) {
179     Boolean disabled = seriesDisabled.get(name);
180     if (disabled == null) {
181       disabled = Boolean.FALSE;
182     }
183     return disabled;
184   }
185 
186   /**
187    * Sets the series disabled.
188    *
189    * @param name the name
190    * @param disabled the disabled
191    */
192   protected void setSeriesDisabled(String name, boolean disabled) {
193     seriesDisabled.put(name, disabled);
194   }
195 
196 }