001 /**
002 * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003 * Licensed under the Apache License, Version 2.0 (the "License");
004 * you may not use this file except in compliance with the License.
005 * You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software
010 * distributed under the License is distributed on an "AS IS" BASIS,
011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 * See the License for the specific language governing permissions and
013 * limitations under the License. See accompanying LICENSE file.
014 */
015 package org.apache.oozie.service;
016
017 import org.apache.hadoop.conf.Configuration;
018 import org.apache.oozie.ErrorCode;
019 import org.apache.oozie.service.Service;
020 import org.apache.oozie.service.ServiceException;
021 import org.apache.oozie.service.Services;
022 import org.apache.oozie.util.IOUtils;
023 import org.xml.sax.SAXException;
024
025 import javax.xml.XMLConstants;
026 import javax.xml.transform.stream.StreamSource;
027 import javax.xml.validation.Schema;
028 import javax.xml.validation.SchemaFactory;
029 import java.io.IOException;
030 import java.util.ArrayList;
031 import java.util.List;
032
033 /**
034 * Service that loads Oozie workflow definition schema and registered extension schemas.
035 */
036 public class SchemaService implements Service {
037
038 public static final String CONF_PREFIX = Service.CONF_PREFIX + "SchemaService.";
039
040 public static final String WF_CONF_EXT_SCHEMAS = CONF_PREFIX + "wf.ext.schemas";
041
042 public static final String COORD_CONF_EXT_SCHEMAS = CONF_PREFIX + "coord.ext.schemas";
043
044 public static final String SLA_CONF_EXT_SCHEMAS = CONF_PREFIX + "sla.ext.schemas";
045
046 public static final String SLA_NAME_SPACE_URI = "uri:oozie:sla:0.1";
047
048 private Schema wfSchema;
049
050 private Schema coordSchema;
051
052 private Schema slaSchema;
053
054 private static final String OOZIE_WORKFLOW_XSD[] = {"oozie-workflow-0.1.xsd", "oozie-workflow-0.2.xsd"};
055 private static final String OOZIE_COORDINATOR_XSD[] = {"oozie-coordinator-0.1.xsd"};
056 private static final String OOZIE_SLA_SEMANTIC_XSD[] = {"gms-oozie-sla-0.1.xsd"};
057
058 private Schema loadSchema(Configuration conf, String[] baseSchemas, String extSchema) throws SAXException,
059 IOException {
060 List<StreamSource> sources = new ArrayList<StreamSource>();
061 for (String baseSchema : baseSchemas) {
062 sources.add(new StreamSource(IOUtils.getResourceAsStream(baseSchema, -1)));
063 }
064 String[] schemas = conf.getStrings(extSchema);
065 if (schemas != null) {
066 for (String schema : schemas) {
067 sources.add(new StreamSource(IOUtils.getResourceAsStream(schema, -1)));
068 }
069 }
070 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
071 return factory.newSchema(sources.toArray(new StreamSource[sources.size()]));
072 }
073
074 /**
075 * Initialize the service.
076 *
077 * @param services services instance.
078 * @throws ServiceException thrown if the service could not be initialized.
079 */
080 public void init(Services services) throws ServiceException {
081 try {
082 wfSchema = loadSchema(services.getConf(), OOZIE_WORKFLOW_XSD, WF_CONF_EXT_SCHEMAS);
083 coordSchema = loadSchema(services.getConf(), OOZIE_COORDINATOR_XSD, COORD_CONF_EXT_SCHEMAS);
084 slaSchema = loadSchema(services.getConf(), OOZIE_SLA_SEMANTIC_XSD, SLA_CONF_EXT_SCHEMAS);
085 }
086 catch (SAXException ex) {
087 throw new ServiceException(ErrorCode.E0130, ex.getMessage(), ex);
088 }
089 catch (IOException ex) {
090 throw new ServiceException(ErrorCode.E0131, ex.getMessage(), ex);
091 }
092 }
093
094 /**
095 * Return the public interface of the service.
096 *
097 * @return {@link SchemaService}.
098 */
099 public Class<? extends Service> getInterface() {
100 return SchemaService.class;
101 }
102
103 /**
104 * Destroy the service.
105 */
106 public void destroy() {
107 wfSchema = null;
108 }
109
110 /**
111 * Return the schema for XML validation of application definitions.
112 *
113 * @param schemaName: Name of schema definition (i.e. WORKFLOW/COORDINATOR)
114 * @return the schema for XML validation of application definitions.
115 */
116 public Schema getSchema(SchemaName schemaName) {
117 if (schemaName == SchemaName.WORKFLOW) {
118 return wfSchema;
119 }
120 else {
121 if (schemaName == SchemaName.COORDINATOR) {
122 return coordSchema;
123 }
124 else {
125 if (schemaName == SchemaName.SLA_ORIGINAL) {
126 return slaSchema;
127 }
128 else {
129 throw new RuntimeException("No schema found with name " + schemaName);
130 }
131 }
132 }
133 }
134
135 public enum SchemaName {
136 WORKFLOW(1), COORDINATOR(2), SLA_ORIGINAL(3);
137 private int id;
138
139 private SchemaName(int id) {
140 this.id = id;
141 }
142
143 public int getId() {
144 return id;
145 }
146 }
147 }