Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / ViewServerActivity.java @ a597c658

History | View | Annotate | Download (16.5 kB)

1
/**
2
 * 
3
 */
4
package com.rackspacecloud.android;
5

    
6
import java.io.IOException;
7
import java.io.StringReader;
8
import java.util.Iterator;
9

    
10
import javax.xml.parsers.FactoryConfigurationError;
11
import javax.xml.parsers.ParserConfigurationException;
12
import javax.xml.parsers.SAXParser;
13
import javax.xml.parsers.SAXParserFactory;
14

    
15
import org.apache.http.HttpResponse;
16
import org.apache.http.client.ClientProtocolException;
17
import org.apache.http.impl.client.BasicResponseHandler;
18
import org.xml.sax.InputSource;
19
import org.xml.sax.SAXException;
20
import org.xml.sax.XMLReader;
21

    
22
import android.app.Activity;
23
import android.app.AlertDialog;
24
import android.app.Dialog;
25
import android.content.Context;
26
import android.content.DialogInterface;
27
import android.graphics.Color;
28
import android.os.AsyncTask;
29
import android.os.Bundle;
30
import android.view.View;
31
import android.view.View.OnClickListener;
32
import android.widget.Button;
33
import android.widget.ImageView;
34
import android.widget.LinearLayout;
35
import android.widget.TextView;
36

    
37
import com.rackspace.cloud.servers.api.client.CloudServersException;
38
import com.rackspace.cloud.servers.api.client.Flavor;
39
import com.rackspace.cloud.servers.api.client.Server;
40
import com.rackspace.cloud.servers.api.client.ServerManager;
41
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
42

    
43
/**
44
 * @author Mike Mayo - mike.mayo@rackspace.com - twitter.com/greenisus
45
 *
46
 */
47
public class ViewServerActivity extends Activity {
48
        
49
        private Server server;
50
        private boolean ipAddressesLoaded; // to prevent polling from loading tons of duplicates
51
        private Flavor[] flavors;
52
        private String[] flavorNames;
53
        private String selectedFlavorId;
54
        private boolean imageLoaded;
55
        Context context;
56
        
57
    /** Called when the activity is first created. */
58
    @Override
59
    public void onCreate(Bundle savedInstanceState) {
60
        super.onCreate(savedInstanceState);
61
        server = (Server) this.getIntent().getExtras().get("server");
62
        context = getApplicationContext();
63
        setContentView(R.layout.viewserver);
64
        restoreState(savedInstanceState);
65
    }
66
    
67
        @Override
68
        protected void onSaveInstanceState(Bundle outState) {
69
                super.onSaveInstanceState(outState);
70
                outState.putSerializable("server", server);
71
                outState.putBoolean("imageLoaded", imageLoaded);
72
        }
73

    
74
    private void restoreState(Bundle state) {
75
            if (state != null && state.containsKey("server")) {
76
                    server = (Server) state.getSerializable("server");
77
                    imageLoaded = state.getBoolean("imageLoaded");
78
            }
79
        loadServerData();
80
        setupButtons();
81
        loadFlavors();
82
    }
83

    
84
    private void loadImage() {
85
            // hate to do this, but devices run out of memory after a few rotations
86
            // because the background images are so large
87
            if (!imageLoaded) {
88
                ImageView osLogo = (ImageView) findViewById(R.id.view_server_os_logo);
89
                osLogo.setAlpha(100);
90
                    osLogo.setImageResource(server.getImage().logoResourceId());
91
                    imageLoaded = true;
92
            }
93

    
94
    }
95
    
96
    private void loadServerData() {
97
            TextView name = (TextView) findViewById(R.id.view_server_name);
98
            name.setText(server.getName());
99
            
100
            TextView os = (TextView) findViewById(R.id.view_server_os);
101
            os.setText(server.getImage().getName());
102
            
103
            TextView memory = (TextView) findViewById(R.id.view_server_memory);
104
            memory.setText(server.getFlavor().getRam() + " MB");
105
            
106
            TextView disk = (TextView) findViewById(R.id.view_server_disk);
107
            disk.setText(server.getFlavor().getDisk() + " GB");
108
            
109
            TextView status = (TextView) findViewById(R.id.view_server_status);
110

    
111
            // show status and possibly the progress, with polling
112
            if (!"ACTIVE".equals(server.getStatus())) {
113
                status.setText(server.getStatus() + " - " + server.getProgress() + "%");
114
                    new PollServerTask().execute((Void[]) null);
115
            } else {
116
                status.setText(server.getStatus());
117
            }
118
            
119
            if (!ipAddressesLoaded) {
120
                    // public IPs
121
                    int layoutIndex = 12; // public IPs start here
122
                    LinearLayout layout = (LinearLayout) this.findViewById(R.id.view_server_layout);            
123
                    String publicIps[] = server.getPublicIpAddresses();
124
                    for (int i = 0; i < publicIps.length; i++) {
125
                        TextView tv = new TextView(this.getBaseContext());
126
                        tv.setLayoutParams(os.getLayoutParams()); // easy quick styling! :)
127
                        tv.setTypeface(tv.getTypeface(), 1); // 1 == bold
128
                        tv.setTextSize(os.getTextSize());
129
                        tv.setTextColor(Color.WHITE);
130
                        tv.setText(publicIps[i]);
131
                        layout.addView(tv, layoutIndex++);
132
                    }
133
                    
134
                    // private IPs
135
                    layoutIndex++; // skip over the Private IPs label
136
                    String privateIps[] = server.getPrivateIpAddresses();
137
                    for (int i = 0; i < privateIps.length; i++) {
138
                        TextView tv = new TextView(this.getBaseContext());
139
                        tv.setLayoutParams(os.getLayoutParams()); // easy quick styling! :)
140
                        tv.setTypeface(tv.getTypeface(), 1); // 1 == bold
141
                        tv.setTextSize(os.getTextSize());
142
                        tv.setTextColor(Color.WHITE);
143
                        tv.setText(privateIps[i]);
144
                        layout.addView(tv, layoutIndex++);
145
                    }
146

    
147
                    loadImage();
148
                    ipAddressesLoaded = true;
149
            }
150
    }
151
    
152
    private void loadFlavors() {
153
                flavorNames = new String[Flavor.getFlavors().size()]; 
154
                flavors = new Flavor[Flavor.getFlavors().size()];
155

    
156
                Iterator<Flavor> iter = Flavor.getFlavors().values().iterator();
157
                int i = 0;
158
                while (iter.hasNext()) {
159
                        Flavor flavor = iter.next();
160
                        flavors[i] = flavor;
161
                        flavorNames[i] = flavor.getName() + ", " + flavor.getDisk() + " GB disk";
162
                        i++;
163
                }
164
                selectedFlavorId = flavors[0].getId();
165
    }
166

    
167
    private void setupButton(int resourceId, OnClickListener onClickListener) {
168
                Button button = (Button) findViewById(resourceId);
169
                button.setOnClickListener(onClickListener);
170
    }
171
    
172
    private void setupButtons() {
173
            setupButton(R.id.view_server_soft_reboot_button, new OnClickListener() {
174
            public void onClick(View v) {
175
                showDialog(R.id.view_server_soft_reboot_button);
176
            }
177
        });
178
            
179
            setupButton(R.id.view_server_hard_reboot_button, new OnClickListener() {
180
            public void onClick(View v) {
181
                showDialog(R.id.view_server_hard_reboot_button);
182
            }
183
            });
184

    
185
            setupButton(R.id.view_server_resize_button, new OnClickListener() {
186
            public void onClick(View v) {
187
                showDialog(R.id.view_server_resize_button);
188
            }
189
            });
190

    
191
            setupButton(R.id.view_server_delete_button, new OnClickListener() {
192
            public void onClick(View v) {
193
                showDialog(R.id.view_server_delete_button);
194
            }
195
            });
196
            
197
    }
198
    
199
    private void showAlert(String title, String message) {
200
                AlertDialog alert = new AlertDialog.Builder(this).create();
201
                alert.setTitle(title);
202
                alert.setMessage(message);
203
                alert.setButton("OK", new DialogInterface.OnClickListener() {
204
              public void onClick(DialogInterface dialog, int which) {
205
                return;
206
            } }); 
207
                alert.show();
208
    }
209
        
210
    /**
211
         * @return the server
212
         */
213
        public Server getServer() {
214
                return server;
215
        }
216

    
217
        /**
218
         * @param server the server to set
219
         */
220
        public void setServer(Server server) {
221
                this.server = server;
222
        }
223

    
224
    @Override
225
    protected Dialog onCreateDialog(int id) {
226
        switch (id) {
227
        case R.id.view_server_soft_reboot_button:
228
            return new AlertDialog.Builder(ViewServerActivity.this)
229
                .setIcon(R.drawable.alert_dialog_icon)
230
                .setTitle("Soft Reboot")
231
                .setMessage("Are you sure you want to perform a soft reboot?")
232
                .setPositiveButton("Reboot Server", new DialogInterface.OnClickListener() {
233
                        public void onClick(DialogInterface dialog, int whichButton) {
234
                                // User clicked OK so do some stuff
235
                                new SoftRebootServerTask().execute((Void[]) null);
236
                        }
237
                })
238
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
239
                        public void onClick(DialogInterface dialog, int whichButton) {
240
                                // User clicked Cancel so do some stuff
241
                        }
242
                })
243
                .create();
244
        case R.id.view_server_hard_reboot_button:
245
            return new AlertDialog.Builder(ViewServerActivity.this)
246
                .setIcon(R.drawable.alert_dialog_icon)
247
                .setTitle("Hard Reboot")
248
                .setMessage("Are you sure you want to perform a hard reboot?")
249
                .setPositiveButton("Reboot Server", new DialogInterface.OnClickListener() {
250
                        public void onClick(DialogInterface dialog, int whichButton) {
251
                                // User clicked OK so do some stuff
252
                                new HardRebootServerTask().execute((Void[]) null);
253
                        }
254
                })
255
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
256
                        public void onClick(DialogInterface dialog, int whichButton) {
257
                                // User clicked Cancel so do some stuff
258
                        }
259
                })
260
                .create();
261
        case R.id.view_server_resize_button:
262
            return new AlertDialog.Builder(ViewServerActivity.this)
263
            .setItems(flavorNames, new ResizeClickListener())
264
                .setIcon(R.drawable.alert_dialog_icon)
265
                .setTitle("Resize Server")
266
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
267
                        public void onClick(DialogInterface dialog, int whichButton) {
268
                                // User clicked Cancel so do some stuff
269
                        }
270
                })
271
                .create();
272
        case R.id.view_server_delete_button:
273
            return new AlertDialog.Builder(ViewServerActivity.this)
274
                .setIcon(R.drawable.alert_dialog_icon)
275
                .setTitle("Delete Server")
276
                .setMessage("Are you sure you want to delete this server?  This operation cannot be undone and all backups will be deleted.")
277
                .setPositiveButton("Delete Server", new DialogInterface.OnClickListener() {
278
                        public void onClick(DialogInterface dialog, int whichButton) {
279
                                // User clicked OK so do some stuff
280
                                new DeleteServerTask().execute((Void[]) null);
281
                        }
282
                })
283
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
284
                        public void onClick(DialogInterface dialog, int whichButton) {
285
                                // User clicked Cancel so do some stuff
286
                        }
287
                })
288
                .create();
289
        }
290
        return null;
291
    }
292

    
293
    private class ResizeClickListener implements android.content.DialogInterface.OnClickListener {
294

    
295
                public void onClick(DialogInterface dialog, int which) {
296
                        selectedFlavorId = which + "";
297
                        new ResizeServerTask().execute((Void[]) null);
298
                }
299
            
300
    }
301
    
302
    private CloudServersException parseCloudServersException(HttpResponse response) {
303
                CloudServersException cse = new CloudServersException();
304
                try {
305
                    BasicResponseHandler responseHandler = new BasicResponseHandler();
306
                    String body = responseHandler.handleResponse(response);
307
                    CloudServersFaultXMLParser parser = new CloudServersFaultXMLParser();
308
                    SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
309
                    XMLReader xmlReader = saxParser.getXMLReader();
310
                    xmlReader.setContentHandler(parser);
311
                    xmlReader.parse(new InputSource(new StringReader(body)));                            
312
                    cse = parser.getException();                            
313
                } catch (ClientProtocolException e) {
314
                        cse = new CloudServersException();
315
                        cse.setMessage(e.getLocalizedMessage());
316
                } catch (IOException e) {
317
                        cse = new CloudServersException();
318
                        cse.setMessage(e.getLocalizedMessage());
319
                } catch (ParserConfigurationException e) {
320
                        cse = new CloudServersException();
321
                        cse.setMessage(e.getLocalizedMessage());
322
                } catch (SAXException e) {
323
                        cse = new CloudServersException();
324
                        cse.setMessage(e.getLocalizedMessage());
325
                } catch (FactoryConfigurationError e) {
326
                        cse = new CloudServersException();
327
                        cse.setMessage(e.getLocalizedMessage());
328
                }
329
                return cse;
330
    }
331
    
332
    // HTTP request tasks
333
    
334
        private class PollServerTask extends AsyncTask<Void, Void, Server> {
335
            
336
                @Override
337
                protected Server doInBackground(Void... arg0) {
338
                        try {
339
                                server = (new ServerManager()).find(Integer.parseInt(server.getId()), context);
340
                        } catch (NumberFormatException e) {
341
                                // we're polling, so need to show exceptions
342
                        } catch (CloudServersException e) {
343
                                // we're polling, so need to show exceptions
344
                        }
345
                        return server;
346
                }
347
            
348
                @Override
349
                protected void onPostExecute(Server result) {
350
                        server = result;
351
                        loadServerData();
352
                }
353
    }
354

    
355
    
356
        private class SoftRebootServerTask extends AsyncTask<Void, Void, HttpResponse> {
357
            
358
                private CloudServersException exception;
359
                
360
                @Override
361
                protected HttpResponse doInBackground(Void... arg0) {
362
                        HttpResponse resp = null;
363
                        try {
364
                                resp = (new ServerManager()).reboot(server, ServerManager.SOFT_REBOOT, context);
365
                        } catch (CloudServersException e) {
366
                                exception = e;
367
                        }
368
                        return resp;
369
                }
370
            
371
                @Override
372
                protected void onPostExecute(HttpResponse response) {
373

    
374
                        if (response != null) {
375
                                int statusCode = response.getStatusLine().getStatusCode();                                
376
                                if (statusCode != 202) {
377
                                        CloudServersException cse = parseCloudServersException(response);
378
                                        if ("".equals(cse.getMessage())) {
379
                                                showAlert("Error", "There was a problem rebooting your server.");
380
                                        } else {
381
                                                showAlert("Error", "There was a problem rebooting your server: " + cse.getMessage());
382
                                        }
383
                                }
384
                        } else if (exception != null) {
385
                                showAlert("Error", "There was a problem rebooting your server: " + exception.getMessage());
386
                                
387
                        }
388
                }
389
    }
390

    
391
        private class HardRebootServerTask extends AsyncTask<Void, Void, HttpResponse> {
392
            
393
                private CloudServersException exception;
394

    
395
                @Override
396
                protected HttpResponse doInBackground(Void... arg0) {
397
                        HttpResponse resp = null;                        
398
                        try {
399
                                resp = (new ServerManager()).reboot(server, ServerManager.HARD_REBOOT, context);
400
                        } catch (CloudServersException e) {
401
                                exception = e;
402
                        }
403
                        return resp;
404
                }
405
            
406
                @Override
407
                protected void onPostExecute(HttpResponse response) {
408
                        if (response != null) {
409
                                int statusCode = response.getStatusLine().getStatusCode();                        
410
                                if (statusCode != 202) {
411
                                        CloudServersException cse = parseCloudServersException(response);
412
                                        if ("".equals(cse.getMessage())) {
413
                                                showAlert("Error", "There was a problem rebooting your server.");
414
                                        } else {
415
                                                showAlert("Error", "There was a problem rebooting your server: " + cse.getMessage());
416
                                        }
417
                                }
418
                        } else if (exception != null) {
419
                                showAlert("Error", "There was a problem rebooting your server: " + exception.getMessage());
420
                                
421
                        }
422
                }
423
    }
424

    
425
        private class ResizeServerTask extends AsyncTask<Void, Void, HttpResponse> {
426
            
427
                private CloudServersException exception;
428

    
429
                @Override
430
                protected HttpResponse doInBackground(Void... arg0) {
431
                        HttpResponse resp = null;
432
                        try {
433
                                resp = (new ServerManager()).resize(server, Integer.parseInt(selectedFlavorId), context);
434
                        } catch (CloudServersException e) {
435
                                exception = e;
436
                        }
437
                        return resp;
438
                }
439
            
440
                @Override
441
                protected void onPostExecute(HttpResponse response) {
442
                        if (response != null) {
443
                                int statusCode = response.getStatusLine().getStatusCode();                        
444
                                if (statusCode == 202) {
445
                                        new PollServerTask().execute((Void[]) null);
446
                                } else {                                        
447
                                        CloudServersException cse = parseCloudServersException(response);
448
                                        if ("".equals(cse.getMessage())) {
449
                                                showAlert("Error", "There was a problem deleting your server.");
450
                                        } else {
451
                                                showAlert("Error", "There was a problem deleting your server: " + cse.getMessage());
452
                                        }                                        
453
                                }
454
                        } else if (exception != null) {
455
                                showAlert("Error", "There was a problem resizing your server: " + exception.getMessage());
456
                                
457
                        }
458
                        
459
                }
460
    }
461
        
462
        private class DeleteServerTask extends AsyncTask<Void, Void, HttpResponse> {
463
            
464
                private CloudServersException exception;
465

    
466
                @Override
467
                protected HttpResponse doInBackground(Void... arg0) {
468
                        HttpResponse resp = null;
469
                        try {
470
                                resp = (new ServerManager()).delete(server, context);
471
                        } catch (CloudServersException e) {
472
                                exception = e;
473
                        }
474
                        return resp;
475
                }
476
            
477
                @Override
478
                protected void onPostExecute(HttpResponse response) {
479
                        if (response != null) {
480
                                int statusCode = response.getStatusLine().getStatusCode();
481
                                if (statusCode == 202) {
482
                                        setResult(Activity.RESULT_OK);
483
                                        finish();
484
                                } else {
485
                                        CloudServersException cse = parseCloudServersException(response);
486
                                        if ("".equals(cse.getMessage())) {
487
                                                showAlert("Error", "There was a problem deleting your server.");
488
                                        } else {
489
                                                showAlert("Error", "There was a problem deleting your server: " + cse.getMessage());
490
                                        }
491
                                }
492
                        } else if (exception != null) {
493
                                showAlert("Error", "There was a problem deleting your server: " + exception.getMessage());                                
494
                        }                        
495
                }
496
    }
497
}