Przeglądaj źródła

HUE-2996 [oozie] Add back editor submission history

Romain Rigaux 10 lat temu
rodzic
commit
aef2fea

+ 2 - 1
apps/oozie/src/oozie/static/oozie/js/workflow-editor.ko.js

@@ -459,7 +459,7 @@ var Workflow = function (vm, workflow) {
   };
 }
 
-var WorkflowEditorViewModel = function (layout_json, workflow_json, credentials_json, workflow_properties_json, subworkflows_json, can_edit_json) {
+var WorkflowEditorViewModel = function (layout_json, workflow_json, credentials_json, workflow_properties_json, subworkflows_json, can_edit_json, history_json) {
   var self = this;
 
   self.isNested = ko.observable(true);
@@ -516,6 +516,7 @@ var WorkflowEditorViewModel = function (layout_json, workflow_json, credentials_
 
 
   self.subworkflows = ko.observableArray(getOtherSubworkflows(self, subworkflows_json));
+  self.history = ko.mapping.fromJS(history_json);
 
   self.getSubWorkflow = function (uuid) {
     var wf = $.grep(self.subworkflows(), function (wf, i) {

+ 20 - 1
apps/oozie/src/oozie/templates/editor2/workflow_editor.mako

@@ -53,6 +53,10 @@ ${ commonheader(_("Workflow Editor"), "Oozie", user, "40px") | n,unicode }
       <i class="fa fa-fw fa-cog"></i>
     </a>
 
+    <a title="${ _('History') }" rel="tooltip" data-placement="bottom" data-toggle="modal" data-target="#historyModal" data-bind="css: {'btn': true}">
+      <i class="fa fa-fw fa-history"></i>
+    </a>
+
     <a title="${ _('Workspace') }" target="_blank" rel="tooltip" data-placement="right"
         data-original-title="${ _('Go upload additional files and libraries to the deployment directory on HDFS') }"
         data-bind="css: {'btn': true}, attr: { href: '/filebrowser/view=' + $root.workflow.properties.deployment_dir() }">
@@ -341,6 +345,21 @@ ${ workflow.render() }
 </div>
 
 
+<div id="historyModal" class="modal fade hide">
+  <div class="modal-header" style="padding-bottom: 2px">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>${ _('Submission History') }</h3>
+  </div>
+  <div class="modal-body">
+    <ul data-bind="foreach: $root.history" class="unstyled">
+      <li>
+        <span data-bind="text: ko.mapping.toJSON($data)"></span>
+      </li>
+    </ul>
+  </div>
+</div>
+
+
 <div class="submit-modal modal hide"></div>
 
 <div id="chooseFile" class="modal hide fade">
@@ -397,7 +416,7 @@ ${ dashboard.import_bindings() }
 <script type="text/javascript">
   ${ utils.slaGlobal() }
 
-  var viewModel = new WorkflowEditorViewModel(${ layout_json | n,unicode }, ${ workflow_json | n,unicode }, ${ credentials_json | n,unicode }, ${ workflow_properties_json | n,unicode }, ${ subworkflows_json | n,unicode }, ${ can_edit_json | n,unicode });
+  var viewModel = new WorkflowEditorViewModel(${ layout_json | n,unicode }, ${ workflow_json | n,unicode }, ${ credentials_json | n,unicode }, ${ workflow_properties_json | n,unicode }, ${ subworkflows_json | n,unicode }, ${ can_edit_json | n,unicode }, ${ history_json | n,unicode });
   ko.applyBindings(viewModel, $("#editor")[0]);
 
   var shareViewModel = initSharing("#documentShareModal");

+ 1 - 0
apps/oozie/src/oozie/tests.py

@@ -268,6 +268,7 @@ class MockFs():
         self.isDir = True
     return MockWebHdfsStat()
 
+
 class OozieMockBase(object):
 
   def setUp(self):

+ 11 - 1
apps/oozie/src/oozie/views/editor2.py

@@ -103,7 +103,12 @@ def _edit_workflow(request, doc, workflow):
       'workflow_properties_json': json.dumps(WORKFLOW_NODE_PROPERTIES, cls=JSONEncoderForHTML),
       'doc1_id': doc.doc.get().id if doc else -1,
       'subworkflows_json': json.dumps(_get_workflows(request.user), cls=JSONEncoderForHTML),
-      'can_edit_json': json.dumps(doc is None or doc.doc.get().is_editable(request.user))
+      'can_edit_json': json.dumps(doc is None or doc.doc.get().is_editable(request.user)),
+      'history_json': json.dumps([{
+          'history': hist.data_dict.get('history', '{}'),
+          'id': hist.id,
+          'date': hist.last_modified.strftime('%Y-%m-%dT%H:%M')
+        } for hist in doc.get_history()], cls=JSONEncoderForHTML)
   })
 
 
@@ -336,6 +341,7 @@ def submit_workflow(request, doc_id):
 
   return _submit_workflow_helper(request, workflow, submit_action=reverse('oozie:editor_submit_workflow', kwargs={'doc_id': workflow.id}))
 
+
 @check_document_access_permission()
 def submit_single_action(request, doc_id, node_id):
   parent_doc = Document2.objects.get(id=doc_id)
@@ -352,6 +358,7 @@ def submit_single_action(request, doc_id, node_id):
 
   return _submit_workflow_helper(request, workflow, submit_action=reverse('oozie:submit_single_action', kwargs={'doc_id': doc_id, 'node_id': node_id}))
 
+
 def _submit_workflow_helper(request, workflow, submit_action):
   ParametersFormSet = formset_factory(ParameterForm, extra=0)
 
@@ -388,6 +395,9 @@ def _submit_workflow(user, fs, jt, workflow, mapping):
   try:
     submission = Submission(user, workflow, fs, jt, mapping)
     job_id = submission.run()
+
+    workflow.document.add_to_history(submission.user, {'properties': submission.properties, 'oozie_id': submission.oozie_id})
+
     return job_id
   except RestException, ex:
     detail = ex._headers.get('oozie-error-message', ex)

+ 19 - 0
desktop/core/src/desktop/models.py

@@ -789,6 +789,10 @@ class Document2(models.Model):
 
     self.data = json.dumps(data_dict)
 
+  def __str__(self):
+    res = '%s - %s - %s' % (force_unicode(self.name), self.owner, self.uuid)
+    return force_unicode(res)
+
   def get_absolute_url(self):
     if self.type == 'oozie-coordinator2':
       return reverse('oozie:edit_coordinator') + '?coordinator=' + str(self.id)
@@ -819,6 +823,21 @@ class Document2(models.Model):
   def can_read_or_exception(self, user):
     self.doc.get().can_read_or_exception(user)
 
+  def get_history(self):
+    return self.dependencies.filter(is_history=True).order_by('-last_modified')
+
+  def add_to_history(self, user, data_dict):
+    doc_id = self.id # Need to copy as the clone messes it
+
+    history_doc = self.copy(name=self.name, owner=user)
+    history_doc.update_data({'history': data_dict})
+    history_doc.is_history = True
+    history_doc.last_modified = None
+    history_doc.save()
+
+    Document2.objects.get(id=doc_id).dependencies.add(history_doc)
+    return history_doc
+
 
 def get_data_link(meta):
   link = None

+ 13 - 0
desktop/core/src/desktop/tests.py

@@ -907,6 +907,19 @@ class TestDocument(object):
     assert_equal(Document.objects.filter(name=name).count(), 1)
     assert_equal(doc.description, self.document.description)
 
+  def test_add_to_history(self):
+    assert_equal(len(self.document2.get_history()), 0)
+
+    doc_id = self.document2.id
+    history_doc = self.document2.add_to_history(self.user, {'key1': 'val1'})
+
+    assert_equal(len(Document2.objects.get(id=doc_id).dependencies.all()), 1) # Need to get original document dynamically
+    assert_equal(len(Document2.objects.get(id=doc_id).get_history()), 1)
+
+    assert_equal(history_doc, Document2.objects.get(id=doc_id).get_history()[0])
+
+    assert_not_equal(doc_id, history_doc.id)
+
 
 def test_session_secure_cookie():
   with tempfile.NamedTemporaryFile() as cert_file: