/**
* 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.events;
import com.liferay.portal.fabric.server.FabricServerUtil;
import com.liferay.portal.jericho.CachedLoggerProvider;
import com.liferay.portal.kernel.dao.db.DB;
import com.liferay.portal.kernel.dao.db.DBManagerUtil;
import com.liferay.portal.kernel.dao.db.DBType;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.kernel.events.SimpleAction;
import com.liferay.portal.kernel.executor.PortalExecutorManager;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.MessageBus;
import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle;
import com.liferay.portal.kernel.nio.intraband.Intraband;
import com.liferay.portal.kernel.nio.intraband.SystemDataType;
import com.liferay.portal.kernel.nio.intraband.mailbox.MailboxDatagramReceiveHandler;
import com.liferay.portal.kernel.nio.intraband.messaging.MessageDatagramReceiveHandler;
import com.liferay.portal.kernel.nio.intraband.proxy.IntrabandProxyDatagramReceiveHandler;
import com.liferay.portal.kernel.nio.intraband.rpc.RPCDatagramReceiveHandler;
import com.liferay.portal.kernel.patcher.PatcherUtil;
import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil;
import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
import com.liferay.portal.kernel.resiliency.spi.agent.annotation.DistributedRegistry;
import com.liferay.portal.kernel.resiliency.spi.agent.annotation.MatchType;
import com.liferay.portal.kernel.search.IndexerRegistry;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.service.ClassNameLocalServiceUtil;
import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
import com.liferay.portal.kernel.util.BasePortalLifecycle;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.PortalLifecycle;
import com.liferay.portal.kernel.util.PortalLifecycleUtil;
import com.liferay.portal.kernel.util.ReleaseInfo;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.plugin.PluginPackageIndexer;
import com.liferay.portal.tools.DBUpgrader;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.messageboards.util.MBMessageIndexer;
import com.liferay.registry.Registry;
import com.liferay.registry.RegistryUtil;
import com.liferay.registry.ServiceRegistration;
import com.liferay.registry.dependency.ServiceDependencyListener;
import com.liferay.registry.dependency.ServiceDependencyManager;
import com.liferay.taglib.servlet.JspFactorySwapper;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.MimeResponse;
import javax.portlet.PortletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.struts.tiles.taglib.ComponentConstants;
/**
* @author Brian Wing Shun Chan
* @author Alexander Chow
* @author Raymond Augé
*/
public class StartupAction extends SimpleAction {
@Override
public void run(String[] ids) throws ActionException {
try {
doRun(ids);
}
catch (RuntimeException re) {
throw re;
}
catch (Exception e) {
throw new ActionException(e);
}
}
protected void doRun(String[] ids) throws Exception {
// Print release information
Class<?> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
try (InputStream inputStream = classLoader.getResourceAsStream(
"com/liferay/portal/events/dependencies/startup.txt")) {
System.out.println(IOUtils.toString(inputStream));
}
System.out.println("Starting " + ReleaseInfo.getReleaseInfo() + "\n");
// Installed patches
if (_log.isInfoEnabled() && !PatcherUtil.hasInconsistentPatchLevels()) {
String installedPatches = StringUtil.merge(
PatcherUtil.getInstalledPatches(), StringPool.COMMA_AND_SPACE);
if (Validator.isNull(installedPatches)) {
_log.info("There are no patches installed");
}
else {
_log.info(
"The following patches are installed: " + installedPatches);
}
}
// Portal resiliency
ServiceDependencyManager portalResiliencyServiceDependencyManager =
new ServiceDependencyManager();
portalResiliencyServiceDependencyManager.addServiceDependencyListener(
new PortalResiliencyServiceDependencyLister());
portalResiliencyServiceDependencyManager.registerDependencies(
MessageBus.class, PortalExecutorManager.class);
// Shutdown hook
if (_log.isDebugEnabled()) {
_log.debug("Add shutdown hook");
}
Runtime runtime = Runtime.getRuntime();
runtime.addShutdownHook(new Thread(new ShutdownHook()));
// Indexers
ServiceDependencyManager indexerRegistryServiceDependencyManager =
new ServiceDependencyManager();
indexerRegistryServiceDependencyManager.addServiceDependencyListener(
new ServiceDependencyListener() {
@Override
public void dependenciesFulfilled() {
IndexerRegistryUtil.register(new MBMessageIndexer());
IndexerRegistryUtil.register(new PluginPackageIndexer());
}
@Override
public void destroy() {
}
});
indexerRegistryServiceDependencyManager.registerDependencies(
IndexerRegistry.class);
// MySQL version
DB db = DBManagerUtil.getDB();
if ((db.getDBType() == DBType.MYSQL) &&
(GetterUtil.getFloat(db.getVersionString()) < 5.6F)) {
_log.error(
"Please upgrade to at least MySQL 5.6.4. The portal no " +
"longer supports older versions of MySQL.");
System.exit(1);
}
// Check required build number
if (_log.isDebugEnabled()) {
_log.debug("Check required build number");
}
DBUpgrader.checkRequiredBuildNumber(ReleaseInfo.getParentBuildNumber());
Registry registry = RegistryUtil.getRegistry();
Map<String, Object> properties = new HashMap<>();
properties.put("module.service.lifecycle", "database.initialized");
properties.put("service.vendor", ReleaseInfo.getVendor());
properties.put("service.version", ReleaseInfo.getVersion());
final ServiceRegistration<ModuleServiceLifecycle>
moduleServiceLifecycleServiceRegistration =
registry.registerService(
ModuleServiceLifecycle.class,
new ModuleServiceLifecycle() {}, properties);
PortalLifecycleUtil.register(
new BasePortalLifecycle() {
@Override
protected void doPortalDestroy() {
moduleServiceLifecycleServiceRegistration.unregister();
}
@Override
protected void doPortalInit() {
}
},
PortalLifecycle.METHOD_DESTROY);
// Check class names
if (_log.isDebugEnabled()) {
_log.debug("Check class names");
}
ClassNameLocalServiceUtil.checkClassNames();
// Check resource actions
if (_log.isDebugEnabled()) {
_log.debug("Check resource actions");
}
ResourceActionLocalServiceUtil.checkResourceActions();
// Verify
if (_log.isDebugEnabled()) {
_log.debug("Verify database");
}
DBUpgrader.verify();
// Liferay JspFactory
JspFactorySwapper.swap();
// Jericho
CachedLoggerProvider.install();
}
private static final Log _log = LogFactoryUtil.getLog(StartupAction.class);
private static class PortalResiliencyServiceDependencyLister
implements ServiceDependencyListener {
@Override
public void dependenciesFulfilled() {
Registry registry = RegistryUtil.getRegistry();
MessageBus messageBus = registry.getService(MessageBus.class);
try {
DistributedRegistry.registerDistributed(
ComponentConstants.COMPONENT_CONTEXT, Direction.DUPLEX,
MatchType.POSTFIX);
DistributedRegistry.registerDistributed(
MimeResponse.MARKUP_HEAD_ELEMENT, Direction.DUPLEX,
MatchType.EXACT);
DistributedRegistry.registerDistributed(
PortletRequest.LIFECYCLE_PHASE, Direction.DUPLEX,
MatchType.EXACT);
DistributedRegistry.registerDistributed(WebKeys.class);
Intraband intraband = MPIHelperUtil.getIntraband();
intraband.registerDatagramReceiveHandler(
SystemDataType.MAILBOX.getValue(),
new MailboxDatagramReceiveHandler());
intraband.registerDatagramReceiveHandler(
SystemDataType.MESSAGE.getValue(),
new MessageDatagramReceiveHandler(messageBus));
intraband.registerDatagramReceiveHandler(
SystemDataType.PROXY.getValue(),
new IntrabandProxyDatagramReceiveHandler());
intraband.registerDatagramReceiveHandler(
SystemDataType.RPC.getValue(),
new RPCDatagramReceiveHandler());
if (PropsValues.PORTAL_FABRIC_ENABLED) {
FabricServerUtil.start();
}
}
catch (Exception e) {
throw new IllegalStateException(
"Unable to initialize portal resiliency", e);
}
}
@Override
public void destroy() {
}
}
}