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
033import org.ametys.core.schedule.progression.ProgressionTrackerFactory;
034import org.ametys.runtime.i18n.I18nizableText;
035
036/**
037 * ConsistencyCheckTask
038 */
039public class ConsistencyCheckTask extends AbstractMaintenanceTask implements ConsistencyCheckListener
040{
041    /** The JCR Session bound to this task. */
042    protected Session _session;
043
044    private List<IterablePersistenceManager> _pmList;
045
046    @Override
047    protected void initialize() throws RepositoryException
048    {
049        // Create the repository and log in the session.
050        RepositoryContext repositoryContext = createRepositoryContext();
051        _session = repositoryContext.getRepository().login(new SimpleCredentials("__MAINTENANCE_TASK__", "".toCharArray()));
052
053        _pmList = getAllPersistenceManager(repositoryContext);
054
055        // Initialize the task progress object.
056        int count = 0; // number of item that will be scanned.
057
058        try
059        {
060            for (IterablePersistenceManager pm : _pmList)
061            {
062                count += pm.getAllNodeIds(null, 0).size();
063            }
064            
065            _progress = ProgressionTrackerFactory.createContainerProgressionTracker(new I18nizableText("plugin.repositoryapp", "PLUGINS_REPOSITORYAPP_BUTTON_MAINTENANCE_CONSISTENCYCHECK"), _logger);
066            // count for the number of nodes, plus 1 for closing the task
067            _progress.setSize(count + 1);
068        }
069        catch (Exception e)
070        {
071            _progress.setSize(0);
072            _logger.error(e.getLocalizedMessage(), e);
073        }
074    }
075    
076    @Override
077    protected void setLogger()
078    {
079        setLogger(LoggerFactory.getLogger(ConsistencyCheckTask.class));
080    }
081
082    @Override
083    protected void apply() throws RepositoryException
084    {
085        for (PersistenceManager pm : _pmList)
086        {
087            // Do PM consistency check
088            if (pm instanceof AbstractBundlePersistenceManager abpm)
089            {
090                // Perform the check
091                // null -> all uuids, true -> recursive, false -> nofix, null, 
092                // lost+found -> null, this -> listener 
093                ConsistencyReport report = abpm.check(null, true, false, null, this);
094                int numberOfNodesChecked = report.getNodeCount();
095                
096                _logger.info("Consistency check done for persistence manager : '" + pm.toString() + "' in " + (report.getElapsedTimeMs() / 1000f) + " s.");
097                _logger.info(numberOfNodesChecked + " nodes were checked.");
098                _logger.info(report.getItems().isEmpty() ? "No consistency problems were reported." : report.getItems().size() + " consistency problems were reported."); 
099                
100                _progress.increment(numberOfNodesChecked);
101            }
102        }
103    }
104
105    @Override
106    protected void close()
107    {
108        if (_session != null)
109        {
110            _session.logout();
111        }
112        
113        // We need to close the session before shuting the repository down
114        super.close();
115        
116        if (_progress != null)
117        {
118            _progress.increment();
119        }
120    }
121
122    // Listener methods 
123
124    @Override
125    public void startCheck(String id)
126    {
127        // Do Nothing
128    }
129
130    @Override
131    public void report(ReportItem item)
132    {
133        _logger.warn(item.toString());
134    }
135
136    @Override
137    public void error(String id, String message)
138    {
139        _logger.error("error during the consistency check -> id : [ " + id + "]\n" + message);
140    }
141
142    @Override
143    public void info(String id, String message)
144    {
145        _logger.info("error during the consistency check -> id : [ " + id + "]\n" + message);
146    }
147}