com.liferay.portal.poller.PollerRequestHandlerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of portal-impl Show documentation
Show all versions of portal-impl Show documentation
Contains implementation for the portal services.
/**
* Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.poller;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.poller.DefaultPollerResponse;
import com.liferay.portal.kernel.poller.PollerHeader;
import com.liferay.portal.kernel.poller.PollerProcessor;
import com.liferay.portal.kernel.poller.PollerRequest;
import com.liferay.portal.kernel.poller.PollerResponse;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
import com.liferay.portal.model.BrowserTracker;
import com.liferay.portal.model.Company;
import com.liferay.portal.service.BrowserTrackerLocalServiceUtil;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.util.Encryptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
/**
* @author Michael C. Han
* @author Brian Wing Shun Chan
* @author Edward Han
*/
public class PollerRequestHandlerImpl
implements PollerRequestHandler, MessageListener {
@Override
public PollerHeader getPollerHeader(String pollerRequestString) {
if (Validator.isNull(pollerRequestString)) {
return null;
}
Map[] pollerRequestChunks =
parsePollerRequestParameters(pollerRequestString);
return parsePollerRequestHeader(pollerRequestChunks);
}
@Override
public JSONObject processRequest(
HttpServletRequest request, String pollerRequestString)
throws Exception {
if (Validator.isNull(pollerRequestString)) {
return null;
}
Map[] pollerRequestChunks =
parsePollerRequestParameters(pollerRequestString);
PollerHeader pollerHeader = parsePollerRequestHeader(
pollerRequestChunks);
if (!isValidPollerHeader(pollerHeader)) {
if (_log.isWarnEnabled()) {
_log.warn(
"Invalid poller header for request " +
pollerRequestString);
}
return null;
}
boolean receiveRequest = isReceiveRequest(request.getPathInfo());
String pollerSessionId = getPollerSessionId(pollerHeader);
PollerSession pollerSession = null;
synchronized (_pollerSessions) {
pollerSession = _pollerSessions.get(pollerSessionId);
if ((pollerSession == null) && receiveRequest) {
pollerSession = new PollerSession(pollerSessionId);
_pollerSessions.put(pollerSessionId, pollerSession);
}
}
List pollerRequests = createPollerRequests(
request, pollerHeader, pollerRequestChunks, receiveRequest);
executePollerRequests(pollerSession, pollerRequests);
if (receiveRequest) {
return createPollerResponseHeader(pollerHeader);
}
else {
return null;
}
}
@Override
public void receive(Message message) {
Object messagePayload = message.getPayload();
if (!(messagePayload instanceof PollerResponse)) {
return;
}
PollerResponse pollerResponse = (PollerResponse)messagePayload;
PollerHeader pollerHeader = pollerResponse.getPollerHeader();
String pollerSessionId = getPollerSessionId(pollerHeader);
synchronized (_pollerSessions) {
PollerSession pollerSession = _pollerSessions.get(pollerSessionId);
if ((pollerSession != null) &&
pollerSession.completePortletProcessing(
pollerResponse.getPortletId(), message.getResponseId())) {
_pollerSessions.remove(pollerSessionId);
}
}
}
protected PollerRequest createPollerRequest(
HttpServletRequest request, boolean receiveRequest,
PollerHeader pollerHeader, String portletId)
throws Exception {
return createPollerRequest(
request, receiveRequest, pollerHeader, portletId,
new HashMap(), null);
}
protected PollerRequest createPollerRequest(
HttpServletRequest request, boolean receiveRequest,
PollerHeader pollerHeader, String portletId,
Map parameterMap, String chunkId)
throws Exception {
PollerProcessor pollerProcessor =
PollerProcessorUtil.getPollerProcessor(portletId);
if (pollerProcessor == null) {
if (_log.isWarnEnabled()) {
_log.warn(
"Poller processor not found for portlet " + portletId);
}
return null;
}
return new PollerRequest(
request, pollerHeader, portletId, parameterMap, chunkId,
receiveRequest);
}
protected List createPollerRequests(
HttpServletRequest request, PollerHeader pollerHeader,
Map[] pollerRequestChunks, boolean receiveRequest)
throws Exception {
Map portletIdsMap = pollerHeader.getPortletIdsMap();
List pollerRequests = new ArrayList(
portletIdsMap.size());
Set receiveRequestPortletIds = null;
if (receiveRequest) {
receiveRequestPortletIds = new HashSet(
(int)(pollerRequestChunks.length / 0.75) + 1);
}
for (int i = 1; i < pollerRequestChunks.length; i++) {
Map pollerRequestChunk = pollerRequestChunks[i];
String portletId = (String)pollerRequestChunk.get("portletId");
Map parameterMap = parseData(pollerRequestChunk);
String chunkId = (String)pollerRequestChunk.get("chunkId");
try {
PollerRequest pollerRequest = createPollerRequest(
request, receiveRequest, pollerHeader, portletId,
parameterMap, chunkId);
pollerRequests.add(pollerRequest);
if (receiveRequest) {
receiveRequestPortletIds.add(portletId);
}
}
catch (Exception e) {
_log.error(e, e);
}
}
if (receiveRequest) {
Set portletIds = portletIdsMap.keySet();
for (String portletId : portletIds) {
if (receiveRequestPortletIds.contains(portletId)) {
continue;
}
try {
PollerRequest pollerRequest = createPollerRequest(
request, receiveRequest, pollerHeader, portletId);
pollerRequests.add(pollerRequest);
}
catch (Exception e) {
_log.error(e, e);
}
}
}
return pollerRequests;
}
protected JSONObject createPollerResponseHeader(PollerHeader pollerHeader)
throws SystemException {
if (pollerHeader == null) {
return null;
}
boolean suspendPolling = false;
if (pollerHeader.isStartPolling()) {
BrowserTrackerLocalServiceUtil.updateBrowserTracker(
pollerHeader.getUserId(), pollerHeader.getBrowserKey());
}
else {
BrowserTracker browserTracker =
BrowserTrackerLocalServiceUtil.getBrowserTracker(
pollerHeader.getUserId(), pollerHeader.getBrowserKey());
if (browserTracker.getBrowserKey() !=
pollerHeader.getBrowserKey()) {
suspendPolling = true;
}
}
JSONObject pollerResponseHeaderJSONObject =
JSONFactoryUtil.createJSONObject();
pollerResponseHeaderJSONObject.put("userId", pollerHeader.getUserId());
pollerResponseHeaderJSONObject.put("suspendPolling", suspendPolling);
return pollerResponseHeaderJSONObject;
}
protected void executePollerRequests(
PollerSession pollerSession, List pollerRequests) {
for (PollerRequest pollerRequest : pollerRequests) {
PollerRequestResponsePair pollerRequestResponsePair =
new PollerRequestResponsePair(pollerRequest);
String responseId = null;
if (pollerRequest.isReceiveRequest()) {
responseId = PortalUUIDUtil.generate();
PollerResponse pollerResponse = new DefaultPollerResponse(
pollerRequest.getPollerHeader(),
pollerRequest.getPortletId(), pollerRequest.getChunkId());
pollerRequestResponsePair.setPollerResponse(pollerResponse);
if (!pollerSession.beginPortletProcessing(
pollerRequestResponsePair, responseId)) {
continue;
}
}
Message message = new Message();
message.setPayload(pollerRequestResponsePair);
if (pollerRequest.isReceiveRequest()) {
message.setResponseId(responseId);
message.setResponseDestinationName(
DestinationNames.POLLER_RESPONSE);
}
MessageBusUtil.sendMessage(DestinationNames.POLLER, message);
}
}
protected String fixPollerRequestString(String pollerRequestString) {
if (Validator.isNull(pollerRequestString)) {
return null;
}
return StringUtil.replace(
pollerRequestString,
new String[] {
StringPool.OPEN_CURLY_BRACE, StringPool.CLOSE_CURLY_BRACE,
_ESCAPED_OPEN_CURLY_BRACE, _ESCAPED_CLOSE_CURLY_BRACE
},
new String[] {
_OPEN_HASH_MAP_WRAPPER, StringPool.DOUBLE_CLOSE_CURLY_BRACE,
StringPool.OPEN_CURLY_BRACE, StringPool.CLOSE_CURLY_BRACE
});
}
protected String getPollerSessionId(PollerHeader pollerHeader) {
return String.valueOf(pollerHeader.getUserId());
}
protected long getUserId(long companyId, String userIdString) {
long userId = 0;
try {
Company company = CompanyLocalServiceUtil.getCompany(companyId);
userId = GetterUtil.getLong(
Encryptor.decrypt(company.getKeyObj(), userIdString));
}
catch (Exception e) {
_log.error(
"Invalid credentials for company id " + companyId +
" and user id " + userIdString);
}
return userId;
}
protected boolean isReceiveRequest(String path) {
if ((path != null) && path.endsWith(_PATH_RECEIVE)) {
return true;
}
else {
return false;
}
}
protected boolean isValidPollerHeader(PollerHeader pollerHeader) {
if (pollerHeader == null) {
return false;
}
Map portletIdsMap = pollerHeader.getPortletIdsMap();
if ((portletIdsMap == null) || portletIdsMap.isEmpty()) {
return false;
}
return true;
}
protected Map parseData(
Map pollerRequestChunk)
throws Exception {
Map oldParameterMap =
(Map)pollerRequestChunk.get("data");
Map newParameterMap = new HashMap();
if (oldParameterMap == null) {
return newParameterMap;
}
for (Map.Entry entry : oldParameterMap.entrySet()) {
newParameterMap.put(
entry.getKey(), String.valueOf(entry.getValue()));
}
return newParameterMap;
}
protected PollerHeader parsePollerRequestHeader(
Map[] pollerRequestChunks) {
if ((pollerRequestChunks == null) || (pollerRequestChunks.length < 1)) {
return null;
}
Map pollerRequestChunk = pollerRequestChunks[0];
long browserKey = GetterUtil.getLong(
String.valueOf(pollerRequestChunk.get("browserKey")));
long companyId = GetterUtil.getLong(
String.valueOf(pollerRequestChunk.get("companyId")));
Map portletIdsMap =
(Map)pollerRequestChunk.get("portletIdsMap");
boolean startPolling = GetterUtil.getBoolean(
String.valueOf(pollerRequestChunk.get("startPolling")));
String userIdString = GetterUtil.getString(
String.valueOf(pollerRequestChunk.get("userId")));
long userId = getUserId(companyId, userIdString);
if (userId == 0) {
return null;
}
return new PollerHeader(
companyId, userId, browserKey, portletIdsMap, startPolling);
}
protected Map[] parsePollerRequestParameters(
String pollerRequestString) {
String fixedPollerRequestString = fixPollerRequestString(
pollerRequestString);
return (Map[])JSONFactoryUtil.deserialize(
fixedPollerRequestString);
}
private static final String _ESCAPED_CLOSE_CURLY_BRACE =
"[$CLOSE_CURLY_BRACE$]";
private static final String _ESCAPED_OPEN_CURLY_BRACE =
"[$OPEN_CURLY_BRACE$]";
private static final String _OPEN_HASH_MAP_WRAPPER =
"{\"javaClass\":\"java.util.HashMap\",\"map\":{";
private static final String _PATH_RECEIVE = "/receive";
private static Log _log = LogFactoryUtil.getLog(
PollerRequestHandlerImpl.class);
private Map _pollerSessions =
new HashMap();
}