Source code: com/flexstor/flexdbserver/services/asset/AssetServiceManager.java
1 /*
2 * AssetServiceManager.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:28 $ 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.asset;
12
13 import java.io.FileNotFoundException;
14 import java.io.IOException;
15 import java.util.Hashtable;
16 import java.util.Iterator;
17 import java.util.Vector;
18
19 import com.flexstor.common.constants.ActionPropertiesI;
20 import com.flexstor.common.constants.ServicesI;
21 import com.flexstor.common.data.ActionResult;
22 import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
23 import com.flexstor.common.errorlogger.FlexError;
24 import com.flexstor.common.importprocessor.ImportData;
25 import com.flexstor.common.importprocessor.ImportResult;
26 import com.flexstor.common.io.xfile.FlexXFile;
27 import com.flexstor.common.resources.Resources;
28 import com.flexstor.common.services.ServiceArgumentsI;
29 import com.flexstor.common.services.SrvcNotAvailException;
30 import com.flexstor.common.threadmgr.ThreadCallbackI;
31 import com.flexstor.common.util.Diagnostic;
32 import com.flexstor.flexdbserver.services.ServiceManager;
33 import com.flexstor.flexdbserver.util.PathBuilder;
34
35 /**
36 * AssetServiceManager provides functionality to control the
37 * secuencial execution of Services mapped to a specified file Type.
38 *
39 * @author Jose Hernandez
40 * @version 2.2
41 */
42 public class AssetServiceManager
43 extends ServiceManager
44 {
45 // To get the version number from MKS
46 public final static String IDENTIFIER="$Id: AssetServiceManager.java,v 1.4 2003/08/11 02:22:28 aleric Exp $";
47
48 /**
49 * Indicate this Asset Service Manager runs pre or post services for all types.
50 * Declared in constructor.
51 */
52 public static final String PRESERVICES = "preservices";
53 public static final String POSTSERVICES = "postservices";
54
55 /** TypeServiceMapper object used to access mapping file */
56 protected TypeServiceMapper tsMapper = null;
57
58 /** ImportData object to be passed to Service */
59 protected ImportData iData = null;
60
61 /** File Type to execute Services for */
62 protected String sType = "";
63
64 /** List of Services to be executed */
65 protected TypeServiceMapper.TypeService[] services = null;
66
67 /** Flag indicating if the validateAsset() method should be called prior calling the next service */
68 protected boolean bValidateAssets;
69
70 /**
71 * @param iasObserver the ImportAssetService object that instantiated this AssetServiceManager
72 * @param sType the file type name to execute services for.
73 * @param iData the ImportData object to be passed to the Remote Service.
74 * @exception AssetServiceManagerException when any problem occurs avoiding the services execution.
75 */
76 public AssetServiceManager( String sType, ImportData iData, ThreadCallbackI caller )
77 throws AssetServiceManagerException
78 {
79 super( iData, caller );
80 this.sType = sType;
81 this.iData = iData;
82
83 String sMappingFile = null;
84
85 if ( sType.equals(PRESERVICES) || sType.equals(POSTSERVICES) )
86 {
87 sMappingFile = iData.getCtlDataRef().getValuePerKey("CONTROLFILE");
88 }
89 else
90 {
91 String sControlFilePath = iData.getCtlDataRef().getValuePerKey("CONTROLFILESPATH");
92 sMappingFile = sControlFilePath + ServicesI.ROLETYPE_SERVICES_CONFIG_FILE;
93
94 // Check for the existence of roletype_services.config; if it doesn't exist and the old
95 // TypeServiceDat.config file exists, log a warning in logMMDDYY.txt
96 // Done for compatibility issues. It should be removed probably in FLEXSTORdb 3.x
97 if ( !(new FlexXFile(sMappingFile)).exists() && (new FlexXFile(sControlFilePath + "TypeServiceDat.config")).exists() )
98 {
99 sMappingFile = sControlFilePath + "TypeServiceDat.config";
100 iData.addErrorRecord( new FlexError(FlexError.WARNING, Resources.get(5883), IDENTIFIER, sMappingFile + " should be renamed " + sControlFilePath + "roletype_services.config") );
101 }
102 }
103
104 try
105 {
106 // looks for the mapping file in the control file path
107 tsMapper = new TypeServiceMapper( sMappingFile );
108 }
109 catch( FileNotFoundException e )
110 {
111 //5559=Mapping file not found: %%1
112 throw new AssetServiceManagerException( Resources.get(5559, sMappingFile) );
113 }
114 catch( IOException e )
115 {
116 //5548=Error reading mapping file: %%1
117 throw new AssetServiceManagerException( Resources.get(5548, sMappingFile) );
118 }
119
120 // get names of services to be executed for this type
121 services = tsMapper.getServices( sType );
122
123 if ( services == null )
124 {
125 //5495=No Services mapped to type <%%1>.
126 throw new AssetServiceManagerException( Resources.get(5495, sType) );
127 }
128
129 // get flag for validating assets (checking if they exist in a file system
130 String sValidateAssets = tsMapper.getValue( sType, "validateAssets" );
131 bValidateAssets = sValidateAssets == null ? true : (new Boolean(sValidateAssets)).booleanValue();
132 }
133
134 /**
135 * Main loop for sequencial execution of Services.
136 */
137 protected ActionResult execute()
138 throws InterruptedException
139 {
140 ActionResult rData = null;
141 boolean bLoopBroken = false;
142
143 if ( services != null && services.length > 0 )
144 {
145 int i = 0;
146 String sServiceName;
147 Hashtable htArguments;
148 for ( ; i < services.length; i++ )
149 {
150 try
151 {
152 // Before calling the next service we should make sure that we have valid assets;
153 // for instance, make sure they exist in the file system.
154 // If assets are not valid, remove them from the data object
155 if ( bValidateAssets && !validateAssets() )
156 break;
157
158 sServiceName = services[i].getServiceName();
159 htArguments = services[i].getProperties();
160
161 // Check if the service set the validateAssets property, if so, it will override the
162 // one previously set.
163 String sValidateAssets = (String) htArguments.get("validateAssets");
164 if ( sValidateAssets != null )
165 bValidateAssets = (new Boolean(sValidateAssets)).booleanValue();
166
167
168 putArguments( htArguments );
169 rData = ( ActionResult ) doService( sServiceName, htArguments, iData );
170
171 // if no ImportResult object was returned or service failed,
172 // do not continue with remaining Services
173 if ( rData == null )
174 {
175 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, sServiceName + " returned nothing ");
176 bLoopBroken = true;
177 break;
178 }
179
180 ImportData iDataReturned = null;
181 if ( rData instanceof ImportResult ) // This check is temporary until we use the ActionResult instead of ImportResult
182 {
183 // get updated ImportData object to be passed to next Service
184 iDataReturned = ((ImportResult)rData).getImportData();
185
186 // Use this updated ImportData object for the next service
187 if ( iDataReturned != null )
188 iData = iDataReturned;
189 }
190
191 // Check to see if the service has anything to report
192 String sErrorMsgs = rData.getString( ActionPropertiesI.MESSAGE_STRING );
193 if(sErrorMsgs != null && !sErrorMsgs.equals(""))
194 {
195 iData.addErrorRecord( new FlexError(FlexError.WARNING, Resources.get(6704), "", sErrorMsgs) );
196 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, sServiceName + " reports: " + sErrorMsgs);
197 }
198
199 if ( !rData.isSuccess() )
200 {
201 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, sServiceName + " returned false ");
202 bLoopBroken = true;
203 break;
204 }
205 // if no updated ImportData object is available, do not continue with remaining Services
206 if ( iDataReturned == null )
207 {
208 bLoopBroken = true;
209 break;
210 }
211
212 // Before executing a service, we should check if an interrupt request has been
213 // placed, and if so, throw an InterruptedException to abort this operation
214 if ( abortManager() )
215 throw new InterruptedException();
216 }
217 catch( SrvcNotAvailException e )
218 {
219 //5544=Asset Service Manager
220 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Service could not be executed. " + e.getMessage());
221 iData.addErrorRecord( new FlexError(FlexError.CRITICAL, Resources.get(5544), IDENTIFIER, e) );
222 rData = null;
223 bLoopBroken = true;
224 break;
225 }
226 }
227
228 // If we broke out of the loop and the email service has not been executed and needs to be
229 // executed, do it now.
230 if ( iData != null && bLoopBroken )
231 {
232 for ( ; ++i < services.length; i++ )
233 {
234 sServiceName = services[i].getServiceName();
235 if ( sServiceName.equals( ServicesI.IMPORT_EMAIL_SERVICE )
236 || sServiceName.equals( ServicesI.PRE_IMPORT_EMAIL_SERVICE ) )
237 {
238 try
239 {
240 // get arguments (if any) and execute Service
241 htArguments = services[i].getProperties();
242 putArguments( htArguments );
243 doService( sServiceName, htArguments, iData );
244 }
245 catch( SrvcNotAvailException e )
246 {
247 //5544=Asset Service Manager
248 new FlexError(FlexError.CRITICAL, Resources.get(5544), IDENTIFIER, e);
249 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, e.getMessage());
250 }
251 finally
252 {
253 break;
254 }
255 }
256 }
257 }
258 }
259
260 if ( rData == null || !(rData instanceof ImportResult) ) // This check is temporary until we use the ActionResult instead of ImportResult
261 {
262 rData = new ImportResult( false );
263 ((ImportResult)rData).setImportData( null );
264 }
265 // Set the type of these assets and notify result to ImportAssetService
266 ((ImportResult)rData).setAssetsType( sType );
267
268 return rData;
269 }
270
271 protected ActionResult getResultObjectOnAbnormalEnding()
272 {
273 ImportResult result = new ImportResult( false );
274 result.setImportData( null );
275 return result;
276 }
277
278 /*
279 * Validates assets before calling a service. It make sure that assets exist in the file system.
280 */
281 private boolean validateAssets()
282 {
283 // Check all roles, all types, all flags
284 Vector vAssets = iData.getDisguiseRecordRef().getAssets("ALL", "ALL", "ALL");
285 // If initially there are no assets in this data object, we should continue. It means that
286 // we are importing empty buckets
287 if ( vAssets == null || vAssets.size() == 0 )
288 return true;
289
290 StringBuffer sbError = new StringBuffer();
291 DisguiseAssetRecordData asset;
292 String sPath;
293 FlexXFile fPath;
294 for ( Iterator i = vAssets.iterator(); i.hasNext(); )
295 {
296 asset = (DisguiseAssetRecordData) i.next();
297 sPath = PathBuilder.constructFilePath(asset);
298 if ( sPath != null )
299 {
300 fPath = new FlexXFile( sPath );
301 if ( !fPath.exists() )
302 {
303 iData.getDisguiseRecordRef().deleteAsset( asset );
304 // 5509=Unable to find input file: %%1.
305 sbError.append( Resources.get(5509, sPath ) + "\r\n" );
306 i.remove();
307 }
308 }
309 }
310
311 // Add error message
312 if ( sbError.length() > 0 )
313 iData.addErrorRecord( new FlexError(FlexError.WARNING, Resources.get(5883), IDENTIFIER, sbError.toString() ) );
314
315 // If after removing the non-existent assets we get an empty Vector, return false to indicate
316 // that there are no assets for the next service
317 return vAssets.size() != 0 ? true : false;
318 }
319
320 /**
321 * Read the arguments from the Type-Service Mapper and add them to the service
322 */
323 private void putArguments( Hashtable htArguments )
324 {
325 // Indicates the process that started this service; valid processes are:
326 // Import preservice
327 // Import postservice
328 // Import [role.type]
329 htArguments.put( ServiceArgumentsI.PROCESS, "Import " + sType );
330 htArguments.put( ServiceArgumentsI.FILE_SEPARATOR, java.io.File.separator );
331 }
332
333 } // end of class