root / src / com / rackspacecloud / android / AddMoreNodesActivity.java @ 4f9d1a69
History | View | Annotate | Download (13.7 kB)
1 |
package com.rackspacecloud.android; |
---|---|
2 |
|
3 |
import java.io.IOException; |
4 |
import java.io.StringReader; |
5 |
import java.util.ArrayList; |
6 |
import java.util.Arrays; |
7 |
|
8 |
import javax.xml.parsers.FactoryConfigurationError; |
9 |
import javax.xml.parsers.ParserConfigurationException; |
10 |
import javax.xml.parsers.SAXParser; |
11 |
import javax.xml.parsers.SAXParserFactory; |
12 |
|
13 |
import org.apache.http.HttpResponse; |
14 |
import org.apache.http.client.ClientProtocolException; |
15 |
import org.apache.http.impl.client.BasicResponseHandler; |
16 |
import org.xml.sax.InputSource; |
17 |
import org.xml.sax.SAXException; |
18 |
import org.xml.sax.XMLReader; |
19 |
|
20 |
import com.rackspace.cloud.loadbalancer.api.client.LoadBalancer; |
21 |
import com.rackspace.cloud.loadbalancer.api.client.LoadBalancerManager; |
22 |
import com.rackspace.cloud.loadbalancer.api.client.Node; |
23 |
import com.rackspace.cloud.servers.api.client.Account; |
24 |
import com.rackspace.cloud.servers.api.client.CloudServersException; |
25 |
import com.rackspace.cloud.servers.api.client.Server; |
26 |
import com.rackspace.cloud.servers.api.client.ServerManager; |
27 |
import com.rackspace.cloud.servers.api.client.http.HttpBundle; |
28 |
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser; |
29 |
|
30 |
import android.app.Activity; |
31 |
import android.app.AlertDialog; |
32 |
import android.app.ListActivity; |
33 |
import android.app.ProgressDialog; |
34 |
import android.content.Context; |
35 |
import android.content.DialogInterface; |
36 |
import android.content.Intent; |
37 |
import android.os.AsyncTask; |
38 |
import android.os.Bundle; |
39 |
import android.util.Log; |
40 |
import android.view.LayoutInflater; |
41 |
import android.view.View; |
42 |
import android.view.View.OnClickListener; |
43 |
import android.view.ViewGroup; |
44 |
import android.view.WindowManager; |
45 |
import android.view.ViewGroup.LayoutParams; |
46 |
import android.widget.ArrayAdapter; |
47 |
import android.widget.Button; |
48 |
import android.widget.CheckBox; |
49 |
import android.widget.CompoundButton; |
50 |
import android.widget.LinearLayout; |
51 |
import android.widget.ListView; |
52 |
import android.widget.CompoundButton.OnCheckedChangeListener; |
53 |
import android.widget.ImageView; |
54 |
import android.widget.ProgressBar; |
55 |
import android.widget.TextView; |
56 |
|
57 |
public class AddMoreNodesActivity extends ListActivity { |
58 |
|
59 |
private static final int ADD_NODE_CODE = 178; |
60 |
private Server[] servers; |
61 |
private Context context; |
62 |
private int lastCheckedPos; |
63 |
private ArrayList<Node> nodes; |
64 |
private ArrayList<Node> nodesToAdd; |
65 |
private LoadBalancer loadBalancer;
|
66 |
ProgressDialog pDialog; |
67 |
|
68 |
@Override
|
69 |
public void onCreate(Bundle savedInstanceState) { |
70 |
super.onCreate(savedInstanceState);
|
71 |
nodes = (ArrayList<Node>) this.getIntent().getExtras().get("nodes"); |
72 |
loadBalancer = (LoadBalancer) this.getIntent().getExtras().get("loadBalancer"); |
73 |
setContentView(R.layout.addnodes); |
74 |
restoreState(savedInstanceState); |
75 |
} |
76 |
|
77 |
@Override
|
78 |
protected void onSaveInstanceState(Bundle outState) { |
79 |
super.onSaveInstanceState(outState);
|
80 |
outState.putSerializable("nodes", nodes);
|
81 |
outState.putSerializable("loadBalancer", loadBalancer);
|
82 |
outState.putSerializable("nodesToAdd", nodesToAdd);
|
83 |
} |
84 |
|
85 |
private void restoreState(Bundle state) { |
86 |
|
87 |
context = getApplicationContext(); |
88 |
|
89 |
if (state != null && state.containsKey("nodes")){ |
90 |
nodes = (ArrayList<Node>) state.getSerializable("nodes"); |
91 |
if(nodes == null){ |
92 |
nodes = new ArrayList<Node>(); |
93 |
} |
94 |
} |
95 |
|
96 |
if (state != null && state.containsKey("nodesToAdd")){ |
97 |
nodesToAdd = (ArrayList<Node>) state.getSerializable("nodesToAdd"); |
98 |
} |
99 |
else{
|
100 |
nodesToAdd = new ArrayList<Node>(); |
101 |
} |
102 |
|
103 |
if (state != null && state.containsKey("server")) { |
104 |
servers = (Server[]) state.getSerializable("servers"); |
105 |
if (servers.length == 0) { |
106 |
displayNoServersCell(); |
107 |
} else {
|
108 |
getListView().setDividerHeight(1); // restore divider lines |
109 |
setListAdapter(new ServerAdapter());
|
110 |
} |
111 |
} else {
|
112 |
loadServers(); |
113 |
} |
114 |
|
115 |
Button submitNodes = (Button) findViewById(R.id.submit_nodes_button); |
116 |
submitNodes.setOnClickListener(new OnClickListener() {
|
117 |
|
118 |
@Override
|
119 |
public void onClick(View v) { |
120 |
new AddNodesTask().execute();
|
121 |
} |
122 |
}); |
123 |
} |
124 |
|
125 |
@Override
|
126 |
public void onBackPressed(){ |
127 |
setResult(RESULT_CANCELED); |
128 |
finish(); |
129 |
} |
130 |
|
131 |
private void displayNoServersCell() { |
132 |
String a[] = new String[1]; |
133 |
a[0] = "No Servers"; |
134 |
setListAdapter(new ArrayAdapter<String>(this, R.layout.noserverscell, R.id.no_servers_label, a)); |
135 |
getListView().setTextFilterEnabled(true);
|
136 |
getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row |
137 |
getListView().setItemsCanFocus(false);
|
138 |
} |
139 |
|
140 |
private void setServerList(ArrayList<Server> servers) { |
141 |
if (servers == null) { |
142 |
servers = new ArrayList<Server>(); |
143 |
} |
144 |
|
145 |
for(int i = 0; i < servers.size(); i++) { |
146 |
/*
|
147 |
* if all the IP's of a server are
|
148 |
* already used as nodes, we do not
|
149 |
* need to display that server
|
150 |
*/
|
151 |
if(!notAllIpsNodes(servers.get(i))){
|
152 |
servers.remove(i); |
153 |
} |
154 |
} |
155 |
|
156 |
String[] serverNames = new String[servers.size()]; |
157 |
this.servers = new Server[servers.size()]; |
158 |
|
159 |
for(int i = 0; i < servers.size(); i++){ |
160 |
serverNames[i] = servers.get(i).getName(); |
161 |
this.servers[i] = servers.get(i);
|
162 |
} |
163 |
|
164 |
if (serverNames.length == 0) { |
165 |
displayNoServersCell(); |
166 |
} else {
|
167 |
getListView().setDividerHeight(1); // restore divider lines |
168 |
setListAdapter(new ServerAdapter());
|
169 |
} |
170 |
} |
171 |
|
172 |
/*
|
173 |
* determine if all the IP's of a server are
|
174 |
* already used as nodes
|
175 |
*/
|
176 |
private boolean notAllIpsNodes(Server server){ |
177 |
for(String address : server.getPrivateIpAddresses()){ |
178 |
if(!nodeHasAddress(address)){
|
179 |
return true; |
180 |
} |
181 |
} |
182 |
for(String address : server.getPublicIpAddresses()){ |
183 |
if(!nodeHasAddress(address)){
|
184 |
return true; |
185 |
} |
186 |
} |
187 |
return false; |
188 |
} |
189 |
|
190 |
/*
|
191 |
* determine is an existing node has IP Address,
|
192 |
* address
|
193 |
*/
|
194 |
private boolean nodeHasAddress(String address){ |
195 |
for(Node n : nodes){
|
196 |
if(n.getAddress().equals(address)){
|
197 |
return true; |
198 |
} |
199 |
} |
200 |
return false; |
201 |
} |
202 |
|
203 |
private void loadServers() { |
204 |
new LoadServersTask().execute((Void[]) null); |
205 |
} |
206 |
|
207 |
protected void showDialog() { |
208 |
pDialog = new ProgressDialog(this, R.style.NewDialog); |
209 |
// // Set blur to background
|
210 |
WindowManager.LayoutParams lp = pDialog.getWindow().getAttributes(); |
211 |
lp.dimAmount = 0.0f;
|
212 |
pDialog.getWindow().setAttributes(lp); |
213 |
pDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); |
214 |
pDialog.show(); |
215 |
pDialog.setContentView(new ProgressBar(this), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); |
216 |
} |
217 |
|
218 |
private void showAlert(String title, String message) { |
219 |
AlertDialog alert = new AlertDialog.Builder(this).create(); |
220 |
alert.setTitle(title); |
221 |
alert.setMessage(message); |
222 |
alert.setButton("OK", new DialogInterface.OnClickListener() { |
223 |
public void onClick(DialogInterface dialog, int which) { |
224 |
return;
|
225 |
} }); |
226 |
alert.show(); |
227 |
} |
228 |
|
229 |
// * Adapter/
|
230 |
class ServerAdapter extends ArrayAdapter<Server> { |
231 |
ServerAdapter() { |
232 |
super(AddMoreNodesActivity.this, R.layout.listservernodecell, servers);
|
233 |
} |
234 |
|
235 |
public View getView(int position, View convertView, ViewGroup parent) { |
236 |
|
237 |
final Server server = servers[position];
|
238 |
LayoutInflater inflater = getLayoutInflater(); |
239 |
View row = inflater.inflate(R.layout.listservernodecell, parent, false); |
240 |
|
241 |
TextView label = (TextView) row.findViewById(R.id.label); |
242 |
label.setText(server.getName()); |
243 |
|
244 |
TextView sublabel = (TextView) row.findViewById(R.id.sublabel); |
245 |
sublabel.setText(server.getFlavor().getName() + " - " + server.getImage().getName());
|
246 |
|
247 |
ImageView icon = (ImageView) row.findViewById(R.id.icon); |
248 |
icon.setImageResource(server.getImage().iconResourceId()); |
249 |
|
250 |
String[] publicIp = server.getPublicIpAddresses(); |
251 |
String[] privateIp = server.getPrivateIpAddresses(); |
252 |
|
253 |
ArrayList<String> ipAddressList = new ArrayList<String>(); |
254 |
for(int i = 0; i < privateIp.length; i++){ |
255 |
if(!nodeHasAddress(privateIp[i])){
|
256 |
ipAddressList.add(privateIp[i]); |
257 |
} |
258 |
} |
259 |
for(int i = 0; i < publicIp.length; i++){ |
260 |
if(!nodeHasAddress(publicIp[i])){
|
261 |
ipAddressList.add(publicIp[i]); |
262 |
} |
263 |
} |
264 |
|
265 |
final String[] ipAddresses = ipAddressList.toArray(new String[ipAddressList.size()]); |
266 |
final int pos = position; |
267 |
CheckBox add = (CheckBox) row.findViewById(R.id.add_node_checkbox); |
268 |
|
269 |
add.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
270 |
|
271 |
@Override
|
272 |
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
273 |
if(isChecked){
|
274 |
lastCheckedPos = pos; |
275 |
Intent viewIntent = new Intent(context, AddNodeActivity.class);
|
276 |
viewIntent.putExtra("ipAddresses", ipAddresses);
|
277 |
startActivityForResult(viewIntent, ADD_NODE_CODE); |
278 |
} |
279 |
else{
|
280 |
removeNodeFromList(server); |
281 |
} |
282 |
} |
283 |
}); |
284 |
|
285 |
return(row);
|
286 |
} |
287 |
} |
288 |
|
289 |
/*
|
290 |
* need to remove by id because that is
|
291 |
* what is unique
|
292 |
*/
|
293 |
private void removeNodeFromList(Server server){ |
294 |
for(int i = 0; i < nodes.size(); i++){ |
295 |
Node node = nodes.get(i); |
296 |
if(serverHasIp(server, node.getAddress())){
|
297 |
nodes.remove(i); |
298 |
break;
|
299 |
} |
300 |
} |
301 |
} |
302 |
|
303 |
private boolean serverHasIp(Server server, String address){ |
304 |
String[] addresses = server.getPrivateIpAddresses(); |
305 |
for(int i = 0; i < addresses.length; i++){ |
306 |
if(addresses[i].equals(address)){
|
307 |
return true; |
308 |
} |
309 |
} |
310 |
addresses = server.getPublicIpAddresses(); |
311 |
for(int i = 0; i < addresses.length; i++){ |
312 |
if(addresses[i].equals(address)){
|
313 |
return true; |
314 |
} |
315 |
} |
316 |
return false; |
317 |
} |
318 |
|
319 |
private void startLoadBalancerError(String message, HttpBundle bundle){ |
320 |
Intent viewIntent = new Intent(getApplicationContext(), ServerErrorActivity.class);
|
321 |
viewIntent.putExtra("errorMessage", message);
|
322 |
viewIntent.putExtra("response", bundle.getResponseText());
|
323 |
viewIntent.putExtra("request", bundle.getCurlRequest());
|
324 |
startActivity(viewIntent); |
325 |
} |
326 |
|
327 |
//using cloudServersException, it works for us too
|
328 |
private CloudServersException parseCloudServersException(HttpResponse response) {
|
329 |
CloudServersException cse = new CloudServersException();
|
330 |
try {
|
331 |
BasicResponseHandler responseHandler = new BasicResponseHandler();
|
332 |
String body = responseHandler.handleResponse(response);
|
333 |
CloudServersFaultXMLParser parser = new CloudServersFaultXMLParser();
|
334 |
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); |
335 |
XMLReader xmlReader = saxParser.getXMLReader(); |
336 |
xmlReader.setContentHandler(parser); |
337 |
xmlReader.parse(new InputSource(new StringReader(body))); |
338 |
cse = parser.getException(); |
339 |
} catch (ClientProtocolException e) {
|
340 |
cse = new CloudServersException();
|
341 |
cse.setMessage(e.getLocalizedMessage()); |
342 |
} catch (IOException e) { |
343 |
cse = new CloudServersException();
|
344 |
cse.setMessage(e.getLocalizedMessage()); |
345 |
} catch (ParserConfigurationException e) { |
346 |
cse = new CloudServersException();
|
347 |
cse.setMessage(e.getLocalizedMessage()); |
348 |
} catch (SAXException e) {
|
349 |
cse = new CloudServersException();
|
350 |
cse.setMessage(e.getLocalizedMessage()); |
351 |
} catch (FactoryConfigurationError e) { |
352 |
cse = new CloudServersException();
|
353 |
cse.setMessage(e.getLocalizedMessage()); |
354 |
} |
355 |
return cse;
|
356 |
} |
357 |
|
358 |
private class AddNodesTask extends AsyncTask<Void, Void, HttpBundle> { |
359 |
private CloudServersException exception;
|
360 |
|
361 |
protected void onPreExecute(){ |
362 |
showDialog(); |
363 |
} |
364 |
|
365 |
@Override
|
366 |
protected HttpBundle doInBackground(Void... arg0) { |
367 |
HttpBundle bundle = null;
|
368 |
try {
|
369 |
bundle = (new LoadBalancerManager(context)).addNodes(loadBalancer, nodesToAdd);
|
370 |
} catch (CloudServersException e) {
|
371 |
exception = e; |
372 |
} |
373 |
return bundle;
|
374 |
} |
375 |
|
376 |
@Override
|
377 |
protected void onPostExecute(HttpBundle bundle) { |
378 |
pDialog.dismiss(); |
379 |
HttpResponse response = bundle.getResponse(); |
380 |
if (response != null) { |
381 |
int statusCode = response.getStatusLine().getStatusCode();
|
382 |
if (statusCode == 202) { |
383 |
setResult(Activity.RESULT_OK); |
384 |
finish(); |
385 |
} else {
|
386 |
CloudServersException cse = parseCloudServersException(response); |
387 |
if ("".equals(cse.getMessage())) { |
388 |
startLoadBalancerError("There was a problem creating your load balancer.", bundle);
|
389 |
} else {
|
390 |
//if container with same name already exists
|
391 |
startLoadBalancerError("There was a problem creating your load balancer: " + cse.getMessage() + "\n See details for more information", bundle); |
392 |
} |
393 |
} |
394 |
} else if (exception != null) { |
395 |
startLoadBalancerError("There was a problem creating your container: " + exception.getMessage()+"\n See details for more information.", bundle); |
396 |
} |
397 |
finish(); |
398 |
} |
399 |
} |
400 |
|
401 |
private class LoadServersTask extends AsyncTask<Void, Void, ArrayList<Server>> { |
402 |
private CloudServersException exception;
|
403 |
|
404 |
@Override
|
405 |
protected void onPreExecute(){ |
406 |
showDialog(); |
407 |
} |
408 |
|
409 |
@Override
|
410 |
protected ArrayList<Server> doInBackground(Void... arg0) { |
411 |
ArrayList<Server> servers = null; |
412 |
try {
|
413 |
servers = (new ServerManager()).createList(true, context); |
414 |
} catch (CloudServersException e) {
|
415 |
exception = e; |
416 |
} |
417 |
pDialog.dismiss(); |
418 |
return servers;
|
419 |
} |
420 |
|
421 |
@Override
|
422 |
protected void onPostExecute(ArrayList<Server> result) { |
423 |
if (exception != null) { |
424 |
showAlert("Error", exception.getMessage());
|
425 |
} |
426 |
setServerList(result); |
427 |
} |
428 |
} |
429 |
|
430 |
protected void onActivityResult(int requestCode, int resultCode, Intent data){ |
431 |
int pos = lastCheckedPos;
|
432 |
if(requestCode == ADD_NODE_CODE && resultCode == RESULT_OK){
|
433 |
Node node = new Node();
|
434 |
node.setAddress(data.getStringExtra("nodeIp"));
|
435 |
node.setCondition(data.getStringExtra("nodeCondition"));
|
436 |
node.setName(servers[pos].getName()); |
437 |
node.setPort(data.getStringExtra("nodePort"));
|
438 |
Log.d("info", "nodesToAdd is null? " + Boolean.toString(nodesToAdd == null)); |
439 |
nodesToAdd.add(node); |
440 |
} |
441 |
else if(requestCode == ADD_NODE_CODE && resultCode == RESULT_CANCELED){ |
442 |
//uncheck the node at lastCheckedPos
|
443 |
LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); |
444 |
ListView serversList = (ListView) linear.findViewById(android.R.id.list); |
445 |
View row = serversList.getChildAt(pos);
|
446 |
CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox); |
447 |
checkBox.setChecked(false);
|
448 |
} |
449 |
} |
450 |
|
451 |
|
452 |
} |