2121import javax .inject .Inject ;
2222
2323import org .apache .cloudstack .engine .subsystem .api .storage .CommandResult ;
24+ import org .apache .cloudstack .engine .subsystem .api .storage .CopyCommandResult ;
2425import org .apache .cloudstack .engine .subsystem .api .storage .CreateCmdResult ;
2526import org .apache .cloudstack .engine .subsystem .api .storage .DataObject ;
2627import org .apache .cloudstack .engine .subsystem .api .storage .DataStore ;
2728import org .apache .cloudstack .engine .subsystem .api .storage .ImageService ;
2829import org .apache .cloudstack .engine .subsystem .api .storage .ObjectInDataStoreStateMachine ;
30+ import org .apache .cloudstack .engine .subsystem .api .storage .ObjectInDataStoreStateMachine .Event ;
2931import org .apache .cloudstack .engine .subsystem .api .storage .SnapshotInfo ;
3032import org .apache .cloudstack .engine .subsystem .api .storage .TemplateEvent ;
3133import org .apache .cloudstack .engine .subsystem .api .storage .TemplateInfo ;
3739import org .apache .cloudstack .storage .datastore .DataObjectManager ;
3840import org .apache .cloudstack .storage .datastore .ObjectInDataStoreManager ;
3941import org .apache .cloudstack .storage .image .store .TemplateObject ;
42+ import org .apache .cloudstack .storage .motion .DataMotionService ;
4043import org .apache .log4j .Logger ;
4144import org .springframework .stereotype .Component ;
4245
@@ -49,6 +52,8 @@ public class ImageServiceImpl implements ImageService {
4952 ObjectInDataStoreManager objectInDataStoreMgr ;
5053 @ Inject
5154 DataObjectManager dataObjectMgr ;
55+ @ Inject
56+ DataMotionService motionSrv ;
5257
5358 class CreateTemplateContext <T > extends AsyncRpcConext <T > {
5459 final TemplateInfo srcTemplate ;
@@ -140,17 +145,91 @@ public AsyncCallFuture<CommandResult> deleteTemplateAsync(
140145 return null ;
141146 }
142147
148+ private class CopyTemplateContext <T > extends AsyncRpcConext <T > {
149+ final AsyncCallFuture <CommandResult > future ;
150+ final DataObject object ;
151+ /**
152+ * @param callback
153+ */
154+ public CopyTemplateContext (AsyncCompletionCallback <T > callback , AsyncCallFuture <CommandResult > future , DataObject object ) {
155+ super (callback );
156+ this .future = future ;
157+ this .object = object ;
158+ }
159+
160+ }
143161 @ Override
144162 public AsyncCallFuture <CommandResult > createTemplateFromSnapshotAsync (
145163 SnapshotInfo snapshot , TemplateInfo template , DataStore store ) {
146- // TODO Auto-generated method stub
164+ AsyncCallFuture <CommandResult > future = new AsyncCallFuture <CommandResult >();
165+ DataObject templateOnStore = null ;
166+ try {
167+ templateOnStore = store .create (template );
168+ templateOnStore .processEvent (Event .CreateOnlyRequested );
169+
170+ CopyTemplateContext <CommandResult > context = new CopyTemplateContext <CommandResult >(null , future , templateOnStore );
171+ AsyncCallbackDispatcher <ImageServiceImpl , CopyCommandResult > caller = AsyncCallbackDispatcher .create (this );
172+ caller .setCallback (caller .getTarget ().copyTemplateAsyncCallback (null , null ))
173+ .setContext (context );
174+ this .motionSrv .copyAsync (snapshot , templateOnStore , caller );
175+ } catch (Exception e ) {
176+ s_logger .debug ("Failed to create template: " + template .getId () + "from snapshot: " + snapshot .getId () + ", due to " + e .toString ());
177+ if (templateOnStore != null ) {
178+ try {
179+ templateOnStore .processEvent (Event .OperationFailed );
180+ } catch (Exception e1 ) {
181+
182+ }
183+ }
184+ CommandResult result = new CommandResult ();
185+ result .setResult (e .toString ());
186+ future .complete (result );
187+ }
188+ return future ;
189+ }
190+
191+ protected Void copyTemplateAsyncCallback (AsyncCallbackDispatcher <ImageServiceImpl , CopyCommandResult > callback , CopyTemplateContext <CommandResult > context ) {
192+ CopyCommandResult result = callback .getResult ();
193+ AsyncCallFuture <CommandResult > future = context .future ;
194+ DataObject object = context .object ;
195+ CommandResult res = new CommandResult ();
196+ if (result .isFailed ()) {
197+ res .setResult (result .getResult ());
198+ object .processEvent (Event .OperationFailed );
199+ } else {
200+ object .processEvent (Event .OperationSuccessed );
201+ }
202+ future .complete (res );
147203 return null ;
148204 }
149205
150206 @ Override
151207 public AsyncCallFuture <CommandResult > createTemplateFromVolumeAsync (
152208 VolumeInfo volume , TemplateInfo template , DataStore store ) {
153- // TODO Auto-generated method stub
154- return null ;
209+ AsyncCallFuture <CommandResult > future = new AsyncCallFuture <CommandResult >();
210+ DataObject templateOnStore = null ;
211+ try {
212+ templateOnStore = store .create (template );
213+ templateOnStore .processEvent (Event .CreateOnlyRequested );
214+
215+ CopyTemplateContext <CommandResult > context = new CopyTemplateContext <CommandResult >(null , future , templateOnStore );
216+ AsyncCallbackDispatcher <ImageServiceImpl , CopyCommandResult > caller = AsyncCallbackDispatcher .create (this );
217+ caller .setCallback (caller .getTarget ().copyTemplateAsyncCallback (null , null ))
218+ .setContext (context );
219+ this .motionSrv .copyAsync (volume , templateOnStore , caller );
220+ } catch (Exception e ) {
221+ s_logger .debug ("Failed to create template: " + template .getId () + "from volume: " + volume .getId () + ", due to " + e .toString ());
222+ if (templateOnStore != null ) {
223+ try {
224+ templateOnStore .processEvent (Event .OperationFailed );
225+ } catch (Exception e1 ) {
226+
227+ }
228+ }
229+ CommandResult result = new CommandResult ();
230+ result .setResult (e .toString ());
231+ future .complete (result );
232+ }
233+ return future ;
155234 }
156235}
0 commit comments