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.executor.jpa;
016    
017    import java.sql.Timestamp;
018    import java.util.ArrayList;
019    import java.util.List;
020    import java.util.Map;
021    
022    import javax.persistence.EntityManager;
023    import javax.persistence.Query;
024    
025    import org.apache.oozie.WorkflowJobBean;
026    import org.apache.oozie.WorkflowsInfo;
027    import org.apache.oozie.client.OozieClient;
028    import org.apache.oozie.client.WorkflowJob.Status;
029    import org.apache.openjpa.persistence.OpenJPAPersistence;
030    import org.apache.openjpa.persistence.OpenJPAQuery;
031    import org.apache.openjpa.persistence.jdbc.FetchDirection;
032    import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
033    import org.apache.openjpa.persistence.jdbc.LRSSizeAlgorithm;
034    import org.apache.openjpa.persistence.jdbc.ResultSetType;
035    
036    public class WorkflowsJobGetJPAExecutor implements JPAExecutor<WorkflowsInfo> {
037    
038        private static final String seletStr = "Select w.id, w.appName, w.status, w.run, w.user, w.group, w.createdTimestamp, "
039            + "w.startTimestamp, w.lastModifiedTimestamp, w.endTimestamp from WorkflowJobBean w";
040        private static final String countStr = "Select count(w) from WorkflowJobBean w";
041    
042        private final Map<String, List<String>> filter;
043        private final int start;
044        private final int len;
045    
046        /**
047         * This JPA Executor gets the workflows info for the range.
048         *
049         * @param filter
050         * @param start
051         * @param len
052         */
053        public WorkflowsJobGetJPAExecutor(Map<String, List<String>> filter, int start, int len) {
054            this.filter = filter;
055            this.start = start;
056            this.len = len;
057        }
058    
059        /* (non-Javadoc)
060         * @see org.apache.oozie.executor.jpa.JPAExecutor#execute(javax.persistence.EntityManager)
061         */
062        @SuppressWarnings("unchecked")
063        @Override
064        public WorkflowsInfo execute(EntityManager em) throws JPAExecutorException {
065            List<String> orArray = new ArrayList<String>();
066            List<String> colArray = new ArrayList<String>();
067            List<String> valArray = new ArrayList<String>();
068            StringBuilder sb = new StringBuilder("");
069            boolean isStatus = false;
070            boolean isGroup = false;
071            boolean isAppName = false;
072            boolean isUser = false;
073            boolean isEnabled = false;
074            int index = 0;
075            for (Map.Entry<String, List<String>> entry : filter.entrySet()) {
076                String colName = null;
077                String colVar = null;
078                if (entry.getKey().equals(OozieClient.FILTER_GROUP)) {
079                    List<String> values = filter.get(OozieClient.FILTER_GROUP);
080                    colName = "group";
081                    for (int i = 0; i < values.size(); i++) {
082                        colVar = "group";
083                        colVar = colVar + index;
084                        if (!isEnabled && !isGroup) {
085                            sb.append(seletStr).append(" where w.group IN (:group" + index);
086                            isGroup = true;
087                            isEnabled = true;
088                        }
089                        else {
090                            if (isEnabled && !isGroup) {
091                                sb.append(" and w.group IN (:group" + index);
092                                isGroup = true;
093                            }
094                            else {
095                                if (isGroup) {
096                                    sb.append(", :group" + index);
097                                }
098                            }
099                        }
100                        if (i == values.size() - 1) {
101                            sb.append(")");
102                        }
103                        index++;
104                        valArray.add(values.get(i));
105                        orArray.add(colName);
106                        colArray.add(colVar);
107                    }
108                }
109                else {
110                    if (entry.getKey().equals(OozieClient.FILTER_STATUS)) {
111                        List<String> values = filter.get(OozieClient.FILTER_STATUS);
112                        colName = "status";
113                        for (int i = 0; i < values.size(); i++) {
114                            colVar = "status";
115                            colVar = colVar + index;
116                            if (!isEnabled && !isStatus) {
117                                sb.append(seletStr).append(" where w.status IN (:status" + index);
118                                isStatus = true;
119                                isEnabled = true;
120                            }
121                            else {
122                                if (isEnabled && !isStatus) {
123                                    sb.append(" and w.status IN (:status" + index);
124                                    isStatus = true;
125                                }
126                                else {
127                                    if (isStatus) {
128                                        sb.append(", :status" + index);
129                                    }
130                                }
131                            }
132                            if (i == values.size() - 1) {
133                                sb.append(")");
134                            }
135                            index++;
136                            valArray.add(values.get(i));
137                            orArray.add(colName);
138                            colArray.add(colVar);
139                        }
140                    }
141                    else {
142                        if (entry.getKey().equals(OozieClient.FILTER_NAME)) {
143                            List<String> values = filter.get(OozieClient.FILTER_NAME);
144                            colName = "appName";
145                            for (int i = 0; i < values.size(); i++) {
146                                colVar = "appName";
147                                colVar = colVar + index;
148                                if (!isEnabled && !isAppName) {
149                                    sb.append(seletStr).append(" where w.appName IN (:appName" + index);
150                                    isAppName = true;
151                                    isEnabled = true;
152                                }
153                                else {
154                                    if (isEnabled && !isAppName) {
155                                        sb.append(" and w.appName IN (:appName" + index);
156                                        isAppName = true;
157                                    }
158                                    else {
159                                        if (isAppName) {
160                                            sb.append(", :appName" + index);
161                                        }
162                                    }
163                                }
164                                if (i == values.size() - 1) {
165                                    sb.append(")");
166                                }
167                                index++;
168                                valArray.add(values.get(i));
169                                orArray.add(colName);
170                                colArray.add(colVar);
171                            }
172                        }
173                        else {
174                            if (entry.getKey().equals(OozieClient.FILTER_USER)) {
175                                List<String> values = filter.get(OozieClient.FILTER_USER);
176                                colName = "user";
177                                for (int i = 0; i < values.size(); i++) {
178                                    colVar = "user";
179                                    colVar = colVar + index;
180                                    if (!isEnabled && !isUser) {
181                                        sb.append(seletStr).append(" where w.user IN (:user" + index);
182                                        isUser = true;
183                                        isEnabled = true;
184                                    }
185                                    else {
186                                        if (isEnabled && !isUser) {
187                                            sb.append(" and w.user IN (:user" + index);
188                                            isUser = true;
189                                        }
190                                        else {
191                                            if (isUser) {
192                                                sb.append(", :user" + index);
193                                            }
194                                        }
195                                    }
196                                    if (i == values.size() - 1) {
197                                        sb.append(")");
198                                    }
199                                    index++;
200                                    valArray.add(values.get(i));
201                                    orArray.add(colName);
202                                    colArray.add(colVar);
203                                }
204                            }
205                        }
206                    }
207                }
208            }
209    
210            int realLen = 0;
211    
212            Query q = null;
213            Query qTotal = null;
214            if (orArray.size() == 0) {
215                q = em.createNamedQuery("GET_WORKFLOWS_COLUMNS");
216                q.setFirstResult(start - 1);
217                q.setMaxResults(len);
218                qTotal = em.createNamedQuery("GET_WORKFLOWS_COUNT");
219            }
220            else {
221                if (orArray.size() > 0) {
222                    StringBuilder sbTotal = new StringBuilder(sb);
223                    sb.append(" order by w.startTimestamp desc ");
224                    q = em.createQuery(sb.toString());
225                    q.setFirstResult(start - 1);
226                    q.setMaxResults(len);
227                    qTotal = em.createQuery(sbTotal.toString().replace(seletStr, countStr));
228                    for (int i = 0; i < orArray.size(); i++) {
229                        q.setParameter(colArray.get(i), valArray.get(i));
230                        qTotal.setParameter(colArray.get(i), valArray.get(i));
231                    }
232                }
233            }
234    
235            OpenJPAQuery kq = OpenJPAPersistence.cast(q);
236            JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan();
237            fetch.setFetchBatchSize(20);
238            fetch.setResultSetType(ResultSetType.SCROLL_INSENSITIVE);
239            fetch.setFetchDirection(FetchDirection.FORWARD);
240            fetch.setLRSSizeAlgorithm(LRSSizeAlgorithm.LAST);
241            List<?> resultList = q.getResultList();
242            List<Object[]> objectArrList = (List<Object[]>) resultList;
243            List<WorkflowJobBean> wfBeansList = new ArrayList<WorkflowJobBean>();
244    
245            for (Object[] arr : objectArrList) {
246                WorkflowJobBean ww = getBeanForWorkflowFromArray(arr);
247                wfBeansList.add(ww);
248            }
249    
250            realLen = ((Long) qTotal.getSingleResult()).intValue();
251    
252            return new WorkflowsInfo(wfBeansList, start, len, realLen);
253        }
254    
255        /* (non-Javadoc)
256         * @see org.apache.oozie.executor.jpa.JPAExecutor#getName()
257         */
258        @Override
259        public String getName() {
260            return "WorkflowsJobGetJPAExecutor";
261        }
262    
263        private WorkflowJobBean getBeanForWorkflowFromArray(Object[] arr) {
264    
265            WorkflowJobBean wfBean = new WorkflowJobBean();
266            wfBean.setId((String) arr[0]);
267            if (arr[1] != null) {
268                wfBean.setAppName((String) arr[1]);
269            }
270            if (arr[2] != null) {
271                wfBean.setStatus(Status.valueOf((String) arr[2]));
272            }
273            if (arr[3] != null) {
274                wfBean.setRun((Integer) arr[3]);
275            }
276            if (arr[4] != null) {
277                wfBean.setUser((String) arr[4]);
278            }
279            if (arr[5] != null) {
280                wfBean.setGroup((String) arr[5]);
281            }
282            if (arr[6] != null) {
283                wfBean.setCreatedTime((Timestamp) arr[6]);
284            }
285            if (arr[7] != null) {
286                wfBean.setStartTime((Timestamp) arr[7]);
287            }
288            if (arr[8] != null) {
289                wfBean.setLastModifiedTime((Timestamp) arr[8]);
290            }
291            if (arr[9] != null) {
292                wfBean.setEndTime((Timestamp) arr[9]);
293            }
294            return wfBean;
295        }
296    }