@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel ch = e.getChannel(); Throwable cause = e.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, BAD_REQUEST); return; } LOG.error("Shuffle error: ", cause); shuffleMetrics.failedOutput(); if (ch.isConnected()) { LOG.error("Shuffle error " + e); sendError(ctx, INTERNAL_SERVER_ERROR); } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent evt) throws Exception { HttpRequest request = (HttpRequest) evt.getMessage(); if (request.getMethod() != GET) { sendError(ctx, METHOD_NOT_ALLOWED); return; } final Map<String, List<String>> q = new QueryStringDecoder(request.getUri()).getParameters(); final List<String> mapIds = splitMaps(q.get("map")); final List<String> reduceQ = q.get("reduce"); final List<String> jobQ = q.get("job"); if (LOG.isInfoEnabled()) { LOG.info( "RECV: " + request.getUri() + "\n mapIds: " + mapIds + "\n reduceId: " + reduceQ + "\n jobId: " + jobQ); } if (mapIds == null || reduceQ == null || jobQ == null) { sendError(ctx, "Required param job, map and reduce", BAD_REQUEST); return; } if (reduceQ.size() != 1 || jobQ.size() != 1) { sendError(ctx, "Too many job/reduce parameters", BAD_REQUEST); return; } int reduceId; String jobId; try { reduceId = Integer.parseInt(reduceQ.get(0)); jobId = jobQ.get(0); } catch (NumberFormatException e) { sendError(ctx, "Bad reduce parameter", BAD_REQUEST); return; } catch (IllegalArgumentException e) { sendError(ctx, "Bad job parameter", BAD_REQUEST); return; } final String reqUri = request.getUri(); if (null == reqUri) { // TODO? add upstream? sendError(ctx, FORBIDDEN); return; } // Generate simple response without security HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); Channel ch = evt.getChannel(); ch.write(response); // TODO refactor the following into the pipeline ChannelFuture lastMap = null; for (String mapId : mapIds) { try { lastMap = sendMapOutput(ctx, ch, jobId, mapId, reduceId); if (null == lastMap) { sendError(ctx, NOT_FOUND); shuffleMetrics.failedOutput(); return; } } catch (IOException e) { LOG.error("Shuffle error ", e); shuffleMetrics.failedOutput(); sendError(ctx, e.getMessage(), INTERNAL_SERVER_ERROR); return; } } lastMap.addListener(ChannelFutureListener.CLOSE); }