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 private String userRetryPolicy = "null"; 047 048 NodeDef() { 049 } 050 051 NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions) { 052 this.name = ParamChecker.notEmpty(name, "name"); 053 this.conf = conf; 054 this.handlerClass = ParamChecker.notNull(handlerClass, "handlerClass"); 055 this.transitions = Collections.unmodifiableList(ParamChecker.notEmptyElements(transitions, "transitions")); 056 } 057 058 NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions, String cred) { 059 this(name, conf, handlerClass, transitions); 060 if (cred != null) { 061 this.cred = cred; 062 } 063 } 064 065 NodeDef(String name, String conf, Class<? extends NodeHandler> handlerClass, List<String> transitions, String cred, 066 String userRetryMax, String userRetryInterval, String userRetryPolicy) { 067 this(name, conf, handlerClass, transitions, cred); 068 if (userRetryMax != null) { 069 this.userRetryMax = userRetryMax; 070 } 071 if (userRetryInterval != null) { 072 this.userRetryInterval = userRetryInterval; 073 } 074 if (userRetryPolicy != null) { 075 this.userRetryPolicy = userRetryPolicy; 076 } 077 } 078 079 public boolean equals(NodeDef other) { 080 return !(other == null || getClass() != other.getClass() || !getName().equals(other.getName())); 081 } 082 083 @Override 084 public int hashCode() { 085 return name.hashCode(); 086 } 087 088 public String getName() { 089 return name; 090 } 091 092 public String getCred() { 093 return cred; 094 } 095 096 public Class<? extends NodeHandler> getHandlerClass() { 097 return handlerClass; 098 } 099 100 public List<String> getTransitions() { 101 return transitions; 102 } 103 104 public String getConf() { 105 return conf; 106 } 107 108 public String getUserRetryMax() { 109 return userRetryMax; 110 } 111 112 public String getUserRetryInterval() { 113 return userRetryInterval; 114 } 115 116 public String getNodeDefVersion() { 117 if (nodeDefVersion == null) { 118 try { 119 nodeDefVersion = LiteWorkflowStoreService.getNodeDefDefaultVersion(); 120 } 121 catch (WorkflowException e) { 122 nodeDefVersion = LiteWorkflowStoreService.NODE_DEF_VERSION_2; 123 } 124 } 125 return nodeDefVersion; 126 } 127 128 public String getUserRetryPolicy() { 129 return userRetryPolicy; 130 } 131 132 public void setUserRetryPolicy(String userRetryPolicy) { 133 this.userRetryPolicy = userRetryPolicy; 134 } 135 136 @SuppressWarnings("unchecked") 137 private void readVersionZero(DataInput dataInput, String firstField) throws IOException { 138 if (firstField.equals(LiteWorkflowStoreService.NODE_DEF_VERSION_0)) { 139 name = dataInput.readUTF(); 140 } else { 141 name = firstField; 142 } 143 nodeDefVersion = LiteWorkflowStoreService.NODE_DEF_VERSION_0; 144 cred = dataInput.readUTF(); 145 String handlerClassName = dataInput.readUTF(); 146 if ((handlerClassName != null) && (handlerClassName.length() > 0)) { 147 try { 148 handlerClass = (Class<? extends NodeHandler>) Class.forName(handlerClassName); 149 } 150 catch (ClassNotFoundException ex) { 151 throw new IOException(ex); 152 } 153 } 154 conf = dataInput.readUTF(); 155 if (conf.equals("null")) { 156 conf = null; 157 } 158 int numTrans = dataInput.readInt(); 159 transitions = new ArrayList<String>(numTrans); 160 for (int i = 0; i < numTrans; i++) { 161 transitions.add(dataInput.readUTF()); 162 } 163 } 164 @SuppressWarnings("unchecked") 165 private void readVersionOne(DataInput dataInput, String firstField) throws IOException { 166 readCommon(dataInput, firstField, LiteWorkflowStoreService.NODE_DEF_VERSION_1); 167 } 168 169 /* 170 * Reads according to version 2 171 */ 172 @SuppressWarnings("unchecked") 173 private void readVersionTwo(DataInput dataInput, String firstField) throws IOException { 174 readCommon(dataInput, firstField, LiteWorkflowStoreService.NODE_DEF_VERSION_2); 175 userRetryPolicy = dataInput.readUTF(); 176 } 177 178 /* 179 * Reads common part 180 */ 181 @SuppressWarnings("unchecked") 182 private void readCommon(DataInput dataInput, String firstField, String nodeDefVer) throws IOException { 183 nodeDefVersion = nodeDefVer; 184 name = dataInput.readUTF(); 185 cred = dataInput.readUTF(); 186 if (cred.equals("null")) { 187 cred = null; 188 } 189 String handlerClassName = dataInput.readUTF(); 190 if ((handlerClassName != null) && (handlerClassName.length() > 0)) { 191 try { 192 handlerClass = (Class<? extends NodeHandler>) Class.forName(handlerClassName); 193 } 194 catch (ClassNotFoundException ex) { 195 throw new IOException(ex); 196 } 197 } 198 conf = dataInput.readUTF(); 199 if (conf.equals("null")) { 200 conf = null; 201 } 202 int numTrans = dataInput.readInt(); 203 transitions = new ArrayList<String>(numTrans); 204 for (int i = 0; i < numTrans; i++) { 205 transitions.add(dataInput.readUTF()); 206 } 207 userRetryMax = dataInput.readUTF(); 208 userRetryInterval = dataInput.readUTF(); 209 } 210 211 /* (non-Javadoc) 212 * @see org.apache.hadoop.io.Writable#readFields(java.io.DataInput) 213 */ 214 @Override 215 public void readFields(DataInput dataInput) throws IOException { 216 String firstField = dataInput.readUTF(); 217 if (firstField.equals(LiteWorkflowStoreService.NODE_DEF_VERSION_1)) { 218 // since oozie version 3.1 219 readVersionOne(dataInput, firstField); 220 } 221 else if (firstField.equals(LiteWorkflowStoreService.NODE_DEF_VERSION_2)) { 222 readVersionTwo(dataInput, firstField); 223 } 224 else { 225 readVersionZero(dataInput, firstField); 226 } 227 } 228 229 private void writeVersionZero(DataOutput dataOutput) throws IOException { 230 dataOutput.writeUTF(nodeDefVersion); 231 dataOutput.writeUTF(name); 232 if (cred != null) { 233 dataOutput.writeUTF(cred); 234 } 235 else { 236 dataOutput.writeUTF("null"); 237 } 238 dataOutput.writeUTF(handlerClass.getName()); 239 if (conf != null) { 240 dataOutput.writeUTF(conf); 241 } 242 else { 243 dataOutput.writeUTF("null"); 244 } 245 dataOutput.writeInt(transitions.size()); 246 for (String transition : transitions) { 247 dataOutput.writeUTF(transition); 248 } 249 } 250 251 /** 252 * Write as version one format, this version was since 3.1. 253 * 254 * @param dataOutput data output to serialize node def 255 * @throws IOException thrown if fail to write 256 */ 257 private void writeVersionOne(DataOutput dataOutput) throws IOException { 258 writeCommon(dataOutput); 259 } 260 261 /** 262 * Write as version two format, this version was since 4.4.4.1. 263 * 264 * @param dataOutput data output to serialize node def 265 * @throws IOException thrown if fail to write 266 */ 267 private void writeVersionTwo(DataOutput dataOutput) throws IOException { 268 writeCommon(dataOutput); 269 if (userRetryPolicy != null) { 270 dataOutput.writeUTF(userRetryPolicy); 271 } 272 else { 273 dataOutput.writeUTF("null"); 274 } 275 } 276 277 /* 278 * Write the common part 279 */ 280 private void writeCommon(DataOutput dataOutput) throws IOException { 281 dataOutput.writeUTF(nodeDefVersion); 282 dataOutput.writeUTF(name); 283 if (cred != null) { 284 dataOutput.writeUTF(cred); 285 } 286 else { 287 dataOutput.writeUTF("null"); 288 } 289 dataOutput.writeUTF(handlerClass.getName()); 290 if (conf != null) { 291 dataOutput.writeUTF(conf); 292 } 293 else { 294 dataOutput.writeUTF("null"); 295 } 296 dataOutput.writeInt(transitions.size()); 297 for (String transition : transitions) { 298 dataOutput.writeUTF(transition); 299 } 300 if (userRetryMax != null) { 301 dataOutput.writeUTF(userRetryMax); 302 } 303 else { 304 dataOutput.writeUTF("null"); 305 } 306 if (userRetryInterval != null) { 307 dataOutput.writeUTF(userRetryInterval); 308 } 309 else { 310 dataOutput.writeUTF("null"); 311 } 312 } 313 314 /* (non-Javadoc) 315 * @see org.apache.hadoop.io.Writable#write(java.io.DataOutput) 316 */ 317 @Override 318 public void write(DataOutput dataOutput) throws IOException { 319 if (getNodeDefVersion().equals(LiteWorkflowStoreService.NODE_DEF_VERSION_1)) { 320 // since oozie version 3.1 321 writeVersionOne(dataOutput); 322 } 323 else if (getNodeDefVersion().equals(LiteWorkflowStoreService.NODE_DEF_VERSION_2)) { 324 writeVersionTwo(dataOutput); 325 } 326 else { 327 writeVersionZero(dataOutput); 328 } 329 } 330 331}