diff options
author | ARULNA <arul.nambi@amdocs.com> | 2017-06-12 16:41:12 -0400 |
---|---|---|
committer | ARULNA <arul.nambi@amdocs.com> | 2017-06-12 16:41:28 -0400 |
commit | b4922d319d293894fddd512d29b5f0d1411915d9 (patch) | |
tree | 36cec7575f1631aad41d7b1131d6352847ea0de2 /src/main/java/org/openecomp/sparky/analytics | |
parent | 19dacd2ba38e345eeb5fcfbfe37d615602e8ea44 (diff) |
Initial commit for AAI-UI(sparky-backend)
Change-Id: I785397ed4197663cdf0c1351041d2f708ed08763
Signed-off-by: ARULNA <arul.nambi@amdocs.com>
Diffstat (limited to 'src/main/java/org/openecomp/sparky/analytics')
5 files changed, 825 insertions, 0 deletions
diff --git a/src/main/java/org/openecomp/sparky/analytics/AbstractStatistics.java b/src/main/java/org/openecomp/sparky/analytics/AbstractStatistics.java new file mode 100644 index 0000000..e599165 --- /dev/null +++ b/src/main/java/org/openecomp/sparky/analytics/AbstractStatistics.java @@ -0,0 +1,180 @@ +/** + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed 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. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +package org.openecomp.sparky.analytics; + +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * The Class AbstractStatistics. + */ +public class AbstractStatistics implements ComponentStatistics { + + private HashMap<String, AtomicInteger> namedCounters; + private HashMap<String, HistogramSampler> namedHistograms; + + /** + * Instantiates a new abstract statistics. + */ + protected AbstractStatistics() { + namedCounters = new HashMap<String, AtomicInteger>(); + namedHistograms = new HashMap<String, HistogramSampler>(); + } + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#addCounter(java.lang.String) + */ + /* + * sync-lock the creation of counters during initialization, but run time should not use lock + * synchronization, only thread safe types + * + * @see com.att.ecomp.uicommon.resolver.stat.ComponentStatistics#addCounter(java.lang.String) + */ + @Override + public synchronized void addCounter(String key) { + + AtomicInteger counter = namedCounters.get(key); + + if (counter == null) { + counter = new AtomicInteger(0); + namedCounters.put(key, counter); + } + + } + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#pegCounter(java.lang.String) + */ + @Override + public void pegCounter(String key) { + + AtomicInteger counter = namedCounters.get(key); + + if (counter != null) { + counter.incrementAndGet(); + } + + } + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#incrementCounter(java.lang.String, int) + */ + @Override + public void incrementCounter(String key, int value) { + + AtomicInteger counter = namedCounters.get(key); + + if (counter != null) { + counter.addAndGet(value); + } + + } + + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#addHistogram(java.lang.String, java.lang.String, long, int, int) + */ + @Override + public synchronized void addHistogram(String key, String histName, long maxYValue, int numBins, + int numDecimalPoints) { + HistogramSampler histSampler = namedHistograms.get(key); + + if (histSampler == null) { + histSampler = new HistogramSampler(histName, maxYValue, numBins, numDecimalPoints); + namedHistograms.put(key, histSampler); + } + + } + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#updateHistogram(java.lang.String, long) + */ + @Override + public void updateHistogram(String key, long value) { + HistogramSampler histSampler = namedHistograms.get(key); + + if (histSampler != null) { + histSampler.track(value); + } + } + + /* (non-Javadoc) + * @see org.openecomp.sparky.analytics.ComponentStatistics#reset() + */ + @Override + public void reset() { + + for (HistogramSampler h : namedHistograms.values()) { + h.clear(); + } + + for (AtomicInteger c : namedCounters.values()) { + c.set(0); + } + + } + + /** + * Gets the counter value. + * + * @param key the key + * @return the counter value + */ + protected int getCounterValue(String key) { + + AtomicInteger counter = namedCounters.get(key); + + if (counter == null) { + return -1; + } + + return counter.get(); + + } + + /** + * Gets the histogram stats. + * + * @param key the key + * @param verboseEnabled the verbose enabled + * @param indentPadding the indent padding + * @return the histogram stats + */ + protected String getHistogramStats(String key, boolean verboseEnabled, String indentPadding) { + + HistogramSampler histSampler = namedHistograms.get(key); + + if (histSampler == null) { + return null; + } + + return histSampler.getStats(verboseEnabled, indentPadding); + + } + + + +} diff --git a/src/main/java/org/openecomp/sparky/analytics/AveragingRingBuffer.java b/src/main/java/org/openecomp/sparky/analytics/AveragingRingBuffer.java new file mode 100644 index 0000000..18f5dcf --- /dev/null +++ b/src/main/java/org/openecomp/sparky/analytics/AveragingRingBuffer.java @@ -0,0 +1,122 @@ +/** + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed 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. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +package org.openecomp.sparky.analytics; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * TODO: Fill in description. + * + * @author davea + */ +public class AveragingRingBuffer { + + private int numElements; + + private long[] data; + + private AtomicInteger index; + + private long average; + + private boolean initialAverageCalculated; + + /** + * Instantiates a new averaging ring buffer. + * + * @param size the size + */ + public AveragingRingBuffer(int size) { + + if (size == 0) { + throw new IllegalArgumentException("Size must be greater than zero"); + } + + this.initialAverageCalculated = false; + this.numElements = size; + this.data = new long[this.numElements]; + this.index = new AtomicInteger(-1); + } + + /** + * Calculate average. + * + * @param maxArrayIndex the max array index + */ + private void calculateAverage(int maxArrayIndex) { + + long sum = 0; + + for (int i = 0; i <= maxArrayIndex; i++) { + sum += data[i]; + } + + average = (sum / (maxArrayIndex + 1)); + + } + + public long getAvg() { + + if (!initialAverageCalculated) { + /* + * until the index rolls once we will calculate the average from the data that has been added + * to the array, not including the zero elements + */ + if (index.get() < 0) { + calculateAverage(0); + } else { + calculateAverage(index.get()); + } + + } + + return average; + } + + /** + * Adds the sample. + * + * @param value the value + */ + public synchronized void addSample(long value) { + + index.incrementAndGet(); + + data[index.get()] = value; + + if (index.get() == (numElements - 1)) { + calculateAverage(numElements - 1); + + if (!initialAverageCalculated) { + initialAverageCalculated = true; + } + + index.set(-1); + } + + } + +} diff --git a/src/main/java/org/openecomp/sparky/analytics/ComponentStatistics.java b/src/main/java/org/openecomp/sparky/analytics/ComponentStatistics.java new file mode 100644 index 0000000..285661f --- /dev/null +++ b/src/main/java/org/openecomp/sparky/analytics/ComponentStatistics.java @@ -0,0 +1,81 @@ +/** + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed 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. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +package org.openecomp.sparky.analytics; + + +/** + * The Interface ComponentStatistics. + */ +public interface ComponentStatistics { + + /** + * Adds the counter. + * + * @param key the key + */ + public void addCounter(String key); + + /** + * Peg counter. + * + * @param key the key + */ + public void pegCounter(String key); + + /** + * Increment counter. + * + * @param key the key + * @param value the value + */ + public void incrementCounter(String key, int value); + + /** + * Adds the histogram. + * + * @param key the key + * @param name the name + * @param maxYValue the max Y value + * @param numBins the num bins + * @param numDecimalPoints the num decimal points + */ + public void addHistogram(String key, String name, long maxYValue, int numBins, + int numDecimalPoints); + + /** + * Update histogram. + * + * @param key the key + * @param value the value + */ + public void updateHistogram(String key, long value); + + /** + * Reset. + */ + public void reset(); + +} diff --git a/src/main/java/org/openecomp/sparky/analytics/HistogramSampler.java b/src/main/java/org/openecomp/sparky/analytics/HistogramSampler.java new file mode 100644 index 0000000..7f87bea --- /dev/null +++ b/src/main/java/org/openecomp/sparky/analytics/HistogramSampler.java @@ -0,0 +1,287 @@ +/** + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed 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. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +package org.openecomp.sparky.analytics; + +/** + * A class that models a histogram for reporting and tracking long values with variable steps, bins, + * and floating point accuracy. + * + * @author davea. + */ +public final class HistogramSampler { + + private String label; + + private long binMaxValue; + + private int numBins; + + private double stepSize; + + private long sampleValueTotal; + + private long minValue = -1; + + private long maxValue = 0; + + private long numSamples = 0; + + private long decimalPointAccuracy = 0; + + private static String FORMAT_FLOAT_TEMPLATE = "%%.%df"; + + private String floatFormatStr; + + private long[] histogramBins; + + /** + * Instantiates a new histogram sampler. + * + * @param label the label + * @param maxValue the max value + * @param numBins the num bins + * @param decimalPointAccuracy the decimal point accuracy + */ + public HistogramSampler(String label, long maxValue, int numBins, int decimalPointAccuracy) { + this.label = label; + this.binMaxValue = maxValue; + this.numBins = numBins; + this.stepSize = ((double) binMaxValue / (double) numBins); + this.decimalPointAccuracy = decimalPointAccuracy; + this.floatFormatStr = String.format(FORMAT_FLOAT_TEMPLATE, this.decimalPointAccuracy); + + /* + * [numBins + 1] => last bin is catch-all for outliers + */ + + initializeHistogramBins(numBins + 1); + + } + + /** + * Initialize histogram bins. + * + * @param numBins the num bins + */ + private void initializeHistogramBins(int numBins) { + + histogramBins = new long[numBins]; + int counter = 0; + while (counter < numBins) { + histogramBins[counter] = 0; + counter++; + } + + } + + /* + * Is it really necessary to synchronize the collection, or should we simply switch the underlying + * data type to an AtomicLong + */ + + /** + * Track. + * + * @param value the value + */ + public synchronized void track(long value) { + + if (value < 0) { + return; + } + + sampleValueTotal += value; + numSamples++; + + if (minValue == -1) { + minValue = value; + } + + if (value < minValue) { + minValue = value; + } + + if (value > maxValue) { + maxValue = value; + } + + /* + * One step bin determination + */ + + if (value < (numBins * stepSize)) { + + int index = (int) (value / stepSize); + histogramBins[index]++; + + } else { + // peg the metric in the outlier bin + histogramBins[numBins - 1]++; + } + + } + + /** + * Clear. + */ + public void clear() { + + int counter = 0; + while (counter < numBins) { + histogramBins[counter] = 0; + counter++; + } + + minValue = -1; + maxValue = 0; + numSamples = 0; + sampleValueTotal = 0; + + } + + /** + * Re initialize bins. + * + * @param label the label + * @param numBins the num bins + * @param maxValue the max value + * @param decimalPointAccuracy the decimal point accuracy + */ + public void reInitializeBins(String label, int numBins, long maxValue, int decimalPointAccuracy) { + this.label = label; + this.decimalPointAccuracy = decimalPointAccuracy; + this.floatFormatStr = String.format(FORMAT_FLOAT_TEMPLATE, this.decimalPointAccuracy); + this.numBins = numBins; + this.minValue = -1; + this.maxValue = 0; + initializeHistogramBins(numBins); + this.stepSize = (maxValue / numBins); + clear(); + } + + public long getNumberOfSamples() { + return numSamples; + } + + public long getTotalValueSum() { + return sampleValueTotal; + } + + /** + * Gets the stats. + * + * @param formatted the formatted + * @param indentPadding the indent padding + * @return the stats + */ + public String getStats(boolean formatted, String indentPadding) { + + StringBuilder sb = new StringBuilder(128); + + + if (!formatted) { + // generate CSV in the following format + + /* + * label,minValue,maxValue,avgValue,numSamples,stepSize,numSteps,stepCounters + */ + sb.append(indentPadding); + sb.append(label).append(","); + sb.append(minValue).append(","); + sb.append(maxValue).append(","); + if (numSamples == 0) { + sb.append(0).append(","); + } else { + sb.append((sampleValueTotal / numSamples)).append(","); + } + sb.append(numSamples).append(","); + sb.append(numBins).append(","); + sb.append(String.format(floatFormatStr, stepSize)); + + int counter = 0; + while (counter < numBins) { + + if (counter != (numBins)) { + sb.append(","); + } + + sb.append(histogramBins[counter]); + + counter++; + + } + + return sb.toString(); + + } + + sb.append("\n"); + sb.append(indentPadding).append("Label = ").append(label).append("\n"); + sb.append(indentPadding).append("Min = ").append(minValue).append("\n"); + sb.append(indentPadding).append("Max = ").append(maxValue).append("\n"); + sb.append(indentPadding).append("numSamples = ").append(numSamples).append("\n"); + + if (numSamples == 0) { + sb.append(indentPadding).append("Avg = ").append(0).append("\n"); + } else { + sb.append(indentPadding).append("Avg = ").append((sampleValueTotal / numSamples)) + .append("\n"); + } + + sb.append(indentPadding).append("StepSize = ").append(String.format(floatFormatStr, stepSize)) + .append("\n"); + + sb.append(indentPadding).append("Sample Histogram:").append("\n"); + + int counter = 0; + while (counter < numBins) { + + if (counter == (numBins - 1)) { + // outlier bin + double leftBound = (stepSize * counter); + sb.append(indentPadding).append("\t") + .append(" x >= " + String.format(floatFormatStr, leftBound) + " : " + + histogramBins[counter]) + .append("\n"); + + } else { + double leftBound = (stepSize * counter); + double rightBound = ((stepSize) * (counter + 1)); + sb.append(indentPadding).append("\t") + .append((String.format(floatFormatStr, leftBound) + " < x < " + + String.format(floatFormatStr, rightBound) + " : " + histogramBins[counter])) + .append("\n"); + } + + counter++; + + } + + return sb.toString(); + + } + +} diff --git a/src/main/java/org/openecomp/sparky/analytics/HistoricalCounter.java b/src/main/java/org/openecomp/sparky/analytics/HistoricalCounter.java new file mode 100644 index 0000000..f8c5f05 --- /dev/null +++ b/src/main/java/org/openecomp/sparky/analytics/HistoricalCounter.java @@ -0,0 +1,155 @@ +/** + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed 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. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + + +package org.openecomp.sparky.analytics; + +/** + * A simple class to model a historical counter. A set of values will be tracked and basic + * statistics will be calculated in real time (n, min, max, avg). + * + * @author davea + */ +public class HistoricalCounter { + + private double min; + + private double max; + + private double totalOfSamples; + + private long numSamples; + + private double value; + + private boolean maintainSingleValue; + + /** + * Instantiates a new historical counter. + * + * @param trackSingleValue the track single value + */ + public HistoricalCounter(boolean trackSingleValue) { + min = -1; + max = 0; + totalOfSamples = 0; + value = 0.0; + numSamples = 0; + this.maintainSingleValue = trackSingleValue; + } + + public boolean isSingleValue() { + return maintainSingleValue; + } + + /** + * Update. + * + * @param value the value + */ + public synchronized void update(double value) { + + if (value < 0) { + return; + } + + if (maintainSingleValue) { + + this.value = value; + + } else { + + if (min == -1) { + min = value; + } + + if (value < min) { + min = value; + } + + if (value > max) { + max = value; + } + + totalOfSamples += value; + numSamples++; + } + } + + public double getValue() { + return value; + } + + public double getMin() { + return min; + } + + public double getMax() { + return max; + } + + public long getNumSamples() { + return numSamples; + } + + public double getAvg() { + if (numSamples == 0) { + return 0; + } + + return (totalOfSamples / numSamples); + } + + /** + * Reset. + */ + public synchronized void reset() { + min = -1; + max = 0; + numSamples = 0; + totalOfSamples = 0; + value = 0.0; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(32); + + if (maintainSingleValue) { + sb.append("[ Val=").append(value).append(" ]"); + } else { + sb.append("[ NumSamples=").append(numSamples).append(","); + sb.append(" Min=").append(min).append(","); + sb.append(" Max=").append(max).append(","); + sb.append(" Avg=").append(getAvg()).append(" ]"); + } + + return sb.toString(); + } + +} |