Bug 782915

Summary: rhq-agent's config import does not work
Product: [Other] RHQ Project Reporter: Mike Foley <mfoley>
Component: AgentAssignee: Michael Burman <miburman>
Status: ON_QA --- QA Contact: Mike Foley <mfoley>
Severity: unspecified Docs Contact:
Priority: medium    
Version: 4.3CC: filippespolti, hrupp, loleary, mazz, miburman
Target Milestone: ---   
Target Release: JON 3.1.0   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugzilla.redhat.com/show_bug.cgi?id=1038728
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1038728 (view as bug list) Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Bug Depends On:    
Bug Blocks: 1038728, 1127873    

Description Mike Foley 2012-01-18 15:50:42 EST
Description of problem:  rhq-agent's config import does not work


Version-Release number of selected component (if applicable):  JON 2.4.2


How reproducible:
100%

Steps to Reproduce:
1.  from the agent prompt >  ... type 'config list'
2.  copy that output into a file  ... eg, myfile2.xml
3.  config import  /path/to/file/myfile2.xml
4.  observe error #1 below  
5.  copy prefs.xml to myfile3.xml  
6.  config import /path/to/file/myfile3.xml
7.  observe error #2 below
  
Actual results:  unable to import an agent configuration


Expected results:  
1) able to import a configuration. 
2) i guess the expectation is that either 
a) an agent configuration file is identical to what is displayed with config list, 
b) an agent configuration file is identical to prefs.xml
c) an agent configuration file is otherwise documented as to what it is supposed to look like   


Additional info:

ERROR   -- importing a file created from 'config list'

Failed to perform config command; stack trace follows:
java.util.prefs.InvalidPreferencesFormatException: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 41; Document root element "preferences", must match DOCTYPE root "null".
	at java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:216)
	at java.util.prefs.Preferences.importPreferences(Preferences.java:1253)
	at org.rhq.enterprise.agent.AgentMain.loadConfigurationFile(AgentMain.java:1214)
	at org.rhq.enterprise.agent.promptcmd.ConfigPromptCommand.execute(ConfigPromptCommand.java:82)
	at org.rhq.enterprise.agent.AgentMain.executePromptCommand(AgentMain.java:2860)
	at org.rhq.enterprise.agent.AgentMain$5.run(AgentMain.java:2768)
	at java.lang.Thread.run(Thread.java:636)
Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 41; Document root element "preferences", must match DOCTYPE root "null".
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:387)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:321)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.rootElementSpecified(XMLDTDValidator.java:1624)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.handleStartElement(XMLDTDValidator.java:1903)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:767)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1340)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1293)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3080)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:899)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:625)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:741)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:239)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:288)
	at java.util.prefs.XmlSupport.loadPrefsDoc(XmlSupport.java:250)
	at java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:199)
	... 6 more




ERROR #2 -- trying to import a configuration identical to prefs.xml

> config import /root/.java/.userPrefs/rhq-agent/default/myfile.xml 
Failed to perform config command; stack trace follows:
java.lang.NullPointerException
	at java.util.prefs.XmlSupport.ImportPrefs(XmlSupport.java:326)
	at java.util.prefs.XmlSupport.ImportSubtree(XmlSupport.java:306)
	at java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:214)
	at java.util.prefs.Preferences.importPreferences(Preferences.java:1253)
	at org.rhq.enterprise.agent.AgentMain.loadConfigurationFile(AgentMain.java:1214)
	at org.rhq.enterprise.agent.promptcmd.ConfigPromptCommand.execute(ConfigPromptCommand.java:82)
	at org.rhq.enterprise.agent.AgentMain.executePromptCommand(AgentMain.java:2860)
	at org.rhq.enterprise.agent.AgentMain$5.run(AgentMain.java:2768)
	at java.lang.Thread.run(Thread.java:636)
Comment 1 Charles Crouch 2012-01-20 10:46:51 EST
This is not a mainline usecase, but should obviously still function.
Comment 2 John Mazzitelli 2012-05-14 17:03:07 EDT
for the record, use the "export" option, rather than rely on copy-n-paste so your step 1 and 2 can be combined:

1. from the agent prompt >  ... type 'config export myfile2.xml'

The Java Prefs API javadoc says:

     * The XML document must have the following DOCTYPE declaration:
     * <!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">

The agent uses the Java Pref APIs to export the XML, and this DOES have that DOCTYPE. HOWEVER, in our Java code, we strip it out, with the comment on that code saying this:

        /*
         * Filter out the <!DOCTYPE ... > as parsing the xml later
         * would trigger a lookup over the net to http://java.sun.com,
         * which can make this method fail if the external server is not
         * reachable. See RHQ-520
         */
        String prefs = unformatted.toString();
        int start = prefs.indexOf("<!DOCTYPE");
        int end = prefs.indexOf(">", start);
        String filteredPrefs = prefs.substring(0, start);
        filteredPrefs += prefs.substring(end + 1);

RHQ-520 is bug 536138 - this was code that was committed 4 years ago. Not sure why import is not working all of a sudden.
Comment 4 Filippe Spolti 2014-05-13 18:54:25 EDT
Same problem here.
Version 4.10.0
Comment 5 Heiko W. Rupp 2014-06-23 12:20:44 EDT
I think we need to address this twofold:

- figure out if reading/writing still makes a ping to sun.com with modern jvms. If not, remove the filtering code from RHQ-520 so that in the future the doctype is not removed.

- on import add the doctype back if it does not exist. Something along:
            String new_config = StringPropertyReplacer.replaceProperties(raw_config_file.toString(), replacements);

-----------
            if (!new_config.contains(DOCTYPE_PREFERENCES_SHORT)) {
                String tmp;
                if (new_config.startsWith("<?xml")) { // get xml content after declaratiation
                    tmp = new_config.substring(new_config.indexOf(">")+1);
                } else {
                    tmp = new_config;
                }
                new_config = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n" +
                    DOCTYPE_PREFERENCES + "\n" +
                    tmp;
            }
----------
with String DOCTYPE_PREFERENCES_SHORT = "<!DOCTYPE preferences";


            ByteArrayInputStream new_config_input_stream = new ByteArrayInputStream(new_config.getBytes());


I've run wireshark on config import and on jdk7, no http connection is made at import time.
Comment 6 Michael Burman 2014-07-11 09:35:09 EDT
Java 5, 6, 7 and 8 javadoc says:

"Note that the system URI (http://java.sun.com/dtd/preferences.dtd) is not accessed when exporting or importing preferences; it merely serves as a string to uniquely identify the DTD"

http://docs.oracle.com/javase/7/docs/api/java/util/prefs/Preferences.html

The original bug seems to be because of indentation that's done with DOM (and DocumentBuilderFactory will try to fetch the DTD)
Comment 7 Michael Burman 2014-07-11 15:23:25 EDT
Fixed in master (with unit test):

commit f65fc7a4ea4ef7ac6beeb39af61e814f7eb24f79
Author: burmanm <miburman@redhat.com>
Date:   Fri Jul 11 22:21:35 2014 +0300

    [BZ 782915] Add support for importing agent configuration files without existing DOCTYPE declaration