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},
212                            new Filter[] {filter});
213    
214                    // Verify
215    
216                    if (_log.isDebugEnabled()) {
217                            _log.debug("Verify database");
218                    }
219    
220                    DBUpgrader.verify();
221    
222                    // Cluster master token listener
223    
224                    ServiceDependencyManager clusterMasterExecutorServiceDependencyManager =
225                            new ServiceDependencyManager();
226    
227                    clusterMasterExecutorServiceDependencyManager.
228                            addServiceDependencyListener(
229                                    new ServiceDependencyListener() {
230    
231                                            @Override
232                                            public void dependenciesFulfilled() {
233                                                    ClusterMasterExecutor clusterMasterExecutor =
234                                                            registry.getService(ClusterMasterExecutor.class);
235    
236                                                    if (!clusterMasterExecutor.isEnabled()) {
237                                                            BackgroundTaskManagerUtil.cleanUpBackgroundTasks();
238                                                    }
239                                            }
240    
241                                            @Override
242                                            public void destroy() {
243                                            }
244    
245                                    });
246    
247                    clusterMasterExecutorServiceDependencyManager.registerDependencies(
248                            BackgroundTaskManager.class, ClusterExecutor.class,
249                            ClusterMasterExecutor.class);
250    
251                    // Liferay JspFactory
252    
253                    JspFactorySwapper.swap();
254    
255                    // Jericho
256    
257                    CachedLoggerProvider.install();
258            }
259    
260            private static final Log _log = LogFactoryUtil.getLog(StartupAction.class);
261    
262            private class PortalResiliencyServiceDependencyLister
263                    implements ServiceDependencyListener {
264    
265                    @Override
266                    public void dependenciesFulfilled() {
267                            Registry registry = RegistryUtil.getRegistry();
268    
269                            MessageBus messageBus = registry.getService(MessageBus.class);
270    
271                            try {
272                                    DistributedRegistry.registerDistributed(
273                                            ComponentConstants.COMPONENT_CONTEXT, Direction.DUPLEX,
274                                            MatchType.POSTFIX);
275                                    DistributedRegistry.registerDistributed(
276                                            MimeResponse.MARKUP_HEAD_ELEMENT, Direction.DUPLEX,
277                                            MatchType.EXACT);
278                                    DistributedRegistry.registerDistributed(
279                                            PortletRequest.LIFECYCLE_PHASE, Direction.DUPLEX,
280                                            MatchType.EXACT);
281                                    DistributedRegistry.registerDistributed(WebKeys.class);
282    
283                                    Intraband intraband = MPIHelperUtil.getIntraband();
284    
285                                    intraband.registerDatagramReceiveHandler(
286                                            SystemDataType.MAILBOX.getValue(),
287                                            new MailboxDatagramReceiveHandler());
288    
289                                    intraband.registerDatagramReceiveHandler(
290                                            SystemDataType.MESSAGE.getValue(),
291                                            new MessageDatagramReceiveHandler(messageBus));
292    
293                                    intraband.registerDatagramReceiveHandler(
294                                            SystemDataType.PROXY.getValue(),
295                                            new IntrabandProxyDatagramReceiveHandler());
296    
297                                    intraband.registerDatagramReceiveHandler(
298                                            SystemDataType.RPC.getValue(),
299                                            new RPCDatagramReceiveHandler());
300    
301                                    if (PropsValues.PORTAL_FABRIC_ENABLED) {
302                                            FabricServerUtil.start();
303                                    }
304                            }
305                            catch (Exception e) {
306                                    throw new IllegalStateException(
307                                            "Unable to initialize portal resiliency", e);
308                            }
309                    }
310    
311                    @Override
312                    public void destroy() {
313                    }
314    
315            }
316    
317    }