001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.backends.task; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.Iterator; 033 import java.util.LinkedHashSet; 034 import java.util.List; 035 036 import org.opends.server.core.DirectoryServer; 037 import org.opends.server.types.Attribute; 038 import org.opends.server.types.AttributeType; 039 import org.opends.server.types.AttributeValue; 040 import org.opends.server.types.DirectoryException; 041 import org.opends.server.types.DN; 042 import org.opends.server.types.Entry; 043 import org.opends.server.types.InitializationException; 044 import org.opends.server.types.ResultCode; 045 046 import static org.opends.server.config.ConfigConstants.*; 047 import static org.opends.server.loggers.debug.DebugLogger.*; 048 import org.opends.server.loggers.debug.DebugTracer; 049 import org.opends.server.types.DebugLogLevel; 050 import static org.opends.messages.BackendMessages.*; 051 import static org.opends.server.util.StaticUtils.*; 052 053 054 055 /** 056 * This class defines a information about a recurring task, which will be used 057 * to repeatedly schedule tasks for processing. 058 */ 059 public class RecurringTask 060 { 061 /** 062 * The tracer object for the debug logger. 063 */ 064 private static final DebugTracer TRACER = getTracer(); 065 066 067 068 069 // The DN of the entry that actually defines this task. 070 private DN recurringTaskEntryDN; 071 072 // The entry that actually defines this task. 073 private Entry recurringTaskEntry; 074 075 // The unique ID for this recurring task. 076 private String recurringTaskID; 077 078 // The fully-qualified name of the class that will be used to implement the 079 // class. 080 private String taskClassName; 081 082 // The reference to the task scheduler that will be used to schedule new 083 // iterations of this recurring task. 084 private TaskScheduler taskScheduler; 085 086 087 088 /** 089 * Creates a new recurring task based on the information in the provided 090 * entry. 091 * 092 * @param taskScheduler A reference to the task scheduler that may be 093 * used to schedule new tasks. 094 * @param recurringTaskEntry The entry containing the information to use to 095 * define the task to process. 096 * 097 * @throws DirectoryException If the provided entry does not contain a valid 098 * recurring task definition. 099 */ 100 public RecurringTask(TaskScheduler taskScheduler, Entry recurringTaskEntry) 101 throws DirectoryException 102 { 103 this.taskScheduler = taskScheduler; 104 this.recurringTaskEntry = recurringTaskEntry; 105 this.recurringTaskEntryDN = recurringTaskEntry.getDN(); 106 107 108 // Get the recurring task ID from the entry. If there isn't one, then fail. 109 AttributeType attrType = DirectoryServer.getAttributeType( 110 ATTR_RECURRING_TASK_ID.toLowerCase()); 111 if (attrType == null) 112 { 113 attrType = DirectoryServer.getDefaultAttributeType( 114 ATTR_RECURRING_TASK_ID); 115 } 116 117 List<Attribute> attrList = recurringTaskEntry.getAttribute(attrType); 118 if ((attrList == null) || attrList.isEmpty()) 119 { 120 Message message = 121 ERR_RECURRINGTASK_NO_ID_ATTRIBUTE.get(ATTR_RECURRING_TASK_ID); 122 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 123 } 124 125 if (attrList.size() > 1) 126 { 127 Message message = 128 ERR_RECURRINGTASK_MULTIPLE_ID_TYPES.get(ATTR_RECURRING_TASK_ID); 129 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 130 } 131 132 Attribute attr = attrList.get(0); 133 LinkedHashSet<AttributeValue> values = attr.getValues(); 134 if ((values == null) || values.isEmpty()) 135 { 136 Message message = ERR_RECURRINGTASK_NO_ID.get(ATTR_RECURRING_TASK_ID); 137 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 138 } 139 140 Iterator<AttributeValue> iterator = values.iterator(); 141 AttributeValue value = iterator.next(); 142 if (iterator.hasNext()) 143 { 144 Message message = 145 ERR_RECURRINGTASK_MULTIPLE_ID_VALUES.get(ATTR_RECURRING_TASK_ID); 146 throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message); 147 } 148 149 recurringTaskID = value.getStringValue(); 150 151 152 // FIXME -- Need to have some method of getting the scheduling information 153 // from the recurring task entry. 154 155 156 // Get the class name from the entry. If there isn't one, then fail. 157 attrType = DirectoryServer.getAttributeType( 158 ATTR_RECURRING_TASK_CLASS_NAME.toLowerCase()); 159 if (attrType == null) 160 { 161 attrType = DirectoryServer.getDefaultAttributeType( 162 ATTR_RECURRING_TASK_CLASS_NAME); 163 } 164 165 attrList = recurringTaskEntry.getAttribute(attrType); 166 if ((attrList == null) || attrList.isEmpty()) 167 { 168 Message message = ERR_RECURRINGTASK_NO_CLASS_ATTRIBUTE.get( 169 ATTR_RECURRING_TASK_CLASS_NAME); 170 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 171 } 172 173 if (attrList.size() > 0) 174 { 175 Message message = ERR_RECURRINGTASK_MULTIPLE_CLASS_TYPES.get( 176 ATTR_RECURRING_TASK_CLASS_NAME); 177 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 178 } 179 180 attr = attrList.get(0); 181 values = attr.getValues(); 182 if ((values == null) || values.isEmpty()) 183 { 184 Message message = 185 ERR_RECURRINGTASK_NO_CLASS_VALUES.get(ATTR_RECURRING_TASK_CLASS_NAME); 186 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 187 } 188 189 iterator = values.iterator(); 190 value = iterator.next(); 191 if (iterator.hasNext()) 192 { 193 Message message = ERR_RECURRINGTASK_MULTIPLE_CLASS_VALUES.get( 194 ATTR_RECURRING_TASK_CLASS_NAME); 195 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 196 } 197 198 taskClassName = value.getStringValue(); 199 200 201 // Make sure that the specified class can be loaded. 202 Class taskClass; 203 try 204 { 205 taskClass = DirectoryServer.loadClass(taskClassName); 206 } 207 catch (Exception e) 208 { 209 if (debugEnabled()) 210 { 211 TRACER.debugCaught(DebugLogLevel.ERROR, e); 212 } 213 214 Message message = ERR_RECURRINGTASK_CANNOT_LOAD_CLASS. 215 get(String.valueOf(taskClassName), ATTR_RECURRING_TASK_CLASS_NAME, 216 getExceptionMessage(e)); 217 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message, 218 e); 219 } 220 221 222 // Make sure that the specified class can be instantiated as a task. 223 Task task; 224 try 225 { 226 task = (Task) taskClass.newInstance(); 227 } 228 catch (Exception e) 229 { 230 if (debugEnabled()) 231 { 232 TRACER.debugCaught(DebugLogLevel.ERROR, e); 233 } 234 235 Message message = ERR_RECURRINGTASK_CANNOT_INSTANTIATE_CLASS_AS_TASK.get( 236 String.valueOf(taskClassName), Task.class.getName()); 237 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message, 238 e); 239 } 240 241 242 // Make sure that we can initialize the task with the information in the 243 // provided entry. 244 try 245 { 246 task.initializeTaskInternal(taskScheduler, recurringTaskEntry); 247 } 248 catch (InitializationException ie) 249 { 250 if (debugEnabled()) 251 { 252 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 253 } 254 255 Message message = ERR_RECURRINGTASK_CANNOT_INITIALIZE_INTERNAL.get( 256 String.valueOf(taskClassName), ie.getMessage()); 257 throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), 258 message, ie); 259 } 260 261 task.initializeTask(); 262 } 263 264 265 266 /** 267 * Retrieves the unique ID assigned to this recurring task. 268 * 269 * @return The unique ID assigned to this recurring task. 270 */ 271 public String getRecurringTaskID() 272 { 273 return recurringTaskID; 274 } 275 276 277 278 /** 279 * Retrieves the DN of the entry containing the data for this recurring task. 280 * 281 * @return The DN of the entry containing the data for this recurring task. 282 */ 283 public DN getRecurringTaskEntryDN() 284 { 285 return recurringTaskEntryDN; 286 } 287 288 289 290 /** 291 * Retrieves the entry containing the data for this recurring task. 292 * 293 * @return The entry containing the data for this recurring task. 294 */ 295 public Entry getRecurringTaskEntry() 296 { 297 return recurringTaskEntry; 298 } 299 300 301 302 /** 303 * Retrieves the fully-qualified name of the Java class that provides the 304 * implementation logic for this recurring task. 305 * 306 * @return The fully-qualified name of the Java class that provides the 307 * implementation logic for this recurring task. 308 */ 309 public String getTaskClassName() 310 { 311 return taskClassName; 312 } 313 314 315 316 /** 317 * Schedules the next iteration of this recurring task for processing. 318 * 319 * @return The task that has been scheduled for processing. 320 */ 321 public Task scheduleNextIteration() 322 { 323 // NYI 324 return null; 325 } 326 } 327