Source code: com/flexstor/flexdbserver/services/checkincheckout/PromoteServiceManager.java
1 /*
2 * PromoteServiceManager.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:49 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.flexdbserver.services.checkincheckout;
12
13 import java.util.Iterator;
14 import java.util.Vector;
15
16 import com.flexstor.common.constants.ActionPropertiesI;
17 import com.flexstor.common.constants.AssetRolesI;
18 import com.flexstor.common.constants.ServicesI;
19 import com.flexstor.common.data.ActionData;
20 import com.flexstor.common.data.ActionResult;
21 import com.flexstor.common.data.AssetRecordData;
22 import com.flexstor.common.errorlogger.FlexError;
23 import com.flexstor.common.gateway.CheckOutCheckInGateway;
24 import com.flexstor.common.gateway.exceptions.TransactionFailedException;
25 import com.flexstor.common.resources.Resources;
26 import com.flexstor.common.services.SrvcNotAvailException;
27 import com.flexstor.common.threadmgr.ThreadCallbackI;
28 import com.flexstor.flexdbserver.services.ServiceManager;
29
30 /**
31 * PromoteServiceManager provides functionality to control the
32 * sequencial execution of Services during the promote process
33 */
34 public class PromoteServiceManager
35 extends ServiceManager
36 implements AssetRolesI
37 {
38 // To get the version number from MKS
39 public final static String IDENTIFIER="$Id: PromoteServiceManager.java,v 1.3 2003/08/11 02:22:49 aleric Exp $";
40
41 protected String sServerName = "";
42 protected ActionData data = null;
43 protected boolean bRunRemote = false;
44 protected boolean bContinue = true;
45 protected String fileSeparator = "";
46 protected Vector vRecords = null;
47 protected Vector vBadRecords = null;
48
49 public PromoteServiceManager( String sIdentifier, ActionData data, ThreadCallbackI caller )
50 {
51 super( data, caller );
52 this.sServerName = sIdentifier;
53 this.data = data;
54 vRecords = data.getRecords();
55
56 // Here we should check if the server is the same as the AppServer where we are running;
57 // if it is, then instantiate local services; otherwise, use server name to instantiate
58 // services remotely.
59 /*String sDNSServer = ServerList.getDNSName( sServerName );
60 String sAppServerHost = Settings.getString( Settings.APP_SERVER_HOST );
61
62 if ( sDNSServer.equals( sAppServerHost ) == false )
63 bRunRemote = true;*/
64
65 // Get the system dependent file separator
66 fileSeparator = java.io.File.separator;
67 }
68
69 /**
70 * Main loop for sequencial execution of Services.
71 */
72 public ActionResult execute()
73 throws InterruptedException
74 {
75 // First step, change the status to checked-out
76 if ( setStatusToCheckedOut() )
77 {
78 // Set the keep lowres flag on for all records (actually, for promote there should be only one)
79 // This is a temporary solution until the client side sets this flag.
80 for ( int i = 0; i < vRecords.size(); i++ )
81 ((AssetRecordData) vRecords.elementAt(i)).setBoolean( ActionPropertiesI.KEEP_LOWRES, new Boolean(true) );
82
83 ActionResult result = (new CheckInServiceManager( sServerName, data, null )).execute();
84
85 // Before executing a service, we should check if an interrupt request has been
86 // placed, and if so, throw an InterruptedException to abort this operation
87 if ( abortManager() )
88 throw new InterruptedException();
89
90 if ( result != null )
91 {
92 vBadRecords = result.getBadRecords();
93 vRecords = result.getGoodRecords();
94 try
95 {
96 promoteChildren();
97 }
98 catch ( TransactionFailedException rtfe )
99 {
100 //5067=Promote Service
101 new FlexError( FlexError.WARNING, Resources.get(5067) + " (" + data.getTransId() + ")", IDENTIFIER, rtfe.getOriginalException() );
102 }
103 }
104 else
105 {
106 vBadRecords = vRecords;
107 vRecords = null;
108 }
109
110 // For successful files, the CheckIn Service will change the status in the database to Checked-In,
111 // however, for failed files, it will rolled back to Checked-Out. So we will need to roll back the
112 // status from Checked-Out to Checked-In for those assets that failed to promote.
113 if ( vBadRecords != null && vBadRecords.size() > 0 )
114 rollBackStatusToCheckIn();
115 }
116 else
117 {
118 vBadRecords = vRecords;
119 vRecords = null;
120 }
121
122 ActionResult actionResult;
123 if ( vBadRecords != null && vBadRecords.size() > 0 )
124 {
125 actionResult = new ActionResult(false);
126 actionResult.setBadRecords( vBadRecords );
127 }
128 else
129 actionResult = new ActionResult(true);
130
131 data.setRecords( vRecords );
132 actionResult.setData( data );
133 actionResult.setId( data.getTransId() );
134 return actionResult;
135 }
136
137 protected ActionResult getResultObjectOnAbnormalEnding()
138 {
139 ActionResult actionResult = new ActionResult(false);
140 actionResult.setBadRecords( data.getRecords() );
141 actionResult.setId( data.getTransId() );
142 return actionResult;
143 }
144
145 /**
146 * Set the status in the database to in-progress
147 */
148 private boolean setStatusToCheckedOut()
149 {
150 CheckOutCheckInGateway gateway = new CheckOutCheckInGateway();
151 try
152 {
153 gateway.connect();
154
155 long[] laBadAssets = gateway.updateToInProcessCheckOut( data );
156 if ( laBadAssets != null && laBadAssets.length > 0 )
157 {
158 // if all records failed, return false
159 if ( laBadAssets.length == vRecords.size() )
160 {
161 vBadRecords = vRecords;
162 vRecords = null;
163 return false;
164 }
165 else
166 {
167 // remove the records that could not be updated
168 AssetRecordData record;
169 for ( int i = 0; i < laBadAssets.length; i++ )
170 {
171 for ( Iterator it = vRecords.iterator(); it.hasNext(); )
172 {
173 record = (AssetRecordData) it.next();
174 if ( record.getRecordId() == laBadAssets[i] )
175 {
176 vBadRecords.addElement( record );
177 it.remove();
178 }
179 }
180 }
181 // Reset the records in data to update to checked-out only the ones that succeed previously
182 data.setRecords( null );
183 for ( int i = 0; i < vRecords.size(); i++ )
184 data.addRecord( (AssetRecordData)vRecords.elementAt(i) );
185 }
186 }
187
188 gateway.checkOutAssets( data );
189 return true;
190 }
191 catch ( TransactionFailedException tfe )
192 {
193 // 7046=Unable to change database status for this transaction.
194 new FlexError( FlexError.CRITICAL, Resources.get(5067) + " (" + data.getTransId() + ")", IDENTIFIER, 7046 );
195 return false;
196 }
197 finally
198 {
199 gateway.dispose();
200 }
201 }
202
203 private void rollBackStatusToCheckIn()
204 {
205 CheckOutCheckInGateway gateway = new CheckOutCheckInGateway();
206 try
207 {
208 gateway.connect();
209
210 ActionData badData = new ActionData();
211 badData.setUserId( data.getUserId() );
212
213 for ( int i = 0; i < vBadRecords.size(); i++ )
214 badData.addRecord( (AssetRecordData)vBadRecords.elementAt(i) );
215
216 gateway.cancelCheckOutAssets( badData );
217 }
218 catch ( TransactionFailedException tfe )
219 {
220 // 7046=Unable to change database status for this transaction.
221 new FlexError( FlexError.CRITICAL, Resources.get(5067) + " (" + data.getTransId() + ")", IDENTIFIER, 7046 );
222 }
223 finally
224 {
225 gateway.dispose();
226 }
227 }
228
229 private void promoteChildren()
230 throws TransactionFailedException
231 {
232 ActionData tempData = (ActionData)data.clone();
233 tempData.setRecords( null ); // reset records
234 // Initialize the checkInGateway
235 CheckOutCheckInGateway checkInGateway = new CheckOutCheckInGateway();
236 checkInGateway.connect();
237
238 AssetRecordData record = null;
239 String sLocation;
240 // The version directory of the parent
241 String sVersionDir = null;
242 for ( int i = 0; i < vRecords.size(); i++ )
243 {
244 record = (AssetRecordData) vRecords.elementAt(i);
245 sVersionDir = record.getString( ActionPropertiesI.SOURCE_LOCATION );
246 sVersionDir = sVersionDir.substring( sVersionDir.indexOf(".version") );
247 // Add the thumbnail to the list of files to copy
248 // Call the bean and find out if there are children to add.
249 AssetRecordData childRecord = (AssetRecordData)checkInGateway.getDefaultViewAsset( record );
250 if ( childRecord != null && childRecord.getRecordId() != record.getRecordId() )
251 {
252 sLocation = childRecord.getLocation();
253 // If location contains the string "defaultthumbnail" do not copy
254 if ( sLocation.indexOf( "defaultthumbnail" ) == -1 )
255 {
256 // Promote location will be the location of the original asset
257 childRecord.setString( ActionPropertiesI.DESTINATION_SERVER, childRecord.getServer() );
258 childRecord.setString( ActionPropertiesI.DESTINATION_LOCATION, sLocation );
259 // Set new location for the thumbnail to be in the version directory
260 childRecord.setLocation( sLocation + sVersionDir );
261 tempData.addRecord( childRecord );
262 }
263 }
264 }
265 if ( tempData.getRecords() != null && tempData.getRecords().size() > 0 )
266 executeService( ServicesI.COPY_SERVICE, tempData );
267 }
268
269 private void executeService( String sServiceName, ActionData data )
270 {
271 if ( bRunRemote )
272 sServiceName = sServiceName + "_" + sServerName;
273
274 try
275 {
276 ActionResult result = doService( sServiceName, data );
277 if ( result == null )
278 bContinue = false;
279 else
280 bContinue = result.isSuccess();
281 }
282 catch( SrvcNotAvailException e )
283 {
284 //5067=Promote Service
285 new FlexError(FlexError.CRITICAL, Resources.get(5067) + " (" + data.getTransId() + ")", IDENTIFIER, e);
286 bContinue = false;
287 }
288 }
289 } // end of class