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