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.workflow.lite;
020
021import org.apache.hadoop.io.Writable;
022import org.apache.oozie.service.LiteWorkflowStoreService;
023import org.apache.oozie.util.ParamChecker;
024import org.apache.oozie.workflow.WorkflowException;
025
026import java.io.DataInput;
027import java.io.DataOutput;
028import java.io.IOException;
029import java.util.ArrayList;
030import java.util.Collections;
031import java.util.List;
032
033/**
034 * This node definition is serialized object and should provide readFields() and write() for read and write of fields in
035 * this class.
036 */
037public class NodeDef implements Writable {
038    private String nodeDefVersion = null;
039    private String name = null;
040    private Class<? extends NodeHandler> handlerClass;
041    private String conf = null;
042    private List<String> transitions = new ArrayList<String>();
043    private String cred = "null";
044    private String userRetryMax = "null";
045    private String userRetryInterval = "null";
046
047    NodeDef() {
048    }
049
050    NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions) {
051        this.name = ParamChecker.notEmpty(name, "name");
052        this.conf = conf;
053        this.handlerClass = ParamChecker.notNull(handlerClass, "handlerClass");
054        this.transitions = Collections.unmodifiableList(ParamChecker.notEmptyElements(transitions, "transitions"));
055    }
056
057    NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions, String cred) {
058        this(name, conf, handlerClass, transitions);
059        if (cred != null) {
060            this.cred = cred;
061        }
062    }
063
064    NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions, String cred,
065            String userRetryMax, String userRetryInterval) {
066        this(name, conf, handlerClass, transitions, cred);
067        if (userRetryMax != null) {
068            this.userRetryMax = userRetryMax;
069        }
070        if (userRetryInterval != null) {
071            this.userRetryInterval = userRetryInterval;
072        }
073    }
074
075    public boolean equals(NodeDef other) {
076        return !(other == null || getClass() != other.getClass() || !getName().equals(other.getName()));
077    }
078
079    @Override
080    public int hashCode() {
081        return name.hashCode();
082    }
083
084    public String getName() {
085        return name;
086    }
087
088    public String getCred() {
089        return cred;
090    }
091
092    public Class<? extends NodeHandler> getHandlerClass() {
093        return handlerClass;
094    }
095
096    public List<String> getTransitions() {
097        return transitions;
098    }
099
100    public String getConf() {
101        return conf;
102    }
103
104    public String getUserRetryMax() {
105        return userRetryMax;
106    }
107
108    public String getUserRetryInterval() {
109        return userRetryInterval;
110    }
111
112    public String getNodeDefVersion() {
113        if (nodeDefVersion == null) {
114            try {
115                nodeDefVersion = LiteWorkflowStoreService.getNodeDefDefaultVersion();
116            }
117            catch (WorkflowException e) {
118                nodeDefVersion = LiteWorkflowStoreService.NODE_DEF_VERSION_1;
119            }
120        }
121        return nodeDefVersion;
122    }
123
124    @SuppressWarnings("unchecked")
125    private void readVersionZero(DataInput dataInput, String firstField) throws IOException {
126        if (firstField.equals(LiteWorkflowStoreService.NODE_DEF_VERSION_0)) {
127            name = dataInput.readUTF();
128        } else {
129            name = firstField;
130        }
131        nodeDefVersion = LiteWorkflowStoreService.NODE_DEF_VERSION_0;
132        cred = dataInput.readUTF();
133        String handlerClassName = dataInput.readUTF();
134        if ((handlerClassName != null) && (handlerClassName.length() > 0)) {
135            try {
136                handlerClass = (Class<? extends NodeHandler>) Class.forName(handlerClassName);
137            }
138            catch (ClassNotFoundException ex) {
139                throw new IOException(ex);
140            }
141        }
142        conf = dataInput.readUTF();
143        if (conf.equals("null")) {
144            conf = null;
145        }
146        int numTrans = dataInput.readInt();
147        transitions = new ArrayList<String>(numTrans);
148        for (int i = 0; i < numTrans; i++) {
149            transitions.add(dataInput.readUTF());
150        }
151    }
152    @SuppressWarnings("unchecked")
153    private void readVersionOne(DataInput dataInput, String firstField) throws IOException {
154        nodeDefVersion = LiteWorkflowStoreService.NODE_DEF_VERSION_1;
155        name = dataInput.readUTF();
156        cred = dataInput.readUTF();
157        String handlerClassName = dataInput.readUTF();
158        if ((handlerClassName != null) && (handlerClassName.length() > 0)) {
159            try {
160                handlerClass = (Class<? extends NodeHandler>) Class.forName(handlerClassName);
161            }
162            catch (ClassNotFoundException ex) {
163                throw new IOException(ex);
164            }
165        }
166        conf = dataInput.readUTF();
167        if (conf.equals("null")) {
168            conf = null;
169        }
170        int numTrans = dataInput.readInt();
171        transitions = new ArrayList<String>(numTrans);
172        for (int i = 0; i < numTrans; i++) {
173            transitions.add(dataInput.readUTF());
174        }
175        userRetryMax = dataInput.readUTF();
176        userRetryInterval = dataInput.readUTF();
177    }
178
179    /* (non-Javadoc)
180     * @see org.apache.hadoop.io.Writable#readFields(java.io.DataInput)
181     */
182    @Override
183    public void readFields(DataInput dataInput) throws IOException {
184        String firstField = dataInput.readUTF();
185        if (!firstField.equals(LiteWorkflowStoreService.NODE_DEF_VERSION_1)) {
186            readVersionZero(dataInput, firstField);
187        } else {
188            //since oozie version 3.1
189            readVersionOne(dataInput, firstField);
190        }
191    }
192
193    private void writeVersionZero(DataOutput dataOutput) throws IOException {
194        dataOutput.writeUTF(nodeDefVersion);
195        dataOutput.writeUTF(name);
196        if (cred != null) {
197            dataOutput.writeUTF(cred);
198        }
199        else {
200            dataOutput.writeUTF("null");
201        }
202        dataOutput.writeUTF(handlerClass.getName());
203        if (conf != null) {
204            dataOutput.writeUTF(conf);
205        }
206        else {
207            dataOutput.writeUTF("null");
208        }
209        dataOutput.writeInt(transitions.size());
210        for (String transition : transitions) {
211            dataOutput.writeUTF(transition);
212        }
213    }
214
215    /**
216     * Write as version one format, this version was since 3.1.
217     *
218     * @param dataOutput data output to serialize node def
219     * @throws IOException thrown if fail to write
220     */
221    private void writeVersionOne(DataOutput dataOutput) throws IOException {
222        dataOutput.writeUTF(nodeDefVersion);
223        dataOutput.writeUTF(name);
224        if (cred != null) {
225            dataOutput.writeUTF(cred);
226        }
227        else {
228            dataOutput.writeUTF("null");
229        }
230        dataOutput.writeUTF(handlerClass.getName());
231        if (conf != null) {
232            dataOutput.writeUTF(conf);
233        }
234        else {
235            dataOutput.writeUTF("null");
236        }
237        dataOutput.writeInt(transitions.size());
238        for (String transition : transitions) {
239            dataOutput.writeUTF(transition);
240        }
241        if (userRetryMax != null) {
242            dataOutput.writeUTF(userRetryMax);
243        }
244        else {
245            dataOutput.writeUTF("null");
246        }
247        if (userRetryInterval != null) {
248            dataOutput.writeUTF(userRetryInterval);
249        }
250        else {
251            dataOutput.writeUTF("null");
252        }
253    }
254
255    /* (non-Javadoc)
256     * @see org.apache.hadoop.io.Writable#write(java.io.DataOutput)
257     */
258    @Override
259    public void write(DataOutput dataOutput) throws IOException {
260        if (!getNodeDefVersion().equals(LiteWorkflowStoreService.NODE_DEF_VERSION_1)) {
261            writeVersionZero(dataOutput);
262        } else {
263            //since oozie version 3.1
264            writeVersionOne(dataOutput);
265        }
266    }
267
268}