/**
  * Used in defining the frequency in 'minute' unit.
  *
  * <p>domain: <code> val &gt; 0</code> and should be integer.
  *
  * @param val frequency in number of minutes.
  * @return number of minutes and also set the frequency timeunit to "minute"
  */
 public static int ph1_coord_minutes(int val) {
   val = ParamChecker.checkGTZero(val, "n");
   ELEvaluator eval = ELEvaluator.getCurrent();
   eval.setVariable("timeunit", TimeUnit.MINUTE);
   eval.setVariable("endOfDuration", TimeUnit.NONE);
   return val;
 }
示例#2
0
 public static ELEvaluator createELEvaluatorForGroup(Configuration conf, String group) {
   ELEvaluator eval = Services.get().get(ELService.class).createEvaluator(group);
   for (Map.Entry<String, String> entry : conf) {
     eval.setVariable(entry.getKey(), entry.getValue());
   }
   return eval;
 }
 /**
  * Return Job Name.
  *
  * <p>
  *
  * @return coordinator name
  */
 public static String ph2_coord_name() throws Exception {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordAction action =
       ParamChecker.notNull(
           (SyncCoordAction) eval.getVariable(COORD_ACTION), "Coordinator Action");
   return action.getName();
 }
 /**
  * Return nominal time or Action Creation Time.
  *
  * <p>
  *
  * @return coordinator action creation or materialization date time
  * @throws Exception if unable to format the Date object to String
  */
 public static String ph2_coord_nominalTime() throws Exception {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordAction action =
       ParamChecker.notNull(
           (SyncCoordAction) eval.getVariable(COORD_ACTION), "Coordinator Action");
   return DateUtils.formatDateUTC(action.getNominalTime());
 }
 /**
  * Used in defining the frequency in 'month' unit and specify the "end of month" property.
  *
  * <p>Every instance will start at first day of each month at 00:00 hour.
  *
  * <p>domain: <code> val &gt; 0</code> and should be integer.
  *
  * @param val: frequency in number of months.
  * @return number of months and also set the frequency timeunit to "month" and end_of_duration
  *     flag to "month"
  */
 public static int ph1_coord_endOfMonths(int val) {
   val = ParamChecker.checkGTZero(val, "n");
   ELEvaluator eval = ELEvaluator.getCurrent();
   eval.setVariable("timeunit", TimeUnit.MONTH);
   eval.setVariable("endOfDuration", TimeUnit.END_OF_MONTH);
   return val;
 }
示例#6
0
 public void testEndOfMonths() throws Exception {
   init("coord-job-submit-freq");
   String expr = "${coord:endOfMonths(1)}";
   expr = "${coord:endOfMonths(3)}";
   assertEquals("3", CoordELFunctions.evalAndWrap(eval, expr));
   assertEquals(TimeUnit.MONTH, (TimeUnit) eval.getVariable("timeunit"));
   assertEquals(TimeUnit.END_OF_MONTH, (TimeUnit) eval.getVariable("endOfDuration"));
 }
 /** @return whether a data set is SYNCH or ASYNC */
 private static boolean isSyncDataSet() {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordDataset ds = (SyncCoordDataset) eval.getVariable(DATASET);
   if (ds == null) {
     throw new RuntimeException("Associated Dataset should be defined with key " + DATASET);
   }
   return ds.getType().equalsIgnoreCase("SYNC");
 }
 /** @return dataset TimeUnit */
 private static TimeUnit getDSEndOfFlag() {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordDataset ds = (SyncCoordDataset) eval.getVariable(DATASET);
   if (ds == null) {
     throw new RuntimeException("Associated Dataset should be defined with key " + DATASET);
   }
   return ds.getEndOfDuration(); // == null ? "": ds.getEndOfDuration();
 }
 /** @return dataset TimeZone */
 private static TimeZone getDatasetTZ() {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordDataset ds = (SyncCoordDataset) eval.getVariable(DATASET);
   if (ds == null) {
     throw new RuntimeException("Associated Dataset should be defined with key " + DATASET);
   }
   return ds.getTimeZone();
 }
示例#10
0
 /** @return Actual Time when all the dependencies of an application instance are met. */
 private static Date getActualTime() {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordAction coordAction = (SyncCoordAction) eval.getVariable(COORD_ACTION);
   if (coordAction == null) {
     throw new RuntimeException(
         "Associated Application instance should be defined with key " + COORD_ACTION);
   }
   return coordAction.getActualTime();
 }
示例#11
0
 public static String ph1_coord_dataOut_echo(String n) {
   ELEvaluator eval = ELEvaluator.getCurrent();
   String val = (String) eval.getVariable("oozie.dataname." + n);
   if (val == null || val.equals("data-out") == false) {
     XLog.getLog(CoordELFunctions.class).error("data_out_name " + n + " is not valid");
     throw new RuntimeException("data_out_name " + n + " is not valid");
   }
   return echoUnResolved("dataOut", "'" + n + "'");
 }
示例#12
0
 /**
  * Return Action Start time.
  *
  * <p>
  *
  * @return coordinator action start time
  * @throws Exception if unable to format the Date object to String
  */
 public static String ph2_coord_actualTime() throws Exception {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordAction coordAction = (SyncCoordAction) eval.getVariable(COORD_ACTION);
   if (coordAction == null) {
     throw new RuntimeException(
         "Associated Application instance should be defined with key " + COORD_ACTION);
   }
   return DateUtils.formatDateUTC(coordAction.getActualTime());
 }
示例#13
0
  public void testHours() throws Exception {
    init("coord-job-submit-freq");
    String expr = "${coord:hours(1)}";
    assertEquals("60", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MINUTE, (TimeUnit) eval.getVariable("timeunit"));

    expr = "${coord:hours(coord:hours(1))}";
    assertEquals("3600", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MINUTE, (TimeUnit) eval.getVariable("timeunit"));
  }
示例#14
0
  public void testDay() throws Exception {
    init("coord-job-submit-freq");
    String expr = "${coord:days(1)}";
    assertEquals("1", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.DAY, (TimeUnit) eval.getVariable("timeunit"));

    expr = "${coord:days(256)}";
    assertEquals("256", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.DAY, (TimeUnit) eval.getVariable("timeunit"));
  }
示例#15
0
 /**
  * Used to specify a list of URI's that are used as input dir to the workflow job.
  *
  * <p>Look for two evaluator-level variables
  *
  * <p>A) .datain.<DATAIN_NAME> B) .datain.<DATAIN_NAME>.unresolved
  *
  * <p>A defines the current list of URI.
  *
  * <p>B defines whether there are any unresolved EL-function (i.e latest)
  *
  * <p>If there are something unresolved, this function will echo back the original function
  *
  * <p>otherwise it sends the uris.
  *
  * @param dataInName : Datain name
  * @return the list of URI's separated by INSTANCE_SEPARATOR
  *     <p>if there are unresolved EL function (i.e. latest) , echo back
  *     <p>the function without resolving the function.
  */
 public static String ph3_coord_dataIn(String dataInName) {
   String uris = "";
   ELEvaluator eval = ELEvaluator.getCurrent();
   uris = (String) eval.getVariable(".datain." + dataInName);
   Boolean unresolved = (Boolean) eval.getVariable(".datain." + dataInName + ".unresolved");
   if (unresolved != null && unresolved.booleanValue() == true) {
     return "${coord:dataIn('" + dataInName + "')}";
   }
   return uris;
 }
示例#16
0
 /**
  * Check whether a function should be resolved.
  *
  * @param functionName
  * @param n
  * @return null if the functionName needs to be resolved otherwise return the calling function
  *     unresolved.
  */
 private static String checkIfResolved(String functionName, String n) {
   ELEvaluator eval = ELEvaluator.getCurrent();
   String replace = (String) eval.getVariable("resolve_" + functionName);
   if (replace == null || (replace != null && replace.equalsIgnoreCase("false"))) { // Don't
     // resolve
     // return "${coord:" + functionName + "(" + n +")}"; //Unresolved
     eval.setVariable(".wrap", "true");
     return "coord:" + functionName + "(" + n + ")"; // Unresolved
   }
   return null; // Resolved it
 }
示例#17
0
 /**
  * Helper method to wrap around with "${..}".
  *
  * <p>
  *
  * @param eval :EL evaluator
  * @param expr : expression to evaluate
  * @return Resolved expression or echo back the same expression
  * @throws Exception
  */
 public static String evalAndWrap(ELEvaluator eval, String expr) throws Exception {
   try {
     eval.setVariable(".wrap", null);
     String result = eval.evaluate(expr, String.class);
     if (eval.getVariable(".wrap") != null) {
       return "${" + result + "}";
     } else {
       return result;
     }
   } catch (Exception e) {
     throw new Exception("Unable to evaluate :" + expr + ":\n", e);
   }
 }
示例#18
0
 public void testDataIn() throws Exception {
   init("coord-action-start");
   eval.setVariable(
       ".datain.ABC", "file:///tmp/coord/US/2009/1/30,file:///tmp/coord/US/2009/1/31");
   eval.setVariable(".datain.ABC.unresolved", Boolean.FALSE);
   String expr = "${coord:dataIn('ABC')}";
   assertEquals(
       "file:///tmp/coord/US/2009/1/30,file:///tmp/coord/US/2009/1/31",
       CoordELFunctions.evalAndWrap(eval, expr));
   eval.setVariable(
       ".datain.ABC", "file:///tmp/coord/US/2009/1/30,file:///tmp/coord/US/2009/1/31");
   eval.setVariable(".datain.ABC.unresolved", Boolean.TRUE);
   assertEquals(expr, CoordELFunctions.evalAndWrap(eval, expr));
 }
示例#19
0
 /** @return the initial instance of a DataSet in Calendar */
 private static Calendar getInitialInstanceCal() {
   ELEvaluator eval = ELEvaluator.getCurrent();
   SyncCoordDataset ds = (SyncCoordDataset) eval.getVariable(DATASET);
   if (ds == null) {
     throw new RuntimeException("Associated Dataset should be defined with key " + DATASET);
   }
   Calendar effInitTS = Calendar.getInstance();
   effInitTS.setTime(ds.getInitInstance());
   effInitTS.setTimeZone(ds.getTimeZone());
   // To adjust EOD/EOM
   DateUtils.moveToEnd(effInitTS, getDSEndOfFlag());
   return effInitTS;
   // return ds.getInitInstance();
 }
示例#20
0
  public void testFuture() throws Exception {
    init("coord-job-submit-instances");
    String expr = "${coord:future(1, 20)}";

    init("coord-action-start");
    Configuration conf = new Configuration();

    // TODO:Set hadoop properties
    eval.setVariable(CoordELFunctions.CONFIGURATION, conf);
    getTestCaseDir();
    ds.setUriTemplate(getTestCaseFileUri("/${YEAR}/${MONTH}/${DAY}"));
    createTestCaseSubDir("2009/09/10/_SUCCESS".split("/"));
    createTestCaseSubDir("2009/09/11/_SUCCESS".split("/"));
    assertEquals("2009-09-11T23:59Z", CoordELFunctions.evalAndWrap(eval, expr));

    try {
      expr = "${coord:future(-1, 3)}";
      CoordELFunctions.evalAndWrap(eval, expr);
      fail("Should fail for negative instance value");
    } catch (Exception ex) {
    }

    expr = "${coord:future(4, 20)}";
    String res = "${coord:future(4, 20)}";
    assertEquals(res, CoordELFunctions.evalAndWrap(eval, expr));
  }
示例#21
0
  public void testLatest() throws Exception {
    init("coord-action-start");
    String expr = "${coord:latest(0)}";
    Configuration conf = new Configuration();

    // TODO:Set hadoop properties
    eval.setVariable(CoordELFunctions.CONFIGURATION, conf);
    getTestCaseDir();
    ds.setUriTemplate(getTestCaseFileUri("${YEAR}/${MONTH}/${DAY}"));
    createTestCaseSubDir("2009/09/10/_SUCCESS".split("/"));
    // TODO: Create the directories
    assertEquals("2009-09-10T23:59Z", CoordELFunctions.evalAndWrap(eval, expr));
    createTestCaseSubDir("2009/09/09/_SUCCESS".split("/"));
    expr = "${coord:latest(-1)}";
    assertEquals("2009-09-09T23:59Z", CoordELFunctions.evalAndWrap(eval, expr));
    createTestCaseSubDir("2009/09/08/_SUCCESS".split("/"));
    expr = "${coord:latest(-2)}";
    assertEquals("2009-09-08T23:59Z", CoordELFunctions.evalAndWrap(eval, expr));

    expr = "${coord:latest(-100)}";
    assertEquals(expr, CoordELFunctions.evalAndWrap(eval, expr));

    expr = "${coord:latest(1)}";
    try {
      assertEquals(expr, CoordELFunctions.evalAndWrap(eval, expr));
      fail("Should throw exception, because latest for +ve instance is not valid");
    } catch (Exception ex) {
    }
    // Add test cases with EOM and EOD option
  }
示例#22
0
 public void testDataOut() throws Exception {
   init("coord-action-start");
   eval.setVariable(
       ".dataout.ABC", "file:///tmp/coord/US/2009/1/30,file:///tmp/coord/US/2009/1/31");
   String expr = "${coord:dataOut('ABC')}";
   assertEquals(
       "file:///tmp/coord/US/2009/1/30,file:///tmp/coord/US/2009/1/31",
       CoordELFunctions.evalAndWrap(eval, expr));
 }
示例#23
0
  public void testMonth() throws Exception {
    init("coord-job-submit-freq");
    String expr = "${coord:months(1)}";
    assertEquals("1", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MONTH, (TimeUnit) eval.getVariable("timeunit"));

    expr = "${coord:months(1) + 7}";
    assertEquals("8", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MONTH, (TimeUnit) eval.getVariable("timeunit"));

    expr = "${coord:months(256)}";
    assertEquals("256", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MONTH, (TimeUnit) eval.getVariable("timeunit"));

    expr = "${coord:months(coord:months(7))}";
    assertEquals("7", CoordELFunctions.evalAndWrap(eval, expr));
    assertEquals(TimeUnit.MONTH, (TimeUnit) eval.getVariable("timeunit"));
  }
示例#24
0
 private void init(String tag, String uriTemplate) throws Exception {
   eval = Services.get().get(ELService.class).createEvaluator(tag);
   eval.setVariable(OozieClient.USER_NAME, "test_user");
   eval.setVariable(OozieClient.GROUP_NAME, "test_group");
   appInst = new SyncCoordAction();
   ds = new SyncCoordDataset();
   ds.setFrequency(1);
   ds.setInitInstance(DateUtils.parseDateOozieTZ("2009-09-01T23:59Z"));
   ds.setTimeUnit(TimeUnit.DAY);
   ds.setTimeZone(DateUtils.getTimeZone("America/Los_Angeles"));
   ds.setName("test");
   ds.setUriTemplate(uriTemplate);
   ds.setType("SYNC");
   ds.setDoneFlag("");
   appInst.setActualTime(DateUtils.parseDateOozieTZ("2009-09-10T23:59Z"));
   appInst.setNominalTime(DateUtils.parseDateOozieTZ("2009-09-09T23:59Z"));
   appInst.setTimeZone(DateUtils.getTimeZone("America/Los_Angeles"));
   appInst.setActionId("00000-oozie-C@1");
   appInst.setName("mycoordinator-app");
   CoordELFunctions.configureEvaluator(eval, ds, appInst);
 }
示例#25
0
  /**
   * Resolve datasets using job configuration.
   *
   * @param dsElems : Data set XML element.
   * @throws CoordinatorJobException thrown if failed to resolve datasets
   */
  private void resolveDataSets(List<Element> dsElems) throws CoordinatorJobException {
    for (Element dsElem : dsElems) {
      // Setting up default TimeUnit and EndOFDuraion
      evalFreq.setVariable("timeunit", TimeUnit.MINUTE);
      evalFreq.setVariable("endOfDuration", TimeUnit.NONE);

      String val = resolveAttribute("frequency", dsElem, evalFreq);
      int ival = ParamChecker.checkInteger(val, "frequency");
      ParamChecker.checkGTZero(ival, "frequency");
      addAnAttribute(
          "freq_timeunit",
          dsElem,
          evalFreq.getVariable("timeunit") == null
              ? TimeUnit.MINUTE.toString()
              : ((TimeUnit) evalFreq.getVariable("timeunit")).toString());
      addAnAttribute(
          "end_of_duration",
          dsElem,
          evalFreq.getVariable("endOfDuration") == null
              ? TimeUnit.NONE.toString()
              : ((TimeUnit) evalFreq.getVariable("endOfDuration")).toString());
      val = resolveAttribute("initial-instance", dsElem, evalNofuncs);
      ParamChecker.checkUTC(val, "initial-instance");
      val = resolveAttribute("timezone", dsElem, evalNofuncs);
      ParamChecker.checkTimeZone(val, "timezone");
      resolveTagContents("uri-template", dsElem, evalNofuncs);
      resolveTagContents("done-flag", dsElem, evalNofuncs);
    }
  }
示例#26
0
  public void testFormatTime() throws Exception {
    String expr1 = "${coord:formatTime(\"2009-09-08T23:59Z\", \"yyyy\")}";
    String expr2 = "${coord:formatTime(\"2009-09-08T23:59Z\", \"yyyyMMdd_HHmmss\")}";
    init("coord-action-create");
    assertEquals("2009", CoordELFunctions.evalAndWrap(eval, expr1));
    assertEquals("20090908_235900", CoordELFunctions.evalAndWrap(eval, expr2));
    init("coord-action-create-inst");
    assertEquals("2009", CoordELFunctions.evalAndWrap(eval, expr1));
    assertEquals("20090908_235900", CoordELFunctions.evalAndWrap(eval, expr2));
    init("coord-action-start");
    assertEquals("2009", CoordELFunctions.evalAndWrap(eval, expr1));
    assertEquals("20090908_235900", CoordELFunctions.evalAndWrap(eval, expr2));

    String utcDate = "2009-09-08T23:59Z";
    String expr3 = "${coord:formatTime(date, \"yyyy\")}";
    String expr3_eval = "${coord:formatTime('" + utcDate + "' , " + "yyyy)}";
    init("coord-job-submit-instances");
    eval.setVariable("date", utcDate);
    assertEquals(expr3_eval, CoordELFunctions.evalAndWrap(eval, expr3));
    init("coord-job-submit-data");
    eval.setVariable("date", utcDate);
    assertEquals(expr3_eval, CoordELFunctions.evalAndWrap(eval, expr3));
  }
示例#27
0
  public void testDataNamesPh1() throws Exception {
    init("coord-job-submit-data");
    String expr = "${coord:dataIn('ABC')}";
    eval.setVariable("oozie.dataname.ABC", "data-in");
    assertEquals("${coord:dataIn('ABC')}", CoordELFunctions.evalAndWrap(eval, expr));

    expr = "${coord:dataIn('ABCD')}";
    try {
      assertEquals("${coord:dataIn('ABCD')}", CoordELFunctions.evalAndWrap(eval, expr));
      fail("should throw exception beacuse Data in is not defiend");
    } catch (Exception ex) {
    }

    expr = "${coord:dataOut('EFG')}";
    eval.setVariable("oozie.dataname.EFG", "data-out");
    assertEquals("${coord:dataOut('EFG')}", CoordELFunctions.evalAndWrap(eval, expr));

    expr = "${coord:dataOut('EFGH')}";
    try {
      assertEquals("${coord:dataOut('EFGH')}", CoordELFunctions.evalAndWrap(eval, expr));
      fail("should throw exception beacuse Data in is not defiend");
    } catch (Exception ex) {
    }
  }
示例#28
0
  /**
   * Resolve SLA events
   *
   * @param eAppXml job XML
   * @param coordJob coordinator job bean
   * @throws CommandException thrown if failed to resolve sla events
   */
  private void resolveSLA(Element eAppXml, CoordinatorJobBean coordJob) throws CommandException {
    Element eSla =
        eAppXml
            .getChild("action", eAppXml.getNamespace())
            .getChild("info", Namespace.getNamespace(SchemaService.SLA_NAME_SPACE_URI));

    if (eSla != null) {
      String slaXml = XmlUtils.prettyPrint(eSla).toString();
      try {
        // EL evaluation
        slaXml = evalSla.evaluate(slaXml, String.class);
        // Validate against semantic SXD
        XmlUtils.validateData(slaXml, SchemaName.SLA_ORIGINAL);
      } catch (Exception e) {
        throw new CommandException(ErrorCode.E1004, "Validation ERROR :" + e.getMessage(), e);
      }
    }
  }
示例#29
0
 /**
  * @param tm
  * @return a new Evaluator to be used for URI-template evaluation
  */
 private static ELEvaluator getUriEvaluator(Calendar tm) {
   ELEvaluator retEval = new ELEvaluator();
   retEval.setVariable("YEAR", tm.get(Calendar.YEAR));
   retEval.setVariable(
       "MONTH",
       (tm.get(Calendar.MONTH) + 1) < 10
           ? "0" + (tm.get(Calendar.MONTH) + 1)
           : (tm.get(Calendar.MONTH) + 1));
   retEval.setVariable(
       "DAY",
       tm.get(Calendar.DAY_OF_MONTH) < 10
           ? "0" + tm.get(Calendar.DAY_OF_MONTH)
           : tm.get(Calendar.DAY_OF_MONTH));
   retEval.setVariable(
       "HOUR",
       tm.get(Calendar.HOUR_OF_DAY) < 10
           ? "0" + tm.get(Calendar.HOUR_OF_DAY)
           : tm.get(Calendar.HOUR_OF_DAY));
   retEval.setVariable(
       "MINUTE",
       tm.get(Calendar.MINUTE) < 10 ? "0" + tm.get(Calendar.MINUTE) : tm.get(Calendar.MINUTE));
   return retEval;
 }
示例#30
0
  /**
   * Resolve basic entities using job Configuration.
   *
   * @param conf :Job configuration
   * @param appXml : Original job XML
   * @param coordJob : Coordinator job bean to be populated.
   * @return Resolved job XML element.
   * @throws CoordinatorJobException thrown if failed to resolve basic entities
   * @throws Exception thrown if failed to resolve basic entities
   */
  @SuppressWarnings("unchecked")
  protected Element resolveInitial(Configuration conf, String appXml, CoordinatorJobBean coordJob)
      throws CoordinatorJobException, Exception {
    Element eAppXml = XmlUtils.parseXml(appXml);
    // job's main attributes
    // frequency
    String val = resolveAttribute("frequency", eAppXml, evalFreq);
    int ival = ParamChecker.checkInteger(val, "frequency");
    ParamChecker.checkGTZero(ival, "frequency");
    coordJob.setFrequency(ival);
    TimeUnit tmp =
        (evalFreq.getVariable("timeunit") == null)
            ? TimeUnit.MINUTE
            : ((TimeUnit) evalFreq.getVariable("timeunit"));
    addAnAttribute("freq_timeunit", eAppXml, tmp.toString());
    // TimeUnit
    coordJob.setTimeUnit(CoordinatorJob.Timeunit.valueOf(tmp.toString()));
    // End Of Duration
    tmp =
        evalFreq.getVariable("endOfDuration") == null
            ? TimeUnit.NONE
            : ((TimeUnit) evalFreq.getVariable("endOfDuration"));
    addAnAttribute("end_of_duration", eAppXml, tmp.toString());
    // coordJob.setEndOfDuration(tmp) // TODO: Add new attribute in Job bean

    // Application name
    if (this.coordName == null) {
      val = resolveAttribute("name", eAppXml, evalNofuncs);
      coordJob.setAppName(val);
    } else {
      // this coord job is created from bundle
      coordJob.setAppName(this.coordName);
    }

    // start time
    val = resolveAttribute("start", eAppXml, evalNofuncs);
    ParamChecker.checkUTC(val, "start");
    coordJob.setStartTime(DateUtils.parseDateUTC(val));
    // end time
    val = resolveAttribute("end", eAppXml, evalNofuncs);
    ParamChecker.checkUTC(val, "end");
    coordJob.setEndTime(DateUtils.parseDateUTC(val));
    // Time zone
    val = resolveAttribute("timezone", eAppXml, evalNofuncs);
    ParamChecker.checkTimeZone(val, "timezone");
    coordJob.setTimeZone(val);

    // controls
    val =
        resolveTagContents(
            "timeout", eAppXml.getChild("controls", eAppXml.getNamespace()), evalNofuncs);
    if (val == "") {
      val = Services.get().getConf().get(CONF_DEFAULT_TIMEOUT_NORMAL);
    }

    ival = ParamChecker.checkInteger(val, "timeout");
    if (ival < 0 || ival > Services.get().getConf().getInt(CONF_DEFAULT_MAX_TIMEOUT, 129600)) {
      ival = Services.get().getConf().getInt(CONF_DEFAULT_MAX_TIMEOUT, 129600);
    }
    coordJob.setTimeout(ival);

    val =
        resolveTagContents(
            "concurrency", eAppXml.getChild("controls", eAppXml.getNamespace()), evalNofuncs);
    if (val == null || val.isEmpty()) {
      val = Services.get().getConf().get(CONF_DEFAULT_CONCURRENCY, "-1");
    }
    ival = ParamChecker.checkInteger(val, "concurrency");
    coordJob.setConcurrency(ival);

    val =
        resolveTagContents(
            "throttle", eAppXml.getChild("controls", eAppXml.getNamespace()), evalNofuncs);
    if (val == null || val.isEmpty()) {
      int defaultThrottle = Services.get().getConf().getInt(CONF_DEFAULT_THROTTLE, 12);
      ival = defaultThrottle;
    } else {
      ival = ParamChecker.checkInteger(val, "throttle");
    }
    int maxQueue = Services.get().getConf().getInt(CONF_QUEUE_SIZE, 10000);
    float factor = Services.get().getConf().getFloat(CONF_MAT_THROTTLING_FACTOR, 0.10f);
    int maxThrottle = (int) (maxQueue * factor);
    if (ival > maxThrottle || ival < 1) {
      ival = maxThrottle;
    }
    LOG.debug("max throttle " + ival);
    coordJob.setMatThrottling(ival);

    val =
        resolveTagContents(
            "execution", eAppXml.getChild("controls", eAppXml.getNamespace()), evalNofuncs);
    if (val == "") {
      val = Execution.FIFO.toString();
    }
    coordJob.setExecution(Execution.valueOf(val));
    String[] acceptedVals = {
      Execution.LIFO.toString(), Execution.FIFO.toString(), Execution.LAST_ONLY.toString()
    };
    ParamChecker.isMember(val, acceptedVals, "execution");

    // datasets
    resolveTagContents(
        "include", eAppXml.getChild("datasets", eAppXml.getNamespace()), evalNofuncs);
    // for each data set
    resolveDataSets(eAppXml);
    HashMap<String, String> dataNameList = new HashMap<String, String>();
    resolveIOEvents(eAppXml, dataNameList);

    resolveTagContents(
        "app-path",
        eAppXml
            .getChild("action", eAppXml.getNamespace())
            .getChild("workflow", eAppXml.getNamespace()),
        evalNofuncs);
    // TODO: If action or workflow tag is missing, NullPointerException will
    // occur
    Element configElem =
        eAppXml
            .getChild("action", eAppXml.getNamespace())
            .getChild("workflow", eAppXml.getNamespace())
            .getChild("configuration", eAppXml.getNamespace());
    evalData =
        CoordELEvaluator.createELEvaluatorForDataEcho(conf, "coord-job-submit-data", dataNameList);
    if (configElem != null) {
      for (Element propElem :
          (List<Element>) configElem.getChildren("property", configElem.getNamespace())) {
        resolveTagContents("name", propElem, evalData);
        // Want to check the data-integrity but don't want to modify the
        // XML
        // for properties only
        Element tmpProp = (Element) propElem.clone();
        resolveTagContents("value", tmpProp, evalData);
      }
    }
    resolveSLA(eAppXml, coordJob);
    return eAppXml;
  }