final String applicationName = appSpec.getName();
final ArchiveBundler bundler = new ArchiveBundler(o.getArchive());
// Make sure we have a directory to store the original artifact.
Location outputDir = locationFactory.create(configuration.get(Constants.AppFabric.OUTPUT_DIR));
final Location newOutputDir = outputDir.append(o.getApplicationId().getAccountId());
// Check exists, create, check exists again to avoid failure due to race condition.
if (!newOutputDir.exists() && !newOutputDir.mkdirs() && !newOutputDir.exists()) {
throw new IOException("Failed to create directory");
}
// Now, we iterate through all ProgramSpecification and generate programs
Iterable<ProgramSpecification> specifications = Iterables.concat(
appSpec.getMapReduce().values(),
appSpec.getFlows().values(),
appSpec.getProcedures().values(),
appSpec.getWorkflows().values(),
appSpec.getServices().values(),
appSpec.getSpark().values()
);
// Generate webapp program if required
Set<String> servingHostNames = WebappProgramRunner.getServingHostNames(o.getArchive().getInputStream());
if (!servingHostNames.isEmpty()) {
specifications = Iterables.concat(specifications, ImmutableList.of(
createWebappSpec(ProgramType.WEBAPP.toString().toLowerCase())));
}
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(
Executors.newFixedThreadPool(10, Threads.createDaemonThreadFactory("program-gen-%d"))
);
try {
List<ListenableFuture<Location>> futures = Lists.newArrayList();
for (final ProgramSpecification spec: specifications) {
ListenableFuture<Location> future = executorService.submit(
new Callable<Location>() {
@Override
public Location call() throws Exception {
ProgramType type = ProgramTypes.fromSpecification(spec);
String name = String.format(Locale.ENGLISH, "%s/%s", type, applicationName);
Location programDir = newOutputDir.append(name);
if (!programDir.exists()) {
programDir.mkdirs();
}
Location output = programDir.append(String.format("%s.jar", spec.getName()));
return ProgramBundle.create(o.getApplicationId(), bundler, output, spec.getName(),
spec.getClassName(), type, appSpec);
}
});
futures.add(future);