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