/**
* Copyright (c) 2000-present 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.kernel.cluster;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.module.framework.service.IdentifiableOSGiServiceInvokerUtil;
import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import com.liferay.portal.kernel.security.auth.PrincipalThreadLocal;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionCheckerFactoryUtil;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.GroupThreadLocal;
import com.liferay.portal.kernel.util.LocaleThreadLocal;
import com.liferay.portal.kernel.util.MethodHandler;
import com.liferay.portal.kernel.util.MethodKey;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* @author Shuyang Zhou
*/
public class ClusterableInvokerUtil {
public static MethodHandler createMethodHandler(
Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
Object targetObject, Method method, Object[] arguments) {
MethodHandler methodHandler =
IdentifiableOSGiServiceInvokerUtil.createMethodHandler(
targetObject, method, arguments);
Map<String, Serializable> context =
ClusterableContextThreadLocal.collectThreadLocalContext();
_populateContextFromThreadLocals(context);
String clusterInvokeAcceptorClassName =
clusterInvokeAcceptorClass.getName();
if (clusterInvokeAcceptorClass == ClusterInvokeAcceptor.class) {
clusterInvokeAcceptorClassName = null;
}
return new MethodHandler(
_invokeMethodKey, methodHandler, clusterInvokeAcceptorClassName,
context);
}
public static void invokeOnCluster(
Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
Object targetObject, Method method, Object[] arguments)
throws Throwable {
MethodHandler methodHandler = createMethodHandler(
clusterInvokeAcceptorClass, targetObject, method, arguments);
ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
methodHandler, true);
clusterRequest.setFireAndForget(true);
ClusterExecutorUtil.execute(clusterRequest);
}
public static Object invokeOnMaster(
Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
Object targetObject, Method method, Object[] arguments)
throws Throwable {
MethodHandler methodHandler = createMethodHandler(
clusterInvokeAcceptorClass, targetObject, method, arguments);
Future<Object> futureResult = ClusterMasterExecutorUtil.executeOnMaster(
methodHandler);
return futureResult.get(
_CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT, TimeUnit.SECONDS);
}
@SuppressWarnings("unused")
private static Object _invoke(
MethodHandler methodHandler, String clusterInvokeAcceptorClassName,
Map<String, Serializable> context)
throws Exception {
if (Validator.isNotNull(clusterInvokeAcceptorClassName)) {
ClusterInvokeAcceptor clusterInvokeAcceptor =
ClusterInvokeAcceptorUtil.getClusterInvokeAcceptor(
clusterInvokeAcceptorClassName);
if (!clusterInvokeAcceptor.accept(context)) {
return null;
}
}
_populateThreadLocalsFromContext(context);
return methodHandler.invoke();
}
private static void _populateContextFromThreadLocals(
Map<String, Serializable> context) {
if (!context.containsKey("companyId")) {
context.put("companyId", CompanyThreadLocal.getCompanyId());
}
if (!context.containsKey("defaultLocale")) {
context.put("defaultLocale", LocaleThreadLocal.getDefaultLocale());
}
if (!context.containsKey("groupId")) {
context.put("groupId", GroupThreadLocal.getGroupId());
}
if (!context.containsKey("principalName")) {
context.put("principalName", PrincipalThreadLocal.getName());
}
if (!context.containsKey("principalPassword")) {
context.put(
"principalPassword", PrincipalThreadLocal.getPassword());
}
if (!context.containsKey("siteDefaultLocale")) {
context.put(
"siteDefaultLocale", LocaleThreadLocal.getSiteDefaultLocale());
}
if (!context.containsKey("themeDisplayLocale")) {
context.put(
"themeDisplayLocale",
LocaleThreadLocal.getThemeDisplayLocale());
}
}
private static void _populateThreadLocalsFromContext(
Map<String, Serializable> context) {
long companyId = GetterUtil.getLong(context.get("companyId"));
if (companyId > 0) {
CompanyThreadLocal.setCompanyId(companyId);
}
Locale defaultLocale = (Locale)context.get("defaultLocale");
if (defaultLocale != null) {
LocaleThreadLocal.setDefaultLocale(defaultLocale);
}
long groupId = GetterUtil.getLong(context.get("groupId"));
if (groupId > 0) {
GroupThreadLocal.setGroupId(groupId);
}
String principalName = GetterUtil.getString(
context.get("principalName"));
if (Validator.isNotNull(principalName)) {
PrincipalThreadLocal.setName(principalName);
}
PermissionChecker permissionChecker = null;
if (Validator.isNotNull(principalName)) {
try {
User user = UserLocalServiceUtil.fetchUser(
PrincipalThreadLocal.getUserId());
permissionChecker = PermissionCheckerFactoryUtil.create(user);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
if (permissionChecker != null) {
PermissionThreadLocal.setPermissionChecker(permissionChecker);
}
String principalPassword = GetterUtil.getString(
context.get("principalPassword"));
if (Validator.isNotNull(principalPassword)) {
PrincipalThreadLocal.setPassword(principalPassword);
}
Locale siteDefaultLocale = (Locale)context.get("siteDefaultLocale");
if (siteDefaultLocale != null) {
LocaleThreadLocal.setSiteDefaultLocale(siteDefaultLocale);
}
Locale themeDisplayLocale = (Locale)context.get("themeDisplayLocale");
if (themeDisplayLocale != null) {
LocaleThreadLocal.setThemeDisplayLocale(themeDisplayLocale);
}
}
private static final long _CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT =
GetterUtil.getLong(
PropsUtil.get(PropsKeys.CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT));
private static final MethodKey _invokeMethodKey = new MethodKey(
ClusterableInvokerUtil.class, "_invoke", MethodHandler.class,
String.class, Map.class);
}