org.perfcake.validation.RulesValidatorHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of perfcake Show documentation
Show all versions of perfcake Show documentation
A Lightweight Performance Testing Framework
The newest version!
/*
* -----------------------------------------------------------------------\
* PerfCake
*
* Copyright (C) 2010 - 2016 the original author or authors.
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -----------------------------------------------------------------------/
*/
package org.perfcake.validation;
import org.perfcake.message.Message;
import org.perfcake.util.Utils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.io.KieResources;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Helps to build KieContainer based on the Drools rules provided. Used by {@link org.perfcake.validation.RulesValidator}.
*
* @author Martin Večeřa
*/
class RulesValidatorHelper {
/**
* A logger for this class.
*/
static final Logger log = LogManager.getLogger(RulesValidatorHelper.class);
/**
* Constant to hold the DSL language file name in the virtual Drools file system.
*/
private static final String DSL = "messageValidator.dsl";
/**
* Assertions checked by the helper.
*/
private final Map assertions;
/**
* KIE container that holds all Drools related data.
*/
private final KieContainer kieContainer;
/**
* Gets a new helper based on the assertions.
*
* @param assertions
* Assertions that should be added to the rules.
* @throws ValidationException
* When the KIE container construction fails.
*/
public RulesValidatorHelper(final Map assertions) throws ValidationException {
this.assertions = assertions;
final KieServices kieServices = KieServices.Factory.get();
kieContainer = build(kieServices, assertions);
}
/**
* Validates the response given the original message and the previously configured assertions.
*
* @param originalMessage
* The original message.
* @param response
* The response message.
* @return Map with unused/invalid assertions.
*/
public Map validate(final Message originalMessage, final Message response, final Properties messageAttributes) {
final KieSession kieSession = kieContainer.newKieSession();
final Map unusedAssertions = new HashMap<>();
unusedAssertions.putAll(assertions);
kieSession.setGlobal("rulesUsed", unusedAssertions);
kieSession.setGlobal("messageAttributes", messageAttributes);
if (originalMessage != null) {
originalMessage.setProperty(RulesValidator.RULES_ORIGINAL_MESSAGE, "true");
kieSession.insert(originalMessage);
}
if (response != null) {
kieSession.insert(response);
}
kieSession.fireAllRules();
kieSession.dispose();
return unusedAssertions;
}
/**
* Build a KIE container from the assertions.
*
* @param kieServices
* Existing KieServices instance which should be used to build the KIE container.
* @param assertions
* Assertions that represent the rules.
* @return The new KIE container.
*/
private KieContainer build(final KieServices kieServices, final Map assertions) throws ValidationException {
if (log.isDebugEnabled()) {
log.debug("Building rules...");
}
final StringBuilder sBuilder = new StringBuilder();
sBuilder.append("package org.perfcake.validation\n\n");
sBuilder.append("global java.util.Map rulesUsed\n");
sBuilder.append("global java.util.Properties messageAttributes\n");
sBuilder.append("import java.util.Map\n");
sBuilder.append("import java.util.Properties\n");
sBuilder.append("import org.perfcake.message.Message\n");
sBuilder.append("import org.perfcake.validation.RulesValidator\n");
sBuilder.append("import org.perfcake.validation.ValidatorUtil\n");
sBuilder.append("import org.perfcake.validation.ValidatorUtil.MessagePart\n");
sBuilder.append("import org.perfcake.validation.ValidatorUtil.Operator\n");
sBuilder.append("import org.perfcake.validation.ValidatorUtil.Occurrence\n");
sBuilder.append("expander ").append(DSL).append("\n");
for (int i = 0; i < assertions.size(); i++) {
String assertion = assertions.get(i);
assertion = assertion.trim();
if (assertion.length() > 0 && !assertion.startsWith("#")) {
final int lineNumber = i + 1;
// rules numbered from 1
final String rule = String.format("rule \"Line %d\"%n dialect \"java\"%n when%n %s%n then%n > rulesUsed.remove(%d);%nend%n", lineNumber, assertion, lineNumber - 1);
sBuilder.append(rule);
}
}
if (log.isTraceEnabled()) {
log.trace("Built rules:\n" + sBuilder.toString());
}
final KieRepository krp = kieServices.getRepository();
final KieFileSystem kfs = kieServices.newKieFileSystem();
final KieResources krs = kieServices.getResources();
final Resource dslResource = krs.newClassPathResource(DSL);
final Resource rulesResource = krs.newReaderResource(new StringReader(sBuilder.toString()), Utils.getDefaultEncoding());
kfs.write("src/main/resources/" + DSL, dslResource);
kfs.write("src/main/resources/org/perfcake/validation/rules.dslr", rulesResource);
final KieBuilder kb = kieServices.newKieBuilder(kfs);
kb.buildAll();
// Check the builder for errors
if (kb.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
if (log.isErrorEnabled()) {
log.error(kb.getResults().getMessages().toString());
}
throw new ValidationException("Unable to compile rules.");
}
return kieServices.newKieContainer(krp.getDefaultReleaseId());
}
}