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.test.listeners;
016    
017    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
018    import com.liferay.portal.kernel.cache.Lifecycle;
019    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
020    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
021    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.search.SearchEngineUtil;
025    import com.liferay.portal.kernel.search.SearchException;
026    import com.liferay.portal.kernel.test.AbstractExecutionTestListener;
027    import com.liferay.portal.kernel.test.TestContext;
028    import com.liferay.portal.kernel.util.FileUtil;
029    import com.liferay.portal.kernel.util.PropsKeys;
030    import com.liferay.portal.kernel.util.SystemProperties;
031    import com.liferay.portal.log.Log4JLoggerTestUtil;
032    import com.liferay.portal.test.jdbc.ResetDatabaseUtil;
033    import com.liferay.portal.upgrade.util.Table;
034    import com.liferay.portal.util.PortalInstances;
035    import com.liferay.portal.util.PropsUtil;
036    import com.liferay.portal.util.PropsValues;
037    
038    import java.io.File;
039    import java.io.IOException;
040    
041    import java.util.Arrays;
042    import java.util.HashMap;
043    import java.util.LinkedList;
044    import java.util.Map;
045    import java.util.Queue;
046    
047    import org.apache.log4j.Level;
048    
049    /**
050     * @author Shuyang Zhou
051     */
052    public class ResetDatabaseExecutionTestListener
053            extends AbstractExecutionTestListener {
054    
055            @Override
056            public void runAfterTest(TestContext testContext) {
057                    restoreDLStores(false);
058                    restoreSearchIndices(false);
059    
060                    ResetDatabaseUtil.resetModifiedTables();
061    
062                    Log4JLoggerTestUtil.setLoggerLevel(Table.class.getName(), _level);
063    
064                    CacheRegistryUtil.clear();
065                    SingleVMPoolUtil.clear();
066                    MultiVMPoolUtil.clear();
067    
068                    ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);
069            }
070    
071            @Override
072            public void runBeforeClass(TestContext testContext) {
073                    _level = Log4JLoggerTestUtil.setLoggerLevel(
074                            Table.class.getName(), Level.WARN);
075    
076                    try {
077                            if (ResetDatabaseUtil.initialize()) {
078                                    backupDLStores(true);
079                                    backupSearchIndices(true);
080                            }
081                            else {
082                                    restoreDLStores(true);
083                                    restoreSearchIndices(true);
084                            }
085                    }
086                    finally {
087                            Log4JLoggerTestUtil.setLoggerLevel(Table.class.getName(), _level);
088                    }
089            }
090    
091            @Override
092            public void runBeforeTest(TestContext testContext) {
093                    _level = Log4JLoggerTestUtil.setLoggerLevel(
094                            Table.class.getName(), Level.WARN);
095    
096                    ResetDatabaseUtil.startRecording();
097    
098                    backupDLStores(false);
099                    backupSearchIndices(false);
100            }
101    
102            protected void backupDLStores(boolean initialize) {
103                    String dlFileSystemStoreDirName = null;
104    
105                    if (initialize) {
106                            dlFileSystemStoreDirName =
107                                    SystemProperties.get(SystemProperties.TMP_DIR) +
108                                            "/temp-init-dl-file-system-" + System.currentTimeMillis();
109    
110                            _initializedDLFileSystemStoreDirName = dlFileSystemStoreDirName;
111    
112                            Runtime runtime = Runtime.getRuntime();
113    
114                            runtime.addShutdownHook(
115                                    new DeleteFileShutdownHook(dlFileSystemStoreDirName));
116                    }
117                    else {
118                            dlFileSystemStoreDirName =
119                                    SystemProperties.get(SystemProperties.TMP_DIR) +
120                                            "/temp-dl-file-system-" + System.currentTimeMillis();
121    
122                            _dlFileSystemStoreDirName = dlFileSystemStoreDirName;
123                    }
124    
125                    try {
126                            FileUtil.copyDirectory(
127                                    new File(PropsValues.DL_STORE_FILE_SYSTEM_ROOT_DIR),
128                                    new File(dlFileSystemStoreDirName));
129                    }
130                    catch (IOException ioe) {
131                            throw new RuntimeException(ioe);
132                    }
133    
134                    String dlJCRStoreDirName = null;
135    
136                    if (initialize) {
137                            dlJCRStoreDirName =
138                                    SystemProperties.get(SystemProperties.TMP_DIR) +
139                                            "/temp-init-dl-jcr-" + System.currentTimeMillis();
140    
141                            _initializedDLJCRStoreDirName = dlJCRStoreDirName;
142    
143                            Runtime runtime = Runtime.getRuntime();
144    
145                            runtime.addShutdownHook(
146                                    new DeleteFileShutdownHook(dlJCRStoreDirName));
147                    }
148                    else {
149                            dlJCRStoreDirName =
150                                    SystemProperties.get(SystemProperties.TMP_DIR) +
151                                            "/temp-dl-jcr-" + System.currentTimeMillis();
152    
153                            _dlJCRStoreDirName = dlJCRStoreDirName;
154                    }
155    
156                    try {
157                            FileUtil.copyDirectory(
158                                    new File(
159                                            PropsUtil.get(PropsKeys.JCR_JACKRABBIT_REPOSITORY_ROOT)),
160                                    new File(dlJCRStoreDirName));
161                    }
162                    catch (IOException ioe) {
163                            throw new RuntimeException(ioe);
164                    }
165            }
166    
167            protected void backupSearchIndices(boolean initialize) {
168                    for (long companyId : PortalInstances.getCompanyIds()) {
169                            String backupName = null;
170    
171                            if (initialize) {
172                                    backupName =
173                                            "temp-init-search-" + companyId + "-" +
174                                                    System.currentTimeMillis();
175                            }
176                            else {
177                                    backupName =
178                                            "temp-search-" + companyId + "-" +
179                                                    System.currentTimeMillis();
180                            }
181    
182                            try {
183                                    String backupFileName = SearchEngineUtil.backup(
184                                            companyId, SearchEngineUtil.SYSTEM_ENGINE_ID, backupName);
185    
186                                    if (initialize) {
187                                            Runtime runtime = Runtime.getRuntime();
188    
189                                            runtime.addShutdownHook(
190                                                    new DeleteFileShutdownHook(backupFileName));
191                                    }
192                            }
193                            catch (Exception e) {
194                                    throw new RuntimeException(e);
195                            }
196                            finally {
197                                    if (initialize) {
198                                            _initializedIndexNames.put(companyId, backupName);
199                                    }
200                                    else {
201                                            _indexNames.put(companyId, backupName);
202                                    }
203                            }
204                    }
205            }
206    
207            protected void restoreDLStores(boolean initialize) {
208                    FileUtil.deltree(PropsValues.DL_STORE_FILE_SYSTEM_ROOT_DIR);
209    
210                    String dlFileSystemStoreDirName = _initializedDLFileSystemStoreDirName;
211    
212                    if (!initialize) {
213                            dlFileSystemStoreDirName = _dlFileSystemStoreDirName;
214    
215                            _dlFileSystemStoreDirName = null;
216                    }
217    
218                    FileUtil.move(
219                            new File(dlFileSystemStoreDirName),
220                            new File(PropsValues.DL_STORE_FILE_SYSTEM_ROOT_DIR));
221    
222                    FileUtil.deltree(
223                            PropsUtil.get(PropsKeys.JCR_JACKRABBIT_REPOSITORY_ROOT));
224    
225                    String dlJCRStoreDirName = _initializedDLJCRStoreDirName;
226    
227                    if (!initialize) {
228                            dlJCRStoreDirName = _dlJCRStoreDirName;
229    
230                            _dlJCRStoreDirName = null;
231                    }
232    
233                    FileUtil.move(
234                            new File(dlJCRStoreDirName),
235                            new File(PropsUtil.get(PropsKeys.JCR_JACKRABBIT_REPOSITORY_ROOT)));
236            }
237    
238            protected void restoreSearchIndices(boolean initialize) {
239                    Map<Long, String> backupFileNames = _indexNames;
240    
241                    if (initialize) {
242                            backupFileNames = _initializedIndexNames;
243                    }
244    
245                    for (Map.Entry<Long, String> entry : backupFileNames.entrySet()) {
246                            String backupFileName = entry.getValue();
247    
248                            try {
249                                    SearchEngineUtil.restore(entry.getKey(), backupFileName);
250                            }
251                            catch (Exception e) {
252                                    throw new RuntimeException(e);
253                            }
254                            finally {
255                                    if (!initialize) {
256                                            try {
257                                                    SearchEngineUtil.removeBackup(
258                                                            entry.getKey(), backupFileName);
259                                            }
260                                            catch (SearchException e) {
261                                                    if (_log.isInfoEnabled()) {
262                                                            _log.info("Unable to remove backup", e);
263                                                    }
264                                            }
265                                    }
266                            }
267                    }
268    
269                    if (!initialize) {
270                            backupFileNames.clear();
271                    }
272            }
273    
274            private static final Log _log = LogFactoryUtil.getLog(
275                    ResetDatabaseExecutionTestListener.class);
276    
277            private static String _initializedDLFileSystemStoreDirName;
278            private static String _initializedDLJCRStoreDirName;
279            private static final Map<Long, String> _initializedIndexNames =
280                    new HashMap<Long, String>();
281    
282            private String _dlFileSystemStoreDirName;
283            private String _dlJCRStoreDirName;
284            private final Map<Long, String> _indexNames = new HashMap<Long, String>();
285            private Level _level;
286    
287            private class DeleteFileShutdownHook extends Thread {
288    
289                    public DeleteFileShutdownHook(String fileName) {
290                            _fileName = fileName;
291                    }
292    
293                    @Override
294                    public void run() {
295                            File file = new File(_fileName);
296    
297                            Queue<File> queue = new LinkedList<File>();
298    
299                            queue.offer(file);
300    
301                            while ((file = queue.poll()) != null) {
302                                    if (file.isFile()) {
303                                            file.delete();
304                                    }
305                                    else if (file.isDirectory()) {
306                                            File[] files = file.listFiles();
307    
308                                            if (files.length == 0) {
309                                                    file.delete();
310                                            }
311                                            else {
312                                                    queue.addAll(Arrays.asList(files));
313                                                    queue.add(file);
314                                            }
315                                    }
316                            }
317                    }
318    
319                    private final String _fileName;
320    
321            }
322    
323    }