You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sqoop.apache.org by ja...@apache.org on 2013/06/23 00:34:21 UTC

git commit: SQOOP-1088: Sqoop2: Submission history API

Updated Branches:
  refs/heads/sqoop2 05bd42e18 -> f0e8fee3e


SQOOP-1088: Sqoop2: Submission history API

(Mengwei Ding via Jarek Jarcec Cecho)


Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/f0e8fee3
Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/f0e8fee3
Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/f0e8fee3

Branch: refs/heads/sqoop2
Commit: f0e8fee3e0cf0e11980135ee7d945922e65932d5
Parents: 05bd42e
Author: Jarek Jarcec Cecho <ja...@apache.org>
Authored: Sat Jun 22 15:33:31 2013 -0700
Committer: Jarek Jarcec Cecho <ja...@apache.org>
Committed: Sat Jun 22 15:33:49 2013 -0700

----------------------------------------------------------------------
 .../org/apache/sqoop/client/SqoopClient.java    |  27 ++-
 .../org/apache/sqoop/client/core/Constants.java |  16 ++
 .../sqoop/client/request/SqoopRequests.java     |   4 +
 .../sqoop/client/request/SubmissionRequest.java |  18 ++
 .../apache/sqoop/client/shell/ShowCommand.java  |   8 +-
 .../client/shell/ShowSubmissionFunction.java    | 106 +++++++++
 .../client/shell/SubmissionStatusFunction.java  |   9 +-
 .../sqoop/client/utils/SubmissionDisplayer.java |  10 +
 .../main/resources/client-resource.properties   |   7 +
 .../org/apache/sqoop/json/SubmissionBean.java   | 135 ++++++-----
 .../apache/sqoop/json/TestSubmissionBean.java   | 226 ++++++++++++++++++-
 .../apache/sqoop/repository/JdbcRepository.java |  32 +++
 .../sqoop/repository/JdbcRepositoryHandler.java |  16 ++
 .../org/apache/sqoop/repository/Repository.java |  14 ++
 docs/src/site/sphinx/CommandLineClient.rst      |  19 ++
 .../sqoop/repository/derby/DerbyRepoError.java  |   6 +
 .../derby/DerbyRepositoryHandler.java           |  60 ++++-
 .../repository/derby/DerbySchemaQuery.java      |  19 +-
 .../sqoop/handler/SubmissionRequestHandler.java |  25 ++
 19 files changed, 687 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/SqoopClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/SqoopClient.java b/client/src/main/java/org/apache/sqoop/client/SqoopClient.java
index 9c7b351..4ca71a4 100644
--- a/client/src/main/java/org/apache/sqoop/client/SqoopClient.java
+++ b/client/src/main/java/org/apache/sqoop/client/SqoopClient.java
@@ -361,7 +361,7 @@ public class SqoopClient {
    * @return
    */
   public MSubmission startSubmission(long jid) {
-    return requests.createSubmission(jid).getSubmission();
+    return requests.createSubmission(jid).getSubmissions().get(0);
   }
 
   /**
@@ -379,7 +379,7 @@ public class SqoopClient {
       throw new SqoopException(ClientError.CLIENT_0008);
     }
     boolean first = true;
-    MSubmission submission = requests.createSubmission(jid).getSubmission();
+    MSubmission submission = requests.createSubmission(jid).getSubmissions().get(0);
     while(submission.getStatus().isRunning()) {
       if(first) {
         submissionCallback(callback, submission, SubmissionStatus.SUBMITTED);
@@ -425,7 +425,7 @@ public class SqoopClient {
    * @return
    */
   public MSubmission stopSubmission(long jid) {
-    return requests.deleteSubmission(jid).getSubmission();
+    return requests.deleteSubmission(jid).getSubmissions().get(0);
   }
 
   /**
@@ -435,7 +435,26 @@ public class SqoopClient {
    * @return
    */
   public MSubmission getSubmissionStatus(long jid) {
-    return requests.readSubmission(jid).getSubmission();
+    return requests.readSubmission(jid).getSubmissions().get(0);
+  }
+
+  /**
+   * Retrieve list of all submissions.
+   *
+   * @return
+   */
+  public List<MSubmission> getSubmissions() {
+    return requests.readHistory(null).getSubmissions();
+  }
+
+  /**
+   * Retrieve list of submissions for given jobId.
+   *
+   * @param jid Job id
+   * @return
+   */
+  public List<MSubmission> getSubmissionsForJob(long jid) {
+    return requests.readHistory(jid).getSubmissions();
   }
 
   private Status applyValidations(ValidationBean bean, MConnection connection) {

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/core/Constants.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/core/Constants.java b/client/src/main/java/org/apache/sqoop/client/core/Constants.java
index 056fcc8..06f8162 100644
--- a/client/src/main/java/org/apache/sqoop/client/core/Constants.java
+++ b/client/src/main/java/org/apache/sqoop/client/core/Constants.java
@@ -51,6 +51,7 @@ public class Constants {
   public static final String OPT_PROTOCOL = "protocol";
   public static final String OPT_SYNCHRONOUS = "synchronous";
   public static final String OPT_POLL_TIMEOUT = "poll-timeout";
+  public static final String OPT_DETAIL = "detail";
 
   public static final char OPT_XID_CHAR = 'x';
   public static final char OPT_ALL_CHAR = 'a';
@@ -68,6 +69,7 @@ public class Constants {
   public static final char OPT_PROTOCOL_CHAR = 'p';
   public static final char OPT_SYNCHRONOUS_CHAR = 's';
   public static final char OPT_POLL_TIMEOUT_CHAR = 'p';
+  public static final char OPT_DETAIL_CHAR = 'd';
 
   // Resource keys for various commands, command options,
   // functions and descriptions
@@ -97,6 +99,7 @@ public class Constants {
 
   public static final String FN_CONNECTION = "connection";
   public static final String FN_JOB = "job";
+  public static final String FN_SUBMISSION = "submission";
   public static final String FN_SERVER = "server";
   public static final String FN_OPTION = "option";
   public static final String FN_CONNECTOR = "connector";
@@ -271,6 +274,11 @@ public class Constants {
   public static final String RES_SHOW_PROMPT_JOB_XID_CID_INFO =
       "show.prompt_job_xid_cid_info";
 
+  public static final String RES_SHOW_PROMPT_DISPLAY_ALL_SUBMISSIONS =
+      "show.prompt_display_all_submissions";
+  public static final String RES_SHOW_PROMPT_DISPLAY_ALL_SUBMISSIONS_JOB_ID =
+      "show.prompt_display_all_submissions_jid";
+
   public static final String RES_SHOW_PROMPT_DISPLAY_ALL_SERVERS =
       "show.prompt_display_all_servers";
   public static final String RES_SHOW_PROMPT_DISPLAY_SERVER_HOST =
@@ -338,6 +346,14 @@ public class Constants {
       "table.header.type";
   public static final String RES_TABLE_HEADER_CONNECTOR =
       "table.header.connector";
+  public static final String RES_TABLE_HEADER_JOB_ID =
+      "table.header.jid";
+  public static final String RES_TABLE_HEADER_EXTERNAL_ID =
+      "table.header.eid";
+  public static final String RES_TABLE_HEADER_STATUS =
+      "table.header.status";
+  public static final String RES_TABLE_HEADER_DATE =
+      "table.header.date";
 
   public static final String RES_FORMDISPLAYER_SUPPORTED_JOBTYPE =
       "formdisplayer.supported_job_types";

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/request/SqoopRequests.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/request/SqoopRequests.java b/client/src/main/java/org/apache/sqoop/client/request/SqoopRequests.java
index 32d4ae1..f102c8f 100644
--- a/client/src/main/java/org/apache/sqoop/client/request/SqoopRequests.java
+++ b/client/src/main/java/org/apache/sqoop/client/request/SqoopRequests.java
@@ -126,6 +126,10 @@ public class SqoopRequests {
     getJobRequest().delete(serverUrl, jid);
   }
 
+  public SubmissionBean readHistory(Long jid) {
+    return getSubmissionRequest().readHistory(serverUrl, jid);
+  }
+
   public SubmissionBean readSubmission(Long jid) {
     return getSubmissionRequest().read(serverUrl, jid);
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/request/SubmissionRequest.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/request/SubmissionRequest.java b/client/src/main/java/org/apache/sqoop/client/request/SubmissionRequest.java
index 69edabb..bafb30f 100644
--- a/client/src/main/java/org/apache/sqoop/client/request/SubmissionRequest.java
+++ b/client/src/main/java/org/apache/sqoop/client/request/SubmissionRequest.java
@@ -31,6 +31,24 @@ public class SubmissionRequest extends  Request {
 
   public static final String ACTION = RESOURCE + "action/";
 
+  public static final String HISTORY = RESOURCE + "history/";
+
+  public SubmissionBean readHistory(String serverUrl, Long jid) {
+    String response;
+    if (jid == null) {
+      response = super.get(serverUrl + HISTORY + "all");
+    } else {
+      response = super.get(serverUrl + HISTORY + jid);
+    }
+
+    JSONObject jsonObject = (JSONObject) JSONValue.parse(response);
+
+    SubmissionBean submissionBean = new SubmissionBean();
+    submissionBean.restore(jsonObject);
+
+    return submissionBean;
+  }
+
   public SubmissionBean read(String serverUrl, Long jid) {
     String response = super.get(serverUrl + ACTION + jid);
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java b/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java
index e24a7e8..4245717 100644
--- a/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java
+++ b/client/src/main/java/org/apache/sqoop/client/shell/ShowCommand.java
@@ -29,6 +29,7 @@ public class ShowCommand extends SqoopCommand
   private ShowVersionFunction versionFunction;
   private ShowConnectorFunction connectorFunction;
   private ShowJobFunction jobFunction;
+  private ShowSubmissionFunction submissionFunction;
   private ShowFrameworkFunction frameworkFunction;
   private ShowConnectionFunction connectionFunction;
   private ShowOptionFunction optionFunction;
@@ -38,7 +39,7 @@ public class ShowCommand extends SqoopCommand
     super(shell, Constants.CMD_SHOW, Constants.CMD_SHOW_SC,
         new String[] {Constants.FN_SERVER, Constants.FN_VERSION,
           Constants.FN_CONNECTOR, Constants.FN_FRAMEWORK,
-          Constants.FN_CONNECTION, Constants.FN_JOB, Constants.FN_OPTION },
+          Constants.FN_CONNECTION, Constants.FN_JOB, Constants.FN_SUBMISSION, Constants.FN_OPTION },
           Constants.PRE_SHOW, Constants.SUF_INFO);
   }
 
@@ -86,6 +87,11 @@ public class ShowCommand extends SqoopCommand
         jobFunction = new ShowJobFunction();
       }
       return jobFunction.execute(args);
+    } else if (func.equals(Constants.FN_SUBMISSION)) {
+      if (submissionFunction == null) {
+        submissionFunction = new ShowSubmissionFunction();
+      }
+      return submissionFunction.execute(args);
     } else if (func.equals(Constants.FN_OPTION)) {
       if (optionFunction == null) {
         optionFunction = new ShowOptionFunction();

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/shell/ShowSubmissionFunction.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/shell/ShowSubmissionFunction.java b/client/src/main/java/org/apache/sqoop/client/shell/ShowSubmissionFunction.java
new file mode 100644
index 0000000..666eb7a
--- /dev/null
+++ b/client/src/main/java/org/apache/sqoop/client/shell/ShowSubmissionFunction.java
@@ -0,0 +1,106 @@
+/**
+ * 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.
+ */
+package org.apache.sqoop.client.shell;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.sqoop.client.core.Constants;
+import org.apache.sqoop.client.utils.SubmissionDisplayer;
+import org.apache.sqoop.client.utils.TableDisplayer;
+import org.apache.sqoop.model.MSubmission;
+import org.apache.sqoop.submission.SubmissionStatus;
+
+import static org.apache.sqoop.client.shell.ShellEnvironment.*;
+
+public class ShowSubmissionFunction extends SqoopFunction {
+  @SuppressWarnings("static-access")
+  protected ShowSubmissionFunction() {
+    this.addOption(OptionBuilder
+        .withDescription(resourceString(Constants.RES_SHOW_PROMPT_DISPLAY_ALL_SUBMISSIONS))
+        .withLongOpt(Constants.OPT_DETAIL)
+        .create(Constants.OPT_DETAIL_CHAR));
+    this.addOption(OptionBuilder.hasArg().withArgName(Constants.OPT_JID)
+        .withDescription(resourceString(Constants.RES_SHOW_PROMPT_DISPLAY_ALL_SUBMISSIONS_JOB_ID))
+        .withLongOpt(Constants.OPT_JID)
+        .create(Constants.OPT_JID_CHAR));
+  }
+
+  @Override
+  public Object executeFunction(CommandLine line) {
+    if (line.hasOption(Constants.OPT_DETAIL)) {
+      if (line.hasOption(Constants.OPT_JID)) {
+        showSubmissions(getLong(line, Constants.OPT_JID));
+      } else {
+        showSubmissions(null);
+      }
+    } else {
+      if (line.hasOption(Constants.OPT_JID)) {
+        showSummary(getLong(line, Constants.OPT_JID));
+      } else {
+        showSummary(null);
+      }
+    }
+
+    return null;
+  }
+
+  private void showSummary(Long jid) {
+    List<MSubmission> submissions;
+    if (jid == null) {
+      submissions = client.getSubmissions();
+    } else {
+      submissions = client.getSubmissionsForJob(jid);
+    }
+
+    List<String> header = new LinkedList<String>();
+    header.add(resourceString(Constants.RES_TABLE_HEADER_JOB_ID));
+    header.add(resourceString(Constants.RES_TABLE_HEADER_EXTERNAL_ID));
+    header.add(resourceString(Constants.RES_TABLE_HEADER_STATUS));
+    header.add(resourceString(Constants.RES_TABLE_HEADER_DATE));
+
+    List<String> jids = new LinkedList<String>();
+    List<String> eids = new LinkedList<String>();
+    List<String> status = new LinkedList<String>();
+    List<String> dates = new LinkedList<String>();
+
+    for (MSubmission submission : submissions) {
+      jids.add(String.valueOf(submission.getJobId()));
+      eids.add(String.valueOf(submission.getExternalId()));
+      status.add(submission.getStatus().toString());
+      dates.add(submission.getLastUpdateDate().toString());
+    }
+
+    TableDisplayer.display(header, jids, eids, status, dates);
+  }
+
+  private void showSubmissions(Long jid) {
+    List<MSubmission> submissions;
+    if (jid == null) {
+      submissions = client.getSubmissions();
+    } else {
+      submissions = client.getSubmissionsForJob(jid);
+    }
+
+    for (MSubmission submission : submissions) {
+      SubmissionDisplayer.displaySubmission(submission);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/shell/SubmissionStatusFunction.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/shell/SubmissionStatusFunction.java b/client/src/main/java/org/apache/sqoop/client/shell/SubmissionStatusFunction.java
index 1a6d896..29144d1 100644
--- a/client/src/main/java/org/apache/sqoop/client/shell/SubmissionStatusFunction.java
+++ b/client/src/main/java/org/apache/sqoop/client/shell/SubmissionStatusFunction.java
@@ -46,13 +46,8 @@ public class SubmissionStatusFunction extends  SqoopFunction {
     }
 
     MSubmission submission = client.getSubmissionStatus(getLong(line, Constants.OPT_JID));
-    if(submission.getStatus().isFailure() || submission.getStatus().equals(SubmissionStatus.SUCCEEDED)) {
-      SubmissionDisplayer.displayHeader(submission);
-      SubmissionDisplayer.displayFooter(submission);
-    } else {
-      SubmissionDisplayer.displayHeader(submission);
-      SubmissionDisplayer.displayProgress(submission);
-    }
+    SubmissionDisplayer.displaySubmission(submission);
+
     return null;
   }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/java/org/apache/sqoop/client/utils/SubmissionDisplayer.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sqoop/client/utils/SubmissionDisplayer.java b/client/src/main/java/org/apache/sqoop/client/utils/SubmissionDisplayer.java
index 530ac92..360a931 100644
--- a/client/src/main/java/org/apache/sqoop/client/utils/SubmissionDisplayer.java
+++ b/client/src/main/java/org/apache/sqoop/client/utils/SubmissionDisplayer.java
@@ -125,4 +125,14 @@ public final class SubmissionDisplayer {
       }
     }
   }
+
+  public static void displaySubmission(MSubmission submission) {
+    if(submission.getStatus().isFailure() || submission.getStatus().equals(SubmissionStatus.SUCCEEDED)) {
+      SubmissionDisplayer.displayHeader(submission);
+      SubmissionDisplayer.displayFooter(submission);
+    } else {
+      SubmissionDisplayer.displayHeader(submission);
+      SubmissionDisplayer.displayProgress(submission);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/client/src/main/resources/client-resource.properties
----------------------------------------------------------------------
diff --git a/client/src/main/resources/client-resource.properties b/client/src/main/resources/client-resource.properties
index b159757..8a570a1 100644
--- a/client/src/main/resources/client-resource.properties
+++ b/client/src/main/resources/client-resource.properties
@@ -144,6 +144,9 @@ show.prompt_jobs_to_show = @|bold {0} job(s) to show: |@
 show.prompt_job_info = Job with id {0} and name {1} (Created {2}, Updated {3})
 show.prompt_job_xid_cid_info = Using Connection id {0} and Connector id {1}
 
+show.prompt_display_all_submissions = Display all submissions
+show.prompt_display_all_submissions_jid = Display all submissions given jid
+
 show.prompt_display_all_servers = Display all server information
 show.prompt_display_server_host = Display server host name
 show.prompt_display_server_port = Display server port number
@@ -177,6 +180,10 @@ table.header.version = Version
 table.header.class = Class
 table.header.type = Type
 table.header.connector = Connector
+table.header.jid = Job Id
+table.header.eid = External Id
+table.header.status = Status
+table.header.date = Last Update Date
 
 #Form displayer resources
 formdisplayer.supported_job_types = Supported job types

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/common/src/main/java/org/apache/sqoop/json/SubmissionBean.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/sqoop/json/SubmissionBean.java b/common/src/main/java/org/apache/sqoop/json/SubmissionBean.java
index 1ef72eb..91f2007 100644
--- a/common/src/main/java/org/apache/sqoop/json/SubmissionBean.java
+++ b/common/src/main/java/org/apache/sqoop/json/SubmissionBean.java
@@ -22,9 +22,12 @@ import org.apache.sqoop.submission.SubmissionStatus;
 import org.apache.sqoop.submission.counter.Counter;
 import org.apache.sqoop.submission.counter.CounterGroup;
 import org.apache.sqoop.submission.counter.Counters;
+import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -33,6 +36,7 @@ import java.util.Set;
  */
 public class SubmissionBean implements JsonBean {
 
+  private static final String ALL = "all";
   private static final String JOB = "job";
   private static final String CREATION_DATE = "creation-date";
   private static final String LAST_UPDATE_DATE = "last-update-date";
@@ -44,15 +48,22 @@ public class SubmissionBean implements JsonBean {
   private static final String PROGRESS = "progress";
   private static final String COUNTERS = "counters";
 
-  private MSubmission submission;
+  private List<MSubmission> submissions;
 
-  public MSubmission getSubmission() {
-    return submission;
+  public List<MSubmission> getSubmissions() {
+    return submissions;
   }
 
   // For "extract"
   public SubmissionBean(MSubmission submission) {
-    this.submission = submission;
+    this();
+    this.submissions = new ArrayList<MSubmission>();
+    this.submissions.add(submission);
+  }
+
+  public SubmissionBean(List<MSubmission> submissions) {
+    this();
+    this.submissions = submissions;
   }
 
   // For "restore"
@@ -62,35 +73,44 @@ public class SubmissionBean implements JsonBean {
   @Override
   @SuppressWarnings("unchecked")
   public JSONObject extract(boolean skipSensitive) {
-    JSONObject ret = new JSONObject();
+    JSONArray array = new JSONArray();
 
-    ret.put(JOB, submission.getJobId());
-    ret.put(STATUS, submission.getStatus().name());
-    ret.put(PROGRESS, submission.getProgress());
+    for(MSubmission submission : this.submissions) {
+      JSONObject object = new JSONObject();
 
-    if(submission.getCreationDate() != null) {
-      ret.put(CREATION_DATE, submission.getCreationDate().getTime());
-    }
-    if(submission.getLastUpdateDate() != null) {
-      ret.put(LAST_UPDATE_DATE, submission.getLastUpdateDate().getTime());
-    }
-    if(submission.getExternalId() != null) {
-      ret.put(EXTERNAL_ID, submission.getExternalId());
-    }
-    if(submission.getExternalLink() != null) {
-      ret.put(EXTERNAL_LINK, submission.getExternalLink());
-    }
-    if(submission.getExceptionInfo() != null) {
-      ret.put(EXCEPTION, submission.getExceptionInfo());
-    }
-    if(submission.getExceptionStackTrace() != null) {
-      ret.put(EXCEPTION_TRACE, submission.getExceptionStackTrace());
-    }
-    if(submission.getCounters() != null) {
-      ret.put(COUNTERS, extractCounters(submission.getCounters()));
+      object.put(JOB, submission.getJobId());
+      object.put(STATUS, submission.getStatus().name());
+      object.put(PROGRESS, submission.getProgress());
+
+      if(submission.getCreationDate() != null) {
+        object.put(CREATION_DATE, submission.getCreationDate().getTime());
+      }
+      if(submission.getLastUpdateDate() != null) {
+        object.put(LAST_UPDATE_DATE, submission.getLastUpdateDate().getTime());
+      }
+      if(submission.getExternalId() != null) {
+        object.put(EXTERNAL_ID, submission.getExternalId());
+      }
+      if(submission.getExternalLink() != null) {
+        object.put(EXTERNAL_LINK, submission.getExternalLink());
+      }
+      if(submission.getExceptionInfo() != null) {
+        object.put(EXCEPTION, submission.getExceptionInfo());
+      }
+      if(submission.getExceptionStackTrace() != null) {
+        object.put(EXCEPTION_TRACE, submission.getExceptionStackTrace());
+      }
+      if(submission.getCounters() != null) {
+        object.put(COUNTERS, extractCounters(submission.getCounters()));
+      }
+
+      array.add(object);
     }
 
-    return ret;
+    JSONObject all = new JSONObject();
+    all.put(ALL, array);
+
+    return all;
   }
 
   @SuppressWarnings("unchecked")
@@ -110,32 +130,41 @@ public class SubmissionBean implements JsonBean {
 
   @Override
   public void restore(JSONObject json) {
+    this.submissions = new ArrayList<MSubmission>();
 
-    submission = new MSubmission();
-    submission.setJobId((Long) json.get(JOB));
-    submission.setStatus(SubmissionStatus.valueOf((String) json.get(STATUS)));
-    submission.setProgress((Double) json.get(PROGRESS));
+    JSONArray array = (JSONArray) json.get(ALL);
 
-    if(json.containsKey(CREATION_DATE)) {
-      submission.setCreationDate(new Date((Long) json.get(CREATION_DATE)));
-    }
-    if(json.containsKey(LAST_UPDATE_DATE)) {
-      submission.setLastUpdateDate(new Date((Long) json.get(LAST_UPDATE_DATE)));
-    }
-    if(json.containsKey(EXTERNAL_ID)) {
-      submission.setExternalId((String) json.get(EXTERNAL_ID));
-    }
-    if(json.containsKey(EXTERNAL_LINK)) {
-      submission.setExternalLink((String) json.get(EXTERNAL_LINK));
-    }
-    if(json.containsKey(EXCEPTION)) {
-      submission.setExceptionInfo((String) json.get(EXCEPTION));
-    }
-    if(json.containsKey(EXCEPTION_TRACE)) {
-      submission.setExceptionStackTrace((String) json.get(EXCEPTION_TRACE));
-    }
-    if(json.containsKey(COUNTERS)) {
-      submission.setCounters(restoreCounters((JSONObject) json.get(COUNTERS)));
+    for (Object obj : array) {
+      JSONObject object = (JSONObject) obj;
+      MSubmission submission = new MSubmission();
+
+      submission.setJobId((Long) object.get(JOB));
+      submission.setStatus(SubmissionStatus.valueOf((String) object.get(STATUS)));
+      submission.setProgress((Double) object.get(PROGRESS));
+
+      if(object.containsKey(CREATION_DATE)) {
+        submission.setCreationDate(new Date((Long) object.get(CREATION_DATE)));
+      }
+      if(object.containsKey(LAST_UPDATE_DATE)) {
+        submission.setLastUpdateDate(new Date((Long) object.get(LAST_UPDATE_DATE)));
+      }
+      if(object.containsKey(EXTERNAL_ID)) {
+        submission.setExternalId((String) object.get(EXTERNAL_ID));
+      }
+      if(object.containsKey(EXTERNAL_LINK)) {
+        submission.setExternalLink((String) object.get(EXTERNAL_LINK));
+      }
+      if(object.containsKey(EXCEPTION)) {
+        submission.setExceptionInfo((String) object.get(EXCEPTION));
+      }
+      if(object.containsKey(EXCEPTION_TRACE)) {
+        submission.setExceptionStackTrace((String) object.get(EXCEPTION_TRACE));
+      }
+      if(object.containsKey(COUNTERS)) {
+        submission.setCounters(restoreCounters((JSONObject) object.get(COUNTERS)));
+      }
+
+      this.submissions.add(submission);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/common/src/test/java/org/apache/sqoop/json/TestSubmissionBean.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/json/TestSubmissionBean.java b/common/src/test/java/org/apache/sqoop/json/TestSubmissionBean.java
index 6ee9aa1..19a5bba 100644
--- a/common/src/test/java/org/apache/sqoop/json/TestSubmissionBean.java
+++ b/common/src/test/java/org/apache/sqoop/json/TestSubmissionBean.java
@@ -26,7 +26,9 @@ import org.apache.sqoop.submission.counter.Counters;
 import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 
 /**
  *
@@ -35,6 +37,11 @@ public class TestSubmissionBean extends TestCase {
 
   public void testTransferUnknown() {
     transfer(MSubmission.UNKNOWN);
+
+    List<MSubmission> submissions = new ArrayList<MSubmission>();
+    submissions.add(MSubmission.UNKNOWN);
+    submissions.add(MSubmission.UNKNOWN);
+    transfer(submissions);
   }
 
   public void testTransferJobId() {
@@ -43,6 +50,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals(666, target.getJobId());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setJobId(777);
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setJobId(888);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals(777, targets.get(0).getJobId());
+    assertNotNull(targets.get(1));
+    assertEquals(888, targets.get(1).getJobId());
   }
 
   public void testTransferCreationDate() {
@@ -52,6 +73,22 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals(date, target.getCreationDate());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    Date datex = new Date(1000);
+    sourcex.setCreationDate(datex);
+    sources.add(sourcex);
+    Date datey = new Date(2000);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setCreationDate(datey);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals(datex, targets.get(0).getCreationDate());
+    assertNotNull(targets.get(1));
+    assertEquals(datey, targets.get(1).getCreationDate());
   }
 
   public void testTransferLastUpdateDate() {
@@ -61,6 +98,22 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals(date, target.getLastUpdateDate());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    Date datex = new Date(1000);
+    sourcex.setLastUpdateDate(datex);
+    sources.add(sourcex);
+    Date datey = new Date(2000);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setLastUpdateDate(datey);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals(datex, targets.get(0).getLastUpdateDate());
+    assertNotNull(targets.get(1));
+    assertEquals(datey, targets.get(1).getLastUpdateDate());
   }
 
   public void testTransferStatus() {
@@ -69,6 +122,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals(SubmissionStatus.SUCCEEDED, target.getStatus());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setStatus(SubmissionStatus.RUNNING);
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setStatus(SubmissionStatus.BOOTING);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals(SubmissionStatus.RUNNING, targets.get(0).getStatus());
+    assertNotNull(targets.get(1));
+    assertEquals(SubmissionStatus.BOOTING, targets.get(1).getStatus());
   }
 
   public void testTransferExternalId() {
@@ -77,6 +144,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals("Job-x", target.getExternalId());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setExternalId("Job-y");
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setExternalId("Job-z");
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals("Job-y", targets.get(0).getExternalId());
+    assertNotNull(targets.get(1));
+    assertEquals("Job-z", targets.get(1).getExternalId());
   }
 
   public void testTransferExternalLink() {
@@ -85,6 +166,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals("http://", target.getExternalLink());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setExternalLink("http://localhost:80");
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setExternalLink("http://localhost:8080");
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals("http://localhost:80", targets.get(0).getExternalLink());
+    assertNotNull(targets.get(1));
+    assertEquals("http://localhost:8080", targets.get(1).getExternalLink());
   }
 
   public void testTransferException() {
@@ -93,6 +188,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals("EndOfTheWorldException", target.getExceptionInfo());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setExceptionInfo("TheNewEraException");
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setExceptionInfo("EndOfTheWorldAgainException");
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals("TheNewEraException", targets.get(0).getExceptionInfo());
+    assertNotNull(targets.get(1));
+    assertEquals("EndOfTheWorldAgainException", targets.get(1).getExceptionInfo());
   }
 
   public void testTransferExceptionTrace() {
@@ -101,6 +210,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals("void.java(3): line infinity", target.getExceptionStackTrace());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setExceptionStackTrace("void.java(4): segment fault in Java");
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setExceptionStackTrace("void.java(5): core dumps in Java");
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals("void.java(4): segment fault in Java", targets.get(0).getExceptionStackTrace());
+    assertNotNull(targets.get(1));
+    assertEquals("void.java(5): core dumps in Java", targets.get(1).getExceptionStackTrace());
   }
 
   public void testTransferProgress() {
@@ -109,6 +232,20 @@ public class TestSubmissionBean extends TestCase {
 
     MSubmission target = transfer(source);
     assertEquals(25.0, target.getProgress());
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setProgress(50.0);
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setProgress(99.9);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    assertEquals(50.0, targets.get(0).getProgress());
+    assertNotNull(targets.get(1));
+    assertEquals(99.9, targets.get(1).getProgress());
   }
 
   public void testTransferCounters() {
@@ -148,6 +285,75 @@ public class TestSubmissionBean extends TestCase {
     counter = group.getCounter("YY");
     assertNotNull(counter);
     assertEquals(22, counter.getValue());
+
+    Counters countersx = new Counters();
+    countersx.addCounterGroup(new CounterGroup("C")
+      .addCounter(new Counter("XXX", 111))
+      .addCounter(new Counter("YYY", 222))
+    );
+    countersx.addCounterGroup(new CounterGroup("D")
+      .addCounter(new Counter("XXXX", 1111))
+      .addCounter(new Counter("YYYY", 2222))
+    );
+
+    Counters countersy = new Counters();
+    countersy.addCounterGroup(new CounterGroup("E")
+      .addCounter(new Counter("XXXXX", 11111))
+      .addCounter(new Counter("YYYYY", 22222))
+    );
+    countersy.addCounterGroup(new CounterGroup("F")
+      .addCounter(new Counter("XXXXXX", 111111))
+      .addCounter(new Counter("YYYYYY", 222222))
+    );
+
+    List<MSubmission> sources = new ArrayList<MSubmission>();
+    MSubmission sourcex = new MSubmission();
+    sourcex.setCounters(countersx);
+    sources.add(sourcex);
+    MSubmission sourcey = new MSubmission();
+    sourcey.setCounters(countersy);
+    sources.add(sourcey);
+
+    List<MSubmission> targets = transfer(sources);
+    assertNotNull(targets.get(0));
+    target = targets.get(0).getCounters();
+    group = target.getCounterGroup("C");
+    assertNotNull(group);
+    counter = group.getCounter("XXX");
+    assertNotNull(counter);
+    assertEquals(111, counter.getValue());
+    counter = group.getCounter("YYY");
+    assertNotNull(counter);
+    assertEquals(222, counter.getValue());
+
+    group = target.getCounterGroup("D");
+    assertNotNull(group);
+    counter = group.getCounter("XXXX");
+    assertNotNull(counter);
+    assertEquals(1111, counter.getValue());
+    counter = group.getCounter("YYYY");
+    assertNotNull(counter);
+    assertEquals(2222, counter.getValue());
+
+    assertNotNull(targets.get(1));
+    target = targets.get(1).getCounters();
+    group = target.getCounterGroup("E");
+    assertNotNull(group);
+    counter = group.getCounter("XXXXX");
+    assertNotNull(counter);
+    assertEquals(11111, counter.getValue());
+    counter = group.getCounter("YYYYY");
+    assertNotNull(counter);
+    assertEquals(22222, counter.getValue());
+
+    group = target.getCounterGroup("F");
+    assertNotNull(group);
+    counter = group.getCounter("XXXXXX");
+    assertNotNull(counter);
+    assertEquals(111111, counter.getValue());
+    counter = group.getCounter("YYYYYY");
+    assertNotNull(counter);
+    assertEquals(222222, counter.getValue());
   }
 
   /**
@@ -166,8 +372,26 @@ public class TestSubmissionBean extends TestCase {
     SubmissionBean retrievedBean = new SubmissionBean();
     retrievedBean.restore(retrievedJson);
 
-    return retrievedBean.getSubmission();
+    return retrievedBean.getSubmissions().get(0);
   }
 
+  /**
+   * Simulate transfer of a list of MSubmission structures using SubmissionBean
+   *
+   * @param submissions Submissions to transfer
+   * @return
+   */
+  private List<MSubmission> transfer(List<MSubmission> submissions) {
+    SubmissionBean bean = new SubmissionBean(submissions);
+    JSONObject json = bean.extract(false);
+
+    String string = json.toString();
+
+    JSONObject retrievedJson = (JSONObject) JSONValue.parse(string);
+    SubmissionBean retrievedBean = new SubmissionBean();
+    retrievedBean.restore(retrievedJson);
+
+    return retrievedBean.getSubmissions();
+  }
 }
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/core/src/main/java/org/apache/sqoop/repository/JdbcRepository.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/repository/JdbcRepository.java b/core/src/main/java/org/apache/sqoop/repository/JdbcRepository.java
index d42e34a..135c2d2 100644
--- a/core/src/main/java/org/apache/sqoop/repository/JdbcRepository.java
+++ b/core/src/main/java/org/apache/sqoop/repository/JdbcRepository.java
@@ -463,6 +463,38 @@ public class JdbcRepository extends Repository {
   /**
    * {@inheritDoc}
    */
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<MSubmission> findSubmissions() {
+    return (List<MSubmission>) doWithConnection(new DoWithConnection() {
+      @Override
+      public Object doIt(Connection conn) throws Exception {
+        return handler.findSubmissions(conn);
+      }
+    });
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<MSubmission> findSubmissionsForJob(final long jobId) {
+    return (List<MSubmission>) doWithConnection(new DoWithConnection() {
+      @Override
+      public Object doIt(Connection conn) throws Exception {
+        if(!handler.existsJob(jobId, conn)) {
+          throw new SqoopException(RepositoryError.JDBCREPO_0020,
+            "Invalid id: " + jobId);
+        }
+        return handler.findSubmissionsForJob(jobId, conn);
+      }
+    });
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public MSubmission findSubmissionLastForJob(final long jobId) {
     return (MSubmission) doWithConnection(new DoWithConnection() {

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/core/src/main/java/org/apache/sqoop/repository/JdbcRepositoryHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/repository/JdbcRepositoryHandler.java b/core/src/main/java/org/apache/sqoop/repository/JdbcRepositoryHandler.java
index 3d29ab5..538def5 100644
--- a/core/src/main/java/org/apache/sqoop/repository/JdbcRepositoryHandler.java
+++ b/core/src/main/java/org/apache/sqoop/repository/JdbcRepositoryHandler.java
@@ -350,6 +350,22 @@ public abstract class JdbcRepositoryHandler {
   public abstract List<MSubmission> findSubmissionsUnfinished(Connection conn);
 
   /**
+   * Return list of all submissions from metadata repository.
+   *
+   * @param conn Connection to metadata repository
+   * @return List of all submissions.
+   */
+  public abstract List<MSubmission> findSubmissions(Connection conn);
+
+  /**
+   * Return list of submissions from metadata repository for given jobId.
+   * @param jobId Job id
+   * @param conn Connection to metadata repository
+   * @return List of submissions
+   */
+  public abstract List<MSubmission> findSubmissionsForJob(long jobId, Connection conn);
+
+  /**
    * Find last submission for given jobId.
    *
    * @param jobId Job id

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/core/src/main/java/org/apache/sqoop/repository/Repository.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/repository/Repository.java b/core/src/main/java/org/apache/sqoop/repository/Repository.java
index 21dd759..666bfc1 100644
--- a/core/src/main/java/org/apache/sqoop/repository/Repository.java
+++ b/core/src/main/java/org/apache/sqoop/repository/Repository.java
@@ -218,6 +218,20 @@ public abstract class Repository {
   public abstract List<MSubmission> findSubmissionsUnfinished();
 
   /**
+   * Return all submissions from repository
+   *
+   * @return List of all submissions
+   */
+  public abstract List<MSubmission> findSubmissions();
+
+  /**
+   * Return all submissions for given jobId.
+   *
+   * @return List of of submissions
+   */
+  public abstract List<MSubmission> findSubmissionsForJob(long jobId);
+
+  /**
    * Find last submission for given jobId.
    *
    * @param jobId Job id

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/docs/src/site/sphinx/CommandLineClient.rst
----------------------------------------------------------------------
diff --git a/docs/src/site/sphinx/CommandLineClient.rst b/docs/src/site/sphinx/CommandLineClient.rst
index 073d547..a14898f 100644
--- a/docs/src/site/sphinx/CommandLineClient.rst
+++ b/docs/src/site/sphinx/CommandLineClient.rst
@@ -271,6 +271,25 @@ Example: ::
 
   show job --all
 
+Show Submission Function
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Show persisted submission objects.
+
++-----------------------+---------------------------------------------+
+| Argument              |  Description                                |
++=======================+=============================================+
+| ``-j``, ``--jid <x>`` | Show available submissions for given job    |
++-----------------------+---------------------------------------------+
+| ``-d``, ``--detail``  | Show jobs in full details                   |
++-----------------------+---------------------------------------------+
+
+Example: ::
+
+  show submission
+  show submission --jid 1
+  show submission --jid 1 --detail
+
 Create Command
 --------------
 

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepoError.java
----------------------------------------------------------------------
diff --git a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepoError.java b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepoError.java
index 327896c..4455f48 100644
--- a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepoError.java
+++ b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepoError.java
@@ -163,6 +163,12 @@ public enum DerbyRepoError implements ErrorCode {
 
   DERBYREPO_0038("Update of connector failed"),
 
+  /** Can't retrieve all submissions **/
+  DERBYREPO_0039("Can't retrieve all submissions"),
+
+  /** Can't retrieve submissions for a job **/
+  DERBYREPO_0040("Can't retrieve submissions for a job"),
+
   ;
 
   private final String message;

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
----------------------------------------------------------------------
diff --git a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
index 45a0da4..0ea7bac 100644
--- a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
+++ b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbyRepositoryHandler.java
@@ -1167,11 +1167,67 @@ public class DerbyRepositoryHandler extends JdbcRepositoryHandler {
    * {@inheritDoc}
    */
   @Override
+  public List<MSubmission> findSubmissions(Connection conn) {
+    List<MSubmission> submissions = new LinkedList<MSubmission>();
+    PreparedStatement stmt = null;
+    ResultSet rs = null;
+    try {
+      stmt = conn.prepareStatement(STMT_SELECT_SUBMISSIONS);
+      rs = stmt.executeQuery();
+
+      while(rs.next()) {
+        submissions.add(loadSubmission(rs, conn));
+      }
+
+      rs.close();
+      rs = null;
+    } catch (SQLException ex) {
+      logException(ex);
+      throw new SqoopException(DerbyRepoError.DERBYREPO_0039, ex);
+    } finally {
+      closeResultSets(rs);
+      closeStatements(stmt);
+    }
+
+    return submissions;
+  }
+
+  @Override
+  public List<MSubmission> findSubmissionsForJob(long jobId, Connection conn) {
+    List<MSubmission> submissions = new LinkedList<MSubmission>();
+    PreparedStatement stmt = null;
+    ResultSet rs = null;
+    try {
+      stmt = conn.prepareStatement(STMT_SELECT_SUBMISSIONS_FOR_JOB);
+      stmt.setLong(1, jobId);
+      rs = stmt.executeQuery();
+
+      while(rs.next()) {
+        submissions.add(loadSubmission(rs, conn));
+      }
+
+      rs.close();
+      rs = null;
+    } catch (SQLException ex) {
+      logException(ex);
+      throw new SqoopException(DerbyRepoError.DERBYREPO_0040, ex);
+    } finally {
+      closeResultSets(rs);
+      closeStatements(stmt);
+    }
+
+    return submissions;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public MSubmission findSubmissionLastForJob(long jobId, Connection conn) {
     PreparedStatement stmt = null;
     ResultSet rs = null;
     try {
-      stmt = conn.prepareStatement(STMT_SELECT_SUBMISSION_LAST_FOR_JOB);
+      stmt = conn.prepareStatement(STMT_SELECT_SUBMISSIONS_FOR_JOB);
       stmt.setLong(1, jobId);
       stmt.setMaxRows(1);
       rs = stmt.executeQuery();
@@ -1183,7 +1239,7 @@ public class DerbyRepositoryHandler extends JdbcRepositoryHandler {
       return loadSubmission(rs, conn);
     } catch (SQLException ex) {
       logException(ex, jobId);
-      throw new SqoopException(DerbyRepoError.DERBYREPO_0037, ex);
+      throw new SqoopException(DerbyRepoError.DERBYREPO_0040, ex);
     } finally {
       closeResultSets(rs);
       closeStatements(stmt);

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
----------------------------------------------------------------------
diff --git a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
index c8ce3aa..7a9ce50 100644
--- a/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
+++ b/repository/repository-derby/src/main/java/org/apache/sqoop/repository/derby/DerbySchemaQuery.java
@@ -713,8 +713,23 @@ public final class DerbySchemaQuery {
     + " FROM " + TABLE_SQ_SUBMISSION
     + " WHERE " + COLUMN_SQS_STATUS + " = ?";
 
-  // DML: Last submission for a job
-  public static final String STMT_SELECT_SUBMISSION_LAST_FOR_JOB =
+  // DML : Get all submissions
+  public static final String STMT_SELECT_SUBMISSIONS =
+    "SELECT "
+    + COLUMN_SQS_ID + ", "
+    + COLUMN_SQS_JOB + ", "
+    + COLUMN_SQS_STATUS + ", "
+    + COLUMN_SQS_CREATION_DATE + ", "
+    + COLUMN_SQS_UPDATE_DATE + ", "
+    + COLUMN_SQS_EXTERNAL_ID + ", "
+    + COLUMN_SQS_EXTERNAL_LINK + ", "
+    + COLUMN_SQS_EXCEPTION + ", "
+    + COLUMN_SQS_EXCEPTION_TRACE
+    + " FROM " + TABLE_SQ_SUBMISSION
+    + " ORDER BY " + COLUMN_SQS_UPDATE_DATE + " DESC";
+
+  // DML: Get submissions for a job
+  public static final String STMT_SELECT_SUBMISSIONS_FOR_JOB =
     "SELECT "
     + COLUMN_SQS_ID + ", "
     + COLUMN_SQS_JOB + ", "

http://git-wip-us.apache.org/repos/asf/sqoop/blob/f0e8fee3/server/src/main/java/org/apache/sqoop/handler/SubmissionRequestHandler.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/sqoop/handler/SubmissionRequestHandler.java b/server/src/main/java/org/apache/sqoop/handler/SubmissionRequestHandler.java
index 1c40fc1..1f7a208 100644
--- a/server/src/main/java/org/apache/sqoop/handler/SubmissionRequestHandler.java
+++ b/server/src/main/java/org/apache/sqoop/handler/SubmissionRequestHandler.java
@@ -17,6 +17,8 @@
  */
 package org.apache.sqoop.handler;
 
+import java.util.List;
+
 import org.apache.log4j.Logger;
 import org.apache.sqoop.common.SqoopException;
 import org.apache.sqoop.framework.FrameworkManager;
@@ -24,6 +26,7 @@ import org.apache.sqoop.framework.JobManager;
 import org.apache.sqoop.json.JsonBean;
 import org.apache.sqoop.json.SubmissionBean;
 import org.apache.sqoop.model.MSubmission;
+import org.apache.sqoop.repository.RepositoryManager;
 import org.apache.sqoop.server.RequestContext;
 import org.apache.sqoop.server.RequestHandler;
 import org.apache.sqoop.server.common.ServerError;
@@ -73,6 +76,10 @@ public class SubmissionRequestHandler implements RequestHandler {
       return handleNotification(ctx, urlElements[length - 1]);
     }
 
+    if(action.equals("history")) {
+      return handleHistoryEvent(ctx, urlElements[length - 1]);
+    }
+
     throw new SqoopException(ServerError.SERVER_0003,
       "Do not know what to do.");
   }
@@ -104,6 +111,14 @@ public class SubmissionRequestHandler implements RequestHandler {
     return null;
   }
 
+  private JsonBean handleHistoryEvent(RequestContext ctx, String sjid) {
+    if (sjid.equals("all")) {
+      return getSubmissions();
+    } else {
+      return getSubmissionsForJob(Long.parseLong(sjid));
+    }
+  }
+
   private JsonBean submissionStop(long jid) {
     MSubmission submission = JobManager.getInstance().stop(jid);
     return new SubmissionBean(submission);
@@ -118,4 +133,14 @@ public class SubmissionRequestHandler implements RequestHandler {
     MSubmission submission = JobManager.getInstance().status(jid);
     return new SubmissionBean(submission);
   }
+
+  private JsonBean getSubmissions() {
+    List<MSubmission> submissions = RepositoryManager.getInstance().getRepository().findSubmissions();
+    return new SubmissionBean(submissions);
+  }
+
+  private JsonBean getSubmissionsForJob(long jid) {
+    List<MSubmission> submissions = RepositoryManager.getInstance().getRepository().findSubmissionsForJob(jid);
+    return new SubmissionBean(submissions);
+  }
 }