001
014
015 package com.liferay.portal.kernel.resiliency.mpi;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.messaging.config.MessagingConfigurator;
020 import com.liferay.portal.kernel.messaging.config.MessagingConfiguratorRegistry;
021 import com.liferay.portal.kernel.nio.intraband.Intraband;
022 import com.liferay.portal.kernel.nio.intraband.IntrabandFactoryUtil;
023 import com.liferay.portal.kernel.resiliency.spi.SPI;
024 import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration;
025 import com.liferay.portal.kernel.resiliency.spi.SPIRegistryUtil;
026 import com.liferay.portal.kernel.resiliency.spi.provider.SPIProvider;
027 import com.liferay.portal.kernel.util.PropsKeys;
028 import com.liferay.portal.kernel.util.PropsUtil;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.Validator;
031
032 import java.rmi.NoSuchObjectException;
033 import java.rmi.RemoteException;
034 import java.rmi.server.UnicastRemoteObject;
035
036 import java.util.ArrayList;
037 import java.util.List;
038 import java.util.Map;
039 import java.util.concurrent.ConcurrentHashMap;
040 import java.util.concurrent.ConcurrentMap;
041 import java.util.concurrent.locks.Lock;
042 import java.util.concurrent.locks.ReentrantLock;
043
044
047 public class MPIHelperUtil {
048
049 public static Intraband getIntraband() {
050 return _intraband;
051 }
052
053 public static MPI getMPI() {
054 return _mpi;
055 }
056
057 public static SPI getSPI(String spiProviderName, String spiId) {
058 SPIKey spiKey = new SPIKey(spiProviderName, spiId);
059
060 SPI spi = _spis.get(spiKey);
061
062 if (spi != null) {
063 spi = _checkSPILiveness(spi);
064 }
065
066 return spi;
067 }
068
069 public static SPIProvider getSPIProvider(String spiProviderName) {
070 return _spiProviders.get(spiProviderName);
071 }
072
073 public static List<SPIProvider> getSPIProviders() {
074 return new ArrayList<SPIProvider>(_spiProviders.values());
075 }
076
077 public static List<SPI> getSPIs() {
078 List<SPI> spis = new ArrayList<SPI>();
079
080 for (SPI spi : _spis.values()) {
081 spi = _checkSPILiveness(spi);
082
083 if (spi != null) {
084 spis.add(spi);
085 }
086 }
087
088 return spis;
089 }
090
091 public static List<SPI> getSPIs(String spiProviderName) {
092 List<SPI> spis = new ArrayList<SPI>();
093
094 for (Map.Entry<SPIKey, SPI> entry : _spis.entrySet()) {
095 SPIKey spiKey = entry.getKey();
096
097 if (!spiProviderName.equals(spiKey._spiProviderName)) {
098 continue;
099 }
100
101 SPI spi = entry.getValue();
102
103 spi = _checkSPILiveness(spi);
104
105 if (spi != null) {
106 spis.add(spi);
107 }
108 }
109
110 return spis;
111 }
112
113 public static boolean registerSPI(SPI spi) {
114 _lock.lock();
115
116 try {
117 MPI mpi = spi.getMPI();
118
119 if (mpi != _mpi) {
120 if (_log.isWarnEnabled()) {
121 _log.warn(
122 "Not registering SPI " + spi + " with foreign MPI " +
123 mpi + " versus " + _mpi);
124 }
125
126 return false;
127 }
128
129 String spiProviderName = spi.getSPIProviderName();
130
131 SPIProvider spiProvider = _spiProviders.get(spiProviderName);
132
133 if (spiProvider == null) {
134 if (_log.isWarnEnabled()) {
135 _log.warn(
136 "Not registering SPI " + spi +
137 " with unknown SPI provider " + spiProviderName);
138 }
139
140 return false;
141 }
142
143 SPIConfiguration spiConfiguration = spi.getSPIConfiguration();
144
145 SPIKey spiKey = new SPIKey(
146 spiProviderName, spiConfiguration.getSPIId());
147
148 SPI previousSPI = _spis.putIfAbsent(spiKey, spi);
149
150 if (previousSPI != null) {
151 if (_log.isWarnEnabled()) {
152 _log.warn(
153 "Not registering SPI " + spi +
154 " because it duplicates " + previousSPI);
155 }
156
157 return false;
158 }
159 else {
160 SPIRegistryUtil.registerSPI(spi);
161
162 for (String servletContextName :
163 spiConfiguration.getServletContextNames()) {
164
165 List<MessagingConfigurator> messagingConfigurators =
166 MessagingConfiguratorRegistry.getMessagingConfigurators(
167 servletContextName);
168
169 if (messagingConfigurators != null) {
170 for (MessagingConfigurator messagingConfigurator :
171 messagingConfigurators) {
172
173 messagingConfigurator.disconnect();
174 }
175 }
176 }
177
178 if (_log.isInfoEnabled()) {
179 _log.info("Registered SPI " + spi);
180 }
181
182 return true;
183 }
184 }
185 catch (RemoteException re) {
186 throw new RuntimeException(re);
187 }
188 finally {
189 _lock.unlock();
190 }
191 }
192
193 public static boolean registerSPIProvider(SPIProvider spiProvider) {
194 String spiProviderName = spiProvider.getName();
195
196 SPIProvider previousSPIProvider = null;
197
198 _lock.lock();
199
200 try {
201 previousSPIProvider = _spiProviders.putIfAbsent(
202 spiProviderName, spiProvider);
203 }
204 finally {
205 _lock.unlock();
206 }
207
208 if (previousSPIProvider != null) {
209 if (_log.isWarnEnabled()) {
210 _log.warn(
211 "Not registering SPI provider " + spiProvider +
212 " because it duplicates " + previousSPIProvider);
213 }
214
215 return false;
216 }
217 else {
218 if (_log.isInfoEnabled()) {
219 _log.info("Registered SPI provider " + spiProvider);
220 }
221
222 return true;
223 }
224 }
225
226 public static void shutdown() {
227 try {
228 UnicastRemoteObject.unexportObject(_mpiImpl, true);
229 }
230 catch (NoSuchObjectException nsoe) {
231 if (_log.isWarnEnabled()) {
232 _log.warn("Unable to unexport " + _mpiImpl, nsoe);
233 }
234 }
235 }
236
237 public static boolean unregisterSPI(SPI spi) {
238 _lock.lock();
239
240 try {
241 MPI mpi = spi.getMPI();
242
243 if (mpi != _mpi) {
244 if (_log.isWarnEnabled()) {
245 _log.warn(
246 "Not unregistering SPI " + spi + " with foreign MPI " +
247 mpi + " versus " + _mpi);
248 }
249
250 return false;
251 }
252
253 String spiProviderName = spi.getSPIProviderName();
254
255 SPIProvider spiProvider = _spiProviders.get(spiProviderName);
256
257 if (spiProvider == null) {
258 if (_log.isWarnEnabled()) {
259 _log.warn(
260 "Not unregistering SPI " + spi +
261 " with unknown SPI provider " + spiProviderName);
262 }
263
264 return false;
265 }
266
267 SPIConfiguration spiConfiguration = spi.getSPIConfiguration();
268
269 String spiId = spiConfiguration.getSPIId();
270
271 SPIKey spiKey = new SPIKey(spiProviderName, spiId);
272
273 if (_spis.remove(spiKey, spi)) {
274 SPIRegistryUtil.unregisterSPI(spi);
275
276 for (String servletContextName :
277 spiConfiguration.getServletContextNames()) {
278
279 List<MessagingConfigurator> messagingConfigurators =
280 MessagingConfiguratorRegistry.getMessagingConfigurators(
281 servletContextName);
282
283 if (messagingConfigurators != null) {
284 for (MessagingConfigurator messagingConfigurator :
285 messagingConfigurators) {
286
287 messagingConfigurator.connect();
288 }
289 }
290 }
291
292 if (_log.isInfoEnabled()) {
293 _log.info("Unregistered SPI " + spi);
294 }
295
296 return true;
297 }
298 else {
299 if (_log.isWarnEnabled()) {
300 _log.warn("Not unregistering unregistered SPI " + spi);
301 }
302
303 return false;
304 }
305 }
306 catch (RemoteException re) {
307 throw new RuntimeException(re);
308 }
309 finally {
310 _lock.unlock();
311 }
312 }
313
314 public static boolean unregisterSPIProvider(SPIProvider spiProvider) {
315 _lock.lock();
316
317 try {
318 String spiProviderName = spiProvider.getName();
319
320 if (_spiProviders.remove(spiProviderName, spiProvider)) {
321 for (Map.Entry<SPIKey, SPI> entry : _spis.entrySet()) {
322 SPIKey spiKey = entry.getKey();
323
324 if (!spiProviderName.equals(spiKey._spiProviderName)) {
325 continue;
326 }
327
328 SPI spi = entry.getValue();
329
330 try {
331 spi.destroy();
332
333 if (_log.isInfoEnabled()) {
334 _log.info(
335 "Unregistered SPI " + spi +
336 " while unregistering SPI provider " +
337 spiProvider);
338 }
339 }
340 catch (RemoteException re) {
341 _log.error(
342 "Unable to unregister SPI " + spi +
343 " while unregistering SPI provider " +
344 spiProvider,
345 re);
346 }
347 }
348
349 if (_log.isInfoEnabled()) {
350 _log.info("Unregistered SPI provider " + spiProvider);
351 }
352
353 return true;
354 }
355 else {
356 if (_log.isWarnEnabled()) {
357 _log.warn(
358 "Not unregistering unregistered SPI provider " +
359 spiProvider);
360 }
361
362 return false;
363 }
364 }
365 finally {
366 _lock.unlock();
367 }
368 }
369
370 private static SPI _checkSPILiveness(SPI spi) {
371 boolean alive = false;
372
373 try {
374 alive = spi.isAlive();
375 }
376 catch (RemoteException re) {
377 _log.error(re);
378 }
379
380 if (alive) {
381 return spi;
382 }
383
384 unregisterSPI(spi);
385
386 return null;
387 }
388
389 private static Log _log = LogFactoryUtil.getLog(MPIHelperUtil.class);
390
391 private static Intraband _intraband;
392 private static Lock _lock = new ReentrantLock();
393 private static MPI _mpi;
394 private static MPI _mpiImpl;
395 private static ConcurrentMap<String, SPIProvider> _spiProviders =
396 new ConcurrentHashMap<String, SPIProvider>();
397 private static ConcurrentMap<SPIKey, SPI> _spis =
398 new ConcurrentHashMap<SPIKey, SPI>();
399
400 private static class MPIImpl implements MPI {
401
402 @Override
403 public boolean isAlive() {
404 return true;
405 }
406
407 }
408
409 private static class SPIKey {
410
411 public SPIKey(String spiProviderName, String spiId) {
412 _spiProviderName = spiProviderName;
413 _spiId = spiId;
414 }
415
416 @Override
417 public boolean equals(Object obj) {
418 SPIKey spiKey = (SPIKey)obj;
419
420 if (Validator.equals(
421 _spiProviderName, spiKey._spiProviderName) &&
422 Validator.equals(_spiId, spiKey._spiId)) {
423
424 return true;
425 }
426
427 return false;
428 }
429
430 @Override
431 public int hashCode() {
432 return _spiProviderName.hashCode() * 11 + _spiId.hashCode();
433 }
434
435 @Override
436 public String toString() {
437 return _spiProviderName.concat(StringPool.POUND).concat(_spiId);
438 }
439
440 private String _spiId;
441 private String _spiProviderName;
442
443 }
444
445 static {
446
447
448
449 _mpiImpl = new MPIImpl();
450
451 try {
452 if (PropsUtil.getProps() != null) {
453 System.setProperty(
454 PropsKeys.INTRABAND_IMPL,
455 PropsUtil.get(PropsKeys.INTRABAND_IMPL));
456 System.setProperty(
457 PropsKeys.INTRABAND_TIMEOUT_DEFAULT,
458 PropsUtil.get(PropsKeys.INTRABAND_TIMEOUT_DEFAULT));
459 System.setProperty(
460 PropsKeys.INTRABAND_WELDER_IMPL,
461 PropsUtil.get(PropsKeys.INTRABAND_WELDER_IMPL));
462 }
463
464 _intraband = IntrabandFactoryUtil.createIntraband();
465
466 _mpi = (MPI)UnicastRemoteObject.exportObject(_mpiImpl, 0);
467 }
468 catch (Exception e) {
469 throw new ExceptionInInitializerError(e);
470 }
471 }
472
473 }