Skip to content

Commit bc6b017

Browse files
Fix test rules functionality (#449)
* Add InvalidRulesException to be thrown if different template names are used in the rules * Refactored rulecheck to be named ruletest * Add new test/update existing tests * Fix the looping of list if more events than rules are beings tested * Move test rule service + interface to rules package * Add javadoc to RuleTestService methods
1 parent 1bbc61b commit bc6b017

File tree

15 files changed

+346
-271
lines changed

15 files changed

+346
-271
lines changed

src/functionaltests/java/com/ericsson/ei/rules/RuleTestSteps.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.io.File;
77

8+
import com.ericsson.ei.controller.RuleTestControllerImpl;
89
import org.apache.commons.io.FileUtils;
910
import org.json.JSONArray;
1011
import org.json.JSONObject;
@@ -14,9 +15,7 @@
1415
import org.springframework.boot.web.server.LocalServerPort;
1516
import org.springframework.http.ResponseEntity;
1617
import org.springframework.test.context.TestPropertySource;
17-
import org.springframework.test.util.ReflectionTestUtils;
1818

19-
import com.ericsson.ei.controller.RuleTestController;
2019
import com.ericsson.ei.utils.FunctionalTestBase;
2120
import com.ericsson.ei.utils.HttpRequest;
2221
import com.ericsson.ei.utils.HttpRequest.HttpMethod;
@@ -36,7 +35,7 @@ public class RuleTestSteps extends FunctionalTestBase {
3635
private static final String TEST_RESOURCES_PATH = "src/test/resources";
3736

3837
@Autowired
39-
private RuleTestController ruleTestController;
38+
private RuleTestControllerImpl ruleTestControllerImpl;
4039

4140
private String rules;
4241
private String events;
@@ -47,13 +46,13 @@ public class RuleTestSteps extends FunctionalTestBase {
4746
private ResponseEntity response;
4847

4948
@Given("^rules checking is enabled$")
50-
public void rules_checking_is_enabled() throws Throwable {
51-
ReflectionTestUtils.setField(ruleTestController, "testEnabled", true);
49+
public void rules_checking_is_enabled() {
50+
ruleTestControllerImpl.setTestEnabled(true);
5251
}
5352

5453
@Given("^rules checking is not enabled$")
55-
public void rules_checking_is_not_enabled() throws Throwable {
56-
ReflectionTestUtils.setField(ruleTestController, "testEnabled", false);
54+
public void rules_checking_is_not_enabled() {
55+
ruleTestControllerImpl.setTestEnabled(false);
5756
}
5857

5958
@Given("^file with JMESPath rules \"([^\"]*)\" and file with events \"([^\"]*)\"$")

src/functionaltests/resources/features/ruleTest.feature

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
#Author: valentin.tyhonov@ericsson.com
21

3-
@RuleCheck
2+
@RuleTest
43
Feature: Test rule test feature
54

65
@ExecuteRuleSingle
@@ -21,7 +20,7 @@ Feature: Test rule test feature
2120
@ExecuteIncorrectRule
2221
Scenario: Execute incorrect list of JMESPath rules on list of JSON objects
2322
Given rules checking is enabled
24-
And file with JMESPath rules "/AggregateListRules.json" and file with events "/subscription_single.json"
23+
And file with JMESPath rules "/InvalidRules.json" and file with events "/AggregateListEvents.json"
2524
When make a POST request to the REST API "/rule-test/run-full-aggregation"
2625
Then get response code of 400
2726

src/main/java/com/ericsson/ei/controller/RuleTestControllerImpl.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import javax.servlet.http.HttpServletRequest;
66

7+
import com.ericsson.ei.exception.InvalidRulesException;
78
import org.json.JSONArray;
89
import org.json.JSONException;
910
import org.json.JSONObject;
@@ -20,7 +21,7 @@
2021
import com.ericsson.ei.controller.model.RuleCheckBody;
2122
import com.ericsson.ei.controller.model.RulesCheckBody;
2223
import com.ericsson.ei.jmespath.JmesPathInterface;
23-
import com.ericsson.ei.services.IRuleCheckService;
24+
import com.ericsson.ei.rules.IRuleTestService;
2425
import com.ericsson.ei.utils.ResponseMessage;
2526

2627
import io.swagger.annotations.ApiOperation;
@@ -36,7 +37,7 @@ public class RuleTestControllerImpl implements RuleTestController {
3637
private JmesPathInterface jmesPathInterface;
3738

3839
@Autowired
39-
private IRuleCheckService ruleCheckService;
40+
private IRuleTestService ruleTestService;
4041

4142
@Setter
4243
@Value("${test.aggregation.enabled:false}")
@@ -49,10 +50,7 @@ public class RuleTestControllerImpl implements RuleTestController {
4950
* This method interacts with JmesPathInterface class method runRuleOnEvent to
5051
* evaluate a rule on JSON object.
5152
*
52-
* @param rule-
53-
* takes a String as a rule that need to be evaluated on JSON content
54-
* @param jsonContent-
55-
* takes JSON object as a String
53+
* @param body - the request body contains a rule and an event
5654
* @return a String object
5755
*
5856
*/
@@ -87,7 +85,7 @@ public ResponseEntity<?> createRuleTestRunFullAggregation(
8785
final HttpServletRequest httpRequest) {
8886
if (testEnabled) {
8987
try {
90-
String aggregatedObject = ruleCheckService.prepareAggregatedObject(
88+
String aggregatedObject = ruleTestService.prepareAggregatedObject(
9189
new JSONArray(body.getListRulesJson()), new JSONArray(body.getListEventsJson()));
9290
if (aggregatedObject != null && !aggregatedObject.equals("[]")) {
9391
return new ResponseEntity<>(aggregatedObject, HttpStatus.OK);
@@ -97,8 +95,13 @@ public ResponseEntity<?> createRuleTestRunFullAggregation(
9795
String errorJsonAsString = ResponseMessage.createJsonMessage(errorMessage);
9896
return new ResponseEntity<>(errorJsonAsString, HttpStatus.BAD_REQUEST);
9997
}
100-
} catch (JSONException | IOException e) {
101-
String errorMessage = "Internal Server Error: Failed to generate aggregated object.";
98+
}
99+
catch (InvalidRulesException e) {
100+
String errorJsonAsString = ResponseMessage.createJsonMessage(e.getMessage());
101+
return new ResponseEntity<>(errorJsonAsString, HttpStatus.BAD_REQUEST);
102+
}
103+
catch (JSONException | IOException e) {
104+
String errorMessage = "Failed to generate aggregated object.";
102105
LOGGER.error(errorMessage, e);
103106
String errorJsonAsString = ResponseMessage.createJsonMessage(errorMessage);
104107
return new ResponseEntity<>(errorJsonAsString, HttpStatus.INTERNAL_SERVER_ERROR);
@@ -117,11 +120,11 @@ public ResponseEntity<?> createRuleTestRunFullAggregation(
117120
@ApiOperation(value = "Check if rules test service is enabled", tags = {"Rule-test"},
118121
response = String.class)
119122
public ResponseEntity<?> getRuleTest(HttpServletRequest httpRequest) {
120-
LOGGER.debug("Getting Enabling Status of Rules Check Service");
123+
LOGGER.debug("Getting Enabled Status of Rules Test Service");
121124
try {
122125
return new ResponseEntity<>(new JSONObject().put("status", testEnabled).toString(), HttpStatus.OK);
123126
} catch (Exception e) {
124-
String errorMessage = "Internal Server Error: Failed to get status.";
127+
String errorMessage = "Failed to get status.";
125128
LOGGER.error(errorMessage, e);
126129
String errorJsonAsString = ResponseMessage.createJsonMessage(errorMessage);
127130
return new ResponseEntity<>(errorJsonAsString, HttpStatus.INTERNAL_SERVER_ERROR);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ericsson.ei.exception;
2+
3+
public class InvalidRulesException extends Exception {
4+
5+
private static final long serialVersionUID = 1L;
6+
7+
public InvalidRulesException(String message) {
8+
super(message);
9+
}
10+
11+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.ericsson.ei.rules;
2+
3+
import java.io.IOException;
4+
5+
import com.ericsson.ei.exception.InvalidRulesException;
6+
import org.json.JSONArray;
7+
import org.json.JSONException;
8+
9+
10+
public interface IRuleTestService {
11+
12+
/**
13+
* This method is used to start a test aggregation on given set of rules and events. The
14+
* rules are validated to ensure they all contain the same template name.
15+
* Before starting the process the event ids gets a suffix attached, to identify these as
16+
* test events. When test aggregation is done it is removed from the database.
17+
*
18+
* @param listRulesJson a JSONArray containing a list of rules to test
19+
* @param listEventsJson a JSONArray containing a list of events to test
20+
* @throws JSONException
21+
* @throws IOException
22+
* @throws InvalidRulesException
23+
* */
24+
String prepareAggregatedObject(JSONArray listRulesJson, JSONArray listEventsJson)
25+
throws JSONException, IOException, InvalidRulesException;
26+
27+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.ericsson.ei.rules;
2+
3+
import com.ericsson.ei.exception.InvalidRulesException;
4+
import com.ericsson.ei.handlers.EventHandler;
5+
import com.ericsson.ei.handlers.EventToObjectMapHandler;
6+
import com.ericsson.ei.jmespath.JmesPathInterface;
7+
import com.ericsson.ei.queryservice.ProcessAggregatedObject;
8+
import org.json.JSONArray;
9+
import org.json.JSONException;
10+
import org.json.JSONObject;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.stereotype.Component;
15+
16+
import java.io.IOException;
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
20+
@Component
21+
public class RuleTestService implements IRuleTestService {
22+
private static final Logger LOGGER = LoggerFactory.getLogger(RuleTestService.class);
23+
24+
@Autowired
25+
private JmesPathInterface jmesPathInterface;
26+
27+
@Autowired
28+
private EventHandler eventHandler;
29+
30+
@Autowired
31+
private ProcessAggregatedObject processAggregatedObject;
32+
33+
@Autowired
34+
private EventToObjectMapHandler eventToObjectMapHandler;
35+
36+
@Override
37+
public String prepareAggregatedObject(JSONArray listRulesJson, JSONArray listEventsJson)
38+
throws JSONException, IOException, InvalidRulesException {
39+
eventHandler.getRulesHandler().setParsedJson(listRulesJson.toString());
40+
41+
String templateName = validateRuleTemplateNames(listRulesJson);
42+
43+
prepareEventsForTestAggregation(listEventsJson, templateName);
44+
45+
List<String> responseList = processAggregatedObject.getAggregatedObjectByTemplateName(templateName);
46+
String response = responseList.toString();
47+
48+
// Delete the aggregated object
49+
processAggregatedObject.deleteAggregatedObject(templateName);
50+
// Delete the event object mapper
51+
eventToObjectMapHandler.deleteEventObjectMap(templateName);
52+
53+
return response;
54+
}
55+
56+
/**
57+
* This method iterates through the list of rules to extract the template name from each rule.
58+
* All rules should contain the same template name, which is returned.
59+
*
60+
* @throws InvalidRulesException if the rules contain several template names
61+
* @return a single template name used in all rules
62+
* */
63+
private String validateRuleTemplateNames(JSONArray listRulesJson)
64+
throws InvalidRulesException {
65+
List<String> templateNames = new ArrayList<String>();
66+
for (int i = 0; i < listRulesJson.length(); i++) {
67+
String templateName = jmesPathInterface.runRuleOnEvent("TemplateName",
68+
listRulesJson.getJSONObject(i).toString()).asText("TEST");
69+
if (!templateNames.contains(templateName)) {
70+
templateNames.add(templateName);
71+
}
72+
}
73+
74+
if (templateNames.size() != 1) {
75+
String errorMessage = "Different template names are not allowed in rules, Please use "
76+
+ "one template name for all rules.";
77+
throw new InvalidRulesException(errorMessage);
78+
}
79+
80+
String templateName = templateNames.iterator().next();
81+
return templateName;
82+
}
83+
84+
/**
85+
* Iterates through a list of events and adding a suffix to their ids and the ids in their
86+
* links. This is to easily identify which events are used in a test aggregation.
87+
*/
88+
private void prepareEventsForTestAggregation(JSONArray listEventsJson, String suffix) {
89+
for (int i = 0; i < listEventsJson.length(); i++) {
90+
addTemplateNameToIds(listEventsJson.getJSONObject(i), suffix);
91+
LOGGER.debug("Event to prepare aggregated object :: {}",
92+
listEventsJson.getJSONObject(i).toString());
93+
eventHandler.eventReceived(listEventsJson.getJSONObject(i).toString());
94+
}
95+
}
96+
97+
/**
98+
* Takes an Eiffel event and a suffix to attach to the event id and all ids in the links.
99+
* @throws JSONException
100+
* */
101+
private void addTemplateNameToIds(JSONObject jsonObject, final String suffix) throws JSONException {
102+
String idTemplateSuffix = jmesPathInterface.runRuleOnEvent("meta.id", jsonObject.toString()).asText() + "_"
103+
+ suffix;
104+
if (jsonObject.has("meta"))
105+
jsonObject.getJSONObject("meta").put("id", idTemplateSuffix);
106+
if (jsonObject.has("links")) {
107+
for (int i = 0; i < jsonObject.getJSONArray("links").length(); i++) {
108+
JSONObject link = jsonObject.getJSONArray("links").getJSONObject(i);
109+
link.put("target", link.getString("target") + "_" + suffix);
110+
}
111+
}
112+
}
113+
}

src/main/java/com/ericsson/ei/rules/RulesHandler.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import org.springframework.stereotype.Component;
3535

3636
import com.ericsson.ei.jmespath.JmesPathInterface;
37-
import com.ericsson.ei.services.RuleCheckService;
3837
import com.fasterxml.jackson.core.JsonProcessingException;
3938
import com.fasterxml.jackson.databind.JsonNode;
4039
import com.fasterxml.jackson.databind.ObjectMapper;

src/main/java/com/ericsson/ei/services/IRuleCheckService.java

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)