001    /**
002     * 
003     */
004    package de.jw.cloud42.webapp;
005    
006    import java.io.File;
007    import java.util.ArrayList;
008    import java.util.HashMap;
009    import java.util.List;
010    import java.util.logging.Logger;
011    
012    import javax.faces.application.FacesMessage;
013    
014    import org.jboss.seam.ScopeType;
015    import org.jboss.seam.annotations.In;
016    import org.jboss.seam.annotations.Name;
017    import org.jboss.seam.annotations.Scope;
018    import org.jboss.seam.annotations.Synchronized;
019    import org.jboss.seam.faces.FacesMessages;
020    import org.richfaces.event.UploadEvent;
021    
022    import de.jw.cloud42.core.domain.RemoteResult;
023    import de.jw.cloud42.core.remoting.RemoteControl;
024    import de.jw.cloud42.webapp.utils.FileUtils;
025    
026    
027    /**
028     * Seam component, handles bundling new AMIs and holds corresponding properties.
029     * 
030     * @author fbitzer
031     *
032     */
033    @Name("bundlingManager")
034    @Scope(ScopeType.SESSION)
035    @Synchronized(timeout=1000000000)
036    public class BundlingManager {
037    
038            @In
039            UserManager userManager;
040            
041            /**
042             * Inject faces messages to trigger error and success messages.
043             */
044            @In 
045            FacesMessages facesMessages;
046            
047            
048            private HashMap<String, BundlingThread> bundlingThreads = new HashMap<String, BundlingThread>();
049            
050            //the Member variables for the input fields in the UI
051            private String bucket;
052            private String imageName;
053            private boolean use64Bit;
054            
055            private boolean doNotify;
056            private String messageTopic;
057            private String messageText;
058            private String messageInfo;
059            
060            private byte[] certFile;
061            private byte[] pkFile;
062            
063            /**
064             * Starts bundling a new AMI.
065             * 
066             * @param dnsName
067             * @param keyName
068             */
069            public void bundle(String dnsName, String keyName){
070                    
071                    //check input first
072                    
073                    if (this.bucket.equals("")){
074                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "msg_invalidInput", "No bucket.");
075                            return;
076                    }
077                    
078                    if (this.certFile==null){
079                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "msg_invalidInput", "No certificate.");
080                            return;
081                    }
082                    if (this.pkFile==null){
083                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "msg_invalidInput", "No key file.");
084                            return;
085                    }
086                    
087                    if (this.imageName.equals("")){
088                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "msg_invalidInput", "No image name.");
089                            return;
090                    }
091                    
092                    
093                    
094                    //get the private key for the keyname
095                    String privateKey = userManager.getKeyForName(keyName);
096                    
097                    //create a thread for bundling
098                    BundlingThread t = new BundlingThread(dnsName, privateKey, userManager.getCurrentCredentials(),
099                                    bucket, imageName, use64Bit, 
100                                    doNotify, messageTopic, messageText, messageInfo, privateKey.getBytes(), certFile);
101    
102                    
103                    t.start();
104                    
105                    //add the thread to the list of currently running threads
106                    bundlingThreads.put(dnsName, t);
107                    
108                    
109                    
110            }
111            
112            /**
113             * Checks if bundling is in progress for a particular instance.
114             * @param dnsName Hostname of the instance to check
115             * 
116             * @return
117             */
118            public boolean bundlingInProgress(String dnsName){
119                    
120                    //check if there is a thread attached to the hostname
121                    BundlingThread t = bundlingThreads.get(dnsName);
122                    
123                    
124                    if (t != null){
125                            //yes, there is a thread
126                            if (t.getState() == Thread.State.TERMINATED) {
127                                    //its state is terminated so bundling has ended -> check the result
128                                    if (t.getResult().getExitCode() != 0) {
129                                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_ERROR, "msg_bundlingError", t.getResult().getExceptionMessage());
130                                    
131                                    } else {
132                                            facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_INFO, "msg_bundlingOK", dnsName);
133                                            
134                                    }
135                                    //remove the ended thread
136                                    bundlingThreads.remove(dnsName);
137                                    
138                                    return false;
139                            } else {
140                                    //thread found, but not finished -> bundling is running
141                                    return true;
142                            }
143                    } else {
144                            //no bundling thread found -> no bundling in progress
145                            return false;
146                    }
147                    
148            }
149            
150            
151            /**
152             * Resets the dialog by resetting the member variables.
153             */
154            public void resetBundlingDialog(){
155                    bucket = "";
156                    imageName ="";
157                    use64Bit = false;
158                    certFile = null;
159                    pkFile = null;
160                    
161                    doNotify = false;
162                    messageTopic = "";
163                    messageText = "";
164                    messageInfo = "";
165            }
166            
167            /**
168             * fileUploadListener function for RichFaces fileupload component.
169             * Reads the content of the uploaded file into a byte array and stores it in the
170             * <code>certFile</code> property.
171             * @param e
172             */
173            public void fileUploadListener(UploadEvent e){
174                    
175                    this.certFile = getFile(e);
176                            
177            }
178            
179            /**
180             * fileUploadListener function for RichFaces fileupload component.
181             * Reads the content of the uploaded file into a byte array and stores it in the
182             * <code>pkFile</code> property.
183             * @param e
184             */
185            public void fileUploadListenerPK(UploadEvent e){
186                    
187                    this.pkFile = getFile(e);
188                    
189            }
190            
191            
192            //-------Getters and Setters---------------
193            /**
194             * @return the bucket
195             */
196            public String getBucket() {
197                    return bucket;
198            }
199            /**
200             * @param bucket the bucket to set
201             */
202            public void setBucket(String bucket) {
203                    this.bucket = bucket;
204            }
205            /**
206             * @return the imageName
207             */
208            public String getImageName() {
209                    return imageName;
210            }
211            /**
212             * @param imageName the imageName to set
213             */
214            public void setImageName(String imageName) {
215                    this.imageName = imageName;
216            }
217            /**
218             * @return the use64Bit
219             */
220            public boolean isUse64Bit() {
221                    return use64Bit;
222            }
223            /**
224             * @param use64Bit the use64Bit to set
225             */
226            public void setUse64Bit(boolean use64Bit) {
227                    this.use64Bit = use64Bit;
228            }
229            /**
230             * @return the doNotify
231             */
232            public boolean isDoNotify() {
233                    return doNotify;
234            }
235            /**
236             * @param doNotify the doNotify to set
237             */
238            public void setDoNotify(boolean doNotify) {
239                    this.doNotify = doNotify;
240            }
241            /**
242             * @return the messageTopic
243             */
244            public String getMessageTopic() {
245                    return messageTopic;
246            }
247            /**
248             * @param messageTopic the messageTopic to set
249             */
250            public void setMessageTopic(String messageTopic) {
251                    this.messageTopic = messageTopic;
252            }
253            /**
254             * @return the messageText
255             */
256            public String getMessageText() {
257                    return messageText;
258            }
259            /**
260             * @param messageText the messageText to set
261             */
262            public void setMessageText(String messageText) {
263                    this.messageText = messageText;
264            }
265            /**
266             * @return the messageInfo
267             */
268            public String getMessageInfo() {
269                    return messageInfo;
270            }
271            /**
272             * @param messageInfo the messageInfo to set
273             */
274            public void setMessageInfo(String messageInfo) {
275                    this.messageInfo = messageInfo;
276            }
277    
278    
279    
280            /**
281             * @return the certFile
282             */
283            public byte[] getCertFile() {
284                    return certFile;
285            }
286    
287    
288    
289            /**
290             * @param certFile the certFile to set
291             */
292            public void setCertFile(byte[] certFile) {
293                    this.certFile = certFile;
294            }
295    
296    
297    
298            /**
299             * @return the pkFile
300             */
301            public byte[] getPkFile() {
302                    return pkFile;
303            }
304    
305    
306    
307            /**
308             * @param pkFile the pkFile to set
309             */
310            public void setPkFile(byte[] pkFile) {
311                    this.pkFile = pkFile;
312            }
313    
314    
315            /**
316             * Private helper function, extracts an uploaded private key or certificate file.
317             * @param e RichFaces upload event
318             * @return
319             */
320            private byte[] getFile(UploadEvent e){
321                    try {
322                            File f = e.getUploadItem().getFile();
323                            
324                            byte[] result = FileUtils.getBytesFromFile(f);
325                            
326                            e.getUploadItem().getFile().delete();
327                            
328                            return result;
329                    
330                    } catch (Exception ex) {
331                            Logger.getAnonymousLogger().warning("Uploading file failed: " + ex.getMessage());
332                    }
333                    return null;
334            }
335            
336            
337            
338            
339    }