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