<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="SV" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hi,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">The KnowledgeAgents are set up thus:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; ResourceFactory.getResourceChangeNotifierService().start();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; ResourceFactory.getResourceChangeScannerService().start();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; KnowledgeAgent knowledgeAgent = KnowledgeAgentFactory.newKnowledgeAgent(agentName);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; knowledgeAgent.monitorResourceChangeEvents(true);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; Resource resource = ResourceFactory.newClassPathResource(changeSetResourcePath, getClass());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; knowledgeAgent.applyChangeSet(resource);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; ResourceFactory.getResourceChangeNotifierService().start();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; ResourceFactory.getResourceChangeScannerService().start();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">And the changesets look like this (xsd stuff removed for brevity):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&lt;change-set&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; &lt;add&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource username=&quot;ruleclient&quot; password=&quot;hunter2&quot; basicAuthentication=&quot;enabled&quot;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source=&quot;http://guvnorhost/drools-guvnor/org.drools.guvnor.Guvnor/package/my.package/LATEST&quot;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;PKG&quot; /&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; &lt;/add&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&lt;/change-set&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">We've tried using a KnowledgeAgentEventListener which throws an exception when it detects test failures:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; public class VetoListener extends DefaultKnowledgeAgentEventListener {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!allTestsPass()) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException(&quot;tests failed, not applying change set&quot;);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean allTestsPass(){<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get test results from ${guvnor_url}/org.drools.guvnor.Guvnor/package/my.package/LATEST/SCENARIOS<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// and check if there were any failures<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; // Usage:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; knowledgeAgent.addEventListener(new VetoListener());<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">I've also tried modifying the event's changeset (I know you shouldn't), but it doesn't stop the changes from being applied:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!allTestsPass()) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event.getChangeSet().getResourcesModified().clear();<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ... and clear all the other collections you can get from event.getChangeSet()<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family:Consolas">&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">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?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Thanks in advance, <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">/g</span><span lang="EN-US" style="color:#1F497D;mso-fareast-language:SV"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>
</div>
</body>
</html>