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