001/*
002*  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013*  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.workspaces.repository.maintenance;
017
018import java.util.List;
019
020import javax.jcr.RepositoryException;
021import javax.jcr.Session;
022import javax.jcr.SimpleCredentials;
023
024import org.apache.jackrabbit.core.RepositoryContext;
025import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
026import org.apache.jackrabbit.core.persistence.PersistenceManager;
027import org.apache.jackrabbit.core.persistence.bundle.AbstractBundlePersistenceManager;
028import org.apache.jackrabbit.core.persistence.check.ConsistencyCheckListener;
029import org.apache.jackrabbit.core.persistence.check.ConsistencyReport;
030import org.apache.jackrabbit.core.persistence.check.ReportItem;
031import org.slf4j.LoggerFactory;
032
033/**
034 * ConsistencyCheckTask
035 */
036public class ConsistencyCheckTask extends AbstractMaintenanceTask implements ConsistencyCheckListener
037{
038    /** The JCR Session bound to this task. */
039    protected Session _session;
040
041    private List<IterablePersistenceManager> _pmList;
042
043    @Override
044    protected void initialize() throws RepositoryException
045    {
046        // Create the repository and log in the session.
047        RepositoryContext repositoryContext = createRepositoryContext();
048        _session = repositoryContext.getRepository().login(new SimpleCredentials("__MAINTENANCE_TASK__", "".toCharArray()));
049
050        _pmList = getAllPersistenceManager(repositoryContext);
051
052        // Initialize the task progress object.
053        int count = 0; // number of item that will be scanned.
054
055        try
056        {
057            for (IterablePersistenceManager pm : _pmList)
058            {
059                count += pm.getAllNodeIds(null, 0).size();
060            }
061            _progress = new TaskProgress(count);
062        }
063        catch (Exception e)
064        {
065            _progress = new TaskProgress(0);
066            _progress.setInErrorState(e);
067            _logger.error(e.getLocalizedMessage(), e);
068        }
069    }
070    
071    @Override
072    protected void setLogger()
073    {
074        setLogger(LoggerFactory.getLogger(ConsistencyCheckTask.class));
075    }
076
077    @Override
078    protected void apply() throws RepositoryException
079    {
080        for (PersistenceManager pm : _pmList)
081        {
082            // Do PM consistency check
083            if (pm instanceof AbstractBundlePersistenceManager)
084            {
085                // Perform the check
086                // null -> all uuids, true -> recursive, false -> nofix, null, 
087                // lost+found -> null, this -> listener 
088                ConsistencyReport report = ((AbstractBundlePersistenceManager) pm).check(null, true, false, null, this);
089                
090                _logger.info("Consistency check done for persistence manager : '" + pm.toString() + "' in " + (report.getElapsedTimeMs() / 1000f) + " s.");
091                _logger.info(report.getNodeCount() + " nodes were checked.");
092                _logger.info(report.getItems().isEmpty() ? "No consistency problems were reported." : report.getItems().size() + " consistency problems were reported."); 
093            }
094        }
095    }
096
097    @Override
098    protected void close()
099    {
100        if (_session != null)
101        {
102            _session.logout();
103        }
104        
105        // We need to close the session before shuting the repository down
106        super.close();
107        
108        if (_progress != null)
109        {
110            _progress.progressRelativePercentage(100);
111        }
112    }
113
114    // Listener methods 
115
116    @Override
117    public void startCheck(String id)
118    {
119        if (_progress != null)
120        {
121            _progress.progress();
122        }
123    }
124
125    @Override
126    public void report(ReportItem item)
127    {
128        _logger.warn(item.toString());
129    }
130
131    @Override
132    public void error(String id, String message)
133    {
134        _logger.error("error during the consistency check -> id : [ " + id + "]\n" + message);
135    }
136
137    @Override
138    public void info(String id, String message)
139    {
140        _logger.info("error during the consistency check -> id : [ " + id + "]\n" + message);
141    }
142}