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
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 catch (RemoteException re) {
185 throw new RuntimeException(re);
186 }
187 finally {
188 _lock.unlock();
189 }
190 }
191
192 public static boolean registerSPIProvider(SPIProvider spiProvider) {
193 String spiProviderName = spiProvider.getName();
194
195 SPIProvider previousSPIProvider = null;
196
197 _lock.lock();
198
199 try {
200 previousSPIProvider = _spiProviders.putIfAbsent(
201 spiProviderName, spiProvider);
202 }
203 finally {
204 _lock.unlock();
205 }
206
207 if (previousSPIProvider != null) {
208 if (_log.isWarnEnabled()) {
209 _log.warn(
210 "Not registering SPI provider " + spiProvider +
211 " because it duplicates " + previousSPIProvider);
212 }
213
214 return false;
215 }
216
217 if (_log.isInfoEnabled()) {
218 _log.info("Registered SPI provider " + spiProvider);
219 }
220
221 return true;
222 }
223
224 public static void shutdown() {
225 try {
226 UnicastRemoteObject.unexportObject(_mpiImpl, true);
227 }
228 catch (NoSuchObjectException nsoe) {
229 if (_log.isWarnEnabled()) {
230 _log.warn("Unable to unexport " + _mpiImpl, nsoe);
231 }
232 }
233 }
234
235 public static boolean unregisterSPI(SPI spi) {
236 _lock.lock();
237
238 try {
239 MPI mpi = spi.getMPI();
240
241 if (mpi != _mpi) {
242 if (_log.isWarnEnabled()) {
243 _log.warn(
244 "Not unregistering SPI " + spi + " with foreign MPI " +
245 mpi + " versus " + _mpi);
246 }
247
248 return false;
249 }
250
251 String spiProviderName = spi.getSPIProviderName();
252
253 SPIProvider spiProvider = _spiProviders.get(spiProviderName);
254
255 if (spiProvider == null) {
256 if (_log.isWarnEnabled()) {
257 _log.warn(
258 "Not unregistering SPI " + spi +
259 " with unknown SPI provider " + spiProviderName);
260 }
261
262 return false;
263 }
264
265 SPIConfiguration spiConfiguration = spi.getSPIConfiguration();
266
267 String spiId = spiConfiguration.getSPIId();
268
269 SPIKey spiKey = new SPIKey(spiProviderName, spiId);
270
271 if (_spis.remove(spiKey, spi)) {
272 SPIRegistryUtil.unregisterSPI(spi);
273
274 for (String servletContextName :
275 spiConfiguration.getServletContextNames()) {
276
277 List<MessagingConfigurator> messagingConfigurators =
278 MessagingConfiguratorRegistry.getMessagingConfigurators(
279 servletContextName);
280
281 if (messagingConfigurators != null) {
282 for (MessagingConfigurator messagingConfigurator :
283 messagingConfigurators) {
284
285 messagingConfigurator.connect();
286 }
287 }
288 }
289
290 if (_log.isInfoEnabled()) {
291 _log.info("Unregistered SPI " + spi);
292 }
293
294 return true;
295 }
296
297 if (_log.isWarnEnabled()) {
298 _log.warn("Not unregistering unregistered SPI " + spi);
299 }
300
301 return false;
302 }
303 catch (RemoteException re) {
304 throw new RuntimeException(re);
305 }
306 finally {
307 _lock.unlock();
308 }
309 }
310
311 public static boolean unregisterSPIProvider(SPIProvider spiProvider) {
312 _lock.lock();
313
314 try {
315 String spiProviderName = spiProvider.getName();
316
317 if (_spiProviders.remove(spiProviderName, spiProvider)) {
318 for (Map.Entry<SPIKey, SPI> entry : _spis.entrySet()) {
319 SPIKey spiKey = entry.getKey();
320
321 if (!spiProviderName.equals(spiKey._spiProviderName)) {
322 continue;
323 }
324
325 SPI spi = entry.getValue();
326
327 try {
328 spi.destroy();
329
330 if (_log.isInfoEnabled()) {
331 _log.info(
332 "Unregistered SPI " + spi +
333 " while unregistering SPI provider " +
334 spiProvider);
335 }
336 }
337 catch (RemoteException re) {
338 _log.error(
339 "Unable to unregister SPI " + spi +
340 " while unregistering SPI provider " +
341 spiProvider,
342 re);
343 }
344 }
345
346 if (_log.isInfoEnabled()) {
347 _log.info("Unregistered SPI provider " + spiProvider);
348 }
349
350 return true;
351 }
352
353 if (_log.isWarnEnabled()) {
354 _log.warn(
355 "Not unregistering unregistered SPI provider " +
356 spiProvider);
357 }
358
359 return false;
360 }
361 finally {
362 _lock.unlock();
363 }
364 }
365
366 private static SPI _checkSPILiveness(SPI spi) {
367 boolean alive = false;
368
369 try {
370 alive = spi.isAlive();
371 }
372 catch (RemoteException re) {
373 _log.error(re);
374 }
375
376 if (alive) {
377 return spi;
378 }
379
380 unregisterSPI(spi);
381
382 return null;
383 }
384
385 private static Log _log = LogFactoryUtil.getLog(MPIHelperUtil.class);
386
387 private static Intraband _intraband;
388 private static Lock _lock = new ReentrantLock();
389 private static MPI _mpi;
390 private static MPI _mpiImpl;
391 private static ConcurrentMap<String, SPIProvider> _spiProviders =
392 new ConcurrentHashMap<String, SPIProvider>();
393 private static ConcurrentMap<SPIKey, SPI> _spis =
394 new ConcurrentHashMap<SPIKey, SPI>();
395
396 private static class MPIImpl implements MPI {
397
398 @Override
399 public boolean isAlive() {
400 return true;
401 }
402
403 }
404
405 private static class SPIKey {
406
407 public SPIKey(String spiProviderName, String spiId) {
408 _spiProviderName = spiProviderName;
409 _spiId = spiId;
410 }
411
412 @Override
413 public boolean equals(Object obj) {
414 SPIKey spiKey = (SPIKey)obj;
415
416 if (Validator.equals(
417 _spiProviderName, spiKey._spiProviderName) &&
418 Validator.equals(_spiId, spiKey._spiId)) {
419
420 return true;
421 }
422
423 return false;
424 }
425
426 @Override
427 public int hashCode() {
428 return _spiProviderName.hashCode() * 11 + _spiId.hashCode();
429 }
430
431 @Override
432 public String toString() {
433 return _spiProviderName.concat(StringPool.POUND).concat(_spiId);
434 }
435
436 private String _spiId;
437 private String _spiProviderName;
438
439 }
440
441 static {
442
443
444
445 _mpiImpl = new MPIImpl();
446
447 try {
448 if (PropsUtil.getProps() != null) {
449 System.setProperty(
450 PropsKeys.INTRABAND_IMPL,
451 PropsUtil.get(PropsKeys.INTRABAND_IMPL));
452 System.setProperty(
453 PropsKeys.INTRABAND_TIMEOUT_DEFAULT,
454 PropsUtil.get(PropsKeys.INTRABAND_TIMEOUT_DEFAULT));
455 System.setProperty(
456 PropsKeys.INTRABAND_WELDER_IMPL,
457 PropsUtil.get(PropsKeys.INTRABAND_WELDER_IMPL));
458 }
459
460 _intraband = IntrabandFactoryUtil.createIntraband();
461
462 _mpi = (MPI)UnicastRemoteObject.exportObject(_mpiImpl, 0);
463 }
464 catch (Exception e) {
465 throw new ExceptionInInitializerError(e);
466 }
467 }
468
469 }