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    package org.apache.oozie.command.wf;
019    
020    import org.apache.hadoop.conf.Configuration;
021    import org.apache.oozie.action.hadoop.MapReduceMain;
022    import org.apache.oozie.client.XOozieClient;
023    import org.apache.oozie.command.CommandException;
024    import org.apache.oozie.util.XmlUtils;
025    import org.jdom.Element;
026    import org.jdom.Namespace;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    public abstract class SubmitScriptLanguageXCommand extends SubmitHttpXCommand {
032        public SubmitScriptLanguageXCommand(String name, String type, Configuration conf) {
033            super(name, type, conf);
034        }
035    
036        protected abstract String getLanguageName();
037    
038        protected abstract String getOptions();
039    
040        protected abstract String getScriptParamters();
041    
042        protected Namespace getSectionNamespace() {
043            return Namespace.getNamespace("uri:oozie:workflow:0.2");
044        }
045    
046        private Element generateSection(Configuration conf, Namespace ns) {
047            String name = getLanguageName();
048            Element ele = new Element(name, ns);
049            Element jt = new Element("job-tracker", ns);
050            jt.addContent(conf.get(XOozieClient.JT));
051            ele.addContent(jt);
052            Element nn = new Element("name-node", ns);
053            nn.addContent(conf.get(XOozieClient.NN));
054            ele.addContent(nn);
055    
056            List<String> Dargs = new ArrayList<String>();
057            List<String> otherArgs = new ArrayList<String>();
058            String[] args = MapReduceMain.getStrings(conf, getOptions());
059            for (String arg : args) {
060                if (arg.startsWith("-D")) {
061                    Dargs.add(arg);
062                }
063                else {
064                    otherArgs.add(arg);
065                }
066            }
067            String [] params = MapReduceMain.getStrings(conf, getScriptParamters());
068    
069            // configuration section
070            if (Dargs.size() > 0) {
071                Element configuration = generateConfigurationSection(Dargs, ns);
072                ele.addContent(configuration);
073            }
074    
075            Element script = new Element("script", ns);
076            script.addContent("dummy." + name);
077            ele.addContent(script);
078    
079            // parameter section
080            for (String param : params) {
081                Element parameter = new Element("param", ns);
082                parameter.addContent(param);
083                ele.addContent(parameter);
084            }
085    
086            // argument section
087            for (String arg : otherArgs) {
088                Element argument = new Element("argument", ns);
089                argument.addContent(arg);
090                ele.addContent(argument);
091            }
092    
093            // file section
094            addFileSection(ele, conf, ns);
095    
096            // archive section
097            addArchiveSection(ele, conf, ns);
098    
099            return ele;
100        }
101    
102        private Element generateConfigurationSection(List<String> Dargs, Namespace ns) {
103            Element configuration = new Element("configuration", ns);
104            for (String arg : Dargs) {
105                String name = null, value = null;
106                int pos = arg.indexOf("=");
107                if (pos == -1) { // "-D<name>" or "-D" only
108                    name = arg.substring(2, arg.length());
109                    value = "";
110                }
111                else { // "-D<name>=<value>"
112                    name = arg.substring(2, pos);
113                    value = arg.substring(pos + 1, arg.length());
114                }
115    
116                Element property = new Element("property", ns);
117                Element nameElement = new Element("name", ns);
118                nameElement.addContent(name);
119                property.addContent(nameElement);
120                Element valueElement = new Element("value", ns);
121                valueElement.addContent(value);
122                property.addContent(valueElement);
123                configuration.addContent(property);
124            }
125    
126            return configuration;
127        }
128    
129        /*
130        * (non-Javadoc)
131        *
132        * @see
133        * org.apache.oozie.command.wf.SubmitHttpCommand#getWorkflowXml(org.apache
134        * .hadoop.conf.Configuration)
135        */
136        @Override
137        protected String getWorkflowXml(Configuration conf) {
138            for (String key : MANDATORY_OOZIE_CONFS) {
139                String value = conf.get(key);
140                if (value == null) {
141                    throw new RuntimeException(key + " is not specified");
142                }
143            }
144    
145            Namespace ns = Namespace.getNamespace("uri:oozie:workflow:0.2");
146            Element root = new Element("workflow-app", ns);
147            root.setAttribute("name", "oozie-" + getLanguageName());
148    
149            Element start = new Element("start", ns);
150            String name = getLanguageName();
151            String nodeName = name + "1";
152            start.setAttribute("to", nodeName);
153            root.addContent(start);
154    
155            Element action = new Element("action", ns);
156            action.setAttribute("name", nodeName);
157    
158            Element ele = generateSection(conf, getSectionNamespace());
159            action.addContent(ele);
160    
161            Element ok = new Element("ok", ns);
162            ok.setAttribute("to", "end");
163            action.addContent(ok);
164    
165            Element error = new Element("error", ns);
166            error.setAttribute("to", "fail");
167            action.addContent(error);
168    
169            root.addContent(action);
170    
171            Element kill = new Element("kill", ns);
172            kill.setAttribute("name", "fail");
173            Element message = new Element("message", ns);
174            message.addContent(name + " failed, error message[${wf:errorMessage(wf:lastErrorNode())}]");
175            kill.addContent(message);
176            root.addContent(kill);
177    
178            Element end = new Element("end", ns);
179            end.setAttribute("name", "end");
180            root.addContent(end);
181    
182            return XmlUtils.prettyPrint(root).toString();
183        }
184    
185        @Override
186        public String getEntityKey() {
187            return null;
188        }
189    
190        @Override
191        protected boolean isLockRequired() {
192            return false;
193        }
194    
195        @Override
196        protected void loadState() {
197    
198        }
199    
200        @Override
201        protected void verifyPrecondition() throws CommandException {
202    
203        }
204    }