Skip to content

Commit

Permalink
Load rules via stream
Browse files Browse the repository at this point in the history
  • Loading branch information
luis-pabon-tf committed Mar 22, 2024
1 parent 724c573 commit 206509a
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package gov.hhs.cdc.trustedintermediary.etor.ruleengine;

import gov.hhs.cdc.trustedintermediary.wrappers.Logger;
import java.nio.file.Path;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
Expand All @@ -10,9 +12,6 @@
/** Manages the application of rules loaded from a definitions file using the RuleLoader. */
public class RuleEngine {

private final Path RULES_DEFINITIONS_PATH =
Path.of("../etor/src/main/resources/rule_definitions.json");

private static final RuleEngine INSTANCE = new RuleEngine();

final List<Rule> rules = new ArrayList<>();
Expand All @@ -37,12 +36,15 @@ public void ensureRulesLoaded() {
}

private synchronized void loadRules() {
logger.logInfo("Loading rules definitions from " + RULES_DEFINITIONS_PATH);
try {
var loadedRules = ruleLoader.loadRules(RULES_DEFINITIONS_PATH);
rules.addAll(loadedRules);
} catch (RuleLoaderException e) {
logger.logError("Failed to load rules definitions from: " + RULES_DEFINITIONS_PATH, e);
String fileName = "rule_definitions.json";
try (InputStream ruleDefinitionStream =
getClass().getClassLoader().getResourceAsStream(fileName)) {
assert ruleDefinitionStream != null;
var ruleStream =
new String(ruleDefinitionStream.readAllBytes(), StandardCharsets.UTF_8);
rules.addAll(ruleLoader.loadRules(ruleStream));
} catch (IOException | RuleLoaderException e) {
logger.logError("Failed to load rules definitions from: " + fileName, e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import gov.hhs.cdc.trustedintermediary.wrappers.formatter.Formatter;
import gov.hhs.cdc.trustedintermediary.wrappers.formatter.FormatterProcessingException;
import gov.hhs.cdc.trustedintermediary.wrappers.formatter.TypeReference;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -24,15 +21,14 @@ public static RuleLoader getInstance() {
return INSTANCE;
}

List<ValidationRule> loadRules(Path configPath) throws RuleLoaderException {
public List<ValidationRule> loadRules(String ruleStream) throws RuleLoaderException {
try {
String fileContent = Files.readString(configPath);
Map<String, List<ValidationRule>> jsonObj =
formatter.convertJsonToObject(fileContent, new TypeReference<>() {});
formatter.convertJsonToObject(ruleStream, new TypeReference<>() {});
return jsonObj.getOrDefault("rules", Collections.emptyList());
} catch (IOException | FormatterProcessingException e) {
} catch (FormatterProcessingException e) {
throw new RuleLoaderException(
"Failed to load rules definitions from: " + configPath, e);
"Failed to load rules definitions for provided stream", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import gov.hhs.cdc.trustedintermediary.wrappers.Logger
import org.hl7.fhir.r4.model.Bundle
import spock.lang.Specification

import java.nio.file.Path

class RuleEngineTest extends Specification {
def ruleEngine = RuleEngine.getInstance()
def mockRuleLoader = Mock(RuleLoader)
Expand All @@ -29,7 +27,7 @@ class RuleEngineTest extends Specification {
ruleEngine.ensureRulesLoaded()

then:
1 * mockRuleLoader.loadRules(_ as Path) >> [Mock(Rule)]
1 * mockRuleLoader.loadRules(_ as String) >> [Mock(Rule)]
ruleEngine.rules.size() == 1
}

Expand All @@ -39,13 +37,13 @@ class RuleEngineTest extends Specification {
ruleEngine.ensureRulesLoaded() // Call twice to test if rules are loaded only once

then:
1 * mockRuleLoader.loadRules(_ as Path) >> [Mock(Rule)]
1 * mockRuleLoader.loadRules(_ as String) >> [Mock(Rule)]
}

def "ensureRulesLoaded logs an error if there is an exception loading the rules"() {
given:
def exception = new RuleLoaderException("Error loading rules", new Exception())
mockRuleLoader.loadRules(_ as Path) >> { throw exception }
mockRuleLoader.loadRules(_ as String) >> { throw exception }

when:
ruleEngine.validate(Mock(Bundle))
Expand All @@ -61,7 +59,7 @@ class RuleEngineTest extends Specification {
def fhirBundle = Mock(Bundle)
def invalidRule = Mock(Rule)
invalidRule.getViolationMessage() >> ruleViolationMessage
mockRuleLoader.loadRules(_ as Path) >> [invalidRule]
mockRuleLoader.loadRules(_ as String) >> [invalidRule]

when:
invalidRule.appliesTo(fhirBundle) >> true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ import java.nio.file.Paths

class RuleLoaderTest extends Specification {

Path tempRulesFilePath
String fileContents

def setup() {
TestApplicationContext.reset()
TestApplicationContext.init()
TestApplicationContext.register(RuleLoader, RuleLoader.getInstance())
TestApplicationContext.injectRegisteredImplementations()

tempRulesFilePath = Files.createTempFile("rules", ".json")
String jsonContent = """
fileContents = """
{
"rules": [
{
Expand All @@ -32,11 +31,6 @@ class RuleLoaderTest extends Specification {
]
}
"""
Files.writeString(tempRulesFilePath, jsonContent)
}

def cleanup() {
Files.deleteIfExists(tempRulesFilePath)
}

def "load rules from file"() {
Expand All @@ -46,7 +40,7 @@ class RuleLoaderTest extends Specification {
TestApplicationContext.injectRegisteredImplementations()

when:
List<Rule> rules = RuleLoader.getInstance().loadRules(tempRulesFilePath)
List<Rule> rules = RuleLoader.getInstance().loadRules(fileContents)

then:
rules.size() == 1
Expand All @@ -58,9 +52,9 @@ class RuleLoaderTest extends Specification {
]
}

def "handle IOException when loading rules from file"() {
def "handle FormatterProcessingException when loading rules from file"() {
when:
RuleLoader.getInstance().loadRules(Paths.get("DogCow"))
RuleLoader.getInstance().loadRules("!K@WJ#8uhy")

then:
thrown(RuleLoaderException)
Expand Down

0 comments on commit 206509a

Please sign in to comment.