Bug 1034030

Summary: 0 byte local cache file in UrlResource
Product: [JBoss] JBoss Enterprise BRMS Platform 5 Reporter: Toshiya Kobayashi <tkobayas>
Component: BRE (Expert, Fusion)Assignee: Nobody <nobody>
Status: VERIFIED --- QA Contact: Lukáš Petrovický <lpetrovi>
Severity: high Docs Contact:
Priority: unspecified    
Version: BRMS 5.3.1CC: nwallace
Target Milestone: GA   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1044294 (view as bug list) Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 1022758, 1044294    

Description Toshiya Kobayashi 2013-11-25 06:15:31 UTC
Description of problem:

Assuming you configure KnowledgeAgent/ResourceChangeScanner with ChangeSet.xml to connect to Guvnor. In addition, you configure drools.resource.urlcache to enable local file cache.

If the following scenario happens:

1. ResourceChangeScanner scans for Guvnor
2. Calls UrlResource.getInputStream()
2.1 Gets updated lastModified by HTTP HEAD in UrlResource.grabLastMod()
2.2 Calls UrlResource.cacheStream()
2.2.1 Deletes the file cache and open FileOutputStream. (Now the cache file is 0 byte)
2.2.2 *** Guvnor goes down (shutdown/crash/network issue etc.) ***
2.2.3 grabStream() throws an Exception because Guvnor is unreachable
2.2.4 UrlResource.cacheStream() catches the Exception and leaves the 0 byte cache file
2.3 UrlResource.getInputStream() calls UrlResource.grabStream() again and it throws an Exception again
2.4 UrlResource.getInputStream() catches the Exception and reads the 0 byte cache file and returns its InputStream

KnowledgeAgent will keep failing with the 0 byte cache file.

You can reproduce the scenario by setting a breakpoint in UrlResource.cacheStream() before calling grabStream(). Then shutdown Guvnor.

====
    private void cacheStream() {
        try {
            File fi = getCacheFile();
            if (fi.exists()) fi.delete();
            FileOutputStream fout = new FileOutputStream(fi);
  HERE! ==> InputStream in = grabStream();
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int n;
            while (-1 != (n = in.read(buffer))) {
                fout.write(buffer, 0, n);
            }
            fout.flush();
            fout.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
====


Steps to Reproduce:

See above steps.

Actual results:

local cache file becomes 0 byte and KnowledgeAgent will keep failing with the file.

====[2013-11-25 11:49:11,723:exception]
java.lang.RuntimeException: KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  
	at org.drools.agent.impl.KnowledgeAgentImpl.createPackageFromResource(KnowledgeAgentImpl.java:774)
	at org.drools.agent.impl.KnowledgeAgentImpl.addResourcesToKnowledgeBase(KnowledgeAgentImpl.java:1069)
	at org.drools.agent.impl.KnowledgeAgentImpl.rebuildResources(KnowledgeAgentImpl.java:822)
	at org.drools.agent.impl.KnowledgeAgentImpl.buildKnowledgeBase(KnowledgeAgentImpl.java:671)
	at org.drools.agent.impl.KnowledgeAgentImpl.applyChangeSet(KnowledgeAgentImpl.java:201)
	at org.drools.agent.impl.KnowledgeAgentImpl$ChangeSetNotificationDetector.run(KnowledgeAgentImpl.java:1268)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.EOFException
	at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
	at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
	at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
	at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
	at org.drools.common.DroolsObjectInputStream.<init>(DroolsObjectInputStream.java:68)
	at org.drools.core.util.DroolsStreamUtils.streamIn(DroolsStreamUtils.java:205)
	at org.drools.core.util.DroolsStreamUtils.streamIn(DroolsStreamUtils.java:174)
	at org.drools.agent.impl.KnowledgeAgentImpl.createPackageFromResource(KnowledgeAgentImpl.java:747)
	... 6 more
====

Expected results:

KnowledgeAgent uses old valid file cache until it completely reads updated resources.

Additional info:

Comment 1 Toshiya Kobayashi 2013-11-25 14:16:27 UTC
Sent a pull request.

https://github.com/droolsjbpm/drools/pull/289

Comment 2 Edson Tirelli 2013-12-18 03:33:54 UTC
Applied to 5.3.x, 5.6.x and master:

(5.3.x):
http://github.com/droolsjbpm/drools/commit/05196fa8d

(5.6.x):
http://github.com/droolsjbpm/drools/commit/1621e3bb7

(master):
http://github.com/droolsjbpm/drools/commit/d5e335b86

Thank you!