001
014
015 package com.liferay.portal.tools;
016
017 import com.liferay.portal.dao.orm.common.SQLTransformer;
018 import com.liferay.portal.events.StartupHelperUtil;
019 import com.liferay.portal.kernel.cache.CacheRegistryUtil;
020 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
021 import com.liferay.portal.kernel.dao.db.DB;
022 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
023 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
024 import com.liferay.portal.kernel.exception.PortalException;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.model.Release;
028 import com.liferay.portal.kernel.model.ReleaseConstants;
029 import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle;
030 import com.liferay.portal.kernel.service.ClassNameLocalServiceUtil;
031 import com.liferay.portal.kernel.service.ReleaseLocalServiceUtil;
032 import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
033 import com.liferay.portal.kernel.util.ReleaseInfo;
034 import com.liferay.portal.kernel.util.StringBundler;
035 import com.liferay.portal.kernel.util.Time;
036 import com.liferay.portal.transaction.TransactionsUtil;
037 import com.liferay.portal.util.InitUtil;
038 import com.liferay.portal.util.PropsValues;
039 import com.liferay.registry.Registry;
040 import com.liferay.registry.RegistryUtil;
041 import com.liferay.registry.ServiceRegistrar;
042 import com.liferay.util.dao.orm.CustomSQLUtil;
043
044 import java.sql.Connection;
045 import java.sql.Date;
046 import java.sql.PreparedStatement;
047 import java.sql.ResultSet;
048
049 import java.util.HashMap;
050 import java.util.Map;
051
052 import org.apache.commons.lang.time.StopWatch;
053
054
058 public class DBUpgrader {
059
060 public static void checkRequiredBuildNumber(int requiredBuildNumber)
061 throws PortalException {
062
063 int buildNumber = ReleaseLocalServiceUtil.getBuildNumberOrCreate();
064
065 if (buildNumber > ReleaseInfo.getParentBuildNumber()) {
066 StringBundler sb = new StringBundler(6);
067
068 sb.append("Attempting to deploy an older Liferay Portal version. ");
069 sb.append("Current build number is ");
070 sb.append(buildNumber);
071 sb.append(" and attempting to deploy number ");
072 sb.append(ReleaseInfo.getParentBuildNumber());
073 sb.append(".");
074
075 throw new IllegalStateException(sb.toString());
076 }
077 else if (buildNumber < requiredBuildNumber) {
078 String msg =
079 "You must first upgrade to Liferay Portal " +
080 requiredBuildNumber;
081
082 System.out.println(msg);
083
084 throw new RuntimeException(msg);
085 }
086 }
087
088 public static void main(String[] args) {
089 try {
090 StopWatch stopWatch = new StopWatch();
091
092 stopWatch.start();
093
094 InitUtil.initWithSpring(true, false);
095
096 upgrade();
097 verify();
098
099 InitUtil.registerContext();
100
101 Registry registry = RegistryUtil.getRegistry();
102
103 Map<String, Object> properties = new HashMap<>();
104
105 properties.put("module.service.lifecycle", "portal.initialized");
106 properties.put("service.vendor", ReleaseInfo.getVendor());
107 properties.put("service.version", ReleaseInfo.getVersion());
108
109 registry.registerService(
110 ModuleServiceLifecycle.class, new ModuleServiceLifecycle() {},
111 properties);
112
113 System.out.println(
114 "\nCompleted Liferay core upgrade and verify processes in " +
115 (stopWatch.getTime() / Time.SECOND) + " seconds");
116
117 System.out.println(
118 "Running modules upgrades. Connect to Gogo shell to check " +
119 "the status.");
120 }
121 catch (Exception e) {
122 e.printStackTrace();
123
124 System.exit(1);
125 }
126 }
127
128 public static void upgrade() throws Exception {
129
130
131
132 if (_log.isDebugEnabled()) {
133 _log.debug("Disable cache registry");
134 }
135
136 CacheRegistryUtil.setActive(false);
137
138
139
140 checkRequiredBuildNumber(ReleaseInfo.RELEASE_5_2_3_BUILD_NUMBER);
141
142
143
144 int buildNumber = ReleaseLocalServiceUtil.getBuildNumberOrCreate();
145
146 if (_log.isDebugEnabled()) {
147 _log.debug("Update build " + buildNumber);
148 }
149
150 _checkPermissionAlgorithm();
151 _checkReleaseState(_getReleaseState());
152
153 if (PropsValues.UPGRADE_DATABASE_TRANSACTIONS_DISABLED) {
154 TransactionsUtil.disableTransactions();
155 }
156
157 try {
158 StartupHelperUtil.upgradeProcess(buildNumber);
159 }
160 catch (Exception e) {
161 _updateReleaseState(ReleaseConstants.STATE_UPGRADE_FAILURE);
162
163 throw e;
164 }
165 finally {
166 if (PropsValues.UPGRADE_DATABASE_TRANSACTIONS_DISABLED) {
167 TransactionsUtil.enableTransactions();
168 }
169 }
170
171
172
173 CustomSQLUtil.reloadCustomSQL();
174 SQLTransformer.reloadSQLTransformer();
175
176
177
178 if (StartupHelperUtil.isUpgraded()) {
179 if (_log.isDebugEnabled()) {
180 _log.debug("Update company key");
181 }
182
183 _updateCompanyKey();
184 }
185
186
187
188 if (_log.isDebugEnabled()) {
189 _log.debug("Check class names");
190 }
191
192 ClassNameLocalServiceUtil.checkClassNames();
193
194
195
196 if (_log.isDebugEnabled()) {
197 _log.debug("Check resource actions");
198 }
199
200 ResourceActionLocalServiceUtil.checkResourceActions();
201
202
203
204 if (_log.isDebugEnabled()) {
205 _log.debug("Clear cache if upgrade process was run");
206 }
207
208 if (StartupHelperUtil.isUpgraded()) {
209 MultiVMPoolUtil.clear();
210 }
211 }
212
213 public static void verify() throws Exception {
214
215
216
217 Release release = ReleaseLocalServiceUtil.fetchRelease(
218 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
219
220 if (release == null) {
221 release = ReleaseLocalServiceUtil.addRelease(
222 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME,
223 ReleaseInfo.getParentBuildNumber());
224 }
225
226 _checkReleaseState(release.getState());
227
228
229
230 if (PropsValues.DATABASE_INDEXES_UPDATE_ON_STARTUP) {
231 StartupHelperUtil.setDropIndexes(true);
232
233 StartupHelperUtil.updateIndexes();
234 }
235 else if (StartupHelperUtil.isUpgraded()) {
236 StartupHelperUtil.updateIndexes();
237 }
238
239
240
241 if (PropsValues.VERIFY_DATABASE_TRANSACTIONS_DISABLED) {
242 TransactionsUtil.disableTransactions();
243 }
244
245 boolean newBuildNumber = false;
246
247 if (ReleaseInfo.getBuildNumber() > release.getBuildNumber()) {
248 newBuildNumber = true;
249 }
250
251 try {
252 StartupHelperUtil.verifyProcess(
253 newBuildNumber, release.isVerified());
254 }
255 catch (Exception e) {
256 _updateReleaseState(ReleaseConstants.STATE_VERIFY_FAILURE);
257
258 _log.error(
259 "Unable to execute verify process: " + e.getMessage(), e);
260
261 throw e;
262 }
263 finally {
264 if (PropsValues.VERIFY_DATABASE_TRANSACTIONS_DISABLED) {
265 TransactionsUtil.enableTransactions();
266 }
267 }
268
269
270
271 if (PropsValues.DATABASE_INDEXES_UPDATE_ON_STARTUP ||
272 StartupHelperUtil.isUpgraded()) {
273
274 StartupHelperUtil.updateIndexes(false);
275 }
276
277
278
279 boolean verified = StartupHelperUtil.isVerified();
280
281 if (release.isVerified()) {
282 verified = true;
283 }
284
285 release = ReleaseLocalServiceUtil.updateRelease(
286 release.getReleaseId(), ReleaseInfo.getVersion(),
287 ReleaseInfo.getParentBuildNumber(), ReleaseInfo.getBuildDate(),
288 verified);
289
290
291
292 CacheRegistryUtil.setActive(true);
293
294
295
296 Registry registry = RegistryUtil.getRegistry();
297
298 ServiceRegistrar<Release> serviceRegistrar =
299 registry.getServiceRegistrar(Release.class);
300
301 Map<String, Object> properties = new HashMap<>();
302
303 properties.put("build.date", release.getBuildDate());
304 properties.put("build.number", release.getBuildNumber());
305 properties.put("servlet.context.name", release.getServletContextName());
306
307 serviceRegistrar.registerService(Release.class, release, properties);
308 }
309
310 private static void _checkPermissionAlgorithm() throws Exception {
311 long count = _getResourceCodesCount();
312
313 if (count == 0) {
314 return;
315 }
316
317 StringBundler sb = new StringBundler(8);
318
319 sb.append("Permission conversion to algorithm 6 has not been ");
320 sb.append("completed. Please complete the conversion prior to ");
321 sb.append("starting the portal. The conversion process is available ");
322 sb.append("in portal versions starting with ");
323 sb.append(ReleaseInfo.RELEASE_5_2_3_BUILD_NUMBER);
324 sb.append(" and prior to ");
325 sb.append(ReleaseInfo.RELEASE_6_2_0_BUILD_NUMBER);
326 sb.append(".");
327
328 throw new IllegalStateException(sb.toString());
329 }
330
331 private static void _checkReleaseState(int state) throws Exception {
332 if (state == ReleaseConstants.STATE_GOOD) {
333 return;
334 }
335
336 StringBundler sb = new StringBundler(6);
337
338 sb.append("The database contains changes from a previous upgrade ");
339 sb.append("attempt that failed. Please restore the old database and ");
340 sb.append("file system and retry the upgrade. A patch may be ");
341 sb.append("required if the upgrade failed due to a bug or an ");
342 sb.append("unforeseen data permutation that resulted from a corrupt ");
343 sb.append("database.");
344
345 throw new IllegalStateException(sb.toString());
346 }
347
348 private static int _getReleaseState() throws Exception {
349 Connection con = null;
350 PreparedStatement ps = null;
351 ResultSet rs = null;
352
353 try {
354 con = DataAccess.getConnection();
355
356 ps = con.prepareStatement(
357 "select state_ from Release_ where releaseId = ?");
358
359 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
360
361 rs = ps.executeQuery();
362
363 if (rs.next()) {
364 return rs.getInt("state_");
365 }
366
367 throw new IllegalArgumentException(
368 "No Release exists with the primary key " +
369 ReleaseConstants.DEFAULT_ID);
370 }
371 finally {
372 DataAccess.cleanUp(con, ps, rs);
373 }
374 }
375
376 private static long _getResourceCodesCount() throws Exception {
377 Connection con = null;
378 PreparedStatement ps = null;
379 ResultSet rs = null;
380
381 try {
382 con = DataAccess.getConnection();
383
384 ps = con.prepareStatement("select count(*) from ResourceCode");
385
386 rs = ps.executeQuery();
387
388 if (rs.next()) {
389 int count = rs.getInt(1);
390
391 return count;
392 }
393
394 return 0;
395 }
396 catch (Exception e) {
397 return 0;
398 }
399 finally {
400 DataAccess.cleanUp(con, ps, rs);
401 }
402 }
403
404 private static void _updateCompanyKey() throws Exception {
405 DB db = DBManagerUtil.getDB();
406
407 db.runSQL("update Company set key_ = null");
408 }
409
410 private static void _updateReleaseState(int state) throws Exception {
411 Connection con = null;
412 PreparedStatement ps = null;
413
414 try {
415 con = DataAccess.getConnection();
416
417 ps = con.prepareStatement(
418 "update Release_ set modifiedDate = ?, state_ = ? where " +
419 "releaseId = ?");
420
421 ps.setDate(1, new Date(System.currentTimeMillis()));
422 ps.setInt(2, state);
423 ps.setLong(3, ReleaseConstants.DEFAULT_ID);
424
425 ps.executeUpdate();
426 }
427 finally {
428 DataAccess.cleanUp(con, ps);
429 }
430 }
431
432 private static final Log _log = LogFactoryUtil.getLog(DBUpgrader.class);
433
434 }