/** * Dianping.com Inc. * Copyright (c) 2003-2013 All Rights Reserved. */ package com.dianping.pigeon.remoting.http.provider; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.dianping.pigeon.extension.ExtensionLoader; import com.dianping.pigeon.remoting.common.codec.SerializerType; import com.dianping.pigeon.remoting.http.adapter.HttpAdapter; import com.dianping.pigeon.remoting.http.adapter.HttpAdapterFactory; import org.apache.commons.lang.StringUtils; import com.dianping.pigeon.log.Logger; import com.dianping.pigeon.log.LoggerLoader; import com.dianping.pigeon.remoting.common.codec.Serializer; import com.dianping.pigeon.remoting.common.codec.SerializerFactory; import com.dianping.pigeon.remoting.common.domain.InvocationRequest; import com.dianping.pigeon.remoting.common.domain.InvocationResponse; import com.dianping.pigeon.remoting.common.util.Constants; import com.dianping.pigeon.remoting.http.HttpUtils; import com.dianping.pigeon.remoting.provider.Server; import com.dianping.pigeon.remoting.provider.domain.DefaultProviderContext; import com.dianping.pigeon.remoting.provider.domain.ProviderContext; import com.dianping.pigeon.remoting.provider.util.ProviderUtils; public class HttpServerHandler implements HttpHandler { protected final Logger logger = LoggerLoader.getLogger(this.getClass()); private Server server; protected static Map<Long, HttpCallbackFuture> callbacks = new ConcurrentHashMap<Long, HttpCallbackFuture>(); public HttpServerHandler(Server server) { this.server = server; } @Override public void handle(HttpServletRequest request, HttpServletResponse response) throws Exception { long createTime = System.currentTimeMillis(); Object obj; String customize = request.getParameter("customize"); if("true".equalsIgnoreCase(customize)) { HttpAdapter httpAdapter = ExtensionLoader.getExtension(HttpAdapter.class); if(httpAdapter != null) { obj = HttpUtils.createDefaultRequest(httpAdapter.convert(request)); } else { throw new IllegalArgumentException("ServiceLoader httpAdapter not found!"); } } else if("service".equalsIgnoreCase(customize)) { String serviceName = request.getParameter("url"); if(StringUtils.isNotBlank(serviceName)) { HttpAdapter httpAdapter = HttpAdapterFactory.getHttpAdapters().get(serviceName); if(httpAdapter != null) { obj = HttpUtils.createDefaultRequest(httpAdapter.convert(request)); } else { throw new IllegalArgumentException("HttpAdapter not found!"); } } else { throw new IllegalArgumentException("serviceName can't be blank!"); } } else { String serialize = request.getParameter("serialize"); if (serialize == null) { serialize = request.getHeader("serialize"); } if (StringUtils.isBlank(serialize)) { response.setStatus(200); return; } if (!request.getMethod().equalsIgnoreCase("POST")) { if (SerializerType.isJson(Byte.parseByte(serialize))) { response.setStatus(200); } else { response.setStatus(500); } return; } else { Serializer serializer = SerializerFactory.getSerializer(Byte.parseByte(serialize)); obj = serializer.deserializeRequest(request.getInputStream()); } } InvocationRequest invocationRequest; if (!(obj instanceof InvocationRequest)) { throw new IllegalArgumentException("invalid request type:" + obj.getClass()); } else { invocationRequest = (InvocationRequest) obj; } invocationRequest.getParameters(); invocationRequest.setServiceName(HttpUtils.getDefaultServiceUrl(invocationRequest.getServiceName())); invocationRequest.setCreateMillisTime(createTime); ProviderContext invocationContext = new DefaultProviderContext(invocationRequest, new HttpChannel(request, response)); Future<InvocationResponse> invocationResponse = null; try { callbacks.put(invocationRequest.getSequence(), new HttpCallbackFuture(invocationRequest, invocationContext)); invocationResponse = server.processRequest(invocationRequest, invocationContext); if (invocationResponse != null) { if(Constants.REPLY_MANUAL || invocationContext.isAsync()) { callbacks.get(invocationRequest.getSequence()).getResponse(invocationRequest.getTimeout()); } invocationResponse.get(); } } catch (Throwable e) { if (invocationResponse != null && !invocationResponse.isCancelled()) { invocationResponse.cancel(true); } String msg = "process http request[" + request.getRemoteAddr() + "] failed:" + invocationRequest; // 心跳消息只返回正常的, 异常不返回 if (invocationRequest.getCallType() == Constants.CALLTYPE_REPLY && invocationRequest.getMessageType() != Constants.MESSAGE_TYPE_HEART) { invocationContext.getChannel().write(invocationContext, ProviderUtils.createFailResponse(invocationRequest, e)); logger.error(msg, e); } } finally { callbacks.remove(invocationRequest.getSequence()); } } }