Browse Source

HUE-3797 [scheduler] Refactored and moved Oozie submit coordinator to API

Romain 6 years ago
parent
commit
c6b4288cb2

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

@@ -34,7 +34,6 @@ from oozie.models import Workflow, Node, Java, Mapreduce, Streaming, Coordinator
   Email, SubWorkflow, Generic, Bundle, BundledCoordinator
 
 
-
 LOG = logging.getLogger(__name__)
 
 

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

@@ -676,6 +676,7 @@ def coordinator_parameters(request):
 @check_editor_access_permission
 @check_document_access_permission()
 def submit_coordinator(request, doc_id):
+  # TODO: Replace URL by desktop/scheduler API
   if doc_id.isdigit():
     coordinator = Coordinator(document=Document2.objects.get(id=doc_id))
   else:

+ 52 - 6
desktop/core/src/desktop/lib/scheduler/api.py

@@ -17,11 +17,14 @@
 
 import logging
 
+from oozie.decorators import check_document_access_permission
+from oozie.forms import ParameterForm
+from oozie.views.editor2 import edit_coordinator, new_coordinator
+
 from desktop.auth.backend import is_admin
 from desktop.conf import TASK_SERVER
 from desktop.lib.django_util import JsonResponse
-
-from oozie.views.editor2 import edit_coordinator, new_coordinator, submit_coordinator
+from desktop.lib.scheduler.lib.api import get_api
 
 
 LOG = logging.getLogger(__name__)
@@ -35,8 +38,51 @@ def get_schedule(request):
   return edit_coordinator(request)
 
 
-def submit_schedule(request):
-  if TASK_SERVER.ENABLED.get():
-    pass
+@check_document_access_permission()
+def submit_schedule(request, doc_id):
+  interface = request.GET.get('interface', request.POST.get('interface'), 'oozie')
+  if doc_id.isdigit():
+    coordinator = Coordinator(document=Document2.objects.get(id=doc_id))
+  else:
+    coordinator = Coordinator(document=Document2.objects.get_by_uuid(user=request.user, uuid=doc_id))
+
+  ParametersFormSet = formset_factory(ParameterForm, extra=0)
+
+  if request.method == 'POST':
+    params_form = ParametersFormSet(request.POST)
+
+    if params_form.is_valid():
+      mapping = dict([(param['name'], param['value']) for param in params_form.cleaned_data])
+      mapping['dryrun'] = request.POST.get('dryrun_checkbox') == 'on'
+      jsonify = request.POST.get('format') == 'json'
+      try:
+        job_id = get_api(request, interface).submit_schedule(request, coordinator, mapping)
+      except Exception, e:
+        message = force_unicode(str(e))
+        return JsonResponse({'status': -1, 'message': message}, safe=False)
+      if jsonify:
+        return JsonResponse({'status': 0, 'job_id': job_id, 'type': 'schedule'}, safe=False)
+      else:
+        request.info(_('Schedule submitted.'))
+        return redirect(reverse('oozie:list_oozie_coordinator', kwargs={'job_id': job_id}))
+    else:
+      request.error(_('Invalid submission form: %s') % params_form.errors)
   else:
-    return submit_coordinator(request)
+    parameters = coordinator.find_all_parameters()
+    initial_params = ParameterForm.get_initial_params(dict([(param['name'], param['value']) for param in parameters]))
+    params_form = ParametersFormSet(initial=initial_params)
+
+  popup = render(
+      'scheduler/submit_job_popup.mako',
+      request, {
+          'params_form': params_form,
+          'name': coordinator.name,
+          'action': reverse('oozie:editor_submit_coordinator',  kwargs={'doc_id': coordinator.id}),
+          'show_dryrun': True,
+          'return_json': request.GET.get('format') == 'json',
+          'interface': interface
+      },
+      force_template=True
+  ).content
+
+  return JsonResponse(popup, safe=False)

+ 8 - 6
desktop/core/src/desktop/lib/scheduler/lib/base.py → desktop/core/src/desktop/lib/scheduler/lib/api.py

@@ -15,15 +15,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from desktop.lib.scheduler.lib.beat import CeleryBeatApi
-from desktop.lib.scheduler.lib.oozie import OozieApi
-
 
 def get_api(request, interface):
-
   if interface == 'beat':
+    from desktop.lib.scheduler.lib.beat import CeleryBeatApi
     return CeleryBeatApi(user=request.user)
   elif interface == 'oozie':
+    from desktop.lib.scheduler.lib.oozie import OozieApi
     return OozieApi(user=request.user)
   else:
     raise PopupException(_('Scheduler connector interface not recognized: %s') % interface)
@@ -31,9 +29,13 @@ def get_api(request, interface):
 
 class Api():
 
+  def __init__(self, interface, user):
+    self.interface = interface
+    self.user = user
+
   def get_schedule():
     return JsonResponse({
     })
 
-  def submit_schedule():
-    return
+  def submit_schedule(request, coordinator, mapping):
+    pass

+ 2 - 4
desktop/core/src/desktop/lib/scheduler/lib/beat.py

@@ -1,9 +1,7 @@
 
 
-from desktop.lib.scheduler.lib.base import Api
+from desktop.lib.scheduler.lib.api import Api
 
 
 class CeleryBeatApi(Api):
-
-  def __init__(self, user=None):
-    pass
+  pass

+ 5 - 3
desktop/core/src/desktop/lib/scheduler/lib/oozie.py

@@ -1,8 +1,10 @@
 
-from desktop.lib.scheduler.lib.base import Api
+from desktop.lib.scheduler.lib.api import Api
+
+from oozie.views.editor2 import _submit_coordinator
 
 
 class OozieApi(Api):
 
-  def __init__(self, user=None):
-    pass
+  def submit_schedule(request, coordinator, mapping):
+    return _submit_coordinator(request, coordinator, mapping)

+ 27 - 4
apps/oozie/src/oozie/templates/editor2/submit_job_popup.mako → desktop/core/src/desktop/templates/scheduler/submit_job_popup.mako

@@ -18,7 +18,7 @@
   from django.utils.translation import ugettext as _
 %>
 
-<%namespace name="utils" file="../utils.inc.mako" />
+## <%namespace name="utils" file="../utils.inc.mako" />
 
 <link rel="stylesheet" href="${ static('oozie/css/common-editor.css') }">
 
@@ -32,8 +32,8 @@
       <h2 class="modal-title">${ _('Submit %(job)s?') % {'job': name} }</h2>
     % endif
   </div>
-  <div class="modal-body">
 
+  <div class="modal-body">
       <div id="param-container">
 
        ${ params_form.management_form | n,unicode }
@@ -50,7 +50,7 @@
           >
             <label class="control-label">${ form['name'].form.initial.get('name') }</label>
             <div class="controls">
-              ${ utils.render_field(form['value'], show_label=False, extra_attrs={'class': 'filechooser-input input-xlarge'}) }
+              ${ render_field(form['value'], show_label=False, extra_attrs={'class': 'filechooser-input input-xlarge'}) }
               <div class="btn-group">
                 <a class="btn btn-default dropdown-toggle" data-toggle="dropdown">
                   <i class="fa fa-calendar"></i>
@@ -96,7 +96,7 @@
           <input type="hidden" name="cluster" value="${ cluster_json }"></input>
         % endif
         </label>
-        %endif       
+        %endif
       % if return_json:
         <input type="hidden" name="format" value="json">
       % endif
@@ -189,3 +189,26 @@
   % endif
 
 </script>
+
+<%def name="render_field(field, show_label=True, extra_attrs={}, control_extra='')">
+  % if not field.is_hidden:
+    <% group_class = field.errors and "error" or "" %>
+    <div class="control-group ${group_class}"
+      rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text }" ${control_extra}>
+      % if show_label:
+        <label class="control-label">${ field.label }</label>
+      % endif
+      <div class="controls"
+      % if not show_label:
+        style="margin-left: 0"
+      % endif
+              >
+        <% field.field.widget.attrs.update(extra_attrs) %>
+        ${ field | n,unicode }
+        % if field.errors:
+          <span class="help-inline">${ field.errors | n,unicode }</span>
+        % endif
+      </div>
+    </div>
+  %endif
+</%def>

+ 1 - 1
desktop/core/src/desktop/urls.py

@@ -204,7 +204,7 @@ if ANALYTICS.IS_ENABLED.get():
   ]
 
 dynamic_patterns += [
-  url(r'^desktop/scheduler/', include('desktop.lib.scheduler.urls'))
+  url(r'^scheduler/', include('desktop.lib.scheduler.urls'))
 ]
 
 dynamic_patterns += [