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.servlet; 020 021import java.io.IOException; 022import java.io.UnsupportedEncodingException; 023import java.net.URLDecoder; 024import java.text.ParseException; 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.HashMap; 028import java.util.Calendar; 029import java.util.Collections; 030import java.util.Date; 031import java.util.HashSet; 032import java.util.Iterator; 033import java.util.List; 034import java.util.Map; 035import java.util.Set; 036import java.util.regex.Matcher; 037import java.util.regex.Pattern; 038 039import javax.servlet.ServletException; 040import javax.servlet.http.HttpServletRequest; 041import javax.servlet.http.HttpServletResponse; 042 043import org.apache.oozie.ErrorCode; 044import org.apache.oozie.XException; 045import org.apache.oozie.client.OozieClient; 046import org.apache.oozie.client.event.SLAEvent.EventStatus; 047import org.apache.oozie.client.rest.RestConstants; 048import org.apache.oozie.command.CommandException; 049import org.apache.oozie.executor.jpa.SLARegistrationQueryExecutor; 050import org.apache.oozie.executor.jpa.SLARegistrationQueryExecutor.SLARegQuery; 051import org.apache.oozie.executor.jpa.sla.SLASummaryGetForFilterJPAExecutor; 052import org.apache.oozie.executor.jpa.sla.SLASummaryGetForFilterJPAExecutor.SLASummaryFilter; 053import org.apache.oozie.service.JPAService; 054import org.apache.oozie.service.Services; 055import org.apache.oozie.sla.SLARegistrationBean; 056import org.apache.oozie.sla.SLASummaryBean; 057import org.apache.oozie.util.DateUtils; 058import org.apache.oozie.util.XLog; 059import org.json.simple.JSONObject; 060 061@SuppressWarnings("serial") 062public class V2SLAServlet extends SLAServlet { 063 064 private static final String INSTRUMENTATION_NAME = "v2sla"; 065 private static final JsonRestServlet.ResourceInfo RESOURCES_INFO[] = new JsonRestServlet.ResourceInfo[1]; 066 private static final Set<String> SLA_FILTER_NAMES = new HashSet<String>(); 067 private Pattern p = Pattern.compile("\\d{7}-\\d{15}-.*-B$"); 068 069 static { 070 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_ID); 071 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_PARENT_ID); 072 SLA_FILTER_NAMES.add(OozieClient.FILTER_BUNDLE); 073 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_APPNAME); 074 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_NOMINAL_START); 075 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_NOMINAL_END); 076 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_EVENT_STATUS); 077 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_STATUS); 078 } 079 080 static { 081 RESOURCES_INFO[0] = new JsonRestServlet.ResourceInfo("", Arrays.asList("GET"), 082 Arrays.asList(new JsonRestServlet.ParameterInfo(RestConstants.JOBS_FILTER_PARAM, String.class, false, 083 Arrays.asList("GET")))); 084 } 085 086 public V2SLAServlet() { 087 super(INSTRUMENTATION_NAME, RESOURCES_INFO); 088 } 089 090 @Override 091 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 092 093 XLog.getLog(getClass()).debug("Got SLA GET request:" + request.getQueryString()); 094 try { 095 stopCron(); 096 JSONObject json = getSLASummaryList(request, response); 097 startCron(); 098 if (json == null) { 099 response.setStatus(HttpServletResponse.SC_OK); 100 } 101 else { 102 sendJsonResponse(response, HttpServletResponse.SC_OK, json); 103 } 104 } 105 catch (CommandException ce) { 106 XLog.getLog(getClass()).error("Command exception ", ce); 107 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ce); 108 } 109 catch (RuntimeException re) { 110 XLog.getLog(getClass()).error("Runtime error ", re); 111 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorCode.E0307, re.getMessage()); 112 } 113 } 114 115 private JSONObject getSLASummaryList(HttpServletRequest request, HttpServletResponse response) 116 throws ServletException, CommandException { 117 String timeZoneId = request.getParameter(RestConstants.TIME_ZONE_PARAM) == null ? null : request 118 .getParameter(RestConstants.TIME_ZONE_PARAM); 119 String filterString = request.getParameter(RestConstants.JOBS_FILTER_PARAM); 120 String maxResults = request.getParameter(RestConstants.LEN_PARAM); 121 int numMaxResults = 1000; // Default 122 123 if (maxResults != null) { 124 numMaxResults = Integer.parseInt(maxResults); 125 } 126 127 if (filterString == null || filterString.equals("")) { 128 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0305, 129 RestConstants.JOBS_FILTER_PARAM); 130 } 131 132 try { 133 Map<String, List<String>> filterList = parseFilter(URLDecoder.decode(filterString, "UTF-8"), SLA_FILTER_NAMES); 134 SLASummaryFilter filter = new SLASummaryFilter(); 135 136 if (!filterList.containsKey(OozieClient.FILTER_SLA_APPNAME) 137 && !filterList.containsKey(OozieClient.FILTER_SLA_ID) 138 && !filterList.containsKey(OozieClient.FILTER_SLA_PARENT_ID) 139 && !filterList.containsKey(OozieClient.FILTER_BUNDLE) 140 && !filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_START) 141 && !filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_END)) { 142 StringBuffer st = new StringBuffer(); 143 st.append("At least one of the filter parameters - ").append(OozieClient.FILTER_SLA_APPNAME) 144 .append(",").append(OozieClient.FILTER_SLA_ID).append(",") 145 .append(OozieClient.FILTER_SLA_PARENT_ID).append(",").append(OozieClient.FILTER_BUNDLE) 146 .append(",").append(OozieClient.FILTER_SLA_NOMINAL_START).append(" or ") 147 .append(OozieClient.FILTER_SLA_NOMINAL_END) 148 .append(" should be specified in the filter query parameter"); 149 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0305, st.toString()); 150 } 151 152 if (filterList.containsKey(OozieClient.FILTER_SLA_ID)) { 153 filter.setJobId(filterList.get(OozieClient.FILTER_SLA_ID).get(0)); 154 } 155 if (filterList.containsKey(OozieClient.FILTER_SLA_PARENT_ID)) { 156 filter.setParentId(filterList.get(OozieClient.FILTER_SLA_PARENT_ID).get(0)); 157 } 158 if (filterList.containsKey(OozieClient.FILTER_BUNDLE)) { 159 String bundle = filterList.get(OozieClient.FILTER_BUNDLE).get(0); 160 if (isBundleId(bundle)) { 161 filter.setBundleId(bundle); 162 } 163 else { 164 filter.setBundleName(bundle); 165 } 166 } 167 if (filterList.containsKey(OozieClient.FILTER_SLA_EVENT_STATUS)) { 168 filter.setEventStatus(filterList.get(OozieClient.FILTER_SLA_EVENT_STATUS).get(0)); 169 } 170 if (filterList.containsKey(OozieClient.FILTER_SLA_STATUS)) { 171 filter.setSLAStatus(filterList.get(OozieClient.FILTER_SLA_STATUS).get(0)); 172 } 173 if (filterList.containsKey(OozieClient.FILTER_SLA_APPNAME)) { 174 filter.setAppName(filterList.get(OozieClient.FILTER_SLA_APPNAME).get(0)); 175 } 176 if (filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_START)) { 177 filter.setNominalStart(DateUtils.parseDateUTC(filterList.get(OozieClient.FILTER_SLA_NOMINAL_START).get(0))); 178 } 179 if (filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_END)) { 180 filter.setNominalEnd(DateUtils.parseDateUTC(filterList.get(OozieClient.FILTER_SLA_NOMINAL_END).get(0))); 181 } 182 183 JPAService jpaService = Services.get().get(JPAService.class); 184 List<SLASummaryBean> slaSummaryList = null; 185 if (jpaService != null) { 186 slaSummaryList = jpaService.execute(new SLASummaryGetForFilterJPAExecutor(filter, numMaxResults)); 187 } 188 else { 189 XLog.getLog(getClass()).error(ErrorCode.E0610); 190 } 191 192 List<String> jobIds = new ArrayList<String>(); 193 for(SLASummaryBean summaryBean:slaSummaryList){ 194 jobIds.add(summaryBean.getId()); 195 } 196 List<SLARegistrationBean> SLARegistrationList = SLARegistrationQueryExecutor.getInstance().getList( 197 SLARegQuery.GET_SLA_CONFIGS, jobIds); 198 199 Map<String, Map<String, String>> jobIdSLAConfigMap = new HashMap<String, Map<String, String>>(); 200 for(SLARegistrationBean registrationBean:SLARegistrationList){ 201 jobIdSLAConfigMap.put(registrationBean.getId(), registrationBean.getSLAConfigMap()); 202 } 203 204 return SLASummaryBean.toJSONObject(slaSummaryList, jobIdSLAConfigMap, timeZoneId); 205 } 206 catch (XException ex) { 207 throw new CommandException(ex); 208 } 209 catch (UnsupportedEncodingException e) { 210 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorCode.E0307, 211 "Unsupported Encoding", e); 212 } 213 catch (ParseException e) { 214 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303, 215 filterString, e); 216 } 217 218 } 219 220 private boolean isBundleId(String id) { 221 boolean ret = false; 222 Matcher m = p.matcher(id); 223 if (m.matches()) { 224 return true; 225 } 226 return ret; 227 } 228}