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.util; 020 021import java.util.Iterator; 022import java.util.regex.Matcher; 023import java.util.regex.Pattern; 024import org.apache.oozie.ErrorCode; 025import org.jdom.Element; 026import org.jdom.Namespace; 027 028import org.apache.hadoop.conf.Configuration; 029 030/** 031 * Utility class to parse and verify the <parameters> section in a workflow or coordinator job 032 */ 033public abstract class ParameterVerifier 034{ 035 private static final Pattern nsVersionPattern = Pattern.compile("uri:oozie:(workflow|coordinator|bundle):(\\d+.\\d+)"); 036 037 private static final double workflowMinVersion = 0.4; 038 private static final double coordinatorMinVersion = 0.4; 039 private static final double bundleMinVersion = 0.2; 040 041 /** 042 * Verify the parameters section (if supported in the schema) 043 * 044 * @param conf The job configuration 045 * @param rootElement The root element of the workflow, coordinator, or bundle definition 046 * @throws ParameterVerifierException If required parameters are not defined and have no default values, or if a name is empty 047 */ 048 public static void verifyParameters(Configuration conf, Element rootElement) throws ParameterVerifierException { 049 ParamChecker.notNull(conf, "conf"); 050 if (rootElement == null) { 051 return; 052 } 053 054 if (supportsParameters(rootElement.getNamespaceURI())) { 055 Element params = rootElement.getChild("parameters", rootElement.getNamespace()); 056 if (params != null) { 057 int numMissing = 0; 058 StringBuilder missingParameters = new StringBuilder(); 059 Namespace paramsNs = params.getNamespace(); 060 Iterator<Element> it = params.getChildren("property", paramsNs).iterator(); 061 while (it.hasNext()) { 062 Element prop = it.next(); 063 String name = prop.getChildTextTrim("name", paramsNs); 064 if (name != null) { 065 if (name.isEmpty()) { 066 throw new ParameterVerifierException(ErrorCode.E0739); 067 } 068 if (conf.get(name) == null) { 069 String defaultValue = prop.getChildTextTrim("value", paramsNs); 070 if (defaultValue != null) { 071 conf.set(name, defaultValue); 072 } else { 073 missingParameters.append(name); 074 missingParameters.append(", "); 075 numMissing++; 076 } 077 } 078 } 079 } 080 if (numMissing > 0) { 081 missingParameters.setLength(missingParameters.length() - 2); //remove the trailing ", " 082 throw new ParameterVerifierException(ErrorCode.E0738, numMissing, missingParameters.toString()); 083 } 084 } else { 085 // Log a warning when the <parameters> section is missing 086 XLog.getLog(ParameterVerifier.class).warn("The application does not define formal parameters in its XML " 087 + "definition"); 088 } 089 } 090 } 091 092 static boolean supportsParameters(String namespaceURI) { 093 boolean supports = false; 094 Matcher m = nsVersionPattern.matcher(namespaceURI); 095 if (m.matches() && m.groupCount() == 2) { 096 String type = m.group(1); 097 double ver = Double.parseDouble(m.group(2)); 098 supports = ((type.equals("workflow") && ver >= workflowMinVersion) || 099 (type.equals("coordinator") && ver >= coordinatorMinVersion) || 100 (type.equals("bundle") && ver >= bundleMinVersion)); 101 } 102 return supports; 103 } 104}