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