Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / AddNodesActivity.java @ b2a2d2f1

History | View | Annotate | Download (15.9 kB)

1
package com.rackspacecloud.android;
2

    
3
import java.util.ArrayList;
4

    
5
import com.rackspace.cloud.loadbalancer.api.client.Node;
6
import com.rackspace.cloud.servers.api.client.CloudServersException;
7
import com.rackspace.cloud.servers.api.client.Server;
8
import com.rackspace.cloud.servers.api.client.ServerManager;
9

    
10
import android.content.Intent;
11
import android.os.AsyncTask;
12
import android.os.Bundle;
13
import android.util.Log;
14
import android.view.LayoutInflater;
15
import android.view.View;
16
import android.view.View.OnClickListener;
17
import android.view.ViewGroup;
18
import android.widget.ArrayAdapter;
19
import android.widget.Button;
20
import android.widget.CheckBox;
21
import android.widget.CompoundButton;
22
import android.widget.LinearLayout;
23
import android.widget.ListView;
24
import android.widget.CompoundButton.OnCheckedChangeListener;
25
import android.widget.TextView;
26

    
27
public class AddNodesActivity extends CloudListActivity {
28

    
29
        private static final int ADD_NODE_CODE = 178;
30
        private static final int ADD_EXTERNAL_NODE_CODE = 188;
31

    
32
        //servers are what are displayed in the ListView
33
        //(possible and checked nodes)
34
        private ArrayList<Server> possibleNodes;
35
        //nodes are the nodes the user has selected
36
        private ArrayList<Node> nodes;
37
        //the last position in the listview that was clicked
38
        private int lastCheckedPos;
39
        //the location in nodes of the last node that was clicked
40
        private int positionOfNode;
41

    
42
        @SuppressWarnings("unchecked")
43
        @Override
44
        public void onCreate(Bundle savedInstanceState) {
45
                super.onCreate(savedInstanceState);
46
                nodes = (ArrayList<Node>) this.getIntent().getExtras().get("nodes");
47
                possibleNodes = (ArrayList<Server>) this.getIntent().getExtras().get("possibleNodes");
48
                setContentView(R.layout.addnodes);
49
                restoreState(savedInstanceState);
50
        }
51

    
52
        @Override
53
        protected void onSaveInstanceState(Bundle outState) {
54
                super.onSaveInstanceState(outState);
55
                outState.putSerializable("nodes", nodes);
56
                outState.putSerializable("possibleNodes", possibleNodes);
57
                outState.putInt("lastCheckedPos", lastCheckedPos);
58
                outState.putInt("positionOfNode", positionOfNode);
59
        }
60

    
61
        @SuppressWarnings("unchecked")
62
        protected void restoreState(Bundle state) {
63
                super.restoreState(state);
64

    
65
                if (state != null && state.containsKey("nodes")){
66
                        nodes = (ArrayList<Node>) state.getSerializable("nodes");
67
                        if(nodes == null){
68
                                nodes = new ArrayList<Node>();
69
                        }
70
                }
71

    
72
                if (state != null && state.containsKey("lastCheckedPos")){
73
                        lastCheckedPos = (Integer) state.getSerializable("lastCheckedPos");
74
                }
75

    
76
                if (state != null && state.containsKey("positionOfNode")){
77
                        positionOfNode = (Integer) state.getSerializable("positionOfNode");
78
                }
79

    
80
                if (state != null && state.containsKey("possibleNodes") && state.getSerializable("possibleNodes") != null) {
81
                        possibleNodes = (ArrayList<Server>) state.getSerializable("possibleNodes");
82
                        if (possibleNodes.size() == 0) {
83
                                displayNoServersCell();
84
                        } else {
85
                                getListView().setDividerHeight(1); // restore divider lines
86
                                setListAdapter(new ServerAdapter());
87
                        }
88
                } else {
89
                        loadServers();
90
                }
91

    
92
                Button submitNodes = (Button) findViewById(R.id.submit_nodes_button);
93
                submitNodes.setOnClickListener(new OnClickListener() {
94

    
95
                        @Override
96
                        public void onClick(View v) {
97
                                Intent viewIntent = new Intent();
98
                                viewIntent.putExtra("nodes", nodes);
99
                                viewIntent.putExtra("possibleNodes", possibleNodes);
100
                                setResult(RESULT_OK, viewIntent);
101
                                printTheNodes();
102
                                finish();
103
                        }
104
                });
105

    
106
                Button addExternalNode = (Button) findViewById(R.id.add_external_node);
107
                addExternalNode.setOnClickListener(new OnClickListener() {
108

    
109
                        @Override
110
                        public void onClick(View v) {
111
                                positionOfNode = -1;
112
                                Intent viewIntent = new Intent(getContext(), AddExternalNodeActivity.class);
113
                                //when first creating a load balancer
114
                                //weighting nodes in not an option
115
                                viewIntent.putExtra("weighted", false);
116
                                startActivityForResult(viewIntent, ADD_EXTERNAL_NODE_CODE);
117
                        }
118
                });
119
        }
120

    
121
        @Override
122
        public void onBackPressed(){
123
                setResult(RESULT_CANCELED);
124
                finish();
125
        }
126

    
127
        protected void onListItemClick(ListView l, View v, int position, long id) {
128
                if (possibleNodes != null && possibleNodes.size() > 0) {
129
                        if(!possibleNodes.get(position).getName().equals("External Node")){
130
                                LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); 
131
                                ListView serversList = (ListView) linear.findViewById(android.R.id.list);
132
                                View row = serversList.getChildAt(position);
133
                                CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox);
134
                                if(!checkBox.isChecked()){
135
                                        //if the checkbox was not previously checked, treat the listItemClick
136
                                        //the same as checking the checkbox
137
                                        checkBox.setChecked(!checkBox.isChecked());
138
                                } else {
139
                                        //if the checkbox was already checked when the listItemClick occurred,
140
                                        //then treat it like an edit
141

    
142
                                        Server server = possibleNodes.get(position);
143

    
144
                                        //Need to put all the ip's of the server into one
145
                                        //list so they can all be displayed in one spinner
146
                                        String[] ipAddresses = getAllIpsOfServer(server);
147

    
148
                                        Node node = getNodeFromServer(server);
149

    
150
                                        positionOfNode = findNodePosition(node);
151
                                        lastCheckedPos = position;
152

    
153
                                        Intent viewIntent = new Intent(getContext(), AddNodeActivity.class);
154
                                        viewIntent.putExtra("ipAddresses", ipAddresses);
155
                                        viewIntent.putExtra("name", server.getName());
156
                                        if(node != null){
157
                                                viewIntent.putExtra("node", node);
158
                                        }
159
                                        //weighted is false, because on initial node add
160
                                        //weight is not option
161
                                        viewIntent.putExtra("weighted", false);
162
                                        startActivityForResult(viewIntent, ADD_NODE_CODE);
163
                                }
164
                        } else {
165
                                //When clicked on an external node
166
                                Server server = possibleNodes.get(position);
167
                                Node node = getNodeFromServer(server);
168
                                positionOfNode = findNodePosition(node);
169
                                lastCheckedPos = position;
170
                                Intent viewIntent = new Intent(getContext(), AddExternalNodeActivity.class);
171
                                if(node != null){
172
                                        viewIntent.putExtra("node", node);
173
                                }
174
                                //weighted is false, because on initial node add
175
                                //weight is not option
176
                                viewIntent.putExtra("weighted", false);
177
                                startActivityForResult(viewIntent, ADD_EXTERNAL_NODE_CODE);
178
                        }
179
                }
180
        }
181

    
182
        //return the location of node in nodes
183
        //if it is no in there then -1
184
        private int findNodePosition(Node node){
185
                for(int i = 0; i < nodes.size(); i++){
186
                        String address = node.getAddress();
187
                        if(address.equals(nodes.get(i).getAddress())){
188
                                return i;
189
                        }
190
                }
191
                return -1;
192
        }
193

    
194
        private void displayNoServersCell() {
195
                String a[] = new String[1];
196
                a[0] = "No Nodes";
197
                setListAdapter(new ArrayAdapter<String>(this, R.layout.nonodescell, R.id.no_nodes_label, a));
198
                getListView().setTextFilterEnabled(true);
199
                getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row
200
                getListView().setItemsCanFocus(false);
201
        }
202

    
203
        private void setServerList(ArrayList<Server> servers) {
204
                if (servers == null) {
205
                        servers = new ArrayList<Server>();
206
                }
207
                String[] serverNames = new String[servers.size()];
208
                this.possibleNodes = new ArrayList<Server>();
209

    
210
                if (servers != null) {
211
                        for (int i = 0; i < servers.size(); i++) {
212
                                Server server = servers.get(i);
213
                                this.possibleNodes.add(i, server);
214
                                serverNames[i] = server.getName();
215
                        }
216
                }
217

    
218
                if (serverNames.length == 0) {
219
                        displayNoServersCell();
220
                } else {
221
                        getListView().setDividerHeight(1); // restore divider lines 
222
                        setListAdapter(new ServerAdapter());
223
                }
224
        }
225

    
226
        private void loadServers() {
227
                new LoadServersTask().execute((Void[]) null);
228
        }
229

    
230
        // * Adapter/
231
        class ServerAdapter extends ArrayAdapter<Server> {
232
                ServerAdapter() {
233
                        super(AddNodesActivity.this, R.layout.listservernodecell, possibleNodes);
234
                }
235

    
236
                public View getView(int position, View convertView, ViewGroup parent) {
237

    
238
                        final Server server = possibleNodes.get(position);
239
                        LayoutInflater inflater = getLayoutInflater();
240
                        View row = inflater.inflate(R.layout.listservernodecell, parent, false);
241

    
242
                        TextView label = (TextView) row.findViewById(R.id.label);
243
                        label.setText(server.getName());
244

    
245
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
246
                        if(server.getName().equals("External Node")){
247
                                sublabel.setText(server.getPrivateIpAddresses()[0]);
248
                        } else {
249
                                sublabel.setText(server.getFlavor().getName() + " - " + server.getImage().getName());
250
                        }
251

    
252
                        //Need to put all the ip's of the server into one
253
                        //list so they can all be displayed in one spinner
254
                        final String[] ipAddresses = getAllIpsOfServer(server);
255

    
256
                        final int pos = position;
257
                        CheckBox add = (CheckBox) row.findViewById(R.id.add_node_checkbox);
258

    
259
                        if(inNodeList(server)){
260
                                add.setChecked(true);
261
                        }
262

    
263
                        add.setOnCheckedChangeListener(new OnCheckedChangeListener() {
264

    
265
                                @Override
266
                                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
267
                                        if(isChecked){
268
                                                //if node is being check it won't be in nodes positionOfNode is -1
269
                                                positionOfNode = -1;
270
                                                lastCheckedPos = pos;
271
                                                Intent viewIntent = new Intent(getContext(), AddNodeActivity.class);
272
                                                viewIntent.putExtra("ipAddresses", ipAddresses);
273
                                                viewIntent.putExtra("name", server.getName());
274
                                                //weighted is false, because on initial node add
275
                                                //weight is not option
276
                                                viewIntent.putExtra("weighted", false);
277
                                                startActivityForResult(viewIntent, ADD_NODE_CODE);
278
                                        }
279
                                        else{
280
                                                removeNodeFromList(server);
281
                                                if(server.getName().equals("External Node")){
282
                                                        possibleNodes.remove(server);
283
                                                        setServerList(possibleNodes);
284
                                                }
285
                                        }
286
                                }
287
                        });
288

    
289
                        return(row);
290
                }
291

    
292
                //returns true if an ip from server
293
                //is the address of one of the nodes
294
                private boolean inNodeList(Server server){
295
                        for(Node node : nodes){
296
                                String nodeIp = node.getAddress();
297
                                if(serverHasIp(server, nodeIp)){
298
                                        return true;
299
                                }
300
                        }
301
                        return false;
302
                }
303

    
304
                /*
305
                 *  need to remove by id because that is 
306
                 *  what is unique
307
                 */
308
                private void removeNodeFromList(Server server){
309
                        for(int i = 0; i < nodes.size(); i++){
310
                                Node node = nodes.get(i);
311
                                if(serverHasIp(server, node.getAddress())){
312
                                        nodes.remove(i);
313
                                        break;
314
                                }
315
                        }
316
                }
317
        }
318

    
319
        private String getNameFromIp(String address){
320
                for(Server s: possibleNodes){
321
                        if(serverHasIp(s, address)){
322
                                return s.getName();
323
                        }
324
                }
325
                return "";
326
        }
327

    
328
        //returns true if address is an address of
329
        //one of the users cloud servers
330
        private boolean ipInList(String address){
331
                for(Server s : possibleNodes){
332
                        if(serverHasIp(s, address) && !s.getName().equals("External Node")){
333
                                return true;
334
                        }
335
                }
336
                return false;
337
        }
338

    
339
        //returns true if address is one of server's addresses
340
        private boolean serverHasIp(Server server, String address){
341
                String[] addresses = server.getPrivateIpAddresses();
342
                if(addresses != null){
343
                        for(int i = 0; i < addresses.length; i++){
344
                                if(addresses[i].equals(address)){
345
                                        return true;
346
                                }
347
                        }
348
                }
349
                addresses = server.getPublicIpAddresses();
350
                if(addresses != null){
351
                        for(int i = 0; i < addresses.length; i++){
352
                                if(addresses[i].equals(address)){
353
                                        return true;
354
                                }
355
                        }
356
                }
357
                return false;
358
        }
359

    
360
        //returns the node that is using an ip from server
361
        private Node getNodeFromServer(Server server){
362
                for(Node node : nodes){
363
                        if(serverHasIp(server, node.getAddress())){
364
                                return node;
365
                        }
366
                }
367
                return null;
368
        }
369

    
370
        //returns an array of all the ip's of server
371
        private String[] getAllIpsOfServer(Server server){
372
                String[] publicIp = server.getPublicIpAddresses();
373
                String[] privateIp = server.getPrivateIpAddresses();
374
                if(publicIp == null){
375
                        publicIp = new String[0];
376
                }
377
                if(privateIp == null){
378
                        privateIp = new String[0];
379
                }
380
                String[] ipAddresses = new String[privateIp.length + publicIp.length];
381
                for(int i = 0; i < privateIp.length; i++){
382
                        ipAddresses[i] = privateIp[i];
383
                }
384
                for(int i = 0; i < publicIp.length; i++){
385
                        ipAddresses[i+privateIp.length] = publicIp[i];
386
                }
387

    
388
                return ipAddresses;
389
        }
390

    
391
        private class LoadServersTask extends AsyncTask<Void, Void, ArrayList<Server>> {
392
                private CloudServersException exception;
393

    
394
                @Override
395
                protected void onPreExecute(){
396
                        showDialog();
397
                }
398

    
399
                @Override
400
                protected ArrayList<Server> doInBackground(Void... arg0) {
401
                        ArrayList<Server> servers = null;
402
                        try {
403
                                servers = (new ServerManager()).createList(true, getContext());
404
                        } catch (CloudServersException e) {
405
                                exception = e;                                
406
                        }
407
                        return servers;
408
                }
409

    
410
                @Override
411
                protected void onPostExecute(ArrayList<Server> result) {
412
                        hideDialog();
413
                        if (exception != null) {
414
                                showAlert("Error", exception.getMessage());
415
                        }
416

    
417
                        //Add the external nodes
418
                        for(int i = 0; i < nodes.size(); i++){
419
                                if(nodes.get(i).getName().equals("External Node")){
420
                                        Server server = new Server();
421
                                        server.setName("External Node");
422
                                        String[] ip = {nodes.get(i).getAddress()};
423
                                        server.setPrivateIpAddresses(ip);
424
                                        result.add(server);
425
                                }
426
                        }
427
                        setServerList(result);
428
                }
429
        }
430

    
431
        //removes a node with ip of address from nodes
432
        //if one doesnt exists doesn nothing
433
        /*
434
        private void removeNodeWithIp(String address){
435
                for(int i = 0; i < nodes.size(); i++){
436
                        Node n = nodes.get(i);
437
                        if(n.getAddress().equals(address)){
438
                                nodes.remove(i);
439
                                break;
440
                        }
441
                }
442
        }
443
        */
444

    
445
        protected void onActivityResult(int requestCode, int resultCode, Intent data){        
446
                int pos = lastCheckedPos;
447
                if(requestCode == ADD_NODE_CODE && resultCode == RESULT_OK){
448
                        //data will be null is user back out on edit
449
                        //we dont need to do anything then
450
                        //if new node added data won't be null
451
                        //so create the new node and add it to the list
452
                        if(data != null){
453
                                //will remove the node if it's already in the list 
454
                                //so we can update it
455
                                //removeNodeWithIp(data.getStringExtra("nodeIp"));
456
                                if(positionOfNode >= 0){
457
                                        nodes.remove(positionOfNode);
458
                                }
459

    
460
                                Node node = new Node();
461
                                node.setAddress(data.getStringExtra("nodeIp"));
462
                                node.setCondition(data.getStringExtra("nodeCondition"));
463
                                node.setName(possibleNodes.get(pos).getName());
464
                                node.setPort(data.getStringExtra("nodePort"));
465
                                node.setWeight(data.getStringExtra("nodeWeight"));
466
                                nodes.add(node);
467
                        }
468
                }
469
                else if(requestCode == ADD_NODE_CODE && resultCode == RESULT_CANCELED){
470
                        //uncheck the node at lastCheckedPos
471
                        LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); 
472
                        ListView serversList = (ListView) linear.findViewById(android.R.id.list);
473
                        Log.d("info", "number of items in serverList " + serversList.getChildCount());
474
                        Log.d("info", "lastCheckedPos is " + Integer.toString(pos));
475
                        View row = serversList.getChildAt(pos);
476
                        Log.d("info", ("is row null? " + Boolean.toString(row == null)));
477
                        CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox);
478
                        checkBox.setChecked(false);
479
                }
480

    
481
                else if(requestCode == ADD_EXTERNAL_NODE_CODE && resultCode == RESULT_OK){
482
                        Node node = new Node();
483
                        node.setAddress(data.getStringExtra("nodeIp"));
484
                        node.setCondition(data.getStringExtra("nodeCondition"));
485
                        node.setName("External Node");
486
                        node.setPort(data.getStringExtra("nodePort"));
487
                        node.setWeight(data.getStringExtra("nodeWeight"));
488

    
489
                        /*
490
                         * If the ip is from a cloud server, alert to user
491
                         * so they can select it from there
492
                         */        
493
                        if(!ipInList(node.getAddress())){
494

    
495
                                if(positionOfNode >= 0){
496
                                        nodes.remove(positionOfNode);
497
                                }
498

    
499
                                nodes.add(node);
500
                                //Add it to server list so it display in the listview
501
                                Server server = new Server();
502
                                server.setName("External Node");
503
                                String[] ip = {data.getStringExtra("nodeIp")};
504
                                server.setPrivateIpAddresses(ip);
505
                                possibleNodes.add(server);
506
                                setServerList(possibleNodes);
507
                        } else {
508
                                String name = getNameFromIp(node.getAddress());
509
                                if(name.equals("External Node")){
510
                                        showAlert("Error", "This IP has already been added as an external node, please edit" +
511
                                        "it from the list.");
512
                                } else {
513
                                        showAlert("Error", "This IP belongs to a cloud server: \"" + getNameFromIp(node.getAddress()) 
514
                                                        + "\", please edit it from the list.");
515
                                }
516
                        }
517
                }
518
                printTheNodes();
519
        }
520

    
521
        private void printTheNodes(){
522
                for(Node n: nodes){
523
                        Log.d("info", "address: " + n.getAddress() + " Port: " + n.getPort() + " Cond: " + n.getCondition());
524
                }
525
                Log.d("info", " SPACE ");
526
        }
527

    
528
}