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.executor.jpa;
020
021import java.sql.Timestamp;
022import java.util.ArrayList;
023import java.util.Date;
024import java.util.List;
025
026import javax.persistence.EntityManager;
027import javax.persistence.Query;
028
029import org.apache.oozie.BundleActionBean;
030import org.apache.oozie.ErrorCode;
031import org.apache.oozie.service.JPAService;
032import org.apache.oozie.service.Services;
033
034/**
035 * Query Executor that provides API to run query for Bundle Action
036 */
037public class BundleActionQueryExecutor extends
038        QueryExecutor<BundleActionBean, BundleActionQueryExecutor.BundleActionQuery> {
039
040    public enum BundleActionQuery {
041        UPDATE_BUNDLE_ACTION_PENDING_MODTIME,
042        UPDATE_BUNDLE_ACTION_STATUS_PENDING_MODTIME,
043        UPDATE_BUNDLE_ACTION_STATUS_PENDING_MODTIME_COORDID,
044        GET_BUNDLE_ACTION,
045        GET_BUNDLE_ACTIONS_STATUS_UNIGNORED_FOR_BUNDLE,
046        GET_BUNDLE_WAITING_ACTIONS_OLDER_THAN,
047        GET_BUNDLE_UNIGNORED_ACTION_STATUS_PENDING_FOR_BUNDLE
048    };
049
050    private static BundleActionQueryExecutor instance = new BundleActionQueryExecutor();
051
052    private BundleActionQueryExecutor() {
053    }
054
055    public static QueryExecutor<BundleActionBean, BundleActionQueryExecutor.BundleActionQuery> getInstance() {
056        return BundleActionQueryExecutor.instance;
057    }
058
059    @Override
060    public Query getUpdateQuery(BundleActionQuery namedQuery, BundleActionBean baBean, EntityManager em)
061            throws JPAExecutorException {
062
063        Query query = em.createNamedQuery(namedQuery.name());
064        switch (namedQuery) {
065            case UPDATE_BUNDLE_ACTION_PENDING_MODTIME:
066                query.setParameter("lastModifiedTime", baBean.getLastModifiedTimestamp());
067                query.setParameter("pending", baBean.getPending());
068                query.setParameter("bundleActionId", baBean.getBundleActionId());
069                break;
070            case UPDATE_BUNDLE_ACTION_STATUS_PENDING_MODTIME:
071                query.setParameter("status", baBean.getStatusStr());
072                query.setParameter("lastModifiedTime", baBean.getLastModifiedTimestamp());
073                query.setParameter("pending", baBean.getPending());
074                query.setParameter("bundleActionId", baBean.getBundleActionId());
075                break;
076            case UPDATE_BUNDLE_ACTION_STATUS_PENDING_MODTIME_COORDID:
077                query.setParameter("status", baBean.getStatusStr());
078                query.setParameter("lastModifiedTime", baBean.getLastModifiedTimestamp());
079                query.setParameter("pending", baBean.getPending());
080                query.setParameter("coordId", baBean.getCoordId());
081                query.setParameter("bundleActionId", baBean.getBundleActionId());
082                break;
083            default:
084                throw new JPAExecutorException(ErrorCode.E0603, "QueryExecutor cannot set parameters for "
085                        + namedQuery.name());
086        }
087        return query;
088    }
089
090    @Override
091    public Query getSelectQuery(BundleActionQuery namedQuery, EntityManager em, Object... parameters)
092            throws JPAExecutorException {
093        Query query = em.createNamedQuery(namedQuery.name());
094        switch (namedQuery) {
095            case GET_BUNDLE_ACTION:
096                query.setParameter("bundleActionId", parameters[0]);
097                break;
098            case GET_BUNDLE_ACTIONS_STATUS_UNIGNORED_FOR_BUNDLE:
099                query.setParameter("bundleId", parameters[0]);
100                break;
101            case GET_BUNDLE_WAITING_ACTIONS_OLDER_THAN:
102                Timestamp ts = new Timestamp(System.currentTimeMillis() - (Long)parameters[0] * 1000);
103                query.setParameter("lastModifiedTime", ts);
104                break;
105            case GET_BUNDLE_UNIGNORED_ACTION_STATUS_PENDING_FOR_BUNDLE:
106                query.setParameter("bundleId", parameters[0]);
107                break;
108            default:
109                throw new JPAExecutorException(ErrorCode.E0603, "QueryExecutor cannot set parameters for "
110                        + namedQuery.name());
111        }
112        return query;
113    }
114
115    @Override
116    public int executeUpdate(BundleActionQuery namedQuery, BundleActionBean jobBean) throws JPAExecutorException {
117        JPAService jpaService = Services.get().get(JPAService.class);
118        EntityManager em = jpaService.getEntityManager();
119        Query query = getUpdateQuery(namedQuery, jobBean, em);
120        int ret = jpaService.executeUpdate(namedQuery.name(), query, em);
121        return ret;
122    }
123
124    @Override
125    public BundleActionBean get(BundleActionQuery namedQuery, Object... parameters) throws JPAExecutorException {
126        JPAService jpaService = Services.get().get(JPAService.class);
127        EntityManager em = jpaService.getEntityManager();
128        Query query = getSelectQuery(namedQuery, em, parameters);
129        Object ret = jpaService.executeGet(namedQuery.name(), query, em);
130        if (ret == null) {
131            throw new JPAExecutorException(ErrorCode.E0604, query.toString());
132        }
133        BundleActionBean bean = constructBean(namedQuery, ret);
134        return bean;
135    }
136
137    private BundleActionBean constructBean(BundleActionQuery namedQuery, Object ret) throws JPAExecutorException {
138        BundleActionBean bean;
139        Object[] arr;
140        switch (namedQuery) {
141            case GET_BUNDLE_ACTION:
142            case GET_BUNDLE_ACTIONS_STATUS_UNIGNORED_FOR_BUNDLE:
143                bean = (BundleActionBean) ret;
144                break;
145            case GET_BUNDLE_WAITING_ACTIONS_OLDER_THAN:
146                bean = new BundleActionBean();
147                arr = (Object[]) ret;
148                bean.setBundleActionId((String) arr[0]);
149                bean.setBundleId((String) arr[1]);
150                bean.setStatusStr((String) arr[2]);
151                bean.setCoordId((String) arr[3]);
152                bean.setCoordName((String) arr[4]);
153                break;
154            case GET_BUNDLE_UNIGNORED_ACTION_STATUS_PENDING_FOR_BUNDLE:
155                bean = new BundleActionBean();
156                arr = (Object[]) ret;
157                bean.setCoordId((String) arr[0]);
158                bean.setStatusStr((String) arr[1]);
159                bean.setPending((Integer) arr[2]);
160                break;
161            default:
162                throw new JPAExecutorException(ErrorCode.E0603, "QueryExecutor cannot construct action bean for "
163                        + namedQuery.name());
164        }
165        return bean;
166    }
167
168    @Override
169    public List<BundleActionBean> getList(BundleActionQuery namedQuery, Object... parameters)
170            throws JPAExecutorException {
171        JPAService jpaService = Services.get().get(JPAService.class);
172        EntityManager em = jpaService.getEntityManager();
173        Query query = getSelectQuery(namedQuery, em, parameters);
174        List<?> retList = (List<?>) jpaService.executeGetList(namedQuery.name(), query, em);
175        List<BundleActionBean> beanList = new ArrayList<BundleActionBean>();
176        if (retList != null) {
177            for (Object ret : retList) {
178                beanList.add(constructBean(namedQuery, ret));
179            }
180        }
181        return beanList;
182    }
183
184    @Override
185    public Object getSingleValue(BundleActionQuery namedQuery, Object... parameters) throws JPAExecutorException {
186        throw new UnsupportedOperationException();
187    }
188
189}