001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.oozie.dependency; 020 021import java.net.URI; 022import java.net.URISyntaxException; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.List; 026 027import org.apache.commons.lang.StringUtils; 028import org.apache.hadoop.conf.Configuration; 029import org.apache.oozie.ErrorCode; 030import org.apache.oozie.client.OozieClient; 031import org.apache.oozie.command.CommandException; 032import org.apache.oozie.coord.CoordELFunctions; 033import org.apache.oozie.service.Services; 034import org.apache.oozie.service.URIHandlerService; 035import org.apache.oozie.util.ParamChecker; 036import org.apache.oozie.util.XLog; 037 038public class DependencyChecker { 039 040 /** 041 * Return a string of missing dependencies concatenated by CoordELFunctions.INSTANCE_SEPARATOR 042 * 043 * @param missingDependencies list of missing dependencies 044 * @return missing dependencies as a string 045 */ 046 public static String dependenciesAsString(List<String> missingDependencies) { 047 return StringUtils.join(missingDependencies, CoordELFunctions.INSTANCE_SEPARATOR); 048 } 049 050 /** 051 * Return a array of missing dependencies 052 * 053 * @param missingDependencies missing dependencies concatenated by 054 * CoordELFunctions.INSTANCE_SEPARATOR 055 * @return missing dependencies as a array 056 */ 057 public static String[] dependenciesAsArray(String missingDependencies) { 058 if(StringUtils.isEmpty(missingDependencies)){ 059 return new String[0]; 060 } 061 return missingDependencies.split(CoordELFunctions.INSTANCE_SEPARATOR); 062 } 063 064 /** 065 * Get the currently missing and available dependencies after checking the list of known missing 066 * dependencies against the source. 067 * 068 * @param missingDependencies known missing dependencies 069 * @param actionConf Configuration for the action 070 * @param stopOnFirstMissing Does not continue check for the rest of list if there is a missing 071 * dependency 072 * @return ActionDependency which has the list of missing and available dependencies 073 * @throws CommandException in case of error 074 */ 075 public static ActionDependency checkForAvailability(String missingDependencies, Configuration actionConf, 076 boolean stopOnFirstMissing) throws CommandException { 077 return checkForAvailability(Arrays.asList(dependenciesAsArray(missingDependencies)), actionConf, stopOnFirstMissing); 078 } 079 080 /** 081 * Get the currently missing and available dependencies after checking the list of known missing 082 * dependencies against the source. 083 * 084 * @param missingDependencies known missing dependencies 085 * @param actionConf Configuration for the action 086 * @param stopOnFirstMissing Does not continue check for the rest of list if there is a missing 087 * dependency 088 * @return ActionDependency which has the list of missing and available dependencies 089 * @throws CommandException in case of error 090 */ 091 public static ActionDependency checkForAvailability(List<String> missingDependencies, Configuration actionConf, 092 boolean stopOnFirstMissing) throws CommandException { 093 final XLog LOG = XLog.getLog(DependencyChecker.class); //OOZIE-1251. Don't initialize as static variable. 094 String user = ParamChecker.notEmpty(actionConf.get(OozieClient.USER_NAME), OozieClient.USER_NAME); 095 List<String> missingDeps = new ArrayList<String>(); 096 List<String> availableDeps = new ArrayList<String>(); 097 URIHandlerService uriService = Services.get().get(URIHandlerService.class); 098 boolean continueChecking = true; 099 try { 100 for (int index = 0; index < missingDependencies.size(); index++) { 101 if (continueChecking) { 102 String dependency = missingDependencies.get(index); 103 104 URI uri = new URI(dependency); 105 URIHandler uriHandler = uriService.getURIHandler(uri); 106 LOG.debug("Checking for the availability of dependency [{0}] ", dependency); 107 if (uriHandler.exists(uri, actionConf, user)) { 108 LOG.debug("Dependency [{0}] is available", dependency); 109 availableDeps.add(dependency); 110 } 111 else { 112 LOG.debug("Dependency [{0}] is missing", dependency); 113 missingDeps.add(dependency); 114 if (stopOnFirstMissing) { 115 continueChecking = false; 116 } 117 } 118 119 } 120 else { 121 missingDeps.add(missingDependencies.get(index)); 122 } 123 } 124 } 125 catch (URISyntaxException e) { 126 throw new CommandException(ErrorCode.E0906, e.getMessage(), e); 127 } 128 catch (URIHandlerException e) { 129 throw new CommandException(e); 130 } 131 return new ActionDependency(missingDeps, availableDeps); 132 } 133}