001/* 002 * (C) Copyright 2007-2010 Nuxeo SA (http://nuxeo.com/) and others. 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 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.scheduler; 020 021import java.io.Serializable; 022import java.util.HashMap; 023import java.util.Map; 024 025import javax.security.auth.login.LoginException; 026 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.nuxeo.ecm.core.api.impl.UserPrincipal; 030import org.nuxeo.ecm.core.event.Event; 031import org.nuxeo.ecm.core.event.EventContext; 032import org.nuxeo.ecm.core.event.EventService; 033import org.nuxeo.ecm.core.event.impl.EventContextImpl; 034import org.nuxeo.ecm.core.event.impl.EventImpl; 035import org.nuxeo.runtime.api.Framework; 036import org.nuxeo.runtime.api.login.LoginAs; 037import org.nuxeo.runtime.api.login.NuxeoLoginContext; 038import org.nuxeo.runtime.transaction.TransactionHelper; 039import org.quartz.Job; 040import org.quartz.JobDataMap; 041import org.quartz.JobExecutionContext; 042import org.quartz.JobExecutionException; 043 044/** 045 * A Quartz job whose execution sends a configured event. 046 */ 047public class EventJob implements Job { 048 049 private static final Log log = LogFactory.getLog(EventJob.class); 050 051 /** 052 * Job execution to send the configured event. 053 */ 054 @Override 055 public void execute(JobExecutionContext context) throws JobExecutionException { 056 JobDataMap dataMap = context.getJobDetail().getJobDataMap(); 057 058 // switch to the Nuxeo classloader so that the event listeners 059 // work as usual 060 061 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 062 ClassLoader nuxeoCL = getClass().getClassLoader(); 063 Thread.currentThread().setContextClassLoader(nuxeoCL); 064 try { 065 execute(dataMap); 066 } catch (LoginException e) { 067 String eventId = dataMap.getString("eventId"); 068 log.error("Error while processing scheduled event id: " + eventId, e); 069 } finally { 070 Thread.currentThread().setContextClassLoader(oldCL); 071 } 072 } 073 074 protected void execute(JobDataMap dataMap) throws LoginException { 075 String eventId = dataMap.getString("eventId"); 076 String eventCategory = dataMap.getString("eventCategory"); 077 String username = dataMap.getString("username"); 078 079 SchedulerService scheduler = Framework.getService(SchedulerService.class); 080 if (scheduler == null || !scheduler.hasApplicationStarted()) { 081 // too early 082 return; 083 } 084 085 EventService eventService = Framework.getService(EventService.class); 086 if (eventService == null) { 087 log.error("Cannot find EventService"); 088 return; 089 } 090 091 try (NuxeoLoginContext loginContext = loginSystemOrUser(username)) { 092 // set up event context 093 UserPrincipal principal = new UserPrincipal(username, null, false, false); 094 EventContext eventContext = new EventContextImpl(null, principal); 095 eventContext.setProperty("category", eventCategory); 096 eventContext.setProperties(getWrappedMap(dataMap)); 097 Event event = new EventImpl(eventId, eventContext); 098 099 // start transaction 100 boolean tx = TransactionHelper.startTransaction(); 101 102 // send event 103 log.debug("Sending scheduled event id=" + eventId + ", category=" + eventCategory + ", username=" 104 + username); 105 boolean ok = false; 106 try { 107 eventService.fireEvent(event); 108 ok = true; 109 } finally { 110 if (tx) { 111 if (!ok) { 112 TransactionHelper.setTransactionRollbackOnly(); 113 } 114 TransactionHelper.commitOrRollbackTransaction(); 115 } 116 } 117 } 118 } 119 120 protected NuxeoLoginContext loginSystemOrUser(String username) throws LoginException { 121 if (username == null) { 122 return Framework.loginSystem(); 123 } else { 124 if (Framework.getService(LoginAs.class) != null) { 125 return Framework.loginUser(username); 126 } else if (!Framework.isTestModeSet()) { 127 log.error("LoginAs service not available"); 128 } 129 return null; 130 } 131 } 132 133 /** 134 * @return a plain map from a JobDataMap object 135 * @since 7.10 136 */ 137 private Map<String, Serializable> getWrappedMap(JobDataMap jobMap) { 138 Map<String, Serializable> map = new HashMap<>(); 139 for (String key : jobMap.getKeys()) { 140 map.put(key, (Serializable) jobMap.get(key)); 141 } 142 return map; 143 } 144 145}