You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by vi...@apache.org on 2012/07/16 18:53:55 UTC

svn commit: r1362124 - in /incubator/oozie/trunk: ./ client/src/main/resources/ core/src/main/java/org/apache/oozie/workflow/lite/ core/src/test/java/org/apache/oozie/workflow/lite/ core/src/test/resources/ docs/src/site/twiki/

Author: virag
Date: Mon Jul 16 16:53:54 2012
New Revision: 1362124

URL: http://svn.apache.org/viewvc?rev=1362124&view=rev
Log:
OOZIE-874 Eliminate redundancies in xml (britt via virag)

Added:
    incubator/oozie/trunk/client/src/main/resources/hive-action-0.4.xsd
    incubator/oozie/trunk/client/src/main/resources/shell-action-0.3.xsd
    incubator/oozie/trunk/client/src/main/resources/sqoop-action-0.4.xsd
    incubator/oozie/trunk/core/src/test/resources/wf-schema-valid-global.xml
Modified:
    incubator/oozie/trunk/client/src/main/resources/oozie-workflow-0.4.xsd
    incubator/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
    incubator/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
    incubator/oozie/trunk/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
    incubator/oozie/trunk/release-log.txt

Added: incubator/oozie/trunk/client/src/main/resources/hive-action-0.4.xsd
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/client/src/main/resources/hive-action-0.4.xsd?rev=1362124&view=auto
==============================================================================
--- incubator/oozie/trunk/client/src/main/resources/hive-action-0.4.xsd (added)
+++ incubator/oozie/trunk/client/src/main/resources/hive-action-0.4.xsd Mon Jul 16 16:53:54 2012
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:hive="uri:oozie:hive-action:0.4" elementFormDefault="qualified"
+           targetNamespace="uri:oozie:hive-action:0.4">
+
+    <xs:element name="hive" type="hive:ACTION"/>
+
+    <xs:complexType name="ACTION">
+        <xs:sequence>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="prepare" type="hive:PREPARE" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="job-xml" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="configuration" type="hive:CONFIGURATION" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="script" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="param" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="file" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="archive" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="CONFIGURATION">
+        <xs:sequence>
+            <xs:element name="property" minOccurs="1" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="description" minOccurs="0" maxOccurs="1" type="xs:string"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="PREPARE">
+        <xs:sequence>
+            <xs:element name="delete" type="hive:DELETE" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="mkdir" type="hive:MKDIR" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="DELETE">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="MKDIR">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+</xs:schema>

Modified: incubator/oozie/trunk/client/src/main/resources/oozie-workflow-0.4.xsd
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/client/src/main/resources/oozie-workflow-0.4.xsd?rev=1362124&r1=1362123&r2=1362124&view=diff
==============================================================================
--- incubator/oozie/trunk/client/src/main/resources/oozie-workflow-0.4.xsd (original)
+++ incubator/oozie/trunk/client/src/main/resources/oozie-workflow-0.4.xsd Mon Jul 16 16:53:54 2012
@@ -29,6 +29,7 @@
 
     <xs:complexType name="WORKFLOW-APP">
         <xs:sequence>
+        	<xs:element name="global" type="workflow:GLOBAL" minOccurs="0" maxOccurs="1"/>
         	<xs:element name="credentials" type="workflow:CREDENTIALS" minOccurs="0" maxOccurs="1"/>
             <xs:element name="start" type="workflow:START" minOccurs="1" maxOccurs="1"/>
             <xs:choice minOccurs="0" maxOccurs="unbounded">
@@ -43,6 +44,14 @@
         </xs:sequence>
         <xs:attribute name="name" type="xs:string" use="required"/>
     </xs:complexType>
+    
+    <xs:complexType name="GLOBAL">
+    	<xs:sequence>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="configuration" type="workflow:CONFIGURATION" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+    </xs:complexType>
 
     <xs:complexType name="START">
         <xs:attribute name="to" type="workflow:IDENTIFIER" use="required"/>
@@ -139,8 +148,8 @@
 
     <xs:complexType name="MAP-REDUCE">
         <xs:sequence>
-            <xs:element name="job-tracker" type="xs:string" minOccurs="1" maxOccurs="1"/>
-            <xs:element name="name-node" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="prepare" type="workflow:PREPARE" minOccurs="0" maxOccurs="1"/>
             <xs:choice minOccurs="0" maxOccurs="1">
                 <xs:element name="streaming" type="workflow:STREAMING" minOccurs="0" maxOccurs="1"/>
@@ -155,8 +164,8 @@
 
     <xs:complexType name="PIG">
         <xs:sequence>
-            <xs:element name="job-tracker" type="xs:string" minOccurs="1" maxOccurs="1"/>
-            <xs:element name="name-node" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="prepare" type="workflow:PREPARE" minOccurs="0" maxOccurs="1"/>
             <xs:element name="job-xml" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element name="configuration" type="workflow:CONFIGURATION" minOccurs="0" maxOccurs="1"/>
@@ -188,8 +197,8 @@
 
     <xs:complexType name="JAVA">
         <xs:sequence>
-            <xs:element name="job-tracker" type="xs:string" minOccurs="1" maxOccurs="1"/>
-            <xs:element name="name-node" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <xs:element name="prepare" type="workflow:PREPARE" minOccurs="0" maxOccurs="1"/>
             <xs:element name="job-xml" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
             <xs:element name="configuration" type="workflow:CONFIGURATION" minOccurs="0" maxOccurs="1"/>

Added: incubator/oozie/trunk/client/src/main/resources/shell-action-0.3.xsd
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/client/src/main/resources/shell-action-0.3.xsd?rev=1362124&view=auto
==============================================================================
--- incubator/oozie/trunk/client/src/main/resources/shell-action-0.3.xsd (added)
+++ incubator/oozie/trunk/client/src/main/resources/shell-action-0.3.xsd Mon Jul 16 16:53:54 2012
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:shell="uri:oozie:shell-action:0.3" elementFormDefault="qualified"
+           targetNamespace="uri:oozie:shell-action:0.3">
+
+    <xs:element name="shell" type="shell:ACTION"/>
+
+    <xs:complexType name="ACTION">
+      <xs:sequence>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="prepare" type="shell:PREPARE" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="job-xml" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="configuration" type="shell:CONFIGURATION" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="exec" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="argument" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="env-var" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="file" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="archive" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="capture-output" type="shell:FLAG" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="FLAG"/>
+
+    <xs:complexType name="CONFIGURATION">
+        <xs:sequence>
+            <xs:element name="property" minOccurs="1" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="description" minOccurs="0" maxOccurs="1" type="xs:string"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="PREPARE">
+        <xs:sequence>
+            <xs:element name="delete" type="shell:DELETE" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="mkdir" type="shell:MKDIR" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="DELETE">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="MKDIR">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+</xs:schema>

Added: incubator/oozie/trunk/client/src/main/resources/sqoop-action-0.4.xsd
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/client/src/main/resources/sqoop-action-0.4.xsd?rev=1362124&view=auto
==============================================================================
--- incubator/oozie/trunk/client/src/main/resources/sqoop-action-0.4.xsd (added)
+++ incubator/oozie/trunk/client/src/main/resources/sqoop-action-0.4.xsd Mon Jul 16 16:53:54 2012
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:sqoop="uri:oozie:sqoop-action:0.4" elementFormDefault="qualified"
+           targetNamespace="uri:oozie:sqoop-action:0.4">
+
+    <xs:element name="sqoop" type="sqoop:ACTION"/>
+
+    <xs:complexType name="ACTION">
+        <xs:sequence>
+            <xs:element name="job-tracker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="name-node" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="prepare" type="sqoop:PREPARE" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="job-xml" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="configuration" type="sqoop:CONFIGURATION" minOccurs="0" maxOccurs="1"/>
+            <xs:choice>
+                <xs:element name="command" type="xs:string" minOccurs="1" maxOccurs="1"/>
+                <xs:element name="arg" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
+            </xs:choice>
+            <xs:element name="file" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="archive" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="CONFIGURATION">
+        <xs:sequence>
+            <xs:element name="property" minOccurs="1" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="value" minOccurs="1" maxOccurs="1" type="xs:string"/>
+                        <xs:element name="description" minOccurs="0" maxOccurs="1" type="xs:string"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="PREPARE">
+        <xs:sequence>
+            <xs:element name="delete" type="sqoop:DELETE" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="mkdir" type="sqoop:MKDIR" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="DELETE">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="MKDIR">
+        <xs:attribute name="path" type="xs:string" use="required"/>
+    </xs:complexType>
+
+</xs:schema>

Modified: incubator/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java?rev=1362124&r1=1362123&r2=1362124&view=diff
==============================================================================
--- incubator/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java (original)
+++ incubator/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java Mon Jul 16 16:53:54 2012
@@ -59,6 +59,7 @@ public class LiteWorkflowAppParser {
 
     private static final String SLA_INFO = "info";
     private static final String CREDENTIALS = "credentials";
+    private static final String GLOBAL = "global";
 
     private static final String NAME_A = "name";
     private static final String CRED_A = "cred";
@@ -255,6 +256,7 @@ public class LiteWorkflowAppParser {
     private LiteWorkflowApp parse(String strDef, Element root) throws WorkflowException {
         Namespace ns = root.getNamespace();
         LiteWorkflowApp def = null;
+        Element global = null;
         for (Element eNode : (List<Element>) root.getChildren()) {
             if (eNode.getName().equals(START_E)) {
                 def = new LiteWorkflowApp(root.getAttributeValue(NAME_A), strDef,
@@ -311,7 +313,8 @@ public class LiteWorkflowAppParser {
                                                     }
                                                     else {
                                                         eActionConf = elem;
-                                                    }
+                                                        handleGlobal(ns, global, elem);
+                                                        }
                                                 }
                                             }
                                         }
@@ -330,7 +333,12 @@ public class LiteWorkflowAppParser {
                                             // No operation is required
                                         }
                                         else {
-                                            throw new WorkflowException(ErrorCode.E0703, eNode.getName());
+                                            if (eNode.getName().equals(GLOBAL)) {
+                                                global = eNode;
+                                            }
+                                            else {
+                                                throw new WorkflowException(ErrorCode.E0703, eNode.getName());
+                                            }
                                         }
                                     }
                                 }
@@ -409,4 +417,85 @@ public class LiteWorkflowAppParser {
         }
         traversed.put(node.getName(), VisitStatus.VISITED);
     }
+
+    /**
+     * Handle the global section
+     *
+     * @param ns
+     * @param global
+     * @param eActionConf
+     * @throws WorkflowException
+     */
+
+    private void handleGlobal(Namespace ns, Element global, Element eActionConf) throws WorkflowException {
+
+        if (global != null) {
+            Element globalJobTracker = global.getChild("job-tracker", ns);
+            Element globalNameNode = global.getChild("name-node", ns);
+            Element globalConfiguration = global.getChild("configuration", ns);
+
+            if (globalJobTracker != null && eActionConf.getChild("job-tracker", ns) == null) {
+                Element jobTracker = new Element("job-tracker", ns);
+                jobTracker.setText(globalJobTracker.getText());
+                eActionConf.addContent(0, jobTracker);
+            }
+
+            if (globalNameNode != null && eActionConf.getChild("name-node", ns) == null) {
+                Element nameNode = new Element("name-node", ns);
+                nameNode.setText(globalNameNode.getText());
+                eActionConf.addContent(1, nameNode);
+            }
+
+            if (globalConfiguration != null) {
+                Element actionConfiguration = eActionConf.getChild("configuration", ns);
+                if (actionConfiguration == null) {
+                    actionConfiguration = new Element("configuration", ns);
+                    int index = 2;
+                    index += eActionConf.getChild("prepare", ns) == null ? 0 : 2;
+                    index += eActionConf.getChild("job-xml", ns) == null ? 0 : 2;
+                    index += eActionConf.getChild("pipes", ns) == null ? 0 : 2;
+                    index += eActionConf.getChild("streaming", ns) == null ? 0 : 2;
+
+                    eActionConf.addContent(index, actionConfiguration);
+                }
+                for (Element globalConfig : (List<Element>) globalConfiguration.getChildren()) {
+                    boolean isSet = false;
+                    String globalVarName = globalConfig.getChildText("name", ns);
+                    for (Element local : (List<Element>) actionConfiguration.getChildren()) {
+                        if (local.getChildText("name", ns).equals(globalVarName)) {
+                            isSet = true;
+                        }
+                    }
+                    if (!isSet) {
+                        Element varToCopy = new Element("property", ns);
+                        Element varName = new Element("name", ns);
+                        Element varValue = new Element("value", ns);
+
+                        varName.setText(globalConfig.getChildText("name", ns));
+                        varValue.setText(globalConfig.getChildText("value", ns));
+
+                        varToCopy.addContent(varName);
+                        varToCopy.addContent(varValue);
+
+                        actionConfiguration.addContent(varToCopy);
+                    }
+                }
+            }
+        }
+        else {
+            if (eActionConf.getName().equalsIgnoreCase("pig") || eActionConf.getName().equalsIgnoreCase("map-reduce")
+                    || eActionConf.getName().equalsIgnoreCase("java")
+                    || eActionConf.getName().equalsIgnoreCase("shell")
+                    || eActionConf.getName().equalsIgnoreCase("hive")) {
+
+                if (eActionConf.getChild("name-node", ns) == null) {
+                    throw new WorkflowException(ErrorCode.E0701, "No name-node defined");
+                }
+                if (eActionConf.getChild("job-tracker", ns) == null) {
+                    throw new WorkflowException(ErrorCode.E0701, "No job-tracker defined");
+                }
+            }
+        }
+    }
+
 }

Modified: incubator/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java?rev=1362124&r1=1362123&r2=1362124&view=diff
==============================================================================
--- incubator/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java (original)
+++ incubator/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java Mon Jul 16 16:53:54 2012
@@ -56,6 +56,79 @@ public class TestLiteWorkflowAppParser e
         super.tearDown();
     }
 
+    public void testParserGlobal() throws Exception {
+        LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+                                                                 LiteWorkflowStoreService.LiteDecisionHandler.class,
+                                                                 LiteWorkflowStoreService.LiteActionHandler.class);
+
+        LiteWorkflowApp app = parser.validateAndParse(IOUtils.getResourceAsReader("wf-schema-valid-global.xml", -1));
+
+        String d = app.getNode("d").getConf();
+        String expectedD =
+             "<map-reduce xmlns=\"uri:oozie:workflow:0.4\">\r\n" +
+             "  <job-tracker>foo</job-tracker>\r\n" +
+             "  <name-node>bar</name-node>\r\n" +
+             "  <prepare>\r\n" +
+             "    <delete path=\"/tmp\" />\r\n" +
+             "    <mkdir path=\"/tmp\" />\r\n" +
+             "  </prepare>\r\n" +
+             "  <streaming>\r\n" +
+             "    <mapper>/mycat.sh</mapper>\r\n" +
+             "    <reducer>/mywc.sh</reducer>\r\n" +
+             "  </streaming>\r\n" +
+             "  <job-xml>/tmp</job-xml>\r\n" +
+             "  <configuration>\r\n" +
+             "    <property>\r\n" +
+             "      <name>a</name>\r\n" +
+             "      <value>A</value>\r\n" +
+             "    </property>\r\n" +
+             "    <property>\r\n" +
+             "      <name>b</name>\r\n" +
+             "      <value>B</value>\r\n" +
+             "    </property>\r\n" +
+             "  </configuration>\r\n" +
+             "  <file>/tmp</file>\r\n" +
+             "  <archive>/tmp</archive>\r\n" +
+             "</map-reduce>";
+        assertEquals(expectedD.replaceAll(" ",""), d.replaceAll(" ", ""));
+
+    }
+
+    public void testParserGlobalLocalAlreadyExists() throws Exception{
+        LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+                LiteWorkflowStoreService.LiteDecisionHandler.class,
+                LiteWorkflowStoreService.LiteActionHandler.class);
+
+        LiteWorkflowApp app = parser.validateAndParse(IOUtils.getResourceAsReader("wf-schema-valid-global.xml", -1));
+
+        String e = app.getNode("e").getConf();
+        String expectedE =
+                "<pig xmlns=\"uri:oozie:workflow:0.4\">\r\n" +
+                "  <job-tracker>foo</job-tracker>\r\n" +
+                "  <name-node>bar</name-node>\r\n" +
+                "  <prepare>\r\n" +
+                "    <delete path=\"/tmp\" />\r\n" +
+                "    <mkdir path=\"/tmp\" />\r\n" +
+                "  </prepare>\r\n" +
+                "  <configuration>\r\n" +
+                "    <property>\r\n" +
+                "      <name>a</name>\r\n" +
+                "      <value>A2</value>\r\n" +
+                "    </property>\r\n" +
+                "    <property>\r\n" +
+                "      <name>b</name>\r\n" +
+                "      <value>B</value>\r\n" +
+                "    </property>\r\n" +
+                "  </configuration>\r\n" +
+                "  <script>/tmp</script>\r\n" +
+                "  <param>x</param>\r\n" +
+                "  <file>/tmp</file>\r\n" +
+                "  <file>/tmp</file>\r\n" +
+                "</pig>";
+        assertEquals(expectedE.replaceAll(" ",""), e.replaceAll(" ", ""));
+
+    }
+
     public void testParser() throws Exception {
         LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
                                                                  LiteWorkflowStoreService.LiteDecisionHandler.class,

Added: incubator/oozie/trunk/core/src/test/resources/wf-schema-valid-global.xml
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/test/resources/wf-schema-valid-global.xml?rev=1362124&view=auto
==============================================================================
--- incubator/oozie/trunk/core/src/test/resources/wf-schema-valid-global.xml (added)
+++ incubator/oozie/trunk/core/src/test/resources/wf-schema-valid-global.xml Mon Jul 16 16:53:54 2012
@@ -0,0 +1,110 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<workflow-app xmlns="uri:oozie:workflow:0.4" name="test-wf">
+    <global>
+        <job-tracker>foo</job-tracker>
+        <name-node>bar</name-node>
+        <configuration>
+            <property>
+                <name>a</name>
+                <value>A</value>
+            </property>
+            <property>
+                <name>b</name>
+                <value>B</value>
+            </property>
+        </configuration>
+    </global>
+        
+    <start to="a"/>
+    <decision name="a">
+        <switch>
+            <case to="b">true</case>
+            <case to="c">false</case>
+            <default to="c"/>
+        </switch>
+    </decision>
+    <kill name="b">
+        <message>kill</message>
+    </kill>
+
+    <fork name="c">
+        <path start="d"/>
+        <path start="e"/>
+    </fork>
+
+    <action name="d">
+        <map-reduce>
+            <prepare>
+                <delete path="/tmp"/>
+                <mkdir path="/tmp"/>
+            </prepare>
+            <streaming>
+                <mapper>/mycat.sh</mapper>
+                <reducer>/mywc.sh</reducer>
+            </streaming>
+            <job-xml>/tmp</job-xml>
+            <file>/tmp</file>
+            <archive>/tmp</archive>
+        </map-reduce>
+        <ok to="f"/>
+        <error to="b"/>
+    </action>
+
+    <action name="e">
+        <pig>
+            <prepare>
+                <delete path="/tmp"/>
+                <mkdir path="/tmp"/>
+            </prepare>
+            <configuration>
+                <property>
+                    <name>a</name>
+                    <value>A2</value>
+                </property>
+                <property>
+                    <name>b</name>
+                    <value>B</value>
+                </property>
+            </configuration>
+            <script>/tmp</script>
+            <param>x</param>
+            <file>/tmp</file>
+            <file>/tmp</file>
+        </pig>
+        <ok to="f"/>
+        <error to="b"/>
+    </action>
+
+    <join name="f" to="g"/>
+
+    <action name="g">
+        <fs>
+            <mkdir path='/tmp'/>
+            <chmod path='/tmp' permissions='-rwxrw-rw-' dir-files='false'/>
+            <move source='/tmp' target='/tmp2'/>
+            <delete path='/tmp2'/>
+            <mkdir path='/tmp3'/>
+            <delete path='/tmp3'/>
+        </fs>
+        <ok to="z"/>
+        <error to="b"/>
+    </action>
+
+    <end name="z"/>
+</workflow-app>

Modified: incubator/oozie/trunk/docs/src/site/twiki/WorkflowFunctionalSpec.twiki
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/docs/src/site/twiki/WorkflowFunctionalSpec.twiki?rev=1362124&r1=1362123&r2=1362124&view=diff
==============================================================================
--- incubator/oozie/trunk/docs/src/site/twiki/WorkflowFunctionalSpec.twiki (original)
+++ incubator/oozie/trunk/docs/src/site/twiki/WorkflowFunctionalSpec.twiki Mon Jul 16 16:53:54 2012
@@ -2630,6 +2630,31 @@ Examples of User-Retry in a workflow aci
 </action>
 </verbatim>
 
+---++ 19 Global Configurations
+
+Oozie allows a global section to reduce the redundant job-tracker and name-node declarations for each action. The user can define
+a =global= section in the beginning of the workflow.xml . The global section may contain the configuration, job-tracker, or
+name-node that the user would like to set for every action. If a user then redefines one of these in a specific action node,
+Oozie will update use the specific declaration instead of the global one for that action.
+
+Example of a global element:
+
+<verbatim>
+<workflow-app xmlns="uri:oozie:workflow:0.4" name="wf-name">
+<global>
+   <job-tracker>${job-tracker}</job-tracker>
+   <name-node>${namd-node}</name-node>
+   <configuration>
+        <property>
+            <name>mapred.job.queue.name</name>
+            <value>${queueName}</value>
+        </property>
+    </configuration>
+</global>
+...
+</verbatim>
+
+
 ---++ Appendixes
 
 #OozieWFSchema

Modified: incubator/oozie/trunk/release-log.txt
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/release-log.txt?rev=1362124&r1=1362123&r2=1362124&view=diff
==============================================================================
--- incubator/oozie/trunk/release-log.txt (original)
+++ incubator/oozie/trunk/release-log.txt Mon Jul 16 16:53:54 2012
@@ -1,5 +1,6 @@
 -- Oozie 3.3.0 release (trunk - unreleased)
 
+OOZIE-874 Eliminate redundancies in xml (britt via virag)
 OOZIE-900 Indicate that the exception thrown from the db-cli during an error is for debug purposes (harsh)
 OOZIE-865 ForkJoin validator checks total lengths of forks vs. joins instead of actual paths (rkanter via tucu)
 OOZIE-905 Clarify and improve Oozie logging configuration and streaming (rkanter via tucu)