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.store;
020
021import java.sql.Blob;
022import java.sql.Timestamp;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.HashMap;
026import java.util.List;
027import java.util.Map;
028
029import org.apache.oozie.util.db.Schema;
030import org.apache.oozie.util.db.Schema.Column;
031import org.apache.oozie.util.db.Schema.DBType;
032import org.apache.oozie.util.db.Schema.Index;
033import org.apache.oozie.util.db.Schema.Table;
034
035public class OozieSchema {
036
037    private static String oozieDbName;
038
039    private static final String OOZIE_VERSION = "0.1";
040
041    public static final Map<Table, List<Column>> TABLE_COLUMNS;
042
043    static {
044        Map<Table, List<Column>> tmpColumns = new HashMap<>();
045
046        for (Column column : OozieColumn.values()) {
047            List<Column> tColumns = tmpColumns.get(column.table());
048            if (tColumns == null) {
049                tColumns = new ArrayList<Column>();
050                tmpColumns.put(column.table(), tColumns);
051            }
052            tColumns.add(column);
053        }
054
055        TABLE_COLUMNS = Collections.unmodifiableMap(tmpColumns);
056    }
057
058    public static void setOozieDbName(String dbName) {
059        oozieDbName = dbName;
060    }
061
062    public static enum OozieTable implements Table {
063        WORKFLOWS,
064        ACTIONS,
065        WF_PROCESS_INSTANCE,
066        VERSION;
067
068        @Override
069        public String toString() {
070            return oozieDbName + "." + name().toUpperCase();
071        }
072    }
073
074    public static enum OozieIndex implements Index {
075        IDX_WF_APPNAME(OozieColumn.WF_appName),
076        IDX_WF_USER(OozieColumn.WF_userName),
077        IDX_WF_GROUP(OozieColumn.WF_groupName),
078        IDX_WF_STATUS(OozieColumn.WF_status),
079        IDX_WF_EXTERNAL_ID(OozieColumn.WF_externalId),
080
081        IDX_ACTIONS_BEGINTIME(OozieColumn.ACTIONS_pendingAge),
082        IDX_ACTIONS_WFID(OozieColumn.ACTIONS_wfId);
083
084        final Column column;
085
086        OozieIndex(Column column) {
087            this.column = column;
088        }
089
090        public Column column() {
091            return column;
092        }
093    }
094
095    public static enum OozieColumn implements Column {
096        // Process Instance Table
097        PI_wfId(OozieTable.WF_PROCESS_INSTANCE, String.class, true, 100),
098        PI_state(OozieTable.WF_PROCESS_INSTANCE, Blob.class, false),
099
100        // WorkflowJob Table
101        WF_id(OozieTable.WORKFLOWS, String.class, true, 100),
102        WF_externalId(OozieTable.WORKFLOWS, String.class, false, 100),
103        WF_appName(OozieTable.WORKFLOWS, String.class, false, 100),
104        WF_appPath(OozieTable.WORKFLOWS, String.class, false, 255),
105        WF_conf(OozieTable.WORKFLOWS, String.class, false),
106        WF_protoActionConf(OozieTable.WORKFLOWS, String.class, false),
107        WF_logToken(OozieTable.WORKFLOWS, String.class, false, 100),
108        WF_status(OozieTable.WORKFLOWS, String.class, false, 100),
109        WF_run(OozieTable.WORKFLOWS, Long.class, false),
110        WF_lastModTime(OozieTable.WORKFLOWS, Timestamp.class, false),
111        WF_createdTime(OozieTable.WORKFLOWS, Timestamp.class, false),
112        WF_startTime(OozieTable.WORKFLOWS, Timestamp.class, false),
113        WF_endTime(OozieTable.WORKFLOWS, Timestamp.class, false),
114        WF_userName(OozieTable.WORKFLOWS, String.class, false, 100),
115        WF_groupName(OozieTable.WORKFLOWS, String.class, false, 100),
116        WF_authToken(OozieTable.WORKFLOWS, String.class, false),
117
118        // Actions Table
119        ACTIONS_id(OozieTable.ACTIONS, String.class, true, 100),
120        ACTIONS_name(OozieTable.ACTIONS, String.class, false, 100),
121        ACTIONS_type(OozieTable.ACTIONS, String.class, false, 100),
122        ACTIONS_wfId(OozieTable.ACTIONS, String.class, false, 100),
123        ACTIONS_conf(OozieTable.ACTIONS, String.class, false),
124        ACTIONS_status(OozieTable.ACTIONS, String.class, false, 100),
125        ACTIONS_externalStatus(OozieTable.ACTIONS, String.class, false, 100),
126        ACTIONS_errorCode(OozieTable.ACTIONS, String.class, false, 100),
127        ACTIONS_errorMessage(OozieTable.ACTIONS, String.class, false),
128        ACTIONS_transition(OozieTable.ACTIONS, String.class, false, 100),
129        ACTIONS_retries(OozieTable.ACTIONS, Long.class, false),
130        ACTIONS_startTime(OozieTable.ACTIONS, Timestamp.class, false),
131        ACTIONS_endTime(OozieTable.ACTIONS, Timestamp.class, false),
132        ACTIONS_lastCheckTime(OozieTable.ACTIONS, Timestamp.class, false),
133        ACTIONS_data(OozieTable.ACTIONS, String.class, false),
134        ACTIONS_externalId(OozieTable.ACTIONS, String.class, false, 100),
135        ACTIONS_trackerUri(OozieTable.ACTIONS, String.class, false, 100),
136        ACTIONS_consoleUrl(OozieTable.ACTIONS, String.class, false, 100),
137        ACTIONS_executionPath(OozieTable.ACTIONS, String.class, false, 255),
138        ACTIONS_pending(OozieTable.ACTIONS, Boolean.class, false),
139        ACTIONS_pendingAge(OozieTable.ACTIONS, Timestamp.class, false),
140        ACTIONS_signalValue(OozieTable.ACTIONS, String.class, false, 100),
141        ACTIONS_logToken(OozieTable.ACTIONS, String.class, false, 100),
142
143        // Version Table
144        VER_versionNumber(OozieTable.VERSION, String.class, false, 255);
145
146        final Table table;
147        final Class<?> type;
148        int length = -1;
149        final boolean isPrimaryKey;
150
151        OozieColumn(Table table, Class<?> type, boolean isPrimaryKey) {
152            this(table, type, isPrimaryKey, -1);
153        }
154
155        OozieColumn(Table table, Class<?> type, boolean isPrimaryKey, int length) {
156            this.table = table;
157            this.type = type;
158            this.isPrimaryKey = isPrimaryKey;
159            this.length = length;
160        }
161
162        private String getName() {
163            String tName = table.name();
164            return tName + "." + columnName();
165        }
166
167        public String columnName() {
168            return name().split("_")[1].toLowerCase();
169        }
170
171        @Override
172        public String toString() {
173            return getName();
174        }
175
176        public Table table() {
177            return table;
178        }
179
180        public Class<?> getType() {
181            return type;
182        }
183
184        public int getLength() {
185            return length;
186        }
187
188        public String asLabel() {
189            return name().toUpperCase();
190        }
191
192        public boolean isPrimaryKey() {
193            return isPrimaryKey;
194        }
195    }
196
197    /**
198     * Generates the create table SQL Statement
199     *
200     * @param table
201     * @param dbType
202     * @return SQL Statement to create the table
203     */
204    public static String generateCreateTableScript(Table table, DBType dbType) {
205        return Schema.generateCreateTableScript(table, dbType, TABLE_COLUMNS.get(table));
206    }
207
208    /**
209     * Gets the query that will be used to validate the connection
210     *
211     * @param dbName
212     * @return String returns the query that will be used to validate the connection
213     */
214    public static String getValidationQuery(String dbName) {
215        return "select count(" + OozieColumn.VER_versionNumber.columnName() + ") from " + dbName + "."
216                + OozieTable.VERSION.name().toUpperCase();
217    }
218
219    /**
220     * Generates the Insert statement to insert the OOZIE_VERSION to table
221     *
222     * @param dbName
223     * @return String returns the Insert statement for the OOZIE_VERSION to a table
224     */
225    public static String generateInsertVersionScript(String dbName) {
226        return "INSERT INTO " + dbName + "." + OozieTable.VERSION.name().toUpperCase() + "("
227                + OozieColumn.VER_versionNumber.columnName() + ") VALUES(" + OOZIE_VERSION + ")";
228    }
229
230    /**
231     * Gets the Oozie Schema Version
232     *
233     * @return String returns the Oozie Schema Version
234     */
235    public static String getOozieVersion() {
236        return OOZIE_VERSION;
237    }
238}