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.tasks;
028 import org.opends.messages.Message;
029 import org.opends.messages.MessageBuilder;
030
031 import static org.opends.server.config.ConfigConstants.*;
032 import static org.opends.server.core.DirectoryServer.getAttributeType;
033 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
034 import static org.opends.server.loggers.debug.DebugLogger.getTracer;
035
036 import java.util.List;
037
038 import org.opends.messages.TaskMessages;
039 import org.opends.server.backends.task.Task;
040 import org.opends.server.backends.task.TaskState;
041 import org.opends.server.loggers.debug.DebugTracer;
042 import org.opends.server.replication.plugin.ReplicationDomain;
043 import org.opends.server.types.Attribute;
044 import org.opends.server.types.AttributeType;
045 import org.opends.server.types.DN;
046 import org.opends.server.types.DirectoryException;
047 import org.opends.server.types.Entry;
048 import org.opends.server.types.ResultCode;
049
050 /**
051 * This class provides an implementation of a Directory Server task that can
052 * be used to import data over the replication protocol from another
053 * server hosting the same replication domain.
054 */
055 public class InitializeTask extends Task
056 {
057 /**
058 * The tracer object for the debug logger.
059 */
060 private static final DebugTracer TRACER = getTracer();
061
062 boolean isCompressed = false;
063 boolean isEncrypted = false;
064 boolean skipSchemaValidation = false;
065 String domainString = null;
066 short source;
067 ReplicationDomain domain = null;
068 TaskState initState;
069
070 // The total number of entries expected to be processed when this import
071 // will end successfully
072 long total = 0;
073
074 // The number of entries still to be processed for this import to be
075 // completed
076 long left = 0;
077
078 private Message initTaskError = null;
079
080 /**
081 * {@inheritDoc}
082 */
083 public Message getDisplayName() {
084 return TaskMessages.INFO_TASK_INITIALIZE_NAME.get();
085 }
086
087 /**
088 * {@inheritDoc}
089 */
090 @Override public void initializeTask() throws DirectoryException
091 {
092 if (TaskState.isDone(getTaskState()))
093 {
094 return;
095 }
096
097 // FIXME -- Do we need any special authorization here?
098 Entry taskEntry = getTaskEntry();
099
100 AttributeType typeDomainBase;
101 AttributeType typeSourceScope;
102
103 typeDomainBase =
104 getAttributeType(ATTR_TASK_INITIALIZE_DOMAIN_DN, true);
105 typeSourceScope =
106 getAttributeType(ATTR_TASK_INITIALIZE_SOURCE, true);
107
108 List<Attribute> attrList;
109 attrList = taskEntry.getAttribute(typeDomainBase);
110 domainString = TaskUtils.getSingleValueString(attrList);
111 DN domainDN = DN.nullDN();
112 try
113 {
114 domainDN = DN.decode(domainString);
115 }
116 catch(Exception e)
117 {
118 MessageBuilder mb = new MessageBuilder();
119 mb.append(TaskMessages.ERR_TASK_INITIALIZE_INVALID_DN.get());
120 mb.append(e.getMessage());
121 throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
122 mb.toMessage());
123 }
124
125 domain = ReplicationDomain.retrievesReplicationDomain(domainDN);
126
127 attrList = taskEntry.getAttribute(typeSourceScope);
128 String sourceString = TaskUtils.getSingleValueString(attrList);
129 source = domain.decodeSource(sourceString);
130
131 replaceAttributeValue(ATTR_TASK_INITIALIZE_LEFT, String.valueOf(0));
132 replaceAttributeValue(ATTR_TASK_INITIALIZE_DONE, String.valueOf(0));
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 protected TaskState runTask()
139 {
140 if (debugEnabled())
141 {
142 TRACER.debugInfo("InitializeTask is starting domain: %s source:%d",
143 domain.getBaseDN(), source);
144 }
145 initState = getTaskState();
146 try
147 {
148 // launch the import
149 domain.initializeFromRemote(source, this);
150
151 synchronized(initState)
152 {
153 // Waiting for the end of the job
154 while (initState == TaskState.RUNNING)
155 {
156 initState.wait(1000);
157 replaceAttributeValue(
158 ATTR_TASK_INITIALIZE_LEFT, String.valueOf(left));
159 replaceAttributeValue(
160 ATTR_TASK_INITIALIZE_DONE, String.valueOf(total-left));
161 }
162 }
163 replaceAttributeValue(ATTR_TASK_INITIALIZE_LEFT, String.valueOf(left));
164 replaceAttributeValue(
165 ATTR_TASK_INITIALIZE_DONE, String.valueOf(total-left));
166 }
167 catch(InterruptedException ie) {}
168 catch(DirectoryException de)
169 {
170 logError(de.getMessageObject());
171 initState = TaskState.STOPPED_BY_ERROR;
172 }
173
174 if (initTaskError != null)
175 logError(initTaskError);
176
177 if (debugEnabled())
178 {
179 TRACER.debugInfo("InitializeTask is ending with state:%s",
180 initState.toString());
181 }
182 return initState;
183 }
184
185 /**
186 * Set the state for the current task.
187 *
188 * @param de When the new state is different from COMPLETED_SUCCESSFULLY
189 * this is the exception that contains the cause of the failure.
190 */
191 public void updateTaskCompletionState(DirectoryException de)
192 {
193 try
194 {
195 if (de != null)
196 {
197 initTaskError = de.getMessageObject();
198 }
199 if (de == null)
200 initState = TaskState.COMPLETED_SUCCESSFULLY;
201 else
202 initState = TaskState.STOPPED_BY_ERROR;
203
204 if (debugEnabled())
205 {
206 TRACER.debugInfo("InitializeTask/setState: %s", initState);
207 }
208 synchronized (initState)
209 {
210 initState.notify();
211 }
212 }
213 catch(Exception e)
214 {}
215 }
216
217
218 /**
219 * Set the total number of entries expected to be imported.
220 * @param total The total number of entries.
221 */
222 public void setTotal(long total)
223 {
224 this.total = total;
225 }
226
227 /**
228 * Set the total number of entries still to be imported.
229 * @param left The total number of entries to be imported.
230 */
231 public void setLeft(long left)
232 {
233 this.left = left;
234 }
235 }