db6209af06f71acdf87f47f224b103446cf7403e
[policy/apex-pdp.git] / model / engine-model / src / main / java / org / onap / policy / apex / model / enginemodel / concepts / AxEngineStats.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.model.enginemodel.concepts;
23
24 import java.text.SimpleDateFormat;
25 import java.util.List;
26
27 import javax.persistence.Column;
28 import javax.persistence.EmbeddedId;
29 import javax.persistence.Entity;
30 import javax.persistence.Table;
31 import javax.persistence.Transient;
32 import javax.xml.bind.annotation.XmlAccessType;
33 import javax.xml.bind.annotation.XmlAccessorType;
34 import javax.xml.bind.annotation.XmlElement;
35 import javax.xml.bind.annotation.XmlRootElement;
36 import javax.xml.bind.annotation.XmlType;
37
38 import lombok.Getter;
39
40 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
41 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
43 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
44 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
45 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
47 import org.onap.policy.common.utils.validation.Assertions;
48
49 /**
50  * This class is a java bean that is used to record statistics on Apex engines as they execute. Statistics on the number
51  * of events, the amount of time taken to execute the last policy, the average policy execution time, the up time of the
52  * engine, and the time stamp of the last engine start are recorded.
53  */
54
55 @Entity
56 @Table(name = "AxEngineStats")
57
58 @XmlAccessorType(XmlAccessType.FIELD)
59 @XmlRootElement(name = "apexEngineStats", namespace = "http://www.onap.org/policy/apex-pdp")
60 @XmlType(name = "AxEngineStats", namespace = "http://www.onap.org/policy/apex-pdp", propOrder = {"key", "timeStamp",
61     "eventCount", "lastExecutionTime", "averageExecutionTime", "upTime", "lastStart"})
62 public class AxEngineStats extends AxConcept {
63     private static final long serialVersionUID = -6981129081962785368L;
64     private static final int HASH_CODE_PRIME = 32;
65
66     @EmbeddedId
67     @XmlElement(name = "key", required = true)
68     private AxReferenceKey key;
69
70     @Column
71     @XmlElement(required = true)
72     private long timeStamp;
73
74     @Column
75     @XmlElement(required = true)
76     private long eventCount;
77
78     @Column
79     @XmlElement(required = true)
80     private long lastExecutionTime;
81
82     @Column
83     @XmlElement(required = true)
84     private double averageExecutionTime;
85
86     @Column
87     @XmlElement(required = true)
88     private long upTime;
89
90     @Transient
91     @Getter
92     private transient long lastEnterTime;
93
94     @Column
95     @XmlElement(required = true)
96     private long lastStart;
97
98     /**
99      * The Default Constructor creates an engine statistics instance with a null key and with all values cleared.
100      */
101     public AxEngineStats() {
102         this(new AxReferenceKey());
103         timeStamp = 0;
104         eventCount = 0;
105         lastExecutionTime = 0;
106         averageExecutionTime = 0;
107         upTime = 0;
108         lastEnterTime = 0;
109         lastStart = 0;
110     }
111
112     /**
113      * Copy constructor.
114      *
115      * @param copyConcept the concept to copy from
116      */
117     public AxEngineStats(final AxEngineStats copyConcept) {
118         super(copyConcept);
119     }
120
121     /**
122      * The Keyed Constructor creates an engine statistics instance with the given key and all values cleared.
123      *
124      * @param key the key
125      */
126     public AxEngineStats(final AxReferenceKey key) {
127         this(key, 0, 0, 0, 0, 0, 0);
128     }
129
130     /**
131      * This Constructor creates an engine statistics instance with all its fields set.
132      *
133      * @param key the engine statistics key
134      * @param timeStamp the time stamp at which the statistics were recorded
135      * @param eventCount the number of events processed by the engine
136      * @param lastExecutionTime the amount of time taken to execute the last policy
137      * @param averageExecutionTime the average amount of time taken to execute a policy
138      * @param upTime the time that has elapsed since the policy engine was started
139      * @param lastStart the time at which the policy engine was last started
140      */
141     public AxEngineStats(final AxReferenceKey key, final long timeStamp, final long eventCount,
142             final long lastExecutionTime, final double averageExecutionTime, final long upTime, final long lastStart) {
143         super();
144         Assertions.argumentNotNull(key, "key may not be null");
145
146         this.key = key;
147         this.timeStamp = timeStamp;
148         this.eventCount = eventCount;
149         this.lastExecutionTime = lastExecutionTime;
150         this.averageExecutionTime = averageExecutionTime;
151         this.upTime = upTime;
152         this.lastStart = lastStart;
153     }
154
155     /**
156      * {@inheritDoc}.
157      */
158     @Override
159     public AxReferenceKey getKey() {
160         return key;
161     }
162
163     /**
164      * {@inheritDoc}.
165      */
166     @Override
167     public List<AxKey> getKeys() {
168         return key.getKeys();
169     }
170
171     /**
172      * Sets the engine statistics key.
173      *
174      * @param key the engine statistics key
175      */
176     public void setKey(final AxReferenceKey key) {
177         Assertions.argumentNotNull(key, "key may not be null");
178         this.key = key;
179     }
180
181     /**
182      * Gets the time stamp at which the statistics were recorded.
183      *
184      * @return the time stamp at which the statistics were recorded
185      */
186     public long getTimeStamp() {
187         return timeStamp;
188     }
189
190     /**
191      * Gets the time stamp at which the statistics were recorded as a string.
192      *
193      * @return the time stamp at which the statistics were recorded as a string
194      */
195     public String getTimeStampString() {
196         return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timeStamp);
197     }
198
199     /**
200      * Sets the time stamp at which the statistics were recorded.
201      *
202      * @param timeStamp the time stamp at which the statistics were recorded
203      */
204     public void setTimeStamp(final long timeStamp) {
205         this.timeStamp = timeStamp;
206     }
207
208     /**
209      * Gets the number of events processed by the engine.
210      *
211      * @return the number of events processed by the engine
212      */
213     public long getEventCount() {
214         return eventCount;
215     }
216
217     /**
218      * Sets the number of events processed by the engine.
219      *
220      * @param eventCount the number of events processed by the engine
221      */
222     public void setEventCount(final long eventCount) {
223         this.eventCount = eventCount;
224     }
225
226     /**
227      * Gets the amount of time taken to execute the last policy.
228      *
229      * @return the amount of time taken to execute the last policy
230      */
231     public long getLastExecutionTime() {
232         return lastExecutionTime;
233     }
234
235     /**
236      * Sets the amount of time taken to execute the last policy.
237      *
238      * @param lastExecutionTime the amount of time taken to execute the last policy
239      */
240     public void setLastExecutionTime(final long lastExecutionTime) {
241         this.lastExecutionTime = lastExecutionTime;
242     }
243
244     /**
245      * Gets the average amount of time taken to execute a policy.
246      *
247      * @return the average amount of time taken to execute a policy
248      */
249     public double getAverageExecutionTime() {
250         return averageExecutionTime;
251     }
252
253     /**
254      * Sets the average amount of time taken to execute a policy.
255      *
256      * @param averageExecutionTime the average amount of time taken to execute a policy
257      */
258     public void setAverageExecutionTime(final double averageExecutionTime) {
259         this.averageExecutionTime = averageExecutionTime;
260     }
261
262     /**
263      * Gets the time that has elapsed since the policy engine was started.
264      *
265      * @return the time that has elapsed since the policy engine was started
266      */
267     public long getUpTime() {
268         if (this.getLastStart() != 0) {
269             return upTime + (timeStamp - this.getLastStart());
270         }
271         return upTime;
272     }
273
274     /**
275      * Sets the time that has elapsed since the policy engine was started.
276      *
277      * @param upTime the time that has elapsed since the policy engine was started
278      */
279     public void setUpTime(final long upTime) {
280         this.upTime = upTime;
281     }
282
283     /**
284      * Sets the time at which the policy engine was last started.
285      *
286      * @param lastStart the time at which the policy engine was last started
287      */
288     private void setLastStart(final long lastStart) {
289         this.lastStart = lastStart;
290     }
291
292     /**
293      * Gets the time at which the policy engine was last started.
294      *
295      * @return the time at which the policy engine was last started
296      */
297     public long getLastStart() {
298         return lastStart;
299     }
300
301     /**
302      * Resets all the statistic values to zero.
303      */
304     public synchronized void reset() {
305         timeStamp = 0;
306         eventCount = 0;
307         lastExecutionTime = 0;
308         averageExecutionTime = 0;
309         upTime = 0;
310         lastEnterTime = 0;
311         lastStart = 0;
312     }
313
314     /**
315      * Updates the statistics when called, used by the Apex engine when it starts executing a policy.
316      *
317      * @param eventkey the key of the event that is being executed
318      */
319     public synchronized void executionEnter(final AxArtifactKey eventkey) {
320         final long now = System.currentTimeMillis();
321         eventCount++;
322         if (eventCount < 0) {
323             eventCount = 2;
324         }
325         lastEnterTime = now;
326         timeStamp = now;
327     }
328
329     /**
330      * Updates the statistics when called, used by the Apex engine when it completes executing a policy.
331      */
332     public synchronized void executionExit() {
333         final long now = System.currentTimeMillis();
334         lastExecutionTime = now - lastEnterTime;
335
336         averageExecutionTime = ((averageExecutionTime * (eventCount - 1.0)) + lastExecutionTime) / eventCount;
337         lastEnterTime = 0;
338         timeStamp = System.currentTimeMillis();
339     }
340
341     /**
342      * Updates the statistics when called, used by the Apex engine when it is started.
343      */
344     public synchronized void engineStart() {
345         final long now = System.currentTimeMillis();
346         timeStamp = now;
347         this.setLastStart(now);
348     }
349
350     /**
351      * Updates the statistics when called, used by the Apex engine when it is stopped.
352      */
353     public synchronized void engineStop() {
354         final long now = System.currentTimeMillis();
355         timeStamp = now;
356         upTime += (timeStamp - this.getLastStart());
357         this.setLastStart(0);
358     }
359
360     /**
361      * {@inheritDoc}.
362      */
363     @Override
364     public AxValidationResult validate(final AxValidationResult result) {
365         if (key.equals(AxReferenceKey.getNullKey())) {
366             result.addValidationMessage(
367                     new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
368         }
369
370         return key.validate(result);
371     }
372
373     /**
374      * {@inheritDoc}.
375      */
376     @Override
377     public void clean() {
378         key.clean();
379     }
380
381     /**
382      * {@inheritDoc}.
383      */
384     @Override
385     public String toString() {
386         final StringBuilder builder = new StringBuilder();
387         builder.append(this.getClass().getSimpleName());
388         builder.append(":(");
389         builder.append("engineKey=");
390         builder.append(key);
391         builder.append(",timeStamp=");
392         builder.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timeStamp));
393         builder.append(",eventCount=");
394         builder.append(eventCount);
395         builder.append(",lastExecutionTime=");
396         builder.append(lastExecutionTime);
397         builder.append(",averageExecutionTime=");
398         builder.append(averageExecutionTime);
399         builder.append(",upTime=");
400         builder.append(getUpTime());
401         builder.append(")");
402         return builder.toString();
403     }
404
405     /**
406      * {@inheritDoc}.
407      */
408     @Override
409     public AxConcept copyTo(final AxConcept targetObject) {
410         Assertions.argumentNotNull(targetObject, "target may not be null");
411
412         final Object copyObject = targetObject;
413         Assertions.instanceOf(copyObject, AxEngineStats.class);
414
415         final AxEngineStats copy = ((AxEngineStats) copyObject);
416         copy.setKey(new AxReferenceKey(key));
417         copy.setTimeStamp(timeStamp);
418         copy.setEventCount(eventCount);
419         copy.setLastExecutionTime(lastExecutionTime);
420         copy.setAverageExecutionTime(averageExecutionTime);
421         copy.setUpTime(upTime);
422         copy.setLastStart(lastStart);
423
424         return copy;
425     }
426
427     /**
428      * {@inheritDoc}.
429      */
430     @Override
431     public int hashCode() {
432         final int prime = 31;
433         int result = 1;
434         result = prime * result + key.hashCode();
435         result = prime * result + (int) (timeStamp ^ (timeStamp >>> HASH_CODE_PRIME));
436         result = prime * result + (int) (eventCount ^ (eventCount >>> HASH_CODE_PRIME));
437         result = prime * result + (int) (lastExecutionTime ^ (lastExecutionTime >>> HASH_CODE_PRIME));
438         result = prime * result + ((int) averageExecutionTime ^ ((int) averageExecutionTime >>> HASH_CODE_PRIME));
439         result = prime * result + (int) (upTime ^ (upTime >>> HASH_CODE_PRIME));
440         result = prime * result + (int) (getLastStart() ^ (getLastStart() >>> HASH_CODE_PRIME));
441         return result;
442     }
443
444     /**
445      * {@inheritDoc}.
446      */
447     @Override
448     public boolean equals(final Object obj) {
449         if (obj == null) {
450             return false;
451         }
452         if (this == obj) {
453             return true;
454         }
455
456         if (getClass() != obj.getClass()) {
457             return false;
458         }
459
460         final AxEngineStats other = (AxEngineStats) obj;
461         if (!key.equals(other.key)) {
462             return false;
463         }
464         if (timeStamp != other.timeStamp) {
465             return false;
466         }
467         if (eventCount != other.eventCount) {
468             return false;
469         }
470         if (lastExecutionTime != other.lastExecutionTime) {
471             return false;
472         }
473         if (Double.compare(averageExecutionTime, other.averageExecutionTime) != 0) {
474             return false;
475         }
476         if (upTime != other.upTime) {
477             return false;
478         }
479         return getLastStart() == other.getLastStart();
480     }
481
482     /**
483      * {@inheritDoc}.
484      */
485     @Override
486     public int compareTo(final AxConcept otherObj) {
487         if (otherObj == null) {
488             return -1;
489         }
490         if (this == otherObj) {
491             return 0;
492         }
493         if (getClass() != otherObj.getClass()) {
494             return this.hashCode() - otherObj.hashCode();
495         }
496
497         final AxEngineStats other = (AxEngineStats) otherObj;
498         if (!key.equals(other.key)) {
499             return key.compareTo(other.key);
500         }
501         if (timeStamp != other.timeStamp) {
502             return (int) (timeStamp - other.timeStamp);
503         }
504         if (eventCount != other.eventCount) {
505             return (int) (eventCount - other.eventCount);
506         }
507         if (lastExecutionTime != other.lastExecutionTime) {
508             return (int) (lastExecutionTime - other.lastExecutionTime);
509         }
510         final int result = Double.compare(averageExecutionTime, other.averageExecutionTime);
511         if (result != 0) {
512             return result;
513         }
514         if (upTime != other.upTime) {
515             return (int) (upTime - other.upTime);
516         }
517
518         return Long.compare(lastStart, other.lastStart);
519     }
520 }