AlertUtils { public static String getExpressionWithAbsoluteStartAndEndTimeStamps(DefaultAlertService.NotificationContext context) { String absoluteExpression = ""; try { String expression = "@" + context.getAlert().getExpression().replaceAll("[\\s\\t\\r\\n\\f]*", ""); String regexMatcherWithStartAndEnd = "(?i)\\-[0-9]+(d|m|h|s):\\-[0-9]+(d|m|h|s)"; String regexMatcherWithConstants = "(?i)#\\-[0-9]+(d|h|m|s)"; String regexMatcherWithoutEnd = "(?i)\\@\\-[0-9]+(d|m|h|s)|\\(\\-[0-9]+(d|m|h|s)|,\\-[0-9]+(d|m|h|s)"; Long relativeTo = context.getAlertEnqueueTimestamp(); Matcher m = Pattern.compile(regexMatcherWithStartAndEnd).matcher(expression); while (m.find()) { String[] times = m.group().split(":"); requireArgument(times.length == 2, MessageFormat.format("Regex matching returns single timestamp for string: {0} with regex: {1} and matched group: {2}", expression, regexMatcherWithStartAndEnd, m.group())); Long absoluteTimeStart = MetricReader.getTime(relativeTo, times[0]); Long absoluteTimeEnd = MetricReader.getTime(relativeTo, times[1]); expression = expression.replaceAll(m.group(), "" + absoluteTimeStart + ":" + absoluteTimeEnd); } m = Pattern.compile(regexMatcherWithConstants).matcher(expression); while (m.find()) { String timeStr = m.group(); Long absoluteTime = MetricReader.getTime(relativeTo, timeStr.substring(1)); expression = expression.replaceAll(timeStr, ("" + timeStr.charAt(0)) + absoluteTime); } m = Pattern.compile(regexMatcherWithoutEnd).matcher(expression); while (m.find()) { String timeStr = m.group(); Long absoluteTime = MetricReader.getTime(relativeTo, timeStr.substring(1)); expression = expression.replace(timeStr, ("" + timeStr.charAt(0)) + absoluteTime + (":" + relativeTo)); } absoluteExpression = expression.substring(1); } catch (Exception ex) { _logger.error(MessageFormat.format("Exception occurred while converting relative time within the expression to absolute time for {0}, with error message {1}.", context.getAlert().getExpression(), ex.getMessage())); } return absoluteExpression; }  static boolean isPatternPresentInWhiteList(String expression, List<Pattern> scopeRegexPatterns); static Long getMaximumIntervalLength(String queryExpression); static Long[] getStartAndEndTimes(String originalExpression, Long relativeTo); static String getExpressionWithAbsoluteStartAndEndTimeStamps(DefaultAlertService.NotificationContext context);  }
@Test public void testAbsoluteTimeStampsInExpression() { Long alertEnqueueTime = 1418319600000L; ArrayList<String> expressionArray = new ArrayList<String> (Arrays.asList( "DIFF(COUNT(CULL_BELOW(SHIFT(-25h:-24h:core.IA2.SP1.na70:SFDC_type-Stats-name1-Login-name2-Success.Last1min{device=na70-app*}:avg:10m-max,#24h#),#3#,#value#)),SUM(COUNT(CULL_BELOW(FILL(#-1h#,#-0h#, #10m#, #0m#, #4#),-1h:-0h:core.IA2.SP1.na70:SFDC_type-Stats-name1-Login-name2-Success.Last1min{device=na70-app*}:avg:10m-max,#3#,#value#)),#-1#))", "-20m:-0d:scone.*.*.cs19:acs.DELETERequestProcessingTime_95thPercentile{device=*acs2-1*}:avg", " SCALE( SUM( DIVIDE( DIFF( DOWNSAMPLE( SUM( CULL_BELOW( DERIVATIVE(-1h:-40m:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Query_Count__SolrLive.Count{device=eu11-app*}:sum:1m-max ), #0.001#, #value# ), #union# ), #10m-sum# ), DOWNSAMPLE( SUM( CULL_BELOW( DERIVATIVE(-2h:-40m:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Search_Fallbacks__SolrLive.Count{device=eu11-app*}:sum:1m-max ), #0.01#, #value# ), #union# ), #10m-sum# ), #union# ), CULL_BELOW( DOWNSAMPLE( SUM( CULL_BELOW( DERIVATIVE( -40m:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Query_Count__SolrLive.Count{device=eu11-app*}:sum:1m-max ), #0.001#, #value# ), #union# ), #10m-sum# ), #1000#, #value# ) ), #-1# ), #-100# ) ", "ABOVE(-1d:scope:metric:avg:4h-avg, #0.5#, #avg#)", "ABOVE(-1h:scope:metric:avg:4h-avg, #0.5#)", "ALIASBYTAG(-1s:scope:metric{device=*,source=*}:sum)", "FILL( #-1D#, #-0d#,#4h#,#0m#,#100#)", "GROUPBY(-2d:-1d:scope:metricA{host=*}:avg,#(myhost[1-9])#, #SUM#, #union#)", "LIMIT( -21d:-1d:scope:metricA:avg:4h-avg, -1d:scope:metricB:avg:4h-avg,#1#)", "RANGE(-10d:scope:metric[ABCD]:avg:1d-max)", "DOWNSAMPLE(DOWNSAMPLE(GROUPBYTAG(CULL_BELOW(-115m:-15m:iot-provisioning-server.SP2.-:health.status{device=provisioning-warden-*}:avg:1m-max, #1#, #value#), #DeploymentName#, #MAX#), #1m-max#), #10m-count#)", "DOWNSAMPLE(CULL_BELOW(DERIVATIVE(-115m:-15m:iot-container.NONE.-:iot.flows.state.load.errors_count{flowsnakeEnvironmentName=iot-prd-stmfa-00ds70000000mqy}:zimsum:1m-sum), #0#, #value#), #10m-sum#)", "DOWNSAMPLE(-2d:argus.alerts:scheduled{alertId=1429851}:zimsum, #5m-sum#,#-2d#, #-0m#, #0#)" )); ArrayList<String> expectedOutput = new ArrayList<String> (Arrays.asList( "DIFF(COUNT(CULL_BELOW(SHIFT(1418229600000:1418233200000:core.IA2.SP1.na70:SFDC_type-Stats-name1-Login-name2-Success.Last1min{device=na70-app*}:avg:10m-max,#24h#),#3#,#value#)),SUM(COUNT(CULL_BELOW(FILL(#1418316000000#,#1418319600000#,#10m#,#0m#,#4#),1418316000000:1418319600000:core.IA2.SP1.na70:SFDC_type-Stats-name1-Login-name2-Success.Last1min{device=na70-app*}:avg:10m-max,#3#,#value#)),#-1#))", "1418318400000:1418319600000:scone.*.*.cs19:acs.DELETERequestProcessingTime_95thPercentile{device=*acs2-1*}:avg", "SCALE(SUM(DIVIDE(DIFF(DOWNSAMPLE(SUM(CULL_BELOW(DERIVATIVE(1418316000000:1418317200000:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Query_Count__SolrLive.Count{device=eu11-app*}:sum:1m-max),#0.001#,#value#),#union#),#10m-sum#),DOWNSAMPLE(SUM(CULL_BELOW(DERIVATIVE(1418312400000:1418317200000:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Search_Fallbacks__SolrLive.Count{device=eu11-app*}:sum:1m-max),#0.01#,#value#),#union#),#10m-sum#),#union#),CULL_BELOW(DOWNSAMPLE(SUM(CULL_BELOW(DERIVATIVE(1418317200000:1418319600000:core.*.*.eu11:SFDC_type-Stats-name1-Search-name2-Client-name3-Query_Count__SolrLive.Count{device=eu11-app*}:sum:1m-max),#0.001#,#value#),#union#),#10m-sum#),#1000#,#value#)),#-1#),#-100#)", "ABOVE(1418233200000:1418319600000:scope:metric:avg:4h-avg,#0.5#,#avg#)", "ABOVE(1418316000000:1418319600000:scope:metric:avg:4h-avg,#0.5#)", "ALIASBYTAG(1418319599000:1418319600000:scope:metric{device=*,source=*}:sum)", "FILL(#1418233200000#,#1418319600000#,#4h#,#0m#,#100#)", "GROUPBY(1418146800000:1418233200000:scope:metricA{host=*}:avg,#(myhost[1-9])#,#SUM#,#union#)", "LIMIT(1416505200000:1418233200000:scope:metricA:avg:4h-avg,1418233200000:1418319600000:scope:metricB:avg:4h-avg,#1#)", "RANGE(1417455600000:1418319600000:scope:metric[ABCD]:avg:1d-max)", "DOWNSAMPLE(DOWNSAMPLE(GROUPBYTAG(CULL_BELOW(1418312700000:1418318700000:iot-provisioning-server.SP2.-:health.status{device=provisioning-warden-*}:avg:1m-max,#1#,#value#),#DeploymentName#,#MAX#),#1m-max#),#10m-count#)", "DOWNSAMPLE(CULL_BELOW(DERIVATIVE(1418312700000:1418318700000:iot-container.NONE.-:iot.flows.state.load.errors_count{flowsnakeEnvironmentName=iot-prd-stmfa-00ds70000000mqy}:zimsum:1m-sum),#0#,#value#),#10m-sum#)", "DOWNSAMPLE(1418146800000:1418319600000:argus.alerts:scheduled{alertId=1429851}:zimsum,#5m-sum#,#1418146800000#,#1418319600000#,#0#)" )); UserService userService = system.getServiceFactory().getUserService(); String alertName = "alert_name-" + TestUtils.createRandomName(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), alertName, expressionArray.get(0), "* * * * *"); Notification notification = new Notification("notification_name", alert, "notifier_name", new ArrayList<String>(), 23); Trigger trigger = new Trigger(alert, Trigger.TriggerType.GREATER_THAN_OR_EQ, "trigger_name", 2D, 5); alert.setNotifications(Arrays.asList(new Notification[] { notification })); alert.setTriggers(Arrays.asList(new Trigger[] { trigger })); alert = system.getServiceFactory().getAlertService().updateAlert(alert); History history = new History(History.JobStatus.SUCCESS.getDescription(), "localhost", BigInteger.ONE, History.JobStatus.SUCCESS); DefaultAlertService.NotificationContext context = new DefaultAlertService.NotificationContext(alert, alert.getTriggers().get(0), notification, 1418320200000L, 0.0, new Metric("scope", "metric"), history); context.setAlertEnqueueTimestamp(alertEnqueueTime); ArrayList<String> actualOutput = new ArrayList<String>(); for (String currentExpression: expressionArray) { alert.setExpression(currentExpression); String currentOutput = AlertUtils.getExpressionWithAbsoluteStartAndEndTimeStamps(context); actualOutput.add(currentOutput); assertEquals(true, MetricReader.isValid(currentOutput)); } assertEquals(expectedOutput, actualOutput); }