You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by ro...@apache.org on 2013/09/21 00:55:42 UTC

svn commit: r1525167 - in /oozie/trunk: ./ core/src/main/java/org/apache/oozie/servlet/ core/src/main/java/org/apache/oozie/util/ core/src/test/java/org/apache/oozie/util/ core/src/test/resources/ webapp/src/main/webapp/

Author: rohini
Date: Fri Sep 20 22:55:41 2013
New Revision: 1525167

URL: http://svn.apache.org/r1525167
Log:
OOZIE-1529 Disable job DAG display for workflow having huge actions (puru via rohini)

Added:
    oozie/trunk/core/src/test/resources/graphWF_26_actions.xml
Modified:
    oozie/trunk/core/src/main/java/org/apache/oozie/servlet/V1JobServlet.java
    oozie/trunk/core/src/main/java/org/apache/oozie/util/GraphGenerator.java
    oozie/trunk/core/src/test/java/org/apache/oozie/util/TestGraphGenerator.java
    oozie/trunk/release-log.txt
    oozie/trunk/webapp/src/main/webapp/oozie-console.js

Modified: oozie/trunk/core/src/main/java/org/apache/oozie/servlet/V1JobServlet.java
URL: http://svn.apache.org/viewvc/oozie/trunk/core/src/main/java/org/apache/oozie/servlet/V1JobServlet.java?rev=1525167&r1=1525166&r2=1525167&view=diff
==============================================================================
--- oozie/trunk/core/src/main/java/org/apache/oozie/servlet/V1JobServlet.java (original)
+++ oozie/trunk/core/src/main/java/org/apache/oozie/servlet/V1JobServlet.java Fri Sep 20 22:55:41 2013
@@ -19,9 +19,11 @@ package org.apache.oozie.servlet;
 
 import java.io.IOException;
 import java.util.List;
+
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import org.apache.hadoop.conf.Configuration;
 import org.apache.oozie.*;
 import org.apache.oozie.client.WorkflowAction;
@@ -36,6 +38,7 @@ import org.apache.oozie.service.Services
 import org.apache.oozie.util.GraphGenerator;
 import org.apache.oozie.util.XLog;
 import org.json.simple.JSONObject;
+import org.xml.sax.SAXException;
 
 
 @SuppressWarnings("serial")
@@ -280,9 +283,10 @@ public class V1JobServlet extends BaseJo
             throws XServletException, IOException {
         String jobId = getResourceName(request);
         if (jobId.endsWith("-W")) {
-            // Applicable only to worflow, for now
-            response.setContentType(RestConstants.PNG_IMAGE_CONTENT_TYPE);
             try {
+                // Applicable only to worflow, for now
+                response.setContentType(RestConstants.PNG_IMAGE_CONTENT_TYPE);
+
                 String showKill = request.getParameter(RestConstants.JOB_SHOW_KILL_PARAM);
                 boolean sK = showKill != null && (showKill.equalsIgnoreCase("yes") || showKill.equals("1") || showKill.equalsIgnoreCase("true"));
 
@@ -290,9 +294,10 @@ public class V1JobServlet extends BaseJo
                         getWorkflowJobDefinition(request, response),
                         (WorkflowJobBean)getWorkflowJob(request, response),
                         sK).write(response.getOutputStream());
+
             }
             catch (Exception e) {
-                throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorCode.E0307, e.getMessage(), e);
+                throw new XServletException(HttpServletResponse.SC_NOT_FOUND, ErrorCode.E0307, e.getMessage(), e);
             }
         }
         else {

Modified: oozie/trunk/core/src/main/java/org/apache/oozie/util/GraphGenerator.java
URL: http://svn.apache.org/viewvc/oozie/trunk/core/src/main/java/org/apache/oozie/util/GraphGenerator.java?rev=1525167&r1=1525166&r2=1525167&view=diff
==============================================================================
--- oozie/trunk/core/src/main/java/org/apache/oozie/util/GraphGenerator.java (original)
+++ oozie/trunk/core/src/main/java/org/apache/oozie/util/GraphGenerator.java Fri Sep 20 22:55:41 2013
@@ -22,6 +22,7 @@ import edu.uci.ics.jung.graph.util.Conte
 import edu.uci.ics.jung.visualization.VisualizationImageServer;
 import edu.uci.ics.jung.visualization.renderers.Renderer;
 import edu.uci.ics.jung.visualization.util.ArrowFactory;
+
 import java.awt.*;
 import java.awt.geom.Ellipse2D;
 import java.awt.geom.Point2D;
@@ -29,13 +30,17 @@ import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringReader;
+import java.nio.charset.Charset;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+
 import javax.imageio.ImageIO;
+import javax.swing.plaf.basic.BasicTextUI;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+
 import org.apache.commons.collections15.Transformer;
 import org.apache.oozie.WorkflowJobBean;
 import org.apache.oozie.client.WorkflowAction;
@@ -55,6 +60,7 @@ public class GraphGenerator {
     private String xml;
     private WorkflowJobBean job;
     private boolean showKill = false;
+    private final int actionsLimit = 25;
 
     /**
      * C'tor
@@ -284,7 +290,6 @@ public class GraphGenerator {
                                 String qName,
                                 Attributes atts)
             throws SAXException {
-
             if(localName.equalsIgnoreCase("start")) {
                 String start = localName.toLowerCase();
                 if(!tags.containsKey(start)) {
@@ -329,6 +334,10 @@ public class GraphGenerator {
                     tags.put(name, new OozieWFNode(name, localName.toLowerCase()));
                 }
             }
+            if (tags.size() > actionsLimit) {
+                tags.clear();
+                throw new SAXException("Can't display the graph. Number of actions are more than display limit " + actionsLimit);
+            }
         }
 
         @Override

Modified: oozie/trunk/core/src/test/java/org/apache/oozie/util/TestGraphGenerator.java
URL: http://svn.apache.org/viewvc/oozie/trunk/core/src/test/java/org/apache/oozie/util/TestGraphGenerator.java?rev=1525167&r1=1525166&r2=1525167&view=diff
==============================================================================
--- oozie/trunk/core/src/test/java/org/apache/oozie/util/TestGraphGenerator.java (original)
+++ oozie/trunk/core/src/test/java/org/apache/oozie/util/TestGraphGenerator.java Fri Sep 20 22:55:41 2013
@@ -15,14 +15,19 @@
  */
 package org.apache.oozie.util;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
+
 import javax.imageio.ImageIO;
+
 import junit.framework.Assert;
 
 import org.apache.oozie.WorkflowJobBean;
@@ -108,6 +113,28 @@ public class TestGraphGenerator extends 
         new File("src/test/resources/invalid.png").delete();
     }
 
+    public void testJobDAGLimit_more() throws IOException {
+        WorkflowJobBean jsonWFJob = new WorkflowJobBean();
+        jsonWFJob.setAppName("My Test App");
+        jsonWFJob.setId("My Test ID");
+        String txt = "src/test/resources/tmp1.txt";
+
+        try {
+            GraphGenerator g = new GraphGenerator(readFile("src/test/resources/graphWF_26_actions.xml"), jsonWFJob);
+            g.write(new FileOutputStream(new File(txt)));
+            Assert.fail("This should not get executed");
+
+        }
+        catch (Exception e) {
+            Assert.assertTrue(e.getMessage().startsWith(
+                    "Can't display the graph. Number of actions are more than display limit"));
+        }
+
+        File f1 = new File(txt);
+        f1.delete();
+
+    }
+
     private static String readFile(String path) throws IOException {
         File f = new File(path);
         System.out.println("Reading input file " + f.getAbsolutePath());

Added: oozie/trunk/core/src/test/resources/graphWF_26_actions.xml
URL: http://svn.apache.org/viewvc/oozie/trunk/core/src/test/resources/graphWF_26_actions.xml?rev=1525167&view=auto
==============================================================================
--- oozie/trunk/core/src/test/resources/graphWF_26_actions.xml (added)
+++ oozie/trunk/core/src/test/resources/graphWF_26_actions.xml Fri Sep 20 22:55:41 2013
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.2" name="sm3-segment-3908-251483">
+    <start to="or_0_1" />
+    <kill name="kill">
+        <message>killed message</message>
+    </kill>
+    <action name="or_0_1">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_2" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_2">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_3" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_3">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_4" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_4">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_5" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_5">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_6" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_6">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_7" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_7">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_8" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_8">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_1_9" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_1_9">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_0" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_0">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_1" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_1">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_2" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_2">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_3" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_3">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_4" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_4">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_5" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_5">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_6" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_6">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_7" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_7">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_8" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_8">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_2_9" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_2_9">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_3_0" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_3_0">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_3_1" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_3_1">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_3_2" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_3_2">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_3_3" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_3_3">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="or_or_0_3_4" />
+        <error to="kill" />
+    </action>
+
+    <action name="or_or_0_3_4">
+        <pig>
+            <job-tracker>${jobTracker}</job-tracker>
+            <name-node>${nameNode}</name-node>
+            <script>echo.pig</script>
+        </pig>
+        <ok to="cleanup" />
+        <error to="kill" />
+    </action>
+
+    <action name="cleanup">
+        <fs>
+        </fs>
+        <ok to="end" />
+        <error to="kill" />
+    </action>
+    <end name="end" />
+</workflow-app>

Modified: oozie/trunk/release-log.txt
URL: http://svn.apache.org/viewvc/oozie/trunk/release-log.txt?rev=1525167&r1=1525166&r2=1525167&view=diff
==============================================================================
--- oozie/trunk/release-log.txt (original)
+++ oozie/trunk/release-log.txt Fri Sep 20 22:55:41 2013
@@ -1,5 +1,6 @@
 -- Oozie 4.1.0 release (trunk - unreleased)
 
+OOZIE-1529 Disable job DAG display for workflow having huge actions (puru via rohini)
 OOZIE-1468 Add created time column in WF_ACTIONS and SLA tables (rohini)
 OOZIE-1524 Change Workflow SELECT query to fetch only necessary columns and consolidate JPA Executors (ryota)
 OOZIE-1515 Passing superset of action id range should be allowed (mona)

Modified: oozie/trunk/webapp/src/main/webapp/oozie-console.js
URL: http://svn.apache.org/viewvc/oozie/trunk/webapp/src/main/webapp/oozie-console.js?rev=1525167&r1=1525166&r2=1525167&view=diff
==============================================================================
--- oozie/trunk/webapp/src/main/webapp/oozie-console.js (original)
+++ oozie/trunk/webapp/src/main/webapp/oozie-console.js Fri Sep 20 22:55:41 2013
@@ -176,7 +176,7 @@ function getPagingBar(dataStore) {
     return pagingBar;
 }
 
-// Image object display
+//Image object display
 Ext.ux.Image = Ext.extend(Ext.BoxComponent, {
 
     url: Ext.BLANK_IMAGE_URL,  //for initial src value
@@ -207,9 +207,19 @@ Ext.ux.Image = Ext.extend(Ext.BoxCompone
 
     setSrc: function(src) {
         this.el.dom.src = src;
+    },
+    setAlt: function(altText) {
+        this.autoEl.alt=altText;
+    },
+
+    onError: function(onErrorTxt) {
+        this.autoEl.onError=onErrorTxt;
     }
 });
 
+function alertOnDAGError(){
+    alert('Runtime error : Can\'t display the graph. Number of actions are more than dispaly limit 25');
+}
 // stuff to show details of a job
 function jobDetailsPopup(response, request) {
     var jobDefinitionArea = new Ext.form.TextArea({
@@ -611,17 +621,14 @@ function jobDetailsPopup(response, reque
         });
     }
 
-    var dagImg = new Ext.ux.Image({
-                id: 'dagImage',
-                url: getOozieBase() + 'job/' + workflowId + "?show=graph",
-                readOnly: true,
-                editable: false,
-                autoScroll: true
+    var imageContainer = new Ext.Container({
+        autoEl: {},
+        height: '1000px',
+        weidht: '1000px',
+        autoScroll: true,
+        style  : { overflow: 'auto', overflowX: 'hidden' }
     });
-
-    function fetchDAG(workflowId) {
-        dagImg.setSrc(getOozieBase() + 'job/' + workflowId + '?show=graph&token=' + Math.random());
-    }
+    var isLoadedDAG = false;
 
     var jobDetailsTab = new Ext.TabPanel({
         activeTab: 0,
@@ -657,7 +664,7 @@ function jobDetailsPopup(response, reque
             }]
         }, {
             title: 'Job DAG',
-            items: dagImg,
+            items: imageContainer,
             tbar: [{
                 text: "&nbsp;&nbsp;&nbsp;",
                 // To avoid OOM
@@ -679,8 +686,20 @@ function jobDetailsPopup(response, reque
         else if (selectedTab.title == 'Job Definition') {
             fetchDefinition(workflowId);
         } else if(selectedTab.title == 'Job DAG') {
-            fetchDAG(workflowId);
-        }
+                if(!isLoadedDAG){
+                var dagImage=   new Ext.ux.Image({
+                        id: 'dagImage',
+                        url: getOozieBase() + 'job/' + workflowId + '?show=graph',
+                        autoScroll: true
+                        });
+                    dagImage.setAlt('Runtime error : Can\'t display the graph. Number of actions are more than display limit 25');
+                    dagImage.onError('alertOnDAGError()');
+                    imageContainer.add(dagImage);
+                    imageContainer.syncSize();
+                    imageContainer.doLayout(true);
+                    isLoadedDAG=true;
+                 }
+                }
         jobs_grid.setVisible(false);
     });
     var win = new Ext.Window({