/** * 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.resiliency.spi.remote; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.nio.intraband.RegistrationReference; import com.liferay.portal.kernel.process.TerminationProcessException; import com.liferay.portal.kernel.resiliency.PortalResiliencyException; import com.liferay.portal.kernel.resiliency.mpi.MPI; import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil; import com.liferay.portal.kernel.resiliency.spi.SPI; import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration; import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgent; import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgentFactoryUtil; import com.liferay.portal.kernel.util.StringPool; import java.rmi.RemoteException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * @author Shuyang Zhou */ public class RemoteSPIProxy implements SPI { public static final int SIGINT = 130; public RemoteSPIProxy( SPI spi, SPIConfiguration spiConfiguration, String spiProviderName, Future<SPI> cancelHandlerFuture, RegistrationReference registrationReference) { _spi = spi; _spiConfiguration = spiConfiguration; _spiProviderName = spiProviderName; _cancelHandlerFuture = cancelHandlerFuture; _registrationReference = registrationReference; _mpi = MPIHelperUtil.getMPI(); _spiAgent = SPIAgentFactoryUtil.createSPIAgent( spiConfiguration, registrationReference); } @Override public void addServlet( String contextPath, String docBasePath, String mappingPattern, String servletClassName) throws RemoteException { _spi.addServlet( contextPath, docBasePath, mappingPattern, servletClassName); } @Override public void addWebapp(String contextPath, String docBasePath) throws RemoteException { _spi.addWebapp(contextPath, docBasePath); } @Override public void destroy() { try { _spi.destroy(); _cancelHandlerFuture.get( _spiConfiguration.getShutdownTimeout(), TimeUnit.MILLISECONDS); } catch (Exception e) { boolean forceDestroy = true; if (e instanceof ExecutionException) { Throwable throwable = e.getCause(); if (throwable instanceof TerminationProcessException) { TerminationProcessException terminationProcessException = (TerminationProcessException)throwable; if (terminationProcessException.getExitCode() == SIGINT) { forceDestroy = false; } } } if (forceDestroy) { _cancelHandlerFuture.cancel(true); if (_log.isWarnEnabled()) { _log.warn("Forcibly destroyed SPI " + _spiConfiguration, e); } } } finally { MPIHelperUtil.unregisterSPI(this); } _spiAgent.destroy(); } @Override public MPI getMPI() { return _mpi; } @Override public RegistrationReference getRegistrationReference() { return _registrationReference; } @Override public SPIAgent getSPIAgent() { return _spiAgent; } @Override public SPIConfiguration getSPIConfiguration() { return _spiConfiguration; } @Override public String getSPIProviderName() { return _spiProviderName; } @Override public void init() throws RemoteException { _spi.init(); try { _spiAgent.init(this); } catch (PortalResiliencyException pre) { throw new RemoteException("Unable to initialize SPI agent", pre); } } @Override public boolean isAlive() throws RemoteException { try { return _spi.isAlive(); } catch (RemoteException re) { try { _cancelHandlerFuture.get(); } catch (Exception e) { throw new RemoteException( "SPI " + toString() + " died unexpectedly", e); } return false; } } @Override public void start() throws RemoteException { _spi.start(); } @Override public void stop() throws RemoteException { _spi.stop(); } @Override public String toString() { return _spiProviderName.concat(StringPool.POUND).concat( _spiConfiguration.toString()); } private static final Log _log = LogFactoryUtil.getLog(RemoteSPIProxy.class); private final Future<SPI> _cancelHandlerFuture; private final MPI _mpi; private final RegistrationReference _registrationReference; private final SPI _spi; private final SPIAgent _spiAgent; private final SPIConfiguration _spiConfiguration; private final String _spiProviderName; }