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