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.web.live; 017 018import java.util.HashMap; 019import java.util.Map; 020 021import javax.jcr.Repository; 022import javax.mail.MessagingException; 023 024import org.apache.avalon.framework.CascadingRuntimeException; 025import org.apache.avalon.framework.component.WrapperComponentManager; 026import org.apache.avalon.framework.context.Context; 027import org.apache.avalon.framework.context.ContextException; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.cocoon.Constants; 031import org.apache.cocoon.Processor; 032import org.apache.cocoon.components.CocoonComponentManager; 033import org.apache.cocoon.util.log.SLF4JLoggerAdapter; 034import org.apache.commons.lang.exception.ExceptionUtils; 035import org.quartz.JobExecutionContext; 036 037import org.ametys.core.util.I18nUtils; 038import org.ametys.core.util.mail.SendMailHelper; 039import org.ametys.plugins.core.impl.schedule.AbstractStaticSchedulable; 040import org.ametys.runtime.config.Config; 041import org.ametys.runtime.i18n.I18nizableText; 042import org.ametys.web.generation.GenerationEnvironment; 043 044/** 045 * Abstract schedulable for rebuilding the live workspace. 046 */ 047public abstract class AbstractRebuildLiveWorkspaceSchedulable extends AbstractStaticSchedulable 048{ 049 /** The i18n text for the subject of the error mail */ 050 protected static I18nizableText __ERROR_MAIL_SUBJECT; 051 /** The i18n text for the body of the error mail */ 052 protected static I18nizableText __ERROR_MAIL_BODY; 053 /** The cocoon environment context. */ 054 protected org.apache.cocoon.environment.Context _environmentContext; 055 /** The utils for i18n */ 056 protected I18nUtils _i18nUtils; 057 /** Component for rebuilding the live workspace */ 058 protected RebuildLiveComponent _rebuildLiveComponent; 059 /** JCR repository */ 060 protected Repository _repository; 061 062 @Override 063 public void contextualize(Context context) throws ContextException 064 { 065 super.contextualize(context); 066 _environmentContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); 067 } 068 069 @Override 070 public void service(ServiceManager manager) throws ServiceException 071 { 072 super.service(manager); 073 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 074 _rebuildLiveComponent = (RebuildLiveComponent) manager.lookup(RebuildLiveComponent.ROLE); 075 _repository = (Repository) manager.lookup(Repository.class.getName()); 076 } 077 078 @Override 079 public void execute(JobExecutionContext context) throws Exception 080 { 081 getLogger().info("Time to rebuild live workspace"); 082 083 // Create environment 084 Map<String, Object> env = _createAndEnterGenerationEnvironment(); 085 086 try 087 { 088 _doExecute(context); 089 } 090 catch (Exception e) 091 { 092 getLogger().error("Unable to rebuild live workspace", e); 093 _initializeErrorMail(context); 094 _sendErrorMail(ExceptionUtils.getStackTrace(e)); 095 throw e; 096 } 097 finally 098 { 099 _leaveGenerationEnvironment(env); 100 } 101 } 102 103 /** 104 * Executes the runnable. Implements this method for building the live. 105 * @param context the context 106 * @throws Exception if an error occured 107 */ 108 protected abstract void _doExecute(JobExecutionContext context) throws Exception; 109 110 /** 111 * Initializes {@link AbstractRebuildLiveWorkspaceSchedulable#__ERROR_MAIL_BODY} and {@link AbstractRebuildLiveWorkspaceSchedulable#__ERROR_MAIL_SUBJECT} 112 * @param context the context 113 */ 114 protected abstract void _initializeErrorMail(JobExecutionContext context); 115 116 private void _sendErrorMail (String message) 117 { 118 String recipient = Config.getInstance().getValueAsString("smtp.mail.sysadminto"); 119 String sender = Config.getInstance().getValueAsString("smtp.mail.from"); 120 try 121 { 122 String subject = _i18nUtils.translate(__ERROR_MAIL_SUBJECT); 123 124 String body = _i18nUtils.translate(__ERROR_MAIL_BODY); 125 body += "\n\n" + message; 126 127 SendMailHelper.sendMail(subject, null, body, recipient, sender); 128 } 129 catch (MessagingException e) 130 { 131 if (getLogger().isWarnEnabled()) 132 { 133 getLogger().warn("Could not send an alert e-mail to " + recipient, e); 134 } 135 } 136 } 137 138 private Map<String, Object> _createAndEnterGenerationEnvironment() 139 { 140 GenerationEnvironment environment; 141 Processor processor; 142 143 try 144 { 145 environment = new GenerationEnvironment(new SLF4JLoggerAdapter(getLogger()), _environmentContext, ""); 146 processor = (Processor) _smanager.lookup(Processor.ROLE); 147 } 148 catch (Exception e) 149 { 150 throw new CascadingRuntimeException("Error during environment's setup.", e); 151 } 152 153 Object processingKey = CocoonComponentManager.startProcessing(environment); 154 int environmentDepth = CocoonComponentManager.markEnvironment(); 155 156 CocoonComponentManager.enterEnvironment(environment, new WrapperComponentManager(_smanager), processor); 157 158 Map<String, Object> result = new HashMap<>(); 159 160 result.put("environment", environment); 161 result.put("processor", processor); 162 result.put("processingKey", processingKey); 163 result.put("environmentDepth", new Integer(environmentDepth)); 164 165 return result; 166 } 167 168 private void _leaveGenerationEnvironment(Map environmentInformation) 169 { 170 GenerationEnvironment environment = (GenerationEnvironment) environmentInformation.get("environment"); 171 Processor processor = (Processor) environmentInformation.get("processor"); 172 Object processingKey = environmentInformation.get("processingKey"); 173 int environmentDepth = ((Integer) environmentInformation.get("environmentDepth")).intValue(); 174 175 CocoonComponentManager.leaveEnvironment(); 176 CocoonComponentManager.endProcessing(environment, processingKey); 177 178 try 179 { 180 CocoonComponentManager.checkEnvironment(environmentDepth, new SLF4JLoggerAdapter(getLogger())); 181 } 182 catch (Exception e) 183 { 184 throw new CascadingRuntimeException("Error checking the environment", e); 185 } 186 187 _smanager.release(processor); 188 } 189}