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.backgroundtask.BackgroundTaskManager;
020    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskManagerUtil;
021    import com.liferay.portal.kernel.cluster.ClusterExecutor;
022    import com.liferay.portal.kernel.cluster.ClusterMasterExecutor;
023    import com.liferay.portal.kernel.dao.db.DB;
024    import com.liferay.portal.kernel.dao.db.DBManagerUtil;
025    import com.liferay.portal.kernel.dao.db.DBType;
026    import com.liferay.portal.kernel.events.ActionException;
027    import com.liferay.portal.kernel.events.SimpleAction;
028    import com.liferay.portal.kernel.executor.PortalExecutorManager;
029    import com.liferay.portal.kernel.log.Log;
030    import com.liferay.portal.kernel.log.LogFactoryUtil;
031    import com.liferay.portal.kernel.messaging.MessageBus;
032    import com.liferay.portal.kernel.nio.intraband.Intraband;
033    import com.liferay.portal.kernel.nio.intraband.SystemDataType;
034    import com.liferay.portal.kernel.nio.intraband.mailbox.MailboxDatagramReceiveHandler;
035    import com.liferay.portal.kernel.nio.intraband.messaging.MessageDatagramReceiveHandler;
036    import com.liferay.portal.kernel.nio.intraband.proxy.IntrabandProxyDatagramReceiveHandler;
037    import com.liferay.portal.kernel.nio.intraband.rpc.RPCDatagramReceiveHandler;
038    import com.liferay.portal.kernel.patcher.PatcherUtil;
039    import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil;
040    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
041    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.DistributedRegistry;
042    import com.liferay.portal.kernel.resiliency.spi.agent.annotation.MatchType;
043    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
044    import com.liferay.portal.kernel.scheduler.SchedulerLifecycle;
045    import com.liferay.portal.kernel.search.IndexerRegistry;
046    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
047    import com.liferay.portal.kernel.util.GetterUtil;
048    import com.liferay.portal.kernel.util.PortalLifecycle;
049    import com.liferay.portal.kernel.util.ReleaseInfo;
050    import com.liferay.portal.kernel.util.StringPool;
051    import com.liferay.portal.kernel.util.StringUtil;
052    import com.liferay.portal.kernel.util.Validator;
053    import com.liferay.portal.kernel.util.WebKeys;
054    import com.liferay.portal.plugin.PluginPackageIndexer;
055    import com.liferay.portal.tools.DBUpgrader;
056    import com.liferay.portal.util.PropsValues;
057    import com.liferay.portlet.messageboards.util.MBMessageIndexer;
058    import com.liferay.registry.Filter;
059    import com.liferay.registry.Registry;
060    import com.liferay.registry.RegistryUtil;
061    import com.liferay.registry.dependency.ServiceDependencyListener;
062    import com.liferay.registry.dependency.ServiceDependencyManager;
063    import com.liferay.taglib.servlet.JspFactorySwapper;
064    
065    import javax.portlet.MimeResponse;
066    import javax.portlet.PortletRequest;
067    
068    import org.apache.struts.tiles.taglib.ComponentConstants;
069    
070    /**
071     * @author Brian Wing Shun Chan
072     * @author Alexander Chow
073     * @author Raymond Aug??
074     */
075    public class StartupAction extends SimpleAction {
076    
077            @Override
078            public void run(String[] ids) throws ActionException {
079                    try {
080                            doRun(ids);
081                    }
082                    catch (RuntimeException re) {
083                            throw re;
084                    }
085                    catch (Exception e) {
086                            throw new ActionException(e);
087                    }
088            }
089    
090            protected void doRun(String[] ids) throws Exception {
091    
092                    // Print release information
093    
094                    System.out.println("Starting " + ReleaseInfo.getReleaseInfo());
095    
096                    // Installed patches
097    
098                    if (_log.isInfoEnabled() && !PatcherUtil.hasInconsistentPatchLevels()) {
099                            String installedPatches = StringUtil.merge(
100                                    PatcherUtil.getInstalledPatches(), StringPool.COMMA_AND_SPACE);
101    
102                            if (Validator.isNull(installedPatches)) {
103                                    _log.info("There are no patches installed");
104                            }
105                            else {
106                                    _log.info(
107                                            "The following patches are installed: " + installedPatches);
108                            }
109                    }
110    
111                    // Portal resiliency
112    
113                    ServiceDependencyManager portalResiliencyServiceDependencyManager =
114                            new ServiceDependencyManager();
115    
116                    portalResiliencyServiceDependencyManager.addServiceDependencyListener(
117                            new PortalResiliencyServiceDependencyLister());
118    
119                    portalResiliencyServiceDependencyManager.registerDependencies(
120                            MessageBus.class, PortalExecutorManager.class);
121    
122                    // Shutdown hook
123    
124                    if (_log.isDebugEnabled()) {
125                            _log.debug("Add shutdown hook");
126                    }
127    
128                    Runtime runtime = Runtime.getRuntime();
129    
130                    runtime.addShutdownHook(new Thread(new ShutdownHook()));
131    
132                    // Indexers
133    
134                    ServiceDependencyManager indexerRegistryServiceDependencyManager =
135                            new ServiceDependencyManager();
136    
137                    indexerRegistryServiceDependencyManager.addServiceDependencyListener(
138                            new ServiceDependencyListener() {
139    
140                                    @Override
141                                    public void dependenciesFulfilled() {
142                                            IndexerRegistryUtil.register(new MBMessageIndexer());
143                                            IndexerRegistryUtil.register(new PluginPackageIndexer());
144                                    }
145    
146                                    @Override
147                                    public void destroy() {
148                                    }
149    
150                            });
151    
152                    indexerRegistryServiceDependencyManager.registerDependencies(
153                            IndexerRegistry.class);
154    
155                    // MySQL version
156    
157                    DB db = DBManagerUtil.getDB();
158    
159                    if ((db.getDBType() == DBType.MYSQL) &&
160                            GetterUtil.getFloat(db.getVersionString()) < 5.6F) {
161    
162                            _log.error(
163                                    "Please upgrade to at least MySQL 5.6.4. The portal no " +
164                                            "longer supports older versions of MySQL.");
165    
166                            System.exit(1);
167                    }
168    
169                    // Upgrade
170    
171                    if (_log.isDebugEnabled()) {
172                            _log.debug("Upgrade database");
173                    }
174    
175                    DBUpgrader.upgrade();
176    
177                    // Scheduler
178    
179                    if (_log.isDebugEnabled()) {
180                            _log.debug("Initialize scheduler engine lifecycle");
181                    }
182    
183                    ServiceDependencyManager schedulerServiceDependencyManager =
184                            new ServiceDependencyManager();
185    
186                    schedulerServiceDependencyManager.addServiceDependencyListener(
187                            new ServiceDependencyListener() {
188    
189                                    @Override
190                                    public void dependenciesFulfilled() {
191                                            SchedulerLifecycle schedulerLifecycle =
192                                                    new SchedulerLifecycle();
193    
194                                            schedulerLifecycle.registerPortalLifecycle(
195                                                    PortalLifecycle.METHOD_INIT);
196                                    }
197    
198                                    @Override
199                                    public void destroy() {
200                                    }
201    
202                            });
203    
204                    final Registry registry = RegistryUtil.getRegistry();
205    
206                    Filter filter = registry.getFilter(
207                            "(objectClass=com.liferay.portal.scheduler.quartz.internal." +
208                                    "QuartzSchemaManager)");
209    
210                    schedulerServiceDependencyManager.registerDependencies(
211                            new Class[] {SchedulerEngineHelper.class}, new Filter[] {filter});
212    
213                    // Verify
214    
215                    if (_log.isDebugEnabled()) {
216                            _log.debug("Verify database");
217                    }
218    
219                    DBUpgrader.verify();
220    
221                    // Cluster master token listener
222    
223                    ServiceDependencyManager clusterMasterExecutorServiceDependencyManager =
224                            new ServiceDependencyManager();
225    
226                    clusterMasterExecutorServiceDependencyManager.
227                            addServiceDependencyListener(
228                                    new ServiceDependencyListener() {
229    
230                                            @Override
231                                            public void dependenciesFulfilled() {
232                                                    ClusterMasterExecutor clusterMasterExecutor =
233                                                            registry.getService(ClusterMasterExecutor.class);
234    
235                                                    if (!clusterMasterExecutor.isEnabled()) {
236                                                            BackgroundTaskManagerUtil.cleanUpBackgroundTasks();
237                                                    }
238                                            }
239    
240                                            @Override
241                                            public void destroy() {
242                                            }
243    
244                                    });
245    
246                    clusterMasterExecutorServiceDependencyManager.registerDependencies(
247                            BackgroundTaskManager.class, ClusterExecutor.class,
248                            ClusterMasterExecutor.class);
249    
250                    // Liferay JspFactory
251    
252                    JspFactorySwapper.swap();
253    
254                    // Jericho
255    
256                    CachedLoggerProvider.install();
257            }
258    
259            private static final Log _log = LogFactoryUtil.getLog(StartupAction.class);
260    
261            private class PortalResiliencyServiceDependencyLister
262                    implements ServiceDependencyListener {
263    
264                    @Override
265                    public void dependenciesFulfilled() {
266                            Registry registry = RegistryUtil.getRegistry();
267    
268                            MessageBus messageBus = registry.getService(MessageBus.class);
269    
270                            try {
271                                    DistributedRegistry.registerDistributed(
272                                            ComponentConstants.COMPONENT_CONTEXT, Direction.DUPLEX,
273                                            MatchType.POSTFIX);
274                                    DistributedRegistry.registerDistributed(
275                                            MimeResponse.MARKUP_HEAD_ELEMENT, Direction.DUPLEX,
276                                            MatchType.EXACT);
277                                    DistributedRegistry.registerDistributed(
278                                            PortletRequest.LIFECYCLE_PHASE, Direction.DUPLEX,
279                                            MatchType.EXACT);
280                                    DistributedRegistry.registerDistributed(WebKeys.class);
281    
282                                    Intraband intraband = MPIHelperUtil.getIntraband();
283    
284                                    intraband.registerDatagramReceiveHandler(
285                                            SystemDataType.MAILBOX.getValue(),
286                                            new MailboxDatagramReceiveHandler());
287    
288                                    intraband.registerDatagramReceiveHandler(
289                                            SystemDataType.MESSAGE.getValue(),
290                                            new MessageDatagramReceiveHandler(messageBus));
291    
292                                    intraband.registerDatagramReceiveHandler(
293                                            SystemDataType.PROXY.getValue(),
294                                            new IntrabandProxyDatagramReceiveHandler());
295    
296                                    intraband.registerDatagramReceiveHandler(
297                                            SystemDataType.RPC.getValue(),
298                                            new RPCDatagramReceiveHandler());
299    
300                                    if (PropsValues.PORTAL_FABRIC_ENABLED) {
301                                            FabricServerUtil.start();
302                                    }
303                            }
304                            catch (Exception e) {
305                                    throw new IllegalStateException(
306                                            "Unable to initialize portal resiliency", e);
307                            }
308                    }
309    
310                    @Override
311                    public void destroy() {
312                    }
313    
314            }
315    
316    }