Author: rkanter
Date: Thu Aug  8 20:45:56 2013
New Revision: 1512024

URL: http://svn.apache.org/r1512024
Log:
OOZIE-1443 forkjoin validation should not allow a fork to go to the same node 
multiple times (rkanter)

Modified:
    oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java
    
oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
    
oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
    oozie/trunk/release-log.txt

Modified: oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java
URL: 
http://svn.apache.org/viewvc/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java?rev=1512024&r1=1512023&r2=1512024&view=diff
==============================================================================
--- oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java (original)
+++ oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java Thu Aug  8 
20:45:56 2013
@@ -149,6 +149,7 @@ public enum ErrorCode {
     E0741(XLog.STD, "Cycle detected transitioning to [{0}] via path {1}"),
     E0742(XLog.STD, "No Fork for Join [{0}] to pair with"),
     E0743(XLog.STD, "Multiple \"ok to\" transitions to the same node, [{0}], 
are not allowed"),
+    E0744(XLog.STD, "A fork, [{0}], is not allowed to have multiple 
transitions to the same node, [{1}]"),
 
     E0800(XLog.STD, "Action it is not running its in [{1}] state, action 
[{0}]"),
     E0801(XLog.STD, "Workflow already running, workflow [{0}]"),

Modified: 
oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
URL: 
http://svn.apache.org/viewvc/oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java?rev=1512024&r1=1512023&r2=1512024&view=diff
==============================================================================
--- 
oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
 (original)
+++ 
oozie/trunk/core/src/main/java/org/apache/oozie/workflow/lite/LiteWorkflowAppParser.java
 Thu Aug  8 20:45:56 2013
@@ -272,7 +272,25 @@ public class LiteWorkflowAppParser {
         }
         else if (node instanceof ForkNodeDef) {
             forkNodes.push(node.getName());
-            for(String transition : (new 
HashSet<String>(node.getTransitions()))) {
+            List<String> transitionsList = node.getTransitions();
+            HashSet<String> transitionsSet = new 
HashSet<String>(transitionsList);
+            // Check that a fork doesn't go to the same node more than once
+            if (!transitionsList.isEmpty() && transitionsList.size() != 
transitionsSet.size()) {
+                // Now we have to figure out which node is the problem and 
what type of node they are (join and kill are ok)
+                for (int i = 0; i < transitionsList.size(); i++) {
+                    String a = transitionsList.get(i);
+                    NodeDef aNode = app.getNode(a);
+                    if (!(aNode instanceof JoinNodeDef) && !(aNode instanceof 
KillNodeDef)) {
+                        for (int k = i+1; k < transitionsList.size(); k++) {
+                            String b = transitionsList.get(k);
+                            if (a.equals(b)) {
+                                throw new WorkflowException(ErrorCode.E0744, 
node.getName(), a);
+                            }
+                        }
+                    }
+                }
+            }
+            for(String transition : transitionsSet) {
                 NodeDef tranNode = app.getNode(transition);
                 validateForkJoin(tranNode, app, forkNodes, joinNodes, path, 
okTo, topDecisionParent);
             }

Modified: 
oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
URL: 
http://svn.apache.org/viewvc/oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java?rev=1512024&r1=1512023&r2=1512024&view=diff
==============================================================================
--- 
oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
 (original)
+++ 
oozie/trunk/core/src/test/java/org/apache/oozie/workflow/lite/TestLiteWorkflowAppParser.java
 Thu Aug  8 20:45:56 2013
@@ -1068,6 +1068,39 @@ public class TestLiteWorkflowAppParser e
         }
     }
 
+    /*
+     * f->(1,2,2)
+     * 1->ok->j
+     * 1->fail->k
+     * 2->ok->j
+     * 2->fail->k
+     * j->end
+     */
+    public void testForkJoinDuplicateTransitionsFromFork() throws 
WorkflowException {
+        LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+                LiteWorkflowStoreService.LiteControlNodeHandler.class,
+                LiteWorkflowStoreService.LiteDecisionHandler.class,
+                LiteWorkflowStoreService.LiteActionHandler.class);
+        LiteWorkflowApp def = new LiteWorkflowApp("name", "def",
+            new 
StartNodeDef(LiteWorkflowStoreService.LiteControlNodeHandler.class, "f"))
+        .addNode(new ForkNodeDef("f", 
LiteWorkflowStoreService.LiteControlNodeHandler.class,
+                        Arrays.asList(new String[]{"one", "two", "two"})))
+        .addNode(new ActionNodeDef("one", dummyConf, 
TestActionNodeHandler.class, "j", "k"))
+        .addNode(new JoinNodeDef("j", 
LiteWorkflowStoreService.LiteControlNodeHandler.class, "end"))
+        .addNode(new ActionNodeDef("two", dummyConf, 
TestActionNodeHandler.class, "j", "k"))
+        .addNode(new KillNodeDef("k", "kill", 
LiteWorkflowStoreService.LiteControlNodeHandler.class))
+        .addNode(new EndNodeDef("end", 
LiteWorkflowStoreService.LiteControlNodeHandler.class));
+        try {
+            invokeForkJoin(parser, def);
+            fail("Expected to catch an exception but did not encounter any");
+        } catch (Exception ex) {
+            WorkflowException we = (WorkflowException) ex.getCause();
+            assertEquals(ErrorCode.E0744, we.getErrorCode());
+            assertTrue(we.getMessage().contains("fork, [f],"));
+            assertTrue(we.getMessage().contains("node, [two]"));
+        }
+    }
+
     // Invoke private validateForkJoin method using Reflection API
     private void invokeForkJoin(LiteWorkflowAppParser parser, LiteWorkflowApp 
def) throws Exception {
         Class<? extends LiteWorkflowAppParser> c = parser.getClass();

Modified: oozie/trunk/release-log.txt
URL: 
http://svn.apache.org/viewvc/oozie/trunk/release-log.txt?rev=1512024&r1=1512023&r2=1512024&view=diff
==============================================================================
--- oozie/trunk/release-log.txt (original)
+++ oozie/trunk/release-log.txt Thu Aug  8 20:45:56 2013
@@ -1,5 +1,6 @@
 -- Oozie 4.1.0 release (trunk - unreleased)
 
+OOZIE-1443 forkjoin validation should not allow a fork to go to the same node 
multiple times (rkanter)
 OOZIE-1471 Support glob in FS action and prepare blocks (ryota)
 OOZIE-1403 forkjoin validation blocks some valid cases involving decision 
nodes (rkanter)
 OOZIE-1449 Coordinator Workflow parent relationship is broken for purge 
service (rkanter)


Reply via email to