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.Arrays; 026import java.util.HashSet; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030 031import javax.servlet.ServletException; 032import javax.servlet.http.HttpServletRequest; 033import javax.servlet.http.HttpServletResponse; 034import org.apache.oozie.ErrorCode; 035import org.apache.oozie.XException; 036import org.apache.oozie.client.OozieClient; 037import org.apache.oozie.client.event.SLAEvent; 038import org.apache.oozie.client.rest.RestConstants; 039import org.apache.oozie.command.CommandException; 040import org.apache.oozie.executor.jpa.sla.SLASummaryGetForFilterJPAExecutor; 041import org.apache.oozie.executor.jpa.sla.SLASummaryGetForFilterJPAExecutor.SLASummaryFilter; 042import org.apache.oozie.service.JPAService; 043import org.apache.oozie.service.Services; 044import org.apache.oozie.sla.SLASummaryBean; 045import org.apache.oozie.util.DateUtils; 046import org.apache.oozie.util.XLog; 047import org.json.simple.JSONObject; 048 049@SuppressWarnings("serial") 050public class V2SLAServlet extends SLAServlet { 051 private static final XLog LOG = XLog.getLog(V2SLAServlet.class); 052 053 private static final String INSTRUMENTATION_NAME = "v2sla"; 054 private static final JsonRestServlet.ResourceInfo RESOURCES_INFO[] = new JsonRestServlet.ResourceInfo[1]; 055 private static final Set<String> SLA_FILTER_NAMES = new HashSet<String>(); 056 057 static { 058 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_ID); 059 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_PARENT_ID); 060 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_APPNAME); 061 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_NOMINAL_START); 062 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_NOMINAL_END); 063 SLA_FILTER_NAMES.add(OozieClient.FILTER_SLA_EVENT_STATUS); 064 } 065 066 static { 067 RESOURCES_INFO[0] = new JsonRestServlet.ResourceInfo("", Arrays.asList("GET"), 068 Arrays.asList(new JsonRestServlet.ParameterInfo(RestConstants.JOBS_FILTER_PARAM, String.class, false, 069 Arrays.asList("GET")))); 070 } 071 072 public V2SLAServlet() { 073 super(INSTRUMENTATION_NAME, RESOURCES_INFO); 074 } 075 076 @Override 077 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 078 079 LOG.debug("Got SLA GET request:" + request.getQueryString()); 080 try { 081 stopCron(); 082 JSONObject json = getSLASummaryList(request, response); 083 startCron(); 084 if (json == null) { 085 response.setStatus(HttpServletResponse.SC_OK); 086 } 087 else { 088 sendJsonResponse(response, HttpServletResponse.SC_OK, json); 089 } 090 } 091 catch (CommandException ce) { 092 XLog.getLog(getClass()).error("Command exception ", ce); 093 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ce); 094 } 095 catch (RuntimeException re) { 096 XLog.getLog(getClass()).error("Runtime error ", re); 097 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorCode.E0307, re.getMessage()); 098 } 099 } 100 101 private JSONObject getSLASummaryList(HttpServletRequest request, HttpServletResponse response) 102 throws ServletException, CommandException { 103 String timeZoneId = request.getParameter(RestConstants.TIME_ZONE_PARAM) == null ? null : request 104 .getParameter(RestConstants.TIME_ZONE_PARAM); 105 String filterString = request.getParameter(RestConstants.JOBS_FILTER_PARAM); 106 String maxResults = request.getParameter(RestConstants.LEN_PARAM); 107 int numMaxResults = 1000; // Default 108 109 if (maxResults != null) { 110 numMaxResults = Integer.parseInt(maxResults); 111 } 112 113 if (filterString == null || filterString.equals("")) { 114 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0305, 115 RestConstants.JOBS_FILTER_PARAM); 116 } 117 118 try { 119 Map<String, List<String>> filterList = parseFilter(URLDecoder.decode(filterString, "UTF-8"), SLA_FILTER_NAMES); 120 SLASummaryFilter filter = new SLASummaryFilter(); 121 if (filterList.containsKey(OozieClient.FILTER_SLA_ID)) { 122 filter.setJobId(filterList.get(OozieClient.FILTER_SLA_ID).get(0)); 123 } 124 if (filterList.containsKey(OozieClient.FILTER_SLA_PARENT_ID)) { 125 filter.setParentId(filterList.get(OozieClient.FILTER_SLA_PARENT_ID).get(0)); 126 } 127 if (filterList.containsKey(OozieClient.FILTER_SLA_EVENT_STATUS)) { 128 final String eventStatusFilter = filterList.get(OozieClient.FILTER_SLA_EVENT_STATUS).get(0); 129 130 LOG.debug("Checking event status filter. [eventStatusFilter={0}]", eventStatusFilter); 131 132 checkEventStatusFilter(eventStatusFilter); 133 134 LOG.debug("Applying event status filter. [eventStatusFilter={0}]", eventStatusFilter); 135 136 filter.setEventStatus(eventStatusFilter); 137 } 138 if (filterList.containsKey(OozieClient.FILTER_SLA_APPNAME)) { 139 filter.setAppName(filterList.get(OozieClient.FILTER_SLA_APPNAME).get(0)); 140 } 141 if (filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_START)) { 142 filter.setNominalStart(DateUtils.parseDateUTC(filterList.get(OozieClient.FILTER_SLA_NOMINAL_START).get(0))); 143 } 144 if (filterList.containsKey(OozieClient.FILTER_SLA_NOMINAL_END)) { 145 filter.setNominalEnd(DateUtils.parseDateUTC(filterList.get(OozieClient.FILTER_SLA_NOMINAL_END).get(0))); 146 } 147 148 if (filter.getAppName() == null && filter.getJobId() == null && filter.getParentId() == null) { 149 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0305, 150 "At least one of the filter parameters - " + OozieClient.FILTER_SLA_ID + "," 151 + OozieClient.FILTER_SLA_PARENT_ID + " or " + OozieClient.FILTER_SLA_APPNAME 152 + " should be specified in the filter query parameter"); 153 } 154 155 JPAService jpaService = Services.get().get(JPAService.class); 156 List<SLASummaryBean> slaSummaryList = null; 157 if (jpaService != null) { 158 slaSummaryList = jpaService.execute(new SLASummaryGetForFilterJPAExecutor(filter, numMaxResults)); 159 } 160 else { 161 XLog.getLog(getClass()).error(ErrorCode.E0610); 162 } 163 164 final boolean includeEventStatus = filterList.containsKey(OozieClient.FILTER_SLA_EVENT_STATUS); 165 return SLASummaryBean.toJSONObject(slaSummaryList, timeZoneId, includeEventStatus); 166 } 167 catch (XException ex) { 168 throw new CommandException(ex); 169 } 170 catch (UnsupportedEncodingException e) { 171 throw new XServletException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ErrorCode.E0307, 172 "Unsupported Encoding", e); 173 } 174 catch (ParseException e) { 175 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303, 176 filterString, e); 177 } 178 179 } 180 181 private void checkEventStatusFilter(final String eventStatusFilter) throws XServletException { 182 if (eventStatusFilter.toUpperCase().contains(SLASummaryBean.EVENT_STATUS_ALL)) { 183 for (final SLAEvent.EventStatus eventStatus : SLAEvent.EventStatus.values()) { 184 if (eventStatusFilter.contains(eventStatus.name())) { 185 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, 186 ErrorCode.E0303, 187 String.format("%s.%s", RestConstants.JOBS_FILTER_PARAM, OozieClient.FILTER_SLA_EVENT_STATUS), 188 eventStatusFilter); 189 } 190 } 191 } 192 } 193}