Просмотр исходного кода

HUE-1656 [oozie] Create Coordinator SLA

Romain Rigaux 12 лет назад
Родитель
Сommit
edf3af6

+ 6 - 0
apps/oozie/src/oozie/models.py

@@ -68,6 +68,8 @@ DEFAULT_SLA = [
     {'key': 'max-duration', 'value': ''},
     {'key': 'alert-events', 'value': ''},
     {'key': 'alert-contact', 'value': ''},
+    #{'key': 'notification-msg', 'value': ''},
+    #{'key': 'alert-contact', 'value': ''},
 ]
 
 class JobManager(models.Manager):
@@ -214,6 +216,8 @@ class Job(models.Model):
 
   @property
   def sla(self):
+    if not self.data: # backward compatible
+      self.data = json.dumps({})
     return json.loads(self.data).get('sla', copy.deepcopy(DEFAULT_SLA))
 
   @property
@@ -221,6 +225,8 @@ class Job(models.Model):
     return json.dumps(self.sla, cls=JSONEncoderForHTML)
 
   def set_sla(self, sla):
+    if not self.data: # backward compatible
+      self.data = json.dumps({})    
     data_json = json.loads(self.data)
     data_json['sla'] = sla
     self.data = json.dumps(data_json)

+ 8 - 0
apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinator.mako

@@ -139,6 +139,9 @@ ${ layout.menubar(section='coordinators', dashboard=True) }
       <li><a href="#configuration" data-toggle="tab">${ _('Configuration') }</a></li>
       <li><a href="#log" data-toggle="tab">${ _('Log') }</a></li>
       <li><a href="#definition" data-toggle="tab">${ _('Definition') }</a></li>
+      % if oozie_coordinator.has_sla:
+      <li><a href="#sla" data-toggle="tab">${ _('SLA') }</a></li>
+      % endif
     </ul>
 
     <div class="tab-content" style="padding-bottom:200px">
@@ -269,6 +272,11 @@ ${ layout.menubar(section='coordinators', dashboard=True) }
       <div class="tab-pane" id="definition">
         <textarea id="definitionEditor">${ oozie_coordinator.definition.decode('utf-8', 'replace') }</textarea>
       </div>
+      
+      % if oozie_coordinator.has_sla:
+      <div class="tab-pane" id="sla">          
+      </div>
+      % endif
     </div>
 
     <div style="margin-bottom: 16px">

+ 4 - 0
apps/oozie/src/oozie/templates/editor/coordinator_properties.mako

@@ -98,6 +98,10 @@
                   .attr("name", "job_properties")
                   .attr("value", ko.utils.stringifyJson(self.job_properties))
                   .appendTo(form);
+          $("<input>").attr("type", "hidden")
+                  .attr("name", "sla")
+                  .attr("value", ko.utils.stringifyJson(window.slaModel.sla))
+                  .appendTo(form);
 
           form.submit();
         };

+ 0 - 1
apps/oozie/src/oozie/templates/editor/edit_bundled_coordinator.mako

@@ -51,7 +51,6 @@ $(document).ready(function () {
     };
   };
 
-
   window.viewModel = new ViewModel();
   ko.applyBindings(window.viewModel, document.getElementById('editBundledCoordinator'));
 

+ 55 - 23
apps/oozie/src/oozie/templates/editor/edit_coordinator.mako

@@ -104,7 +104,7 @@ ${ layout.menubar(section='coordinators') }
             <div class="fieldWrapper">
               ${ utils.render_field_no_popover(coordinator_form['name'], extra_attrs = {'validate':'true'}) }
               ${ utils.render_field_no_popover(coordinator_form['description']) }
-              ${ utils.render_field_no_popover(coordinator_form['workflow'], extra_attrs = {'validate':'true'}) }              
+              ${ utils.render_field_no_popover(coordinator_form['workflow'], extra_attrs = {'validate':'true'}) }
               ${ coordinator_form['parameters'] | n,unicode }
               <div class="hide">
                 ${ utils.render_field_no_popover(coordinator_form['is_shared']) }
@@ -251,9 +251,11 @@ ${ layout.menubar(section='coordinators') }
 
           <div id="step5" class="stepDetails hide">
             <div class="alert alert-info"><h3>${ _('Advanced settings') }</h3></div>
-            ${ properties.print_key_value(coordinator_form['parameters'], 'parameters') }
-            ${ properties.print_key_value(coordinator_form['job_properties'], 'job_properties') }
-            ${ utils.render_field(coordinator_form['timeout']) }
+            <div id="properties-settings">
+              ${ properties.print_key_value(coordinator_form['parameters'], 'parameters') }
+              ${ properties.print_key_value(coordinator_form['job_properties'], 'job_properties') }
+            </div>
+              ${ utils.render_field(coordinator_form['timeout']) }
             <div class="row-fluid">
               <div class="span6">
                 ${ utils.render_field(coordinator_form['concurrency']) }
@@ -262,13 +264,31 @@ ${ layout.menubar(section='coordinators') }
                 ${ utils.render_field(coordinator_form['throttle']) }
               </div>
             </div>
+
             ${ utils.render_field(coordinator_form['execution']) }
             ${ coordinator_form['schema_version'] | n,unicode }
+
+            <div class="control-group">
+              <label class="control-label">
+                <a href="#" id="advanced-btn" onclick="$('#advanced-container').toggle('hide')">
+                <i class="fa fa-share"></i> ${ _('Advanced') }</a>
+              </label>
+              <div class="controls"></div>
+            </div>
+
+            <div id="advanced-container" class="hide">
+              <div id="slaEditord" class="control-group">
+                <label class="control-label">
+                  ${ _('SLA') }
+                </label>
+                ${ utils.slaForm() }
+              </div>
+            </div>
           </div>
 
         </div>
 
-        <div class="form-actions">
+        <div class="form-actions" id="bottom-nav">
           <a id="backBtn" class="btn disabled">${ _('Back') }</a>
           <a id="nextBtn" class="btn btn-primary disable-feedback">${ _('Next') }</a>
           % if coordinator.is_editable(user):
@@ -394,7 +414,7 @@ ${ layout.menubar(section='coordinators') }
               <tr>
                 <td>
                   <a href="${ url('oozie:list_history_record', record_id=record.id) }" data-row-selector="true"></a>
-                ${ utils.format_date(record.submission_date) }
+                  ${ utils.format_date(record.submission_date) }
                 </td>
                 <td>${ record.oozie_job_id }</td>
               </tr>
@@ -499,19 +519,19 @@ ${ layout.menubar(section='coordinators') }
           _clone.appendTo($("#add-dataset-form"));
         });
         $.post("${ url('oozie:create_coordinator_dataset', coordinator=coordinator.id) }",
-                $("#add-dataset-form").serialize(),
-                function (response) {
-                  if (response['status'] != 0) {
-                    $("#add-dataset-form").empty();
-                    $('#add-dataset-body').html(response['data']);
-                    decorateDateTime();
-                    ko.cleanNode(window.document.body);
-                    ko.applyBindings(window.viewModel);
-                  } else {
-                    window.location.replace(response['data']);
-                    window.location.reload();
-                  }
-                }
+            $("#add-dataset-form").serialize(),
+            function (response) {
+              if (response['status'] != 0) {
+                $("#add-dataset-form").empty();
+                $('#add-dataset-body').html(response['data']);
+                decorateDateTime();
+                ko.cleanNode($('#add-dataset-body')[0]);
+                ko.applyBindings(window.viewModel, $('#add-dataset-body')[0]);
+              } else {
+                window.location.replace(response['data']);
+                window.location.reload();
+              }
+            }
         );
       });
 
@@ -527,8 +547,8 @@ ${ layout.menubar(section='coordinators') }
           success:function (response) {
             $("#edit-dataset-body").html(response['data']);
             decorateDateTime();
-            ko.cleanNode(window.document.body);
-            ko.applyBindings(window.viewModel);
+            ko.cleanNode($('#edit-dataset-body')[0]);
+            ko.applyBindings(window.viewModel, $('#edit-dataset-body')[0]);
             routie("editDataset");
           }
         });
@@ -579,8 +599,20 @@ ${ layout.menubar(section='coordinators') }
 
       $("a[data-row-selector='true']").jHueRowSelector();
 
+      var slaModel = function() {
+        var self = this;
+        self.sla = ko.observableArray(${ coordinator.sla_jsescaped | n,unicode });
+      };
+
+      window.slaModel = new slaModel();
+      ko.applyBindings(window.slaModel, document.getElementById('slaEditord'));
+
       window.viewModel.isSaveVisible = ko.observable(false);
-      ko.applyBindings(window.viewModel);
+      ko.applyBindings(window.viewModel, $('#bottom-nav')[0]);
+      ko.applyBindings(window.viewModel, $('#properties-settings')[0]);
+      ko.applyBindings(window.viewModel, $('#step3')[0]);
+      ko.applyBindings(window.viewModel, $('#step4')[0]);
+      ko.applyBindings(window.viewModel, $('#createDataset')[0]);
 
       $("*[rel=popover]").popover({
         placement:'top',
@@ -735,7 +767,7 @@ ${ layout.menubar(section='coordinators') }
   </script>
 % endif
 
-
 ${ utils.decorate_datetime_fields() }
+${ utils.slaGlobal() }
 
 ${ commonfooter(messages) | n,unicode }

+ 1 - 12
apps/oozie/src/oozie/templates/editor/edit_workflow.mako

@@ -1045,21 +1045,10 @@ function checkModelDirtiness() {
   }
 }
 
-function getSLAText(key) {
-  return {
-     'enabled': {'niceName': '${ _("Enabled") }', 'placeHolder': ''},
-     'nominal-time': {'niceName': '${ _("Nominal time") } *', 'placeHolder': '${"$"}{nominal_time}'},
-     'should-start': {'niceName': '${ _("Should start") }', 'placeHolder': '${"$"}{10 * MINUTES}'},
-     'should-end': {'niceName': '${ _("Should end") } *', 'placeHolder': '${"$"}{30 * MINUTES}'},
-     'max-duration': {'niceName': '${ _("Max duration") }', 'placeHolder': '${"$"}{30 * MINUTES}'},
-     'alert-events': {'niceName': '${ _("Alert events") }', 'placeHolder': 'start_miss,end_miss,duration_miss'},
-     'alert-contact': {'niceName': '${ _("Alert contact") }', 'placeHolder': 'joe@example.com,bob@example.com'} 
-  }[key]
-};
-
 </script>
 
 ${ utils.path_chooser_libs(True) }
+${ utils.slaGlobal() }
 
 <script>
   $(document).ready(function(){

+ 5 - 1
apps/oozie/src/oozie/templates/editor/gen/coordinator.xml.mako

@@ -19,6 +19,8 @@
   from oozie.utils import smart_path
 %>
 
+<%namespace name="common" file="workflow-common.xml.mako" />
+
 
 <%def name="render_dataset_instance(dataset)">
   % if dataset.instance_choice == 'default':
@@ -51,7 +53,8 @@
 <coordinator-app name="${ coord.name }"
   frequency="${ coord.frequency }"
   start="${ coord.start_utc }" end="${ coord.end_utc }" timezone="${ coord.timezone }"
-  xmlns="${ coord.schema_version }">
+  xmlns="${ 'uri:oozie:coordinator:0.4' if coord.sla_enabled else coord.schema_version | n,unicode }"
+  ${ 'xmlns:sla="uri:oozie:sla:0.2"' if coord.sla_enabled else '' | n,unicode }>
   % if coord.timeout or coord.concurrency or coord.execution or coord.throttle:
   <controls>
     % if coord.timeout:
@@ -127,5 +130,6 @@
       </configuration>
       % endif
    </workflow>
+   ${ common.sla(coord) }
   </action>
 </coordinator-app>

+ 19 - 0
apps/oozie/src/oozie/templates/utils.inc.mako

@@ -277,6 +277,25 @@
   </div>
 </%def>
 
+
+## Would be nice include it in slaForm() somehow
+<%def name="slaGlobal()">
+<script type="text/javascript" charset="utf-8">
+  function getSLAText(key) {
+    return {
+       'enabled': {'niceName': '${ _("Enabled") }', 'placeHolder': ''},
+       'nominal-time': {'niceName': '${ _("Nominal time") } *', 'placeHolder': '${"$"}{nominal_time}'},
+       'should-start': {'niceName': '${ _("Should start") }', 'placeHolder': '${"$"}{10 * MINUTES}'},
+       'should-end': {'niceName': '${ _("Should end") } *', 'placeHolder': '${"$"}{30 * MINUTES}'},
+       'max-duration': {'niceName': '${ _("Max duration") }', 'placeHolder': '${"$"}{30 * MINUTES}'},
+       'alert-events': {'niceName': '${ _("Alert events") }', 'placeHolder': 'start_miss,end_miss,duration_miss'},
+       'alert-contact': {'niceName': '${ _("Alert contact") }', 'placeHolder': 'joe@example.com,bob@example.com'} 
+    }[key]
+  };
+</script>
+</%def>
+
+
 <%def name="render_constant(label, value)">
   <div class="control-group">
     <label class="control-label">${ label }</label>

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

@@ -185,7 +185,7 @@ class MockOozieApi:
 
   def get_oozie_slas(self, **kwargs):
     return MockOozieApi.WORKFLOWS_SLAS
-    
+
 
 class OozieMockBase(object):
 
@@ -1451,6 +1451,32 @@ class TestEditor(OozieMockBase):
 </coordinator-app>""" in coord.to_xml(), coord.to_xml())
 
 
+  def test_coordinator_gen_sla(self):
+    coord = create_coordinator(self.wf, self.c, self.user)
+    xml = coord.to_xml()
+
+    assert_false('<sla' in xml, xml)
+    assert_false('xmlns="uri:oozie:coordinator:0.4"' in xml, xml)
+    assert_false('xmlns:sla="uri:oozie:sla:0.2"' in xml, xml)
+
+    sla = coord.sla
+    sla[0]['value'] = True
+    sla[1]['value'] = 'now' # nominal-time
+    sla[3]['value'] = '${ 10 * MINUTES}' # should-end
+    coord.set_sla(sla)
+    coord.save()
+
+    xml = coord.to_xml()
+    assert_true('xmlns="uri:oozie:coordinator:0.4"' in xml, xml)
+    assert_true('xmlns:sla="uri:oozie:sla:0.2"' in xml, xml)
+    assert_true("""</workflow>
+          <sla:info>
+            <sla:nominal-time>now</sla:nominal-time>
+            <sla:should-end>${ 10 * MINUTES}</sla:should-end>
+          </sla:info>
+  </action>""" in xml, xml)
+
+
   def test_coordinator_with_data_input_gen_xml(self):
     coord = create_coordinator(self.wf, self.c, self.user)
     create_dataset(coord, self.c)

+ 2 - 1
apps/oozie/src/oozie/views/dashboard.py

@@ -350,7 +350,8 @@ def list_oozie_sla(request):
     if request.POST.get('end'):
       params['nominal_end'] = request.POST.get('end')
       
-    oozie_slas = api.get_oozie_slas(**params)  
+    oozie_slas = api.get_oozie_slas(**params)
+    print oozie_slas  
     
   else:
     oozie_slas = [] # or get latest?

+ 4 - 1
apps/oozie/src/oozie/views/editor.py

@@ -459,7 +459,7 @@ def edit_coordinator(request, coordinator):
     data_output_formset = DataOutputFormSet(request.POST, request.FILES, instance=coordinator)
     new_data_input_formset = NewDataInputFormSet(request.POST, request.FILES, instance=coordinator, prefix='input')
     new_data_output_formset = NewDataOutputFormSet(request.POST, request.FILES, instance=coordinator, prefix='output')
-
+    print request.POST
     if coordinator_form.is_valid() and dataset_formset.is_valid() and data_input_formset.is_valid() and data_output_formset.is_valid() \
         and new_data_input_formset.is_valid() and new_data_output_formset.is_valid():
       coordinator = coordinator_form.save()
@@ -468,6 +468,9 @@ def edit_coordinator(request, coordinator):
       data_output_formset.save()
       new_data_input_formset.save()
       new_data_output_formset.save()
+      
+      coordinator.set_sla(json.loads(request.POST.get('sla')))
+      coordinator.save()
 
       request.info(_('Coordinator saved.'))
       return redirect(reverse('oozie:edit_coordinator', kwargs={'coordinator': coordinator.id}))