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