You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by an...@apache.org on 2012/02/25 01:50:41 UTC
svn commit: r1293498 - in /incubator/oozie/trunk: ./
core/src/main/java/org/apache/oozie/
core/src/main/java/org/apache/oozie/workflow/lite/
core/src/test/java/org/apache/oozie/workflow/lite/
Author: angeloh
Date: Sat Feb 25 00:50:40 2012
New Revision: 1293498
URL: http://svn.apache.org/viewvc?rev=1293498&view=rev
Log:
OOZIE-693 Fork-join validation doesn't check for the 'error to' transition of nodes (Virag Kothari via Angelo)
Modified:
incubator/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java
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/release-log.txt
Modified: incubator/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java?rev=1293498&r1=1293497&r2=1293498&view=diff
==============================================================================
--- incubator/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java (original)
+++ incubator/oozie/trunk/core/src/main/java/org/apache/oozie/ErrorCode.java Sat Feb 25 00:50:40 2012
@@ -138,6 +138,7 @@ public enum ErrorCode {
E0732(XLog.STD, "Fork [{0}]/Join [{1}] not in pair"),
E0733(XLog.STD, "Fork [{0}] without a join"),
E0734(XLog.STD, "Invalid transition from node [{0}] to node [{1}] while using fork/join"),
+ E0735(XLog.STD, "There was an invalid \"error to\" transition to node [{1}] while using fork/join"),
E0800(XLog.STD, "Action it is not running its in [{1}] state, action [{0}]"),
E0801(XLog.STD, "Workflow already running, workflow [{0}]"),
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=1293498&r1=1293497&r2=1293498&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 Sat Feb 25 00:50:40 2012
@@ -164,6 +164,8 @@ public class LiteWorkflowAppParser {
*/
private NodeDef validateFork(NodeDef forkNode, LiteWorkflowApp app) throws WorkflowException {
List<String> transitions = new ArrayList<String>(forkNode.getTransitions());
+ // list for keeping track of "error-to" transitions of Action Node
+ List<String> errorToTransitions = new ArrayList<String>();
String joinNode = null;
for (int i = 0; i < transitions.size(); i++) {
NodeDef node = app.getNode(transitions.get(i));
@@ -177,19 +179,23 @@ public class LiteWorkflowAppParser {
}
}
} else if (node instanceof ActionNodeDef) {
- // Get only the "ok-to" transition of node
- String okToTransition = node.getTransitions().get(0);
// Make sure the transition is valid
- validateTransition(transitions, app, okToTransition, node);
- transitions.add(okToTransition);
+ validateTransition(errorToTransitions, transitions, app, node);
+ // Add the "ok-to" transition of node
+ transitions.add(node.getTransitions().get(0));
+ String errorTo = node.getTransitions().get(1);
+ // Add the "error-to" transition if the transition is a Action Node
+ if (app.getNode(errorTo) instanceof ActionNodeDef) {
+ errorToTransitions.add(errorTo);
+ }
} else if (node instanceof ForkNodeDef) {
forkList.remove(node.getName());
// Make a recursive call to resolve this fork node
NodeDef joinNd = validateFork(node, app);
- String okToTransition = joinNd.getTransitions().get(0);
// Make sure the transition is valid
- validateTransition(transitions, app, okToTransition, node);
- transitions.add(okToTransition);
+ validateTransition(errorToTransitions, transitions, app, node);
+ // Add the "ok-to" transition of node
+ transitions.add(joinNd.getTransitions().get(0));
} else if (node instanceof JoinNodeDef) {
// If joinNode encountered for the first time, remove it from the joinList and remember it
String currentJoin = node.getName();
@@ -213,12 +219,19 @@ public class LiteWorkflowAppParser {
}
- private void validateTransition(List<String> transitions, LiteWorkflowApp app, String okToTransition, NodeDef node)
+ private void validateTransition(List<String> errorToTransitions, List<String> transitions, LiteWorkflowApp app, NodeDef node)
throws WorkflowException {
- // Make sure the transition node is either a join node or is not already visited
- if (transitions.contains(okToTransition) && !(app.getNode(okToTransition) instanceof JoinNodeDef)) {
- throw new WorkflowException(ErrorCode.E0734, node.getName(), okToTransition);
+ for (String transition : node.getTransitions()) {
+ // Make sure the transition node is either a join node or is not already visited
+ if (transitions.contains(transition) && !(app.getNode(transition) instanceof JoinNodeDef)) {
+ throw new WorkflowException(ErrorCode.E0734, node.getName(), transition);
+ }
+ // Make sure the transition node is not the same as an already visited 'error-to' transition
+ if (errorToTransitions.contains(transition)) {
+ throw new WorkflowException(ErrorCode.E0735, node.getName(), transition);
+ }
}
+
}
/**
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=1293498&r1=1293497&r2=1293498&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 Sat Feb 25 00:50:40 2012
@@ -121,7 +121,7 @@ public class TestLiteWorkflowAppParser e
invokeForkJoin(parser, def);
} catch (Exception e) {
e.printStackTrace();
- fail();
+ fail("Unexpected Exception");
}
}
@@ -147,7 +147,7 @@ public class TestLiteWorkflowAppParser e
invokeForkJoin(parser, def);
} catch (Exception e) {
e.printStackTrace();
- fail();
+ fail("Unexpected Exception");
}
}
@@ -183,7 +183,7 @@ public class TestLiteWorkflowAppParser e
invokeForkJoin(parser, def);
} catch (Exception e) {
e.printStackTrace();
- fail();
+ fail("Unexpected Exception");
}
}
@@ -207,7 +207,7 @@ public class TestLiteWorkflowAppParser e
try {
invokeForkJoin(parser, def);
- fail();
+ fail("Expected to catch an exception but did not encounter any");
} catch (Exception ex) {
WorkflowException we = (WorkflowException) ex.getCause();
assertEquals(ErrorCode.E0730, we.getErrorCode());
@@ -245,7 +245,7 @@ public class TestLiteWorkflowAppParser e
try {
invokeForkJoin(parser, def);
- fail();
+ fail("Expected to catch an exception but did not encounter any");
} catch (Exception ex) {
WorkflowException we = (WorkflowException) ex.getCause();
assertEquals(ErrorCode.E0730, we.getErrorCode());
@@ -259,7 +259,7 @@ public class TestLiteWorkflowAppParser e
3->ok->j
3->fail->end
*/
- public void testTransitionFailure() throws WorkflowException{
+ public void testTransitionFailure1() throws WorkflowException{
LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
LiteWorkflowStoreService.LiteDecisionHandler.class,
LiteWorkflowStoreService.LiteActionHandler.class);
@@ -274,7 +274,7 @@ public class TestLiteWorkflowAppParser e
try {
invokeForkJoin(parser, def);
- fail();
+ fail("Expected to catch an exception but did not encounter any");
} catch (Exception ex) {
WorkflowException we = (WorkflowException) ex.getCause();
assertEquals(ErrorCode.E0734, we.getErrorCode());
@@ -287,6 +287,108 @@ public class TestLiteWorkflowAppParser e
/*
f->(2,3)
+ 2->fail->3
+ 2->ok->j
+ 3->ok->j
+ 3->fail->end
+ */
+ public void testTransitionFailure2() throws WorkflowException{
+ LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+ LiteWorkflowStoreService.LiteDecisionHandler.class,
+ LiteWorkflowStoreService.LiteActionHandler.class);
+
+ LiteWorkflowApp def = new LiteWorkflowApp("name", "def", new StartNodeDef("one"))
+ .addNode(new ActionNodeDef("one", dummyConf, TestActionNodeHandler.class, "f","end"))
+ .addNode(new ForkNodeDef("f", Arrays.asList(new String[]{"two","three"})))
+ .addNode(new ActionNodeDef("two", dummyConf, TestActionNodeHandler.class, "j", "three"))
+ .addNode(new ActionNodeDef("three", dummyConf, TestActionNodeHandler.class, "j", "end"))
+ .addNode(new JoinNodeDef("j", "end"))
+ .addNode(new EndNodeDef("end"));
+
+ 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.E0734, we.getErrorCode());
+ // Make sure the message contains the nodes involved in the invalid transition
+ assertTrue(we.getMessage().contains("two"));
+ assertTrue(we.getMessage().contains("three"));
+ }
+
+ }
+
+ /*
+ f->(2,3)
+ 2->ok->j
+ 3->ok->4
+ 2->fail->4
+ 4->ok->j
+ */
+ public void testTransitionFailure3() throws WorkflowException{
+ LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+ LiteWorkflowStoreService.LiteDecisionHandler.class,
+ LiteWorkflowStoreService.LiteActionHandler.class);
+
+ LiteWorkflowApp def = new LiteWorkflowApp("name", "def", new StartNodeDef("one"))
+ .addNode(new ActionNodeDef("one", dummyConf, TestActionNodeHandler.class, "f","end"))
+ .addNode(new ForkNodeDef("f", Arrays.asList(new String[]{"two","three"})))
+ .addNode(new ActionNodeDef("two", dummyConf, TestActionNodeHandler.class, "j", "four"))
+ .addNode(new ActionNodeDef("three", dummyConf, TestActionNodeHandler.class, "four", "end"))
+ .addNode(new ActionNodeDef("four", dummyConf, TestActionNodeHandler.class, "j", "end"))
+ .addNode(new JoinNodeDef("j", "end"))
+ .addNode(new EndNodeDef("end"));
+
+ 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.E0735, we.getErrorCode());
+ // Make sure the message contains the node involved in the invalid transition
+ assertTrue(we.getMessage().contains("four"));
+ }
+ }
+
+ /*
+ * f->(2,3)
+ * 2->ok->j
+ * 3->ok->j
+ * j->end
+ * 2->error->f1
+ * 3->error->f1
+ * f1->(4,5)
+ * (4,5)->j1
+ * j1->end
+ */
+ public void testErrorTransitionForkJoin() throws WorkflowException {
+ LiteWorkflowAppParser parser = new LiteWorkflowAppParser(null,
+ LiteWorkflowStoreService.LiteDecisionHandler.class,
+ LiteWorkflowStoreService.LiteActionHandler.class);
+
+ LiteWorkflowApp def = new LiteWorkflowApp("wf", "<worklfow-app/>", new StartNodeDef("one"))
+ .addNode(new ActionNodeDef("one", dummyConf, TestActionNodeHandler.class, "f", "end"))
+ .addNode(new ForkNodeDef("f", Arrays.asList(new String[]{"two", "three"})))
+ .addNode(new ActionNodeDef("two", dummyConf, TestActionNodeHandler.class, "j", "f1"))
+ .addNode(new ActionNodeDef("three", dummyConf, TestActionNodeHandler.class, "j", "f1"))
+ .addNode(new ForkNodeDef("f1", Arrays.asList(new String[]{"four", "five"})))
+ .addNode(new ActionNodeDef("four", dummyConf, TestActionNodeHandler.class, "j1", "end"))
+ .addNode(new ActionNodeDef("five", dummyConf, TestActionNodeHandler.class, "j1", "end"))
+ .addNode(new JoinNodeDef("j", "six"))
+ .addNode(new JoinNodeDef("j1", "six"))
+ .addNode(new ActionNodeDef("six", dummyConf, TestActionNodeHandler.class, "end", "end"))
+ .addNode(new EndNodeDef("end"));
+
+ try {
+ invokeForkJoin(parser, def);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Unexpected Exception");
+ }
+ }
+
+ /*
+ f->(2,3)
2->decision node->{4,5,4}
4->j
5->j
@@ -310,7 +412,7 @@ public class TestLiteWorkflowAppParser e
invokeForkJoin(parser, def);
} catch (Exception e) {
e.printStackTrace();
- fail();
+ fail("Unexpected Exception");
}
}
@@ -335,7 +437,7 @@ public class TestLiteWorkflowAppParser e
try {
invokeForkJoin(parser, def);
- fail();
+ fail("Expected to catch an exception but did not encounter any");
} catch (Exception ex) {
WorkflowException we = (WorkflowException) ex.getCause();
assertEquals(ErrorCode.E0734, we.getErrorCode());
@@ -374,14 +476,14 @@ public class TestLiteWorkflowAppParser e
invokeForkJoin(parser, def);
} catch (Exception e) {
e.printStackTrace();
- fail();
+ fail("Unexpected Exception");
}
}
// Invoke private validateForkJoin method using Reflection API
private void invokeForkJoin(LiteWorkflowAppParser parser, LiteWorkflowApp def) throws Exception {
Class<? extends LiteWorkflowAppParser> c = parser.getClass();
- Class d = Class.forName("org.apache.oozie.workflow.lite.LiteWorkflowAppParser$VisitStatus");
+ Class<?> d = Class.forName("org.apache.oozie.workflow.lite.LiteWorkflowAppParser$VisitStatus");
Field f = d.getField("VISITING");
Map traversed = new HashMap();
traversed.put(def.getNode(StartNodeDef.START).getName(), f);
Modified: incubator/oozie/trunk/release-log.txt
URL: http://svn.apache.org/viewvc/incubator/oozie/trunk/release-log.txt?rev=1293498&r1=1293497&r2=1293498&view=diff
==============================================================================
--- incubator/oozie/trunk/release-log.txt (original)
+++ incubator/oozie/trunk/release-log.txt Sat Feb 25 00:50:40 2012
@@ -1,5 +1,6 @@
-- Oozie 3.2.0 release
+OOZIE-693 Fork-join validation doesn't check for the 'error to' transition of nodes (Virag Kothari via Angelo)
OOZIE-616 Moving action prepare FS execution to LauncherMapper ( Kiran Nagasubramanian via Angelo)
OOZIE-687 The start time of the action is set after the job is already submitted to hadoop (Mohamed Battisha vis Angelo)
OOZIE-712 Hive testcases fail with 0.23 (tucu)