/** * EasySOA Registry * Copyright 2011-2013 Open Wide * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact : easysoa-dev@googlegroups.com */ package org.easysoa.registry.types.listeners; import java.util.List; import org.apache.log4j.Logger; import org.easysoa.registry.DocumentService; import org.easysoa.registry.types.ResourceDownloadInfo; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; import org.nuxeo.ecm.core.api.repository.RepositoryManager; import org.nuxeo.ecm.core.event.Event; import org.nuxeo.ecm.core.event.EventBundle; import org.nuxeo.ecm.core.event.EventContext; import org.nuxeo.ecm.core.event.PostCommitEventListener; import org.nuxeo.runtime.api.Framework; /** * Listens to periodic custom refreshResources event (to be scheduled) to trigger * refresh of (obviously live) Resources that are encompassed within the NXQL * criteria provided as eventCategory of said schedule. * * To use it, configure such a schedule in a contribution, ex. : * <extension point="schedule" target="org.nuxeo.ecm.core.scheduler.SchedulerService"> <schedule id="refreshResources_MyProject/Deploiement"> <event>refreshResources</event> <!-- refresh all Resources of said subproject --> <!-- eventCategory>spnode:subproject='/default-domain/MyProject/Realisation_v'</eventCategory --> <!-- refresh all Resources of said Project's Subprojects --> <eventCategory>spnode:subproject LIKE '/default-domain/MyProject/%_v'</eventCategory> <!-- refresh every night at 3 am --> <cronExpression>0 3 * * * ?</cronExpression> </schedule> </extension> * * Must be triggered in async (which requires to implement PostCommitEventListener * and postCommit="true", see EventListenerDescriptor.java) manner by Nuxeo's event system, see * http://doc.nuxeo.com/display/NXDOC/Events+and+Listeners * (though it might also be called synchronously) * * Should be registered with async & postCommit on event : readyToDownload fired by AsyncResourceUpdateServiceImpl * * @author mdutoo */ public class RefreshResourcesListener extends EventListenerBase implements PostCommitEventListener { public static final String REFRESH_RESOURCES_EVENT = "refreshResources"; private static Logger logger = Logger.getLogger(RefreshResourcesListener.class); /** * Simplistic async / postcommit impl that dispatches to handleEvent(event) * @param events * @throws ClientException */ @Override public void handleEvent(EventBundle events) throws ClientException { for (Event event : events) { try { this.handleEvent(event); } catch (Exception e) { // TODO transaction ?! logger.error("Error", e); } } } @Override public void handleEvent(Event event) throws ClientException { // NB. not checking event because only registered on refreshResources EventContext context = event.getContext(); // NB. context is not an instanceof DocumentEventContext //String subprojectIdLikePattern = (String) context.getProperty("eventCategory"); final String nxqlCriteria = (String) context.getProperty("eventCategory"); RepositoryManager mgr; try { mgr = Framework.getService(RepositoryManager.class); } catch (Exception ex) { throw new ClientException("Cannot get RepositoryManager", ex); } new UnrestrictedSessionRunner(mgr.getDefaultRepository().getName()) { @Override public void run() throws ClientException { doRefreshResources(this.session, nxqlCriteria); } }.runUnrestricted(); } protected void doRefreshResources(CoreSession session, String nxqlCriteria) throws ClientException { DocumentService documentService; try { documentService = Framework.getService(DocumentService.class); } catch (Exception ex) { throw new ClientException("Cannot get DocumentService", ex); } List<DocumentModel> resourceModels = documentService.query(session, DocumentService.NXQL_SELECT_FROM + "Document" + DocumentService.NXQL_WHERE + "ecm:mixinType='" + ResourceDownloadInfo.FACET_RESOURCEDOWNLOADINFO + "'" + DocumentService.NXQL_AND //+ SubprojectNode.XPATH_SUBPROJECT + " LIKE '" + subprojetIdPattern + "'", + nxqlCriteria, true, false); for (DocumentModel resourceModel : resourceModels) { if (resourceModel.isVersion()) { continue; // obviously can't work on versions } // reset timestamp, which will trigger redownload when ResourceListener listens to change : resourceModel.setPropertyValue(ResourceDownloadInfo.XPATH_TIMESTAMP, null); session.saveDocument(resourceModel); // TODO what if fails : don't block next ones ! restore timestamp, using exception // handling / transaction / rollback ? if possible per Resource ? explicit download ? // (NB. according to nuxeo wiki, the whole async listener is done in its own tx) } session.save(); } }