Issue #1317 - Update the stats config files

Issue #1317 - Peer review comments.

Change-Id: Ic4fa6574a0d71fbdf246483f0ea2553d4d058c9f

Former-commit-id: 1372c08cdc [formerly 1372c08cdc [formerly 8cc9210d25324ab4b5cbd5af3687b371101d282b]]
Former-commit-id: 50f0c4c226
Former-commit-id: 688b7cce30
This commit is contained in:
Mike Duff 2012-11-07 12:48:25 -06:00
parent 1b19c0f3c0
commit a4574d22b1
9 changed files with 569 additions and 147 deletions

View file

@ -5,7 +5,8 @@ Bundle-SymbolicName: com.raytheon.uf.common.stats
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: com.raytheon.uf.common.stats
Export-Package: com.raytheon.uf.common.stats,
com.raytheon.uf.common.stats.xml
Require-Bundle: com.raytheon.uf.common.time;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",

View file

@ -0,0 +1,88 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.stats.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Statistics configuration aggregate element.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 6, 2012 728 mpduff Initial creation.
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@DynamicSerialize
@XmlRootElement(name = "statisticsAggregate")
@XmlAccessorType(XmlAccessType.NONE)
public class StatisticsAggregate {
/** the field to perform the function on. */
@XmlAttribute
@DynamicSerializeElement
private String field;
@XmlAttribute
@DynamicSerializeElement
private String displayName;
/**
* @return the field
*/
public String getField() {
return field;
}
/**
* @param field
* the field to set
*/
public void setField(String field) {
this.field = field;
}
/**
* @return the displayName
*/
public String getDisplayName() {
return displayName;
}
/**
* @param displayName
* the displayName to set
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}

View file

@ -0,0 +1,89 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.stats.xml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Statistical Configuration File.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 6, 2012 728 mpduff Initial creation.
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@DynamicSerialize
@XmlRootElement(name = "statisticsConfig")
@XmlAccessorType(XmlAccessType.NONE)
public class StatisticsConfig implements ISerializableObject {
@XmlElements({ @XmlElement(name = "statisticsEvent", type = StatisticsEvent.class) })
@DynamicSerializeElement
private List<StatisticsEvent> events;
/**
* @return the events
*/
public List<StatisticsEvent> getEvents() {
return events;
}
/**
* @param events
* the events to set
*/
public void setEvents(List<StatisticsEvent> events) {
this.events = events;
}
/**
* Return the list of categories in this config file.
*
* @return List<String> of categories
*/
public List<String> getCategories() {
List<String> categories = new ArrayList<String>();
if (events != null && events.size() > 0) {
for (StatisticsEvent event : events) {
categories.add(event.getCategory());
}
}
return categories;
}
}

View file

@ -0,0 +1,144 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.stats.xml;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Statistics Configuration Event xml element.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 6, 2012 728 mpduff Initial creation.
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@DynamicSerialize
@XmlRootElement(name = "event")
@XmlAccessorType(XmlAccessType.NONE)
public class StatisticsEvent {
@XmlAttribute
@DynamicSerializeElement
private String type;
@XmlAttribute
@DynamicSerializeElement
private String displayName;
@XmlAttribute
@DynamicSerializeElement
private String category;
@XmlElements({ @XmlElement(name = "statisticsGroup", type = StatisticsGroup.class) })
@DynamicSerializeElement
private List<StatisticsGroup> groupList;
@XmlElements({ @XmlElement(name = "statisticsAggregate", type = StatisticsAggregate.class) })
@DynamicSerializeElement
private List<StatisticsAggregate> aggregateList;
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the displayName
*/
public String getDisplayName() {
return displayName;
}
/**
* @param displayName the displayName to set
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* @return the groupList
*/
public List<StatisticsGroup> getGroupList() {
return groupList;
}
/**
* @param groupList the groupList to set
*/
public void setGroupList(List<StatisticsGroup> groupList) {
this.groupList = groupList;
}
/**
* @return the aggregateList
*/
public List<StatisticsAggregate> getAggregateList() {
return aggregateList;
}
/**
* @param aggregateList the aggregateList to set
*/
public void setAggregateList(List<StatisticsAggregate> aggregateList) {
this.aggregateList = aggregateList;
}
/**
* @return the category
*/
public String getCategory() {
return category;
}
/**
* @param category the category to set
*/
public void setCategory(String category) {
this.category = category;
}
}

View file

@ -0,0 +1,87 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.stats.xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Statistics configuration groupBy element.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 6, 2012 728 mpduff Initial creation.
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@DynamicSerialize
@XmlRootElement(name = "statisticsGroup")
@XmlAccessorType(XmlAccessType.NONE)
public class StatisticsGroup {
@XmlAttribute
@DynamicSerializeElement
private String name;
@XmlAttribute
@DynamicSerializeElement
private String displayName;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the displayName
*/
public String getDisplayName() {
return displayName;
}
/**
* @param displayName
* the displayName to set
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}

View file

@ -1,19 +1,19 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
@ -34,6 +34,10 @@ import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.stats.AggregateRecord;
import com.raytheon.uf.common.stats.StatsRecord;
import com.raytheon.uf.common.stats.xml.StatisticsAggregate;
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
import com.raytheon.uf.common.stats.xml.StatisticsGroup;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.TimeRange;
@ -42,30 +46,28 @@ import com.raytheon.uf.edex.database.dao.DaoConfig;
import com.raytheon.uf.edex.stats.dao.StatsDao;
import com.raytheon.uf.edex.stats.handler.StatsHandler;
import com.raytheon.uf.edex.stats.util.ConfigLoader;
import com.raytheon.uf.edex.stats.xml.Aggregate;
import com.raytheon.uf.edex.stats.xml.Item;
import com.raytheon.uf.edex.stats.xml.StatsConfig;
/**
* Aggregates stat records based on the statsConfig files and stores them after
* a configured period.
*
*
* *
*
*
* <pre>
*
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 21, 2012 jsanchez Stored the aggregate buckets in the db.
*
* Aug 21, 2012 jsanchez Stored the aggregate buckets in the db.
* Nov 07, 2012 1317 mpduff Updated Configuration Files.
*
* </pre>
*
*
* @author jsanchez
*
*
*/
public class AggregateManager {
private static final transient IUFStatusHandler statusHandler = UFStatus
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(AggregateManager.class);
private class TimeRangeKey extends TimeRange {
@ -90,6 +92,7 @@ public class AggregateManager {
return 1;
}
@Override
public String toString() {
return super.toString();
}
@ -108,9 +111,9 @@ public class AggregateManager {
private static final int defaultScanInterval = 15;
/** loads localized copies of the statsConfig */
private ConfigLoader configLoader;
private final ConfigLoader configLoader;
private CoreDao aggregateRecordDao = new CoreDao(DaoConfig.forClass(
private final CoreDao aggregateRecordDao = new CoreDao(DaoConfig.forClass(
"metadata", AggregateRecord.class));
public AggregateManager(String bucketInterval, String scanInterval)
@ -124,7 +127,7 @@ public class AggregateManager {
/**
* Tests if the bucket interval and the scan interval are valid values. If
* values are invalid then values will be set to default values.
*
*
* @param bucketInt
* @param scanInt
* @return
@ -183,27 +186,32 @@ public class AggregateManager {
retrieveStatRecords(statsRecordDao, aggregateBuckets);
// loops through map to aggregate buckets
for (StatsConfig statsConfig : configLoader.getConfigurations()) {
String eventType = statsConfig.getEventType();
for (StatisticsConfig statsConfig : configLoader.getConfigurations()) {
for (StatisticsEvent event : statsConfig.getEvents()) {
String eventType = event.getType();
Map<TimeRangeKey, List<StatsRecord>> map = aggregateBuckets
.get(eventType);
// map should never be null, since it will be set in the 'sort'
// method.
for (Iterator<Map.Entry<TimeRangeKey, List<StatsRecord>>> iter = map.entrySet().iterator(); iter.hasNext(); ) {
Entry<TimeRangeKey, List<StatsRecord>> element = iter.next();
TimeRangeKey tr = element.getKey();
List<StatsRecord> records = element.getValue();
if (!records.isEmpty()) {
List<Event> data = extractEvents(records);
aggregate(statsConfig, tr, data);
try {
statsRecordDao.deleteAll(records);
} catch (Exception e) {
statusHandler.error("Error deleting stat records", e);
Map<TimeRangeKey, List<StatsRecord>> map = aggregateBuckets
.get(eventType);
// map should never be null, since it will be set in the 'sort'
// method.
for (Iterator<Map.Entry<TimeRangeKey, List<StatsRecord>>> iter = map
.entrySet().iterator(); iter.hasNext();) {
Entry<TimeRangeKey, List<StatsRecord>> element = iter
.next();
TimeRangeKey tr = element.getKey();
List<StatsRecord> records = element.getValue();
if (!records.isEmpty()) {
List<Event> data = extractEvents(records);
aggregate(event, tr, data);
try {
statsRecordDao.deleteAll(records);
} catch (Exception e) {
statusHandler.error("Error deleting stat records",
e);
}
}
iter.remove();
}
iter.remove();
}
}
}
@ -216,20 +224,22 @@ public class AggregateManager {
Map<String, Map<TimeRangeKey, List<StatsRecord>>> aggregateBuckets)
throws Exception {
Calendar current = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
for (StatsConfig statsConfig : configLoader.getConfigurations()) {
String eventType = statsConfig.getEventType();
// Does not retrieve stat records of current bucket.
// this method should always return a valid array.
StatsRecord[] records = statsRecordDao.retrieveRecords(
getBucketStartTime(current), eventType);
sort(eventType, records, aggregateBuckets);
for (StatisticsConfig statsConfig : configLoader.getConfigurations()) {
for (StatisticsEvent event : statsConfig.getEvents()) {
String eventType = event.getType();
// Does not retrieve stat records of current bucket.
// this method should always return a valid array.
StatsRecord[] records = statsRecordDao.retrieveRecords(
getBucketStartTime(current), eventType);
sort(eventType, records, aggregateBuckets);
}
}
}
/**
* Stores the results into proper aggregate buckets. This method assumes
* that the records are in date order.
*
*
* @param events
*/
private void sort(String eventType, StatsRecord[] records,
@ -263,7 +273,7 @@ public class AggregateManager {
* Creates a time range from a date and the bucket interval. The time range
* start time that will be the date rounded to the next bucket interval. The
* time range end time will be the start time plus the bucket interval.
*
*
* @param date
* @return
*/
@ -281,7 +291,7 @@ public class AggregateManager {
/**
* Calculates the start time that will be the date rounded to the next
* bucket interval
*
*
* @param date
* @return
*/
@ -307,7 +317,7 @@ public class AggregateManager {
/**
* Extracts the events from the stats records.
*
*
* @param records
* @return
*/
@ -331,11 +341,11 @@ public class AggregateManager {
/**
* Performs the aggregation based on the statsConfig file.
*
*
* @param key
* @param data
*/
private void aggregate(StatsConfig statsConfig, TimeRange timeRange,
private void aggregate(StatisticsEvent statsEvent, TimeRange timeRange,
List<Event> data) {
Calendar start = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
start.setTime(timeRange.getStart());
@ -345,8 +355,8 @@ public class AggregateManager {
// collect grouping names from stats config
List<String> groupByColumns = new ArrayList<String>();
for (Item item : statsConfig.getGroupBy().getAttributes()) {
String column = item.getName();
for (StatisticsGroup groupBy : statsEvent.getGroupList()) {
String column = groupBy.getName();
groupByColumns.add(column);
}
@ -357,7 +367,7 @@ public class AggregateManager {
for (String groupKey : map.keySet()) {
List<Event> groupData = map.get(groupKey);
for (Aggregate aggregate : statsConfig.getAggregates()) {
for (StatisticsAggregate aggregate : statsEvent.getAggregateList()) {
String field = aggregate.getField();
try {
double[] values = new double[groupData.size()];
@ -387,8 +397,7 @@ public class AggregateManager {
}
AggregateRecord record = new AggregateRecord(
statsConfig.getEventType(), start, end, groupKey,
field);
statsEvent.getType(), start, end, groupKey, field);
record.setSum(sum);
record.setMin(min);
record.setMax(max);
@ -406,7 +415,7 @@ public class AggregateManager {
* Breaks the list of data into groups based on groupByColumns. The key is a
* concatenation of the column values (i.e. datatype.username). This method
* can group data to n-number of levels.
*
*
* @param data
* @param groupByColumns
* @return
@ -438,7 +447,7 @@ public class AggregateManager {
/**
* Helper method to group data to one level.
*
*
* @param data
* @param column
* @param parent
@ -473,7 +482,7 @@ public class AggregateManager {
/**
* Returns the name of the getter method for the parameter
*
*
* @param parameter
* @return
*/

View file

@ -1,19 +1,19 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
@ -29,33 +29,38 @@ import com.raytheon.uf.common.event.Event;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.stats.StatsRecord;
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.database.dao.CoreDao;
import com.raytheon.uf.edex.database.dao.DaoConfig;
import com.raytheon.uf.edex.event.EventBus;
import com.raytheon.uf.edex.stats.xml.StatsConfig;
/**
* Subscribes to the event bus and stores them in the appropriate stats table
*
*
*
*
* <pre>
*
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 21, 2012 jsanchez Removed instance variable of event bus.
*
* Aug 21, 2012 jsanchez Removed instance variable of event bus.
* Nov 07, 2012 1317 mpduff Updated config files.
*
* </pre>
*
*
* @author jsanchez
*
*
*/
public class StatsHandler {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(StatsHandler.class);
private CoreDao dao = new CoreDao(DaoConfig.forClass("metadata",
private final CoreDao dao = new CoreDao(DaoConfig.forClass("metadata",
StatsRecord.class));
// TODO Make unmodifiable
private static Set<String> validEventTypes = new HashSet<String>();
/**
@ -80,16 +85,23 @@ public class StatsHandler {
record.setEvent(bytes);
dao.persist(record);
} catch (SerializationException e) {
e.printStackTrace();
statusHandler.error("Error transforming to Thrift.", e);
}
}
}
public static void setValidEventTypes(List<StatsConfig> configurations) {
/**
* Set the valid event types.
*
* @param configurations
* List of StatisticsConfig objects
*/
public static void setValidEventTypes(List<StatisticsConfig> configurations) {
validEventTypes = new HashSet<String>();
for (StatsConfig config : configurations) {
validEventTypes.add(config.getEventType());
for (StatisticsConfig config : configurations) {
for (StatisticsEvent event : config.getEvents()) {
validEventTypes.add(event.getType());
}
}
}
}

View file

@ -1,19 +1,19 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
@ -23,70 +23,60 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.stats.xml.StatisticsAggregate;
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.stats.xml.Aggregate;
import com.raytheon.uf.edex.stats.xml.Statistics;
import com.raytheon.uf.edex.stats.xml.StatsConfig;
/**
* Loads statsConfig files from localization.
*
* Loads StatisticsConfig files from localization.
*
* <pre>
*
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 21, 2012 jsanchez Updated error handling and validated config files.
*
* Aug 21, 2012 jsanchez Updated error handling and validated config files.
* Nov 07, 2012 1317 mpduff Update config files.
*
* </pre>
*
*
* @author jsanchez
*
*
*/
public class ConfigLoader {
private static final transient IUFStatusHandler statusHandler = UFStatus
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(ConfigLoader.class);
private JAXBContext jax;
private static final JAXBManager jaxbManager;
static {
try {
jaxbManager = new JAXBManager(StatisticsConfig.class,
Statistics.class);
} catch (JAXBException e) {
throw new ExceptionInInitializerError(e);
}
}
/** Unmarshaller object */
private Unmarshaller unmarshaller;
private final IPathManager pm = PathManagerFactory.getPathManager();
/** Marshaller object */
private Marshaller marshaller;
private IPathManager pm = PathManagerFactory.getPathManager();
private List<StatsConfig> configurations;
private final List<StatisticsConfig> configurations = new ArrayList<StatisticsConfig>();
private final String STATS_DIR = "stats";
/**
* Constructor. Performs an initial statsCon
*/
public ConfigLoader() throws JAXBException {
jax = JAXBContext.newInstance(new Class[] { StatsConfig.class,
Statistics.class });
unmarshaller = jax.createUnmarshaller();
this.marshaller = jax.createMarshaller();
this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
this.configurations = new ArrayList<StatsConfig>();
}
/**
* Loads the statsConfig files in the STATS_DIR directory.
* Loads the StatisticsConfig files in the STATS_DIR directory.
*/
public void load() throws Exception {
LocalizationContext[] searchContext = pm
@ -97,7 +87,6 @@ public class ConfigLoader {
if (localizationFiles != null && localizationFiles.length > 0) {
break;
}
}
if (localizationFiles != null && localizationFiles.length > 0) {
@ -105,8 +94,9 @@ public class ConfigLoader {
for (LocalizationFile localizationFile : localizationFiles) {
if (localizationFile.getFile() != null
&& localizationFile.getFile().exists()) {
StatsConfig config = (StatsConfig) unmarshaller
.unmarshal(localizationFile.getFile());
StatisticsConfig config = (StatisticsConfig) jaxbManager
.jaxbUnmarshalFromXmlFile(localizationFile
.getFile());
config = validateAggregates(config);
configurations.add(config);
}
@ -116,43 +106,43 @@ public class ConfigLoader {
/**
* Removes the aggregate if its not a numerical parameter.
*
*
* @param config
*/
private StatsConfig validateAggregates(StatsConfig config)
private StatisticsConfig validateAggregates(StatisticsConfig config)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(config.getEventType());
List<Aggregate> aggregates = new ArrayList<Aggregate>();
List<StatisticsAggregate> aggregates = new ArrayList<StatisticsAggregate>();
for (StatisticsEvent event : config.getEvents()) {
Class<?> clazz = Class.forName(event.getType());
for (Aggregate aggregate : config.getAggregates()) {
String aggregateField = aggregate.getField();
try {
Field field = clazz.getDeclaredField(aggregateField);
if (!field.getType().isPrimitive()) {
statusHandler
.info("'"
+ aggregateField
+ "' not a primitive type. Aggregate being removed. ");
for (StatisticsAggregate aggregate : event.getAggregateList()) {
String aggregateField = aggregate.getField();
try {
Field field = clazz.getDeclaredField(aggregateField);
if (!field.getType().isPrimitive()) {
statusHandler
.info("'"
+ aggregateField
+ "' not a primitive type. Aggregate being removed. ");
}
aggregates.add(aggregate);
} catch (NoSuchFieldException e) {
statusHandler.info("'" + aggregateField
+ "' not a valid field. Aggregate being removed. ");
}
aggregates.add(aggregate);
} catch (NoSuchFieldException e) {
statusHandler.info("'" + aggregateField
+ "' not a valid field. Aggregate being removed. ");
}
event.setAggregateList(aggregates);
}
config.setAggregates(aggregates.toArray(new Aggregate[aggregates.size()]));
return config;
}
/**
* Returns a list of all statsConfig files.
*
* Returns a list of all StatisticsConfig files.
*
* @return
*/
public List<StatsConfig> getConfigurations() {
public List<StatisticsConfig> getConfigurations() {
return configurations;
}
}

View file

@ -1,9 +1,11 @@
<statsConfig>
<statisticsConfig>
<!-- Event Type should be fully qualified name of stat event -->
<eventType>com.raytheon.uf.common.event.ProcessEvent</eventType>
<groupBy>
<attribute name="pluginName"/>
</groupBy>
<aggregate field="processingTime" unit="ms"/>
<aggregate field="processingLatency" unit="ms"/>
</statsConfig>
<statisticsEvent type="com.raytheon.uf.common.event.ProcessEvent"
displayName="Processing Events" category="Data Ingest Events">
<statisticsGroup name="pluginName" displayName="Data Type" />
<statisticsAggregate field="processingTimeMilliseconds"
displayName="Processing Time" unit="ms" />
<statisticsAggregate field="processingLatencyMilliseconds"
displayName="Processing Latency" unit="ms" />
</statisticsEvent>
</statisticsConfig>