Have you considered using a "staged" approach?
Rather than forwarding LATEST right into production, have one listener
move it into the staging area or not - depending on the tests. The
production side listener(s) are directed onto the staging area.
-W
On 27/06/2012, Gustaf Cele <gustaf.cele(a)databyran.se> wrote:
Hi,
I have a Guvnor server (5.4.0.Final) which provides rules to a client (which
itself is an EJB server app) using KnowledgeAgents to get hold of rule
updates. The knowledge agents are started with changeset XMLs on the
classpath which point at my Guvnor instance.
The KnowledgeAgents are set up thus:
ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();
KnowledgeAgent knowledgeAgent =
KnowledgeAgentFactory.newKnowledgeAgent(agentName);
knowledgeAgent.monitorResourceChangeEvents(true);
Resource resource =
ResourceFactory.newClassPathResource(changeSetResourcePath, getClass());
knowledgeAgent.applyChangeSet(resource);
ResourceFactory.getResourceChangeNotifierService().start();
ResourceFactory.getResourceChangeScannerService().start();
And the changesets look like this (xsd stuff removed for brevity):
<change-set>
<add>
<resource username="ruleclient" password="hunter2"
basicAuthentication="enabled"
source="http://guvnorhost/drools-guvnor/org.drools.guvnor.Guvnor/package/my.package/LATEST"
type="PKG" />
</add>
</change-set>
As you can see, we use LATEST because we want continuous deployment of our
rules. Change a rule, build the package, and have the connected
KnowledgeAgents updated with the new rule. This works very well - a bit too
well, unfortunately. We have a comprehensive test suite, and every now and
then, you'll check in a rule that breaks a test. We want to prevent any
changes to our rules from being propagated to the clients until all the
tests succeed, and this is where we're stuck.
We've tried using a KnowledgeAgentEventListener which throws an exception
when it detects test failures:
public class VetoListener extends DefaultKnowledgeAgentEventListener {
@Override
public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent
event) {
if (!allTestsPass()) {
throw new RuntimeException("tests failed, not applying
change set");
}
}
boolean allTestsPass(){
// Get test results from
${guvnor_url}/org.drools.guvnor.Guvnor/package/my.package/LATEST/SCENARIOS
// and check if there were any failures
}
}
// Usage:
knowledgeAgent.addEventListener(new VetoListener());
This does prevent the new changeset from being applied, but it also seems to
kill the thread polling for new changes entirely. Restarting the
ResourceChange{Scanner,Notifier}Services doesn't help.
I've also tried modifying the event's changeset (I know you shouldn't), but
it doesn't stop the changes from being applied:
public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {
if (!allTestsPass()) {
event.getChangeSet().getResourcesModified().clear();
// ... and clear all the other collections you can get from
event.getChangeSet()
}
}
So, what I wonder is if there is any way of preventing a changeset from
being applied to a KnowledgeAgent's knowledge base when there are failing
test scenarios, but which applies updates as soon as all tests succeed? More
generally, I'm looking for something with fewer manual steps than run
tests-make snapshot-publish, and in particular I want to ensure you never
publish a package when there are tests failing, and it should preferably not
require any changes outside of Guvnor to get out new rules to the client
app. Any ideas?
Thanks in advance,
/g