Add millisecond resolution to alarms.

At the moment it we are using the mysql built in function
NOW() which returns in second resolution.

Change-Id: I1192abb5aab3a9110721cc68f5a1d16a38f77c10
This commit is contained in:
Michael James Hoppal 2016-07-11 13:28:31 -06:00
parent 3927da1697
commit 865816dd78
8 changed files with 47 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
* (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -38,7 +38,7 @@ public interface AlarmDAO {
public List<Alarm> listAll();
/** Updates the alarm state. */
void updateState(String id, AlarmState state);
void updateState(String id, AlarmState state, long msTimestamp);
/** Adds a new AlarmedMetric to an Alarm */
void addAlarmedMetric(String id, MetricDefinitionAndTenantId metricDefinition);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
* (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,9 +36,12 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.TreeMap;
import javax.inject.Inject;
@ -53,9 +56,12 @@ public class AlarmDAOImpl implements AlarmDAO {
private final DBI db;
private final ThreadLocal<SimpleDateFormat> simpleDateFormatter;
@Inject
public AlarmDAOImpl(DBI db) {
this.db = db;
this.simpleDateFormatter = new ThreadLocal<>();
}
@Override
@ -241,16 +247,18 @@ public class AlarmDAOImpl implements AlarmDAO {
public void createAlarm(Alarm alarm) {
Handle h = db.open();
try {
String timestamp = formatDateFromMillis(System.currentTimeMillis());
h.begin();
h.insert(
"insert into alarm (id, alarm_definition_id, state, state_updated_at, created_at, updated_at) values (?, ?, ?, NOW(), NOW(), NOW())",
alarm.getId(), alarm.getAlarmDefinitionId(), alarm.getState().toString());
"insert into alarm (id, alarm_definition_id, state, state_updated_at, created_at, updated_at) values (?, ?, ?, ?, ?, ?)",
alarm.getId(), alarm.getAlarmDefinitionId(), alarm.getState().toString(), timestamp,
timestamp, timestamp);
for (final SubAlarm subAlarm : alarm.getSubAlarms()) {
h.insert(
"insert into sub_alarm (id, alarm_id, sub_expression_id, expression, created_at, updated_at) values (?, ?, ?, ?, NOW(), NOW())",
"insert into sub_alarm (id, alarm_id, sub_expression_id, expression, created_at, updated_at) values (?, ?, ?, ?, ?, ?)",
subAlarm.getId(), subAlarm.getAlarmId(), subAlarm.getAlarmSubExpressionId(), subAlarm
.getExpression().getExpression());
.getExpression().getExpression(), timestamp, timestamp);
}
for (final MetricDefinitionAndTenantId md : alarm.getAlarmedMetrics()) {
createAlarmedMetric(h, md, alarm.getId());
@ -276,11 +284,12 @@ public class AlarmDAOImpl implements AlarmDAO {
}
@Override
public void updateState(String id, AlarmState state) {
public void updateState(String id, AlarmState state, long msTimestamp) {
try (final Handle h = db.open()) {
h.createStatement("update alarm set state = :state, state_updated_at = NOW(), updated_at = NOW() where id = :id")
.bind("id", id).bind("state", state.toString()).execute();
String timestamp = formatDateFromMillis(msTimestamp);
h.createStatement("update alarm set state = :state, state_updated_at = :timestamp, updated_at = :timestamp where id = :id")
.bind("id", id).bind("timestamp", timestamp).bind("state", state.toString()).execute();
}
}
@ -304,6 +313,14 @@ public class AlarmDAOImpl implements AlarmDAO {
}
}
private String formatDateFromMillis(final long msTimestamp) {
if (simpleDateFormatter.get() == null) {
simpleDateFormatter.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
simpleDateFormatter.get().setTimeZone(TimeZone.getTimeZone("GMT-0"));
}
return simpleDateFormatter.get().format(new Date(msTimestamp));
}
private MetricDefinition createMetricDefinitionFromRow(final Map<String, Object> row) {
final Map<String, String> dimensionMap = new HashMap<>();
final String dimensions = getString(row, "dimensions");

View File

@ -1,5 +1,6 @@
/*
* Copyright 2016 FUJITSU LIMITED
* (C) Copyright 2016 Hewlett Packard Enterprise Development LP
*
* 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
@ -134,20 +135,19 @@ public class AlarmSqlImpl
}
@Override
public void updateState(String id, AlarmState state) {
public void updateState(String id, AlarmState state, long msTimestamp) {
Transaction tx = null;
Session session = null;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
final DateTime now = DateTime.now();
final DateTime dt = new DateTime(msTimestamp);
final AlarmDb alarm = (AlarmDb) session.get(AlarmDb.class, id);
alarm.setState(state);
alarm.setUpdatedAt(now);
alarm.setStateUpdatedAt(now);
alarm.setUpdatedAt(dt);
alarm.setStateUpdatedAt(dt);
session.update(alarm);

View File

@ -1,5 +1,5 @@
/*
* (C) Copyright 2014,2016 Hewlett Packard Enterprise Development Company LP.
* (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -224,7 +224,8 @@ public class AlarmThresholdingBolt extends BaseRichBolt {
alarm.getId());
return;
}
alarmDAO.updateState(alarm.getId(), alarm.getState());
long timestamp = getTimestamp();
alarmDAO.updateState(alarm.getId(), alarm.getState(), timestamp);
final List<MetricDefinition> alarmedMetrics = new ArrayList<>(alarm.getAlarmedMetrics().size());
for (final MetricDefinitionAndTenantId mdtid : alarm.getAlarmedMetrics()) {
alarmedMetrics.add(mdtid.metricDefinition);
@ -236,7 +237,7 @@ public class AlarmThresholdingBolt extends BaseRichBolt {
alarmDefinition.getDescription(), initialState, alarm.getState(),
alarmDefinition.getSeverity(), alarm.getLink(), alarm.getLifecycleState(),
alarmDefinition.isActionsEnabled(), stateChangeReason,
alarm.getTransitionSubAlarms(), getTimestamp());
alarm.getTransitionSubAlarms(), timestamp);
try {
alarmEventForwarder.send(Serialization.toJson(event));
} catch (Exception ignore) {

View File

@ -1,5 +1,5 @@
/*
* (C) Copyright 2014,2016 Hewlett Packard Enterprise Development Company LP.
* (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -405,7 +405,7 @@ public class ThresholdingEngineAlarmTest extends TopologyTestCase {
}
@Override
public void updateState(String id, AlarmState state) {
public void updateState(String id, AlarmState state, long msTimeStamp) {
findById(id).setState(state);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
* (C) Copyright 2014,2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -208,7 +208,7 @@ public class AlarmDAOImplTest {
final Alarm newAlarm = new Alarm(alarmDef, AlarmState.OK);
dao.createAlarm(newAlarm);
dao.updateState(newAlarm.getId(), AlarmState.ALARM);
dao.updateState(newAlarm.getId(), AlarmState.ALARM, System.currentTimeMillis());
assertEquals(dao.findById(newAlarm.getId()).getState(), AlarmState.ALARM);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2016 FUJITSU LIMITED
* (C) Copyright 2016 Hewlett Packard Enterprise Development LP
*
* 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
@ -145,7 +146,7 @@ public class AlarmSqlImplTest {
final Alarm newAlarm = new Alarm(alarmDef, AlarmState.OK);
dao.createAlarm(newAlarm);
dao.updateState(newAlarm.getId(), AlarmState.ALARM);
dao.updateState(newAlarm.getId(), AlarmState.ALARM, System.currentTimeMillis());
assertEquals(dao.findById(newAlarm.getId()).getState(), AlarmState.ALARM);
}

View File

@ -1,5 +1,5 @@
/*
* (C) Copyright 2014,2016 Hewlett Packard Enterprise Development Company LP.
* (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,8 @@
package monasca.thresh.infrastructure.thresholding;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -128,7 +130,7 @@ public class AlarmThresholdingBoltTest {
+ "\"timestamp\":1395587091003}}";
verify(alarmEventForwarder, times(1)).send(alarmJson);
verify(alarmDAO, times(1)).updateState(alarmId, AlarmState.ALARM);
verify(alarmDAO, times(1)).updateState(eq(alarmId), eq(AlarmState.ALARM), anyLong());
// Now clear the alarm and ensure another notification gets sent out
subAlarm.setState(AlarmState.OK);
@ -153,7 +155,7 @@ public class AlarmThresholdingBoltTest {
+ "\"subAlarms\":[" + buildSubAlarmJson(alarm.getSubAlarms()) + "],"
+ "\"timestamp\":1395587091003}}";
verify(alarmEventForwarder, times(1)).send(okJson);
verify(alarmDAO, times(1)).updateState(alarmId, AlarmState.OK);
verify(alarmDAO, times(1)).updateState(eq(alarmId), eq(AlarmState.OK), anyLong());
}
public void simpleAlarmUpdate() {