001    /*
002     * SiteConfigGen.java
003     *
004     * Created on October 13, 2005, 12:33 PM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2003-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    
024    package gov.bnl.star.offline.scheduler.util.persistent;
025    
026    import java.io.*;
027    import java.util.Map;
028    import java.util.List;
029    import java.util.Hashtable;
030    import java.util.ArrayList;
031    import java.beans.XMLEncoder;
032    import java.beans.XMLDecoder;
033    
034    import gov.bnl.star.offline.scheduler.ComponentLibrary;
035    import gov.bnl.star.offline.scheduler.Site;
036    import gov.bnl.star.offline.scheduler.GateKeeperAccessPoint;
037    import gov.bnl.star.offline.scheduler.util.ConfigToolkit;
038    
039    /**
040     * Ask the user questions about there site setup and write a stub configuration for there site.
041     * @author  Levente Hajdu
042     */
043    public class SiteConfigGen {
044        
045        /** The function loads the local site from the local site config 
046         *  
047        */
048        static String localConfigFileName;
049        
050        /** Loads the local config into the comp lib. If no local config is found it will make one*/
051        public static void loadLocalSiteConfig(String configFile){
052            //if this is being call the site was not found in global config
053            
054            localConfigFileName = configFile.substring(0,1 + configFile.lastIndexOf(System.getProperty("file.separator")) ) + "localConfig.xml";
055            
056            
057            File localConfigFile = new File(localConfigFileName);
058            String LocalSiteName = (String) ComponentLibrary.getInstance().getComponent("localSite");
059            
060            
061            if(localConfigFile.exists()){
062                //load local config file
063                List localSites = null;
064                
065                
066                try{
067                   XMLDecoderExceptionListener MyExceptionListener = new XMLDecoderExceptionListener();
068                   XMLDecoder d = new XMLDecoder(new BufferedInputStream(new FileInputStream(localConfigFileName)),null, MyExceptionListener);
069                   localSites = (List) d.readObject();
070                   d.close();
071               
072                } catch (Exception e) {
073                          System.out.println("Could not open localConfig File \"" + localConfigFileName + "\".\n");
074                          System.out.println("Suggestions:\n");
075                          System.out.println("-Verify that the file is readable by your account.\n");
076                          System.out.println("-Try to backup and delete this file as it may be corrupt the next time you try to run a job SUMS will ask you questions to rebuild this file (for this write access is also required).\n");
077                          System.out.println("error:\n");
078                          e.printStackTrace();
079                          System.out.println("\nExitting...\n");
080                          System.exit(1);          
081                } 
082                
083                
084                 //copy the sites into the global view
085                List sites = (List) ComponentLibrary.getInstance().getComponent("gridView");
086                if(localSites != null)
087                    for(int i=0; i != localSites.size(); i++){
088                        sites.add( (Site) localSites.get(i));
089                        
090                    }
091    
092                
093                if(! ConfigToolkit.getToolkit().localSiteExists()){
094                    saveAppendExistingLocalConfig(MakeSiteObj(), sites, configFile);
095                }
096                else return;
097                
098       
099            }
100            else{ //if there is no site file that already exists
101                saveAsNewLocalConfig(MakeSiteObj(), localConfigFileName);
102            }
103            
104            //now that we have it saved, we can load it, be careful of endless loop here.
105            loadLocalSiteConfig(configFile);
106            return;
107        }
108        
109        
110        
111        private static void saveAppendExistingLocalConfig(Site site, List sites,String configFile){
112            sites.add(site);
113            saveLocalConfig(sites, configFile);
114        }
115        
116        
117        private static void saveAsNewLocalConfig(Site site,String configFile){
118            List sites = new ArrayList();
119            sites.add(site);
120            saveLocalConfig(sites,configFile);   
121        }
122        
123        
124        private static void saveLocalConfig(List sites,String configFile){
125            try{
126                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(localConfigFileName));
127                //BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(System.out); //only used for testing
128                PrintStream  out = new PrintStream (bufferedOutputStream);
129                //out.print("<!-- Star Unified Meta Scheduler Configuration File -->\n");
130                XMLEncoder e = new XMLEncoder(bufferedOutputStream);
131                e.writeObject(sites);
132                e.close();   
133           } catch (Exception e) {
134               System.out.println("Error : Could not save config file.\n\n");
135               e.printStackTrace();
136           }
137            
138        }
139        
140        
141        private static Site MakeSiteObj(){    
142    
143            String localSiteName = (String) ComponentLibrary.getInstance().getComponent("localSite");
144            //String localSiteName = "***ADD LOCAL SITE HERE***";  
145            
146            
147            System.out.println("Sums could not find your site \""+ localSiteName +"\" in its configuration file. In order to run this job you must first configure a stub site by answering a few questions. This will not modify your existing config file. These parameters will be added to the file localConfig.xml.");
148            System.out.println("\nNote: You must have write access to the directory holding the sums config file.");
149            
150            System.out.print("\nType \"s\" to set up your configuration now or type \"q\" to exit [q\\s]:");
151    
152            if (option('q', 's')){
153                System.out.println("Please contact you local scheduler administrator to configure you local site.\nExiting...");
154                System.exit(1);
155            }
156            
157    
158            System.out.println("Preparing configuration for site=\"" + localSiteName + "\".");
159            
160            
161            String canonicalName = " ";
162            do{
163                System.out.print("Please enter the canonical name of your site. Examples: BNL, PDSF :");
164                canonicalName = GetString();
165                System.out.print("You entered = \""  + canonicalName + "\" is this correct [y/n]:");
166            } while (!option('y', 'n'));
167            
168            
169            String fileTransferGatekeeper =" ";
170            do{
171                System.out.print("Enter the name of the gate keeper that will be used for transferring files back to your local site. Example: stargrid03.bnl.gov :");
172                fileTransferGatekeeper = GetString();
173                System.out.print("You entered = \""  + fileTransferGatekeeper + "\" is this correct [y/n]:");  
174            } while (!option('y', 'n'));
175            
176            
177            String loggingDirectory =" ";
178            do{
179                System.out.println("The log file directory needs to be a place where all user accounts have write access.");
180                System.out.print("Enter the path where you want the scheduler to place its log files. Example: /star/doc/log/ :");
181                loggingDirectory = GetString();
182                if(! loggingDirectory.endsWith("/")) loggingDirectory = loggingDirectory + "/";
183                System.out.print("You entered = \""  + loggingDirectory + "\" is this correct [y/n]:");  
184            } while (!option('y', 'n'));
185            
186            
187            System.out.println("Building config file");
188            
189            
190            
191            
192            
193            
194            //Bild the site config object 
195            Site newSite = new Site();
196            newSite.setSiteName(localSiteName); //turn on later
197            newSite.setCanonicalName(canonicalName);
198           
199            GateKeeperAccessPoint gatekeeper = new GateKeeperAccessPoint();
200            gatekeeper.setUtilization(100);
201            gatekeeper.setName(fileTransferGatekeeper);
202            newSite.AddFileTransferGatekeeper(gatekeeper);
203            
204            Map logconfig = new Hashtable();
205            logconfig.put("directory",loggingDirectory);
206            logconfig.put("level", "CONFIG");
207            newSite.setLogConf(logconfig);
208            
209            Map programLocations = new Hashtable();
210            programLocations.put("ls","/bin/ls");
211            programLocations.put("csh","/bin/csh");
212            newSite.setProgramLocations(programLocations);
213            
214            
215            return newSite;
216                
217        }
218        
219        /** Asks the user to type char a or b, and returns true if the user entered A and false if 
220         *  the user entered b. If the user enters something else they will be asked again. 
221         */
222        private static boolean option(char a, char b){
223            
224            int userInput = 0; //this is realy a char
225            int charBuff = 0; //this is realy a char
226            while(userInput != a && userInput != b){
227                try { //read next char entered by the user
228                        charBuff = System.in.read();
229                    } catch (Exception e) {System.out.println("Exception reading input");}
230                if (charBuff != '\n'){ //strip out the return
231                    userInput = charBuff;
232                    if(userInput != a && userInput != b) //if it's not valid option print out this line:
233                        System.out.print("\nYou must enter \"" + a + "\" or \"" + b + "\":");
234                }         
235            }
236            
237            if(userInput == a) return true;
238            return false;
239        }
240        
241        
242        private static String GetString(){
243            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
244            String line = null;
245            while(line == null){
246                try {   br.readLine(); //flush
247                        line = br.readLine();
248                         
249                    } catch (IOException ioe) {
250                            System.out.println("Error trying to read answer!");
251                    }
252    
253                if(line.compareTo("\n")==0) line = null;  
254            }
255            
256            return line.trim();
257        }
258        
259        
260        
261        /** Creates a new instance of SiteConfigGen */
262        public SiteConfigGen() {
263            
264        }
265        
266        /**
267         * @param args the command line arguments
268         */
269        public static void main(String[] args) {
270            // TODO code application logic here
271            SiteConfigGen config = new SiteConfigGen();
272            //config.addConfig();
273            config.loadLocalSiteConfig("c:\\temp\\myconfig.xml");
274            
275        }
276        
277    }