워크플로를 제출할 때 XML 검증 단계에서 실패한다.
cvc-complex-type.2.4.a: Invalid content was found starting with element
'{"uri:oozie:shell-action:0.1":exec}'. One of '{"uri:oozie:shell-action:0.1":job-tracker}' is expected.
Oozie 는 액션 XML 을 XSD 로 검증한다. 검증기는 선언한 네임스페이스 버전의 스키마를 적용하며, 스키마는 하위 요소의 순서까지 강제한다.
uri:oozie:shell-action:0.1 스키마는 <exec> 앞에 <job-tracker> 와 <name-node> 가 먼저 오기를 요구한다. 두 요소를 생략하거나 순서를 바꾸면 위 오류가 난다. 즉 "exec 가 잘못됐다" 가 아니라 "그 자리에는 job-tracker 가 와야 한다" 는 뜻이다.
<action name="shell-node">
<shell xmlns="uri:oozie:shell-action:0.1">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<configuration>
<property>
<name>mapred.job.queue.name</name>
<value>${queueName}</value>
</property>
</configuration>
<exec>run.sh</exec>
<argument>${inputDir}</argument>
<file>${wfPath}/run.sh#run.sh</file>
<capture-output/>
</shell>
<ok to="end"/>
<error to="fail"/>
</action>
job-tracker 라는 이름은 MapReduce 1 시절의 잔재다. YARN 클러스터에서는 ResourceManager 주소를 그대로 넣는다.
jobTracker=rm-host:8032
nameNode=hdfs://nameservice1
최신 스키마는 요소 이름이 바뀌었다.
<action name="shell-node">
<shell xmlns="uri:oozie:shell-action:1.0">
<resource-manager>${resourceManager}</resource-manager>
<name-node>${nameNode}</name-node>
<exec>run.sh</exec>
<argument>${inputDir}</argument>
<file>${wfPath}/run.sh#run.sh</file>
<capture-output/>
</shell>
<ok to="end"/>
<error to="fail"/>
</action>
워크플로 루트의 스키마 버전도 함께 맞춘다.
<workflow-app xmlns="uri:oozie:workflow:1.0" name="my-wf">
액션 스키마 버전이 워크플로 스키마 버전보다 높으면 검증에 실패한다. 서버가 어떤 버전을 지원하는지는 oozie-site.xml 의 oozie.service.SchemaService.wf.ext.schemas 에 나열돼 있다.
같은 스키마 안에서도 순서를 지켜야 한다. shell 액션은 대략 다음 순서다.
resource-manager(또는 job-tracker) → name-node → prepare → job-xml →
configuration → exec → argument → env-var → file → archive → capture-output
argument 를 exec 앞에 두거나 file 을 configuration 앞에 두면 같은 형태의 오류가 난다. 오류 메시지의 "One of '...' is expected" 부분이 그 자리에 와야 할 요소를 알려 주므로, 그 요소를 앞으로 옮기면 해결된다.
제출 전에 로컬에서 검증한다.
oozie validate workflow.xml
<file> 에 # 로 심볼릭 링크 이름을 지정하지 않으면 실행 디렉터리에서 스크립트를 찾지 못한다.hdfs dfs -chmod 755 를 확인한다.capture-output 을 쓰려면 스크립트가 key=value 형식을 표준 출력으로 내보내야 한다. 그 값은 다음 액션에서 wf:actionData() 로 읽는다.