001
014
015 package com.liferay.portal.kernel.cluster;
016
017 import com.liferay.portal.kernel.module.framework.service.IdentifiableOSGiServiceInvokerUtil;
018 import com.liferay.portal.kernel.util.GetterUtil;
019 import com.liferay.portal.kernel.util.GroupThreadLocal;
020 import com.liferay.portal.kernel.util.LocaleThreadLocal;
021 import com.liferay.portal.kernel.util.MethodHandler;
022 import com.liferay.portal.kernel.util.MethodKey;
023 import com.liferay.portal.kernel.util.PropsKeys;
024 import com.liferay.portal.kernel.util.PropsUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.model.User;
027 import com.liferay.portal.security.auth.CompanyThreadLocal;
028 import com.liferay.portal.security.auth.PrincipalThreadLocal;
029 import com.liferay.portal.security.permission.PermissionChecker;
030 import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
031 import com.liferay.portal.security.permission.PermissionThreadLocal;
032 import com.liferay.portal.service.UserLocalServiceUtil;
033
034 import java.io.Serializable;
035
036 import java.lang.reflect.Method;
037
038 import java.util.Locale;
039 import java.util.Map;
040 import java.util.concurrent.Future;
041 import java.util.concurrent.TimeUnit;
042
043
046 public class ClusterableInvokerUtil {
047
048 public static MethodHandler createMethodHandler(
049 Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
050 Object targetObject, Method method, Object[] arguments) {
051
052 MethodHandler methodHandler =
053 IdentifiableOSGiServiceInvokerUtil.createMethodHandler(
054 targetObject, method, arguments);
055
056 Map<String, Serializable> context =
057 ClusterableContextThreadLocal.collectThreadLocalContext();
058
059 _populateContextFromThreadLocals(context);
060
061 String clusterInvokeAcceptorClassName =
062 clusterInvokeAcceptorClass.getName();
063
064 if (clusterInvokeAcceptorClass == ClusterInvokeAcceptor.class) {
065 clusterInvokeAcceptorClassName = null;
066 }
067
068 return new MethodHandler(
069 _invokeMethodKey, methodHandler, clusterInvokeAcceptorClassName,
070 context);
071 }
072
073 public static void invokeOnCluster(
074 Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
075 Object targetObject, Method method, Object[] arguments)
076 throws Throwable {
077
078 MethodHandler methodHandler = createMethodHandler(
079 clusterInvokeAcceptorClass, targetObject, method, arguments);
080
081 ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
082 methodHandler, true);
083
084 clusterRequest.setFireAndForget(true);
085
086 ClusterExecutorUtil.execute(clusterRequest);
087 }
088
089 public static Object invokeOnMaster(
090 Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
091 Object targetObject, Method method, Object[] arguments)
092 throws Throwable {
093
094 MethodHandler methodHandler = createMethodHandler(
095 clusterInvokeAcceptorClass, targetObject, method, arguments);
096
097 Future<Object> futureResult = ClusterMasterExecutorUtil.executeOnMaster(
098 methodHandler);
099
100 return futureResult.get(
101 _CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT, TimeUnit.SECONDS);
102 }
103
104 @SuppressWarnings("unused")
105 private static Object _invoke(
106 MethodHandler methodHandler, String clusterInvokeAcceptorClassName,
107 Map<String, Serializable> context)
108 throws Exception {
109
110 if (Validator.isNotNull(clusterInvokeAcceptorClassName)) {
111 ClusterInvokeAcceptor clusterInvokeAcceptor =
112 ClusterInvokeAcceptorUtil.getClusterInvokeAcceptor(
113 clusterInvokeAcceptorClassName);
114
115 if (!clusterInvokeAcceptor.accept(context)) {
116 return null;
117 }
118 }
119
120 _populateThreadLocalsFromContext(context);
121
122 return methodHandler.invoke();
123 }
124
125 private static void _populateContextFromThreadLocals(
126 Map<String, Serializable> context) {
127
128 if (!context.containsKey("companyId")) {
129 context.put("companyId", CompanyThreadLocal.getCompanyId());
130 }
131
132 if (!context.containsKey("defaultLocale")) {
133 context.put("defaultLocale", LocaleThreadLocal.getDefaultLocale());
134 }
135
136 if (!context.containsKey("groupId")) {
137 context.put("groupId", GroupThreadLocal.getGroupId());
138 }
139
140 if (!context.containsKey("principalName")) {
141 context.put("principalName", PrincipalThreadLocal.getName());
142 }
143
144 if (!context.containsKey("principalPassword")) {
145 context.put(
146 "principalPassword", PrincipalThreadLocal.getPassword());
147 }
148
149 if (!context.containsKey("siteDefaultLocale")) {
150 context.put(
151 "siteDefaultLocale", LocaleThreadLocal.getSiteDefaultLocale());
152 }
153
154 if (!context.containsKey("themeDisplayLocale")) {
155 context.put(
156 "themeDisplayLocale",
157 LocaleThreadLocal.getThemeDisplayLocale());
158 }
159 }
160
161 private static void _populateThreadLocalsFromContext(
162 Map<String, Serializable> context) {
163
164 long companyId = GetterUtil.getLong(context.get("companyId"));
165
166 if (companyId > 0) {
167 CompanyThreadLocal.setCompanyId(companyId);
168 }
169
170 Locale defaultLocale = (Locale)context.get("defaultLocale");
171
172 if (defaultLocale != null) {
173 LocaleThreadLocal.setDefaultLocale(defaultLocale);
174 }
175
176 long groupId = GetterUtil.getLong(context.get("groupId"));
177
178 if (groupId > 0) {
179 GroupThreadLocal.setGroupId(groupId);
180 }
181
182 String principalName = GetterUtil.getString(
183 context.get("principalName"));
184
185 if (Validator.isNotNull(principalName)) {
186 PrincipalThreadLocal.setName(principalName);
187 }
188
189 PermissionChecker permissionChecker = null;
190
191 if (Validator.isNotNull(principalName)) {
192 try {
193 User user = UserLocalServiceUtil.fetchUser(
194 PrincipalThreadLocal.getUserId());
195
196 permissionChecker = PermissionCheckerFactoryUtil.create(user);
197 }
198 catch (Exception e) {
199 throw new RuntimeException(e);
200 }
201 }
202
203 if (permissionChecker != null) {
204 PermissionThreadLocal.setPermissionChecker(permissionChecker);
205 }
206
207 String principalPassword = GetterUtil.getString(
208 context.get("principalPassword"));
209
210 if (Validator.isNotNull(principalPassword)) {
211 PrincipalThreadLocal.setPassword(principalPassword);
212 }
213
214 Locale siteDefaultLocale = (Locale)context.get("siteDefaultLocale");
215
216 if (siteDefaultLocale != null) {
217 LocaleThreadLocal.setSiteDefaultLocale(siteDefaultLocale);
218 }
219
220 Locale themeDisplayLocale = (Locale)context.get("themeDisplayLocale");
221
222 if (themeDisplayLocale != null) {
223 LocaleThreadLocal.setThemeDisplayLocale(themeDisplayLocale);
224 }
225 }
226
227 private static final long _CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT =
228 GetterUtil.getLong(
229 PropsUtil.get(PropsKeys.CLUSTERABLE_ADVICE_CALL_MASTER_TIMEOUT));
230
231 private static final MethodKey _invokeMethodKey = new MethodKey(
232 ClusterableInvokerUtil.class, "_invoke", MethodHandler.class,
233 String.class, Map.class);
234
235 }