diff --git a/thresh/src/main/java/monasca/thresh/domain/service/AlarmDAO.java b/thresh/src/main/java/monasca/thresh/domain/service/AlarmDAO.java index b3c6b5c..33d2968 100644 --- a/thresh/src/main/java/monasca/thresh/domain/service/AlarmDAO.java +++ b/thresh/src/main/java/monasca/thresh/domain/service/AlarmDAO.java @@ -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 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); diff --git a/thresh/src/main/java/monasca/thresh/infrastructure/persistence/AlarmDAOImpl.java b/thresh/src/main/java/monasca/thresh/infrastructure/persistence/AlarmDAOImpl.java index 8069612..85058e0 100644 --- a/thresh/src/main/java/monasca/thresh/infrastructure/persistence/AlarmDAOImpl.java +++ b/thresh/src/main/java/monasca/thresh/infrastructure/persistence/AlarmDAOImpl.java @@ -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 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 row) { final Map dimensionMap = new HashMap<>(); final String dimensions = getString(row, "dimensions"); diff --git a/thresh/src/main/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImpl.java b/thresh/src/main/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImpl.java index 3a0f632..3866ba7 100644 --- a/thresh/src/main/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImpl.java +++ b/thresh/src/main/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImpl.java @@ -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); diff --git a/thresh/src/main/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBolt.java b/thresh/src/main/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBolt.java index 318f21a..706895e 100644 --- a/thresh/src/main/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBolt.java +++ b/thresh/src/main/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBolt.java @@ -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 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) { diff --git a/thresh/src/test/java/monasca/thresh/ThresholdingEngineAlarmTest.java b/thresh/src/test/java/monasca/thresh/ThresholdingEngineAlarmTest.java index 35e09f9..5241492 100644 --- a/thresh/src/test/java/monasca/thresh/ThresholdingEngineAlarmTest.java +++ b/thresh/src/test/java/monasca/thresh/ThresholdingEngineAlarmTest.java @@ -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); } diff --git a/thresh/src/test/java/monasca/thresh/infrastructure/persistence/AlarmDAOImplTest.java b/thresh/src/test/java/monasca/thresh/infrastructure/persistence/AlarmDAOImplTest.java index 09bcc38..05be4af 100644 --- a/thresh/src/test/java/monasca/thresh/infrastructure/persistence/AlarmDAOImplTest.java +++ b/thresh/src/test/java/monasca/thresh/infrastructure/persistence/AlarmDAOImplTest.java @@ -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); } diff --git a/thresh/src/test/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImplTest.java b/thresh/src/test/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImplTest.java index fd37a73..bb3b7cf 100644 --- a/thresh/src/test/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImplTest.java +++ b/thresh/src/test/java/monasca/thresh/infrastructure/persistence/hibernate/AlarmSqlImplTest.java @@ -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); } diff --git a/thresh/src/test/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBoltTest.java b/thresh/src/test/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBoltTest.java index 8a83d12..0921453 100644 --- a/thresh/src/test/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBoltTest.java +++ b/thresh/src/test/java/monasca/thresh/infrastructure/thresholding/AlarmThresholdingBoltTest.java @@ -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() {