001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.events;
016    
017    import com.liferay.portal.fabric.server.FabricServerUtil;
018    import com.liferay.portal.jericho.CachedLoggerProvider;
019    import com.liferay.portal.kernel.dao.db.DB;
020    import com.liferay.portal.kernel.dao.db.DBManagerUtil;
021    import com.liferay.portal.kernel.dao.db.DBType;
022    import com.liferay.portal.kernel.events.ActionException;
023    import com.liferay.portal.kernel.events.SimpleAction;
024    import com.liferay.portal.kernel.executor.PortalExecutorManager;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.messaging.MessageBus;
028    import com.liferay.portal.kernel.nio.intraband.Intraband;
029    import com.liferay.portal.kernel.nio.intraband.SystemDataType;
030    import com.liferay.portal.kernel.nio.intraband.mailbox.MailboxDatagramReceiveHandler;
031    import com.liferay.portal.kernel.nio.intraband.messaging.MessageDatagramReceiveHandler;
032    import com.liferay.portal.kernel.nio.intraband.proxy.IntrabandProxyDatagramReceiveHandler;
033    import com.liferay.portal.kernel.nio.intraband.rpc.RPCDatagramReceiveHandler;
034    import com.liferay.portal.kernel.patcher.PatcherUtil;
035    import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil;
036    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
037    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.DistributedRegistry;
038    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.MatchType;
039    import com.liferay.portal.kernel.search.IndexerRegistry;
040    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
041    import com.liferay.portal.kernel.service.ClassNameLocalServiceUtil;
042    import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
043    import com.liferay.portal.kernel.util.GetterUtil;
044    import com.liferay.portal.kernel.util.ReleaseInfo;
045    import com.liferay.portal.kernel.util.StringPool;
046    import com.liferay.portal.kernel.util.StringUtil;
047    import com.liferay.portal.kernel.util.Validator;
048    import com.liferay.portal.kernel.util.WebKeys;
049    import com.liferay.portal.plugin.PluginPackageIndexer;
050    import com.liferay.portal.tools.DBUpgrader;
051    import com.liferay.portal.util.PropsValues;
052    import com.liferay.portlet.messageboards.util.MBMessageIndexer;
053    import com.liferay.registry.Registry;
054    import com.liferay.registry.RegistryUtil;
055    import com.liferay.registry.dependency.ServiceDependencyListener;
056    import com.liferay.registry.dependency.ServiceDependencyManager;
057    import com.liferay.taglib.servlet.JspFactorySwapper;
058    
059    import java.io.InputStream;
060    
061    import javax.portlet.MimeResponse;
062    import javax.portlet.PortletRequest;
063    
064    import org.apache.commons.io.IOUtils;
065    import org.apache.struts.tiles.taglib.ComponentConstants;
066    
067    /**
068     * @author Brian Wing Shun Chan
069     * @author Alexander Chow
070     * @author Raymond Aug??
071     */
072    public class StartupAction extends SimpleAction {
073    
074            @Override
075            public void run(String[] ids) throws ActionException {
076                    try {
077                            doRun(ids);
078                    }
079                    catch (RuntimeException re) {
080                            throw re;
081                    }
082                    catch (Exception e) {
083                            throw new ActionException(e);
084                    }
085            }
086    
087            protected void doRun(String[] ids) throws Exception {
088    
089                    // Print release information
090    
091                    Class<?> clazz = getClass();
092    
093                    ClassLoader classLoader = clazz.getClassLoader();
094    
095                    try (InputStream inputStream = classLoader.getResourceAsStream(
096                                    "com/liferay/portal/events/dependencies/startup.txt")) {
097    
098                            System.out.println(IOUtils.toString(inputStream));
099                    }
100    
101                    System.out.println("Starting " + ReleaseInfo.getReleaseInfo() + "\n");
102    
103                    // Installed patches
104    
105                    if (_log.isInfoEnabled() && !PatcherUtil.hasInconsistentPatchLevels()) {
106                            String installedPatches = StringUtil.merge(
107                                    PatcherUtil.getInstalledPatches(), StringPool.COMMA_AND_SPACE);
108    
109                            if (Validator.isNull(installedPatches)) {
110                                    _log.info("There are no patches installed");
111                            }
112                            else {
113                                    _log.info(
114                                            "The following patches are installed: " + installedPatches);
115                            }
116                    }
117    
118                    // Portal resiliency
119    
120                    ServiceDependencyManager portalResiliencyServiceDependencyManager =
121                            new ServiceDependencyManager();
122    
123                    portalResiliencyServiceDependencyManager.addServiceDependencyListener(
124                            new PortalResiliencyServiceDependencyLister());
125    
126                    portalResiliencyServiceDependencyManager.registerDependencies(
127                            MessageBus.class, PortalExecutorManager.class);
128    
129                    // Shutdown hook
130    
131                    if (_log.isDebugEnabled()) {
132                            _log.debug("Add shutdown hook");
133                    }
134    
135                    Runtime runtime = Runtime.getRuntime();
136    
137                    runtime.addShutdownHook(new Thread(new ShutdownHook()));
138    
139                    // Indexers
140    
141                    ServiceDependencyManager indexerRegistryServiceDependencyManager =
142                            new ServiceDependencyManager();
143    
144                    indexerRegistryServiceDependencyManager.addServiceDependencyListener(
145                            new ServiceDependencyListener() {
146    
147                                    @Override
148                                    public void dependenciesFulfilled() {
149                                            IndexerRegistryUtil.register(new MBMessageIndexer());
150                                            IndexerRegistryUtil.register(new PluginPackageIndexer());
151                                    }
152    
153                                    @Override
154                                    public void destroy() {
155                                    }
156    
157                            });
158    
159                    indexerRegistryServiceDependencyManager.registerDependencies(
160                            IndexerRegistry.class);
161    
162                    // MySQL version
163    
164                    DB db = DBManagerUtil.getDB();
165    
166                    if ((db.getDBType() == DBType.MYSQL) &&
167                            GetterUtil.getFloat(db.getVersionString()) < 5.6F) {
168    
169                            _log.error(
170                                    "Please upgrade to at least MySQL 5.6.4. The portal no " +
171                                            "longer supports older versions of MySQL.");
172    
173                            System.exit(1);
174                    }
175    
176                    // Check required build number
177    
178                    if (_log.isDebugEnabled()) {
179                            _log.debug("Check required build number");
180                    }
181    
182                    DBUpgrader.checkRequiredBuildNumber(ReleaseInfo.getParentBuildNumber());
183    
184                    // Check class names
185    
186                    if (_log.isDebugEnabled()) {
187                            _log.debug("Check class names");
188                    }
189    
190                    ClassNameLocalServiceUtil.checkClassNames();
191    
192                    // Check resource actions
193    
194                    if (_log.isDebugEnabled()) {
195                            _log.debug("Check resource actions");
196                    }
197    
198                    ResourceActionLocalServiceUtil.checkResourceActions();
199    
200                    // Verify
201    
202                    if (_log.isDebugEnabled()) {
203                            _log.debug("Verify database");
204                    }
205    
206                    DBUpgrader.verify();
207    
208                    // Liferay JspFactory
209    
210                    JspFactorySwapper.swap();
211    
212                    // Jericho
213    
214                    CachedLoggerProvider.install();
215            }
216    
217            private static final Log _log = LogFactoryUtil.getLog(StartupAction.class);
218    
219            private static class PortalResiliencyServiceDependencyLister
220                    implements ServiceDependencyListener {
221    
222                    @Override
223                    public void dependenciesFulfilled() {
224                            Registry registry = RegistryUtil.getRegistry();
225    
226                            MessageBus messageBus = registry.getService(MessageBus.class);
227    
228                            try {
229                                    DistributedRegistry.registerDistributed(
230                                            ComponentConstants.COMPONENT_CONTEXT, Direction.DUPLEX,
231                                            MatchType.POSTFIX);
232                                    DistributedRegistry.registerDistributed(
233                                            MimeResponse.MARKUP_HEAD_ELEMENT, Direction.DUPLEX,
234                                            MatchType.EXACT);
235                                    DistributedRegistry.registerDistributed(
236                                            PortletRequest.LIFECYCLE_PHASE, Direction.DUPLEX,
237                                            MatchType.EXACT);
238                                    DistributedRegistry.registerDistributed(WebKeys.class);
239    
240                                    Intraband intraband = MPIHelperUtil.getIntraband();
241    
242                                    intraband.registerDatagramReceiveHandler(
243                                            SystemDataType.MAILBOX.getValue(),
244                                            new MailboxDatagramReceiveHandler());
245    
246                                    intraband.registerDatagramReceiveHandler(
247                                            SystemDataType.MESSAGE.getValue(),
248                                            new MessageDatagramReceiveHandler(messageBus));
249    
250                                    intraband.registerDatagramReceiveHandler(
251                                            SystemDataType.PROXY.getValue(),
252                                            new IntrabandProxyDatagramReceiveHandler());
253    
254                                    intraband.registerDatagramReceiveHandler(
255                                            SystemDataType.RPC.getValue(),
256                                            new RPCDatagramReceiveHandler());
257    
258                                    if (PropsValues.PORTAL_FABRIC_ENABLED) {
259                                            FabricServerUtil.start();
260                                    }
261                            }
262                            catch (Exception e) {
263                                    throw new IllegalStateException(
264                                            "Unable to initialize portal resiliency", e);
265                            }
266                    }
267    
268                    @Override
269                    public void destroy() {
270                    }
271    
272            }
273    
274    }