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.time.ZonedDateTime; 019import java.util.HashMap; 020import java.util.Map; 021 022import javax.jcr.Repository; 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.environment.background.BackgroundEnvironment; 034import org.apache.cocoon.util.log.SLF4JLoggerAdapter; 035import org.quartz.JobDataMap; 036import org.quartz.JobExecutionContext; 037 038import org.ametys.cms.schedule.AbstractSendingMailSchedulable; 039import org.ametys.core.schedule.progression.ContainerProgressionTracker; 040import org.ametys.core.user.UserIdentity; 041import org.ametys.plugins.core.schedule.Scheduler; 042import org.ametys.runtime.servlet.RuntimeServlet; 043import org.ametys.runtime.servlet.RuntimeServlet.ForcedMainteanceInformations; 044import org.ametys.runtime.servlet.RuntimeServlet.MaintenanceStatus; 045import org.ametys.runtime.servlet.RuntimeServlet.RunMode; 046 047/** 048 * Abstract schedulable for rebuilding the live workspace. 049 */ 050public abstract class AbstractRebuildLiveWorkspaceSchedulable extends AbstractSendingMailSchedulable 051{ 052 /** The key for the maintenance mode to rebuild the live workspace */ 053 protected static final String JOBDATAMAP_MAINTENANCE_KEY = "maintenance"; 054 055 private static final String __JOBDATAMAP_MAINTENANCE_KEY = Scheduler.PARAM_VALUES_PREFIX + JOBDATAMAP_MAINTENANCE_KEY; 056 057 /** The cocoon environment context. */ 058 protected org.apache.cocoon.environment.Context _environmentContext; 059 /** Component for rebuilding the live workspace */ 060 protected RebuildLiveComponent _rebuildLiveComponent; 061 /** JCR repository */ 062 protected Repository _repository; 063 064 @Override 065 public void contextualize(Context context) throws ContextException 066 { 067 super.contextualize(context); 068 _environmentContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); 069 } 070 071 @Override 072 public void service(ServiceManager manager) throws ServiceException 073 { 074 super.service(manager); 075 _rebuildLiveComponent = (RebuildLiveComponent) manager.lookup(RebuildLiveComponent.ROLE); 076 _repository = (Repository) manager.lookup(Repository.class.getName()); 077 } 078 079 @Override 080 protected void _doExecute(JobExecutionContext context, ContainerProgressionTracker progressionTracker) throws Exception 081 { 082 getLogger().info("Time to rebuild live workspace"); 083 084 085 // Create environment 086 Map<String, Object> env = _createAndEnterGenerationEnvironment(); 087 088 JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); 089 Boolean maintenance = (Boolean) jobDataMap.get(__JOBDATAMAP_MAINTENANCE_KEY); 090 UserIdentity userIdentity = UserIdentity.stringToUserIdentity(jobDataMap.getString(Scheduler.KEY_RUNNABLE_USERIDENTITY)); 091 092 RunMode oldMode = null; 093 try 094 { 095 096 if (Boolean.TRUE.equals(maintenance)) 097 { 098 oldMode = RuntimeServlet.getRunMode(); 099 100 if (oldMode != RunMode.MAINTENANCE) 101 { 102 RuntimeServlet.setMaintenanceStatus(MaintenanceStatus.FORCED, new ForcedMainteanceInformations("", userIdentity, ZonedDateTime.now())); 103 RuntimeServlet.setRunMode(RunMode.MAINTENANCE); 104 } 105 } 106 107 _rebuildLiveWorkspace(context, progressionTracker); 108 } 109 finally 110 { 111 _leaveGenerationEnvironment(env); 112 113 if (Boolean.TRUE.equals(maintenance) && oldMode != RunMode.MAINTENANCE) 114 { 115 RuntimeServlet.setRunMode(oldMode); 116 RuntimeServlet.setMaintenanceStatus(MaintenanceStatus.NONE, null); 117 } 118 } 119 } 120 121 /** 122 * Implements this method for building the live. 123 * @param context the context 124 * @param progressionTracker The progression tracker 125 * @throws Exception if an error occurred 126 */ 127 protected abstract void _rebuildLiveWorkspace(JobExecutionContext context, ContainerProgressionTracker progressionTracker) throws Exception; 128 129 private Map<String, Object> _createAndEnterGenerationEnvironment() 130 { 131 BackgroundEnvironment environment; 132 Processor processor; 133 134 try 135 { 136 environment = new BackgroundEnvironment(new SLF4JLoggerAdapter(getLogger()), _environmentContext); 137 processor = (Processor) _smanager.lookup(Processor.ROLE); 138 } 139 catch (Exception e) 140 { 141 throw new CascadingRuntimeException("Error during environment's setup.", e); 142 } 143 144 Object processingKey = CocoonComponentManager.startProcessing(environment); 145 int environmentDepth = CocoonComponentManager.markEnvironment(); 146 147 CocoonComponentManager.enterEnvironment(environment, new WrapperComponentManager(_smanager), processor); 148 149 Map<String, Object> result = new HashMap<>(); 150 151 result.put("environment", environment); 152 result.put("processor", processor); 153 result.put("processingKey", processingKey); 154 result.put("environmentDepth", Integer.valueOf(environmentDepth)); 155 156 return result; 157 } 158 159 private void _leaveGenerationEnvironment(Map environmentInformation) 160 { 161 BackgroundEnvironment environment = (BackgroundEnvironment) environmentInformation.get("environment"); 162 Processor processor = (Processor) environmentInformation.get("processor"); 163 Object processingKey = environmentInformation.get("processingKey"); 164 int environmentDepth = ((Integer) environmentInformation.get("environmentDepth")).intValue(); 165 166 CocoonComponentManager.leaveEnvironment(); 167 CocoonComponentManager.endProcessing(environment, processingKey); 168 169 try 170 { 171 CocoonComponentManager.checkEnvironment(environmentDepth, new SLF4JLoggerAdapter(getLogger())); 172 } 173 catch (Exception e) 174 { 175 throw new CascadingRuntimeException("Error checking the environment", e); 176 } 177 178 _smanager.release(processor); 179 } 180}