OozieScheduling { public static void writeBundle(Class appClass, AppContext context, Path appPath, List<Schedule> schedules, OutputStream output) throws IOException { Configuration conf = context.getHadoopConf(); XmlStreamWriter streamWriter = WriterFactory.newXmlWriter(output); PrettyPrintXMLWriter writer = new PrettyPrintXMLWriter(streamWriter); writer.startElement(BUNDLE_ELEMENT); writer.addAttribute("name", appClass.getCanonicalName()); writer.addAttribute("xmlns", OOZIE_BUNDLE_NS); writer.startElement("parameters"); Path qualifiedPath = appPath.toUri().getScheme() == null ? appPath.makeQualified(URI.create("hdfs:/"), appPath) : appPath; property(writer, "kiteAppRoot", qualifiedPath.toString()); property(writer, "oozie.libpath", "${kiteAppRoot}/lib"); property(writer, "nameNode", conf.get("fs.default.name")); String resourceManager = conf.get("yarn.resourcemanager.address"); if (resourceManager == null) { String jobTracker = conf.get("mapred.job.tracker"); if (jobTracker != null) resourceManager = jobTracker.replace("8021", "8032"); } if (resourceManager != null) property(writer, "jobTracker", resourceManager); writer.endElement(); int i = 0; for (Schedule schedule: schedules) { writer.startElement("coordinator"); writer.addAttribute("name", schedule.getName()); element(writer, "app-path", "${kiteAppRoot}/" + coordPath(schedule)); writer.endElement(); } writer.endElement(); streamWriter.flush(); }  static String workflowPath(Schedule schedule); static String coordPath(Schedule schedule); static Instant getNominalTime(Configuration conf); static void element(XMLWriter writer, String name, String attributeName,
                              String attributeValue); static void element(XMLWriter writer, String name, String text); static void writeWorkFlow(Schedule schedule,
                                   AppContext context,
                                   OutputStream output); static void writeCoordinator(Schedule schedule,
                                      SchedulableJobManager manager,
                                      OutputStream output); static void property(XMLWriter writer, String name, String value); static void writeBundle(Class appClass,
                                 AppContext context,
                                 Path appPath,
                                 List<Schedule> schedules,
                                 OutputStream output); static Map<String,View> loadViews(SchedulableJobManager manager, Configuration conf); static Map<String,String> getJobSettings(Schedule schedule, Configuration conf); static void writeJobConfiguration(XMLWriter writer, Schedule schedule, Configuration conf);  }
@Test public void testWriteBundle() throws Exception { String appPath = "/test/app/path"; String libPath = "/test/lib/path"; Schedule schedule1 = new Schedule.Builder() .jobName("scheduled-input-output") .jobClass(ScheduledInputOutputJob.class) .frequency("0 * * * *") .withInput("source_users", ScheduledInputOutputApp.INPUT_URI_PATTERN, "0 * * * *") .withOutput("target_users", ScheduledInputOutputApp.OUTPUT_URI_PATTERN) .build(); Schedule schedule2 = new Schedule.Builder() .jobName("alt-scheduled-input-output") .jobClass(AltScheduledInputOutputJob.class) .frequency("0 * * * *") .withInput("source_users", ScheduledInputOutputApp.INPUT_URI_PATTERN, "0 * * * *") .withOutput("target_users", ScheduledInputOutputApp.OUTPUT_URI_PATTERN) .build(); List<Schedule> schedules = Arrays.asList(schedule1, schedule2); ByteArrayOutputStream output = new ByteArrayOutputStream(); OozieScheduling.writeBundle(ScheduledInputOutputApp.class, context, new Path(appPath), schedules, output); Document bundle = XMLUtil.toDom(output); XPath xpath = XMLUtil.getXPath(); assertEquals(schedule1.getName(), xpath.evaluate("bn:bundle-app/bn:coordinator[1]/@name", bundle)); assertEquals(schedule2.getName(), xpath.evaluate("bn:bundle-app/bn:coordinator[2]/@name", bundle)); assertEquals("${kiteAppRoot}/" + OozieScheduling.coordPath(schedule1), xpath.evaluate("bn:bundle-app/bn:coordinator[1]/bn:app-path", bundle)); assertEquals("${kiteAppRoot}/" + OozieScheduling.coordPath(schedule2), xpath.evaluate("bn:bundle-app/bn:coordinator[2]/bn:app-path", bundle)); }