Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / AddNodesActivity.java @ 7dbfc514

History | View | Annotate | Download (16.3 kB)

1
package com.rackspace.cloud.android;
2

    
3
import java.util.ArrayList;
4

    
5
import android.content.Intent;
6
import android.os.AsyncTask;
7
import android.os.Bundle;
8
import android.util.Log;
9
import android.view.LayoutInflater;
10
import android.view.View;
11
import android.view.View.OnClickListener;
12
import android.view.ViewGroup;
13
import android.widget.ArrayAdapter;
14
import android.widget.Button;
15
import android.widget.CheckBox;
16
import android.widget.CompoundButton;
17
import android.widget.CompoundButton.OnCheckedChangeListener;
18
import android.widget.LinearLayout;
19
import android.widget.ListView;
20
import android.widget.TextView;
21

    
22
import com.rackspace.cloud.android.R;
23
import com.rackspace.cloud.loadbalancer.api.client.Node;
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

    
28
public class AddNodesActivity extends CloudListActivity {
29

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

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

    
45
        @SuppressWarnings("unchecked")
46
        @Override
47
        public void onCreate(Bundle savedInstanceState) {
48
                super.onCreate(savedInstanceState);
49
                nodes = (ArrayList<Node>) this.getIntent().getExtras().get("nodes");
50
                selectedPort = (String) this.getIntent().getExtras().get("loadBalancerPort");
51
                //possibleNodes = (ArrayList<Server>) this.getIntent().getExtras().get("possibleNodes");
52
                setContentView(R.layout.addnodes);
53
                restoreState(savedInstanceState);
54
        }
55

    
56
        @Override
57
        protected void onSaveInstanceState(Bundle outState) {
58
                super.onSaveInstanceState(outState);
59
                outState.putSerializable("nodes", nodes);
60
                outState.putSerializable("possibleNodes", possibleNodes);
61
                outState.putInt("lastCheckedPos", lastCheckedPos);
62
                outState.putInt("positionOfNode", positionOfNode);
63
                outState.putString("loadBalancerPort", selectedPort);
64
        }
65

    
66
        @SuppressWarnings("unchecked")
67
        protected void restoreState(Bundle state) {
68
                super.restoreState(state);
69

    
70
                if (state != null && state.containsKey("nodes")){
71
                        nodes = (ArrayList<Node>) state.getSerializable("nodes");
72
                        if(nodes == null){
73
                                nodes = new ArrayList<Node>();
74
                        }
75
                }
76

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

    
81
                if (state != null && state.containsKey("positionOfNode")){
82
                        positionOfNode = (Integer) state.getSerializable("positionOfNode");
83
                }
84
                
85
                if (state != null && state.containsKey("loadBalancerPort")){
86
                        //selectedPort = (String) state.getSerializable("loadBalancerPort");
87
                }
88

    
89
                if (state != null && state.containsKey("possibleNodes") && state.getSerializable("possibleNodes") != null) {
90
                        possibleNodes = (ArrayList<Server>) state.getSerializable("possibleNodes");
91
                        if (possibleNodes.size() == 0) {
92
                                displayNoServersCell();
93
                        } else {
94
                                getListView().setDividerHeight(1); // restore divider lines
95
                                setListAdapter(new ServerAdapter());
96
                        }
97
                } else {
98
                        loadServers();
99
                }
100
                
101

    
102
                Button submitNodes = (Button) findViewById(R.id.submit_nodes_button);
103
                submitNodes.setOnClickListener(new OnClickListener() {
104

    
105
                        @Override
106
                        public void onClick(View v) {
107
                                Intent viewIntent = new Intent();
108
                                viewIntent.putExtra("nodes", nodes);
109
                                viewIntent.putExtra("possibleNodes", possibleNodes);
110
                                setResult(RESULT_OK, viewIntent);
111
                                printTheNodes();
112
                                finish();
113
                        }
114
                });
115

    
116
                Button addExternalNode = (Button) findViewById(R.id.add_external_node);
117
                addExternalNode.setOnClickListener(new OnClickListener() {
118

    
119
                        @Override
120
                        public void onClick(View v) {
121
                                lastCheckedPos = -1;
122
                                positionOfNode = -1;
123
                                Intent viewIntent = new Intent(getContext(), AddExternalNodeActivity.class);
124
                                //when first creating a load balancer
125
                                //weighting nodes in not an option
126
                                viewIntent.putExtra("weighted", false);
127
                                viewIntent.putExtra("loadBalancerPort", selectedPort);
128
                                startActivityForResult(viewIntent, ADD_EXTERNAL_NODE_CODE);
129
                        }
130
                });
131
        }
132

    
133
        @Override
134
        public void onBackPressed(){
135
                setResult(RESULT_CANCELED);
136
                finish();
137
        }
138

    
139
        protected void onListItemClick(ListView l, View v, int position, long id) {
140
                if (possibleNodes != null && possibleNodes.size() > 0) {
141
                        if(!possibleNodes.get(position).getName().equals("External Node")){
142
                                LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); 
143
                                ListView serversList = (ListView) linear.findViewById(android.R.id.list);
144
                                View row = serversList.getChildAt(position);
145
                                CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox);
146
                                if(!checkBox.isChecked()){
147
                                        //if the checkbox was not previously checked, treat the listItemClick
148
                                        //the same as checking the checkbox
149
                                        checkBox.setChecked(!checkBox.isChecked());
150
                                } else {
151
                                        //if the checkbox was already checked when the listItemClick occurred,
152
                                        //then treat it like an edit
153

    
154
                                        Server server = possibleNodes.get(position);
155

    
156
                                        //Need to put all the ip's of the server into one
157
                                        //list so they can all be displayed in one spinner
158
                                        String[] ipAddresses = getAllIpsOfServer(server);
159

    
160
                                        Node node = getNodeFromServer(server);
161

    
162
                                        positionOfNode = findNodePosition(node);
163
                                        lastCheckedPos = position;
164

    
165
                                        Intent viewIntent = new Intent(getContext(), AddNodeActivity.class);
166
                                        viewIntent.putExtra("ipAddresses", ipAddresses);
167
                                        viewIntent.putExtra("name", server.getName());
168
                                        if(node != null){
169
                                                viewIntent.putExtra("node", node);
170
                                        }
171
                                        //weighted is false, because on initial node add
172
                                        //weight is not option
173
                                        viewIntent.putExtra("weighted", false);
174
                                        startActivityForResult(viewIntent, ADD_NODE_CODE);
175
                                }
176
                        } else {
177
                                //When clicked on an external node
178
                                Server server = possibleNodes.get(position);
179
                                Node node = getNodeFromServer(server);
180
                                positionOfNode = findNodePosition(node);
181
                                lastCheckedPos = position;
182
                                Intent viewIntent = new Intent(getContext(), AddExternalNodeActivity.class);
183
                                if(node != null){
184
                                        viewIntent.putExtra("node", node);
185
                                }
186
                                //weighted is false, because on initial node add
187
                                //weight is not option
188
                                viewIntent.putExtra("weighted", false);
189
                                startActivityForResult(viewIntent, ADD_EXTERNAL_NODE_CODE);
190
                        }
191
                }
192
        }
193

    
194
        //return the location of node in nodes
195
        //if it is no in there then -1
196
        private int findNodePosition(Node node){
197
                for(int i = 0; i < nodes.size(); i++){
198
                        String address = node.getAddress();
199
                        if(address.equals(nodes.get(i).getAddress())){
200
                                return i;
201
                        }
202
                }
203
                return -1;
204
        }
205

    
206
        private void displayNoServersCell() {
207
                String a[] = new String[1];
208
                a[0] = "No Nodes";
209
                setListAdapter(new ArrayAdapter<String>(this, R.layout.nonodescell, R.id.no_nodes_label, a));
210
                getListView().setTextFilterEnabled(true);
211
                getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row
212
                getListView().setItemsCanFocus(false);
213
        }
214

    
215
        private void setServerList(ArrayList<Server> servers) {
216
                if (servers == null) {
217
                        servers = new ArrayList<Server>();
218
                }
219
                String[] serverNames = new String[servers.size()];
220
                this.possibleNodes = new ArrayList<Server>();
221

    
222
                if (servers != null) {
223
                        for (int i = 0; i < servers.size(); i++) {
224
                                Server server = servers.get(i);
225
                                this.possibleNodes.add(i, server);
226
                                serverNames[i] = server.getName();
227
                        }
228
                }
229

    
230
                if (serverNames.length == 0) {
231
                        displayNoServersCell();
232
                } else {
233
                        getListView().setDividerHeight(1); // restore divider lines 
234
                        setListAdapter(new ServerAdapter());
235
                }
236
        }
237

    
238
        private void loadServers() {
239
                new LoadServersTask().execute((Void[]) null);
240
        }
241

    
242
        // * Adapter/
243
        class ServerAdapter extends ArrayAdapter<Server> {
244
                ServerAdapter() {
245
                        super(AddNodesActivity.this, R.layout.listservernodecell, possibleNodes);
246
                }
247

    
248
                public View getView(int position, View convertView, ViewGroup parent) {
249

    
250
                        final Server server = possibleNodes.get(position);
251
                        LayoutInflater inflater = getLayoutInflater();
252
                        View row = inflater.inflate(R.layout.listservernodecell, parent, false);
253

    
254
                        TextView label = (TextView) row.findViewById(R.id.label);
255
                        label.setText(server.getName());
256

    
257
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
258
                        if(server.getName().equals("External Node")){
259
                                sublabel.setText(server.getPrivateIpAddresses()[0]);
260
                        } else {
261
                                sublabel.setText(server.getFlavor().getName() + " - " + server.getImage().getName());
262
                        }
263

    
264
                        //Need to put all the ip's of the server into one
265
                        //list so they can all be displayed in one spinner
266
                        final String[] ipAddresses = getAllIpsOfServer(server);
267

    
268
                        final int pos = position;
269
                        CheckBox add = (CheckBox) row.findViewById(R.id.add_node_checkbox);
270

    
271
                        if(inNodeList(server)){
272
                                add.setChecked(true);
273
                        }
274

    
275
                        add.setOnCheckedChangeListener(new OnCheckedChangeListener() {
276

    
277
                                @Override
278
                                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
279
                                        if(isChecked){
280
                                                //if node is being check it won't be in nodes positionOfNode is -1
281
                                                positionOfNode = -1;
282
                                                lastCheckedPos = pos;
283
                                                Intent viewIntent = new Intent(getContext(), AddNodeActivity.class);
284
                                                viewIntent.putExtra("loadBalancerPort", selectedPort);
285
                                                viewIntent.putExtra("ipAddresses", ipAddresses);
286
                                                viewIntent.putExtra("name", server.getName());
287
                                                //weighted is false, because on initial node add
288
                                                //weight is not option
289
                                                viewIntent.putExtra("weighted", false);
290
                                                startActivityForResult(viewIntent, ADD_NODE_CODE);
291
                                        }
292
                                        else{
293
                                                removeNodeFromList(server);
294
                                                if(server.getName().equals("External Node")){
295
                                                        possibleNodes.remove(server);
296
                                                        setServerList(possibleNodes);
297
                                                }
298
                                        }
299
                                }
300
                        });
301

    
302
                        return(row);
303
                }
304

    
305
                //returns true if an ip from server
306
                //is the address of one of the nodes
307
                private boolean inNodeList(Server server){
308
                        for(Node node : nodes){
309
                                String nodeIp = node.getAddress();
310
                                if(serverHasIp(server, nodeIp)){
311
                                        return true;
312
                                }
313
                        }
314
                        return false;
315
                }
316

    
317
                /*
318
                 *  need to remove by id because that is 
319
                 *  what is unique
320
                 */
321
                private void removeNodeFromList(Server server){
322
                        for(int i = 0; i < nodes.size(); i++){
323
                                Node node = nodes.get(i);
324
                                if(serverHasIp(server, node.getAddress())){
325
                                        nodes.remove(i);
326
                                        break;
327
                                }
328
                        }
329
                }
330
        }
331

    
332
        private String getNameFromIp(String address){
333
                for(Server s: possibleNodes){
334
                        if(serverHasIp(s, address)){
335
                                return s.getName();
336
                        }
337
                }
338
                return "";
339
        }
340

    
341
        //returns true if address is an address of
342
        //one of the users cloud servers
343
        private boolean ipInList(String address){
344
                for(Server s : possibleNodes){
345
                        if(serverHasIp(s, address) && !s.getName().equals("External Node")){
346
                                return true;
347
                        }
348
                }
349
                return false;
350
        }
351

    
352
        //returns true if address is one of server's addresses
353
        private boolean serverHasIp(Server server, String address){
354
                String[] addresses = server.getPrivateIpAddresses();
355
                if(addresses != null){
356
                        for(int i = 0; i < addresses.length; i++){
357
                                if(addresses[i].equals(address)){
358
                                        return true;
359
                                }
360
                        }
361
                }
362
                addresses = server.getPublicIpAddresses();
363
                if(addresses != null){
364
                        for(int i = 0; i < addresses.length; i++){
365
                                if(addresses[i].equals(address)){
366
                                        return true;
367
                                }
368
                        }
369
                }
370
                return false;
371
        }
372

    
373
        //returns the node that is using an ip from server
374
        private Node getNodeFromServer(Server server){
375
                for(Node node : nodes){
376
                        if(serverHasIp(server, node.getAddress())){
377
                                return node;
378
                        }
379
                }
380
                return null;
381
        }
382

    
383
        //returns an array of all the ip's of server
384
        private String[] getAllIpsOfServer(Server server){
385
                String[] publicIp = server.getPublicIpAddresses();
386
                String[] privateIp = server.getPrivateIpAddresses();
387
                if(publicIp == null){
388
                        publicIp = new String[0];
389
                }
390
                if(privateIp == null){
391
                        privateIp = new String[0];
392
                }
393
                String[] ipAddresses = new String[privateIp.length + publicIp.length];
394
                for(int i = 0; i < privateIp.length; i++){
395
                        ipAddresses[i] = privateIp[i];
396
                }
397
                for(int i = 0; i < publicIp.length; i++){
398
                        ipAddresses[i+privateIp.length] = publicIp[i];
399
                }
400

    
401
                return ipAddresses;
402
        }
403

    
404
        private class LoadServersTask extends AsyncTask<Void, Void, ArrayList<Server>> {
405
                private CloudServersException exception;
406

    
407
                @Override
408
                protected void onPreExecute(){
409
                        showDialog();
410
                }
411

    
412
                @Override
413
                protected ArrayList<Server> doInBackground(Void... arg0) {
414
                        ArrayList<Server> servers = null;
415
                        try {
416
                                servers = (new ServerManager()).createList(true, getContext());
417
                        } catch (CloudServersException e) {
418
                                exception = e;                                
419
                        }
420
                        return servers;
421
                }
422

    
423
                @Override
424
                protected void onPostExecute(ArrayList<Server> result) {
425
                        hideDialog();
426
                        if (exception != null) {
427
                                showAlert("Error", exception.getMessage());
428
                        }
429

    
430
                        //Add the external nodes
431
                        for(int i = 0; i < nodes.size(); i++){
432
                                if(nodes.get(i).getName().equals("External Node")){
433
                                        Server server = new Server();
434
                                        server.setName("External Node");
435
                                        String[] ip = {nodes.get(i).getAddress()};
436
                                        server.setPrivateIpAddresses(ip);
437
                                        result.add(server);
438
                                }
439
                        }
440
                        setServerList(result);
441
                }
442
        }
443

    
444
        //removes a node with ip of address from nodes
445
        //if one doesnt exists does nothing
446
        /*
447
        private void removeNodeWithIp(String address){
448
                for(int i = 0; i < nodes.size(); i++){
449
                        Node n = nodes.get(i);
450
                        if(n.getAddress().equals(address)){
451
                                nodes.remove(i);
452
                                break;
453
                        }
454
                }
455
        }
456
        */
457

    
458
        protected void onActivityResult(int requestCode, int resultCode, Intent data){        
459
                int pos = lastCheckedPos;
460
                if(requestCode == ADD_NODE_CODE && resultCode == RESULT_OK){
461
                        //data will be null is user back out on edit
462
                        //we dont need to do anything then
463
                        //if new node added data won't be null
464
                        //so create the new node and add it to the list
465
                        if(data != null){
466
                                //will remove the node if it's already in the list 
467
                                //so we can update it
468
                                //removeNodeWithIp(data.getStringExtra("nodeIp"));
469
                                if(positionOfNode >= 0){
470
                                        nodes.remove(positionOfNode);
471
                                }
472

    
473
                                Node node = new Node();
474
                                node.setAddress(data.getStringExtra("nodeIp"));
475
                                node.setCondition(data.getStringExtra("nodeCondition"));
476
                                node.setName(possibleNodes.get(pos).getName());
477
                                node.setPort(data.getStringExtra("nodePort"));
478
                                node.setWeight(data.getStringExtra("nodeWeight"));
479
                                nodes.add(node);
480
                        }
481
                }
482
                else if(requestCode == ADD_NODE_CODE && resultCode == RESULT_CANCELED){
483
                        //uncheck the node at lastCheckedPos
484
                        LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); 
485
                        ListView serversList = (ListView) linear.findViewById(android.R.id.list);
486
                        View row = serversList.getChildAt(pos);
487
                        CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox);
488
                        checkBox.setChecked(false);
489
                }
490

    
491
                else if(requestCode == ADD_EXTERNAL_NODE_CODE && resultCode == RESULT_OK){
492
                        Node node = new Node();
493
                        node.setAddress(data.getStringExtra("nodeIp"));
494
                        node.setCondition(data.getStringExtra("nodeCondition"));
495
                        node.setName("External Node");
496
                        node.setPort(data.getStringExtra("nodePort"));
497
                        node.setWeight(data.getStringExtra("nodeWeight"));
498

    
499
                        /*
500
                         * If the ip is from a cloud server, alert to user
501
                         * so they can select it from there
502
                         */        
503
                        if(!ipInList(node.getAddress())){
504

    
505
                                if(positionOfNode >= 0){
506
                                        nodes.remove(positionOfNode);
507
                                }
508

    
509
                                nodes.add(node);
510
                                //Add it to server list so it display in the listview
511
                                Server server = new Server();
512
                                server.setName("External Node");
513
                                String[] ip = {data.getStringExtra("nodeIp")};
514
                                server.setPrivateIpAddresses(ip);
515
                                
516
                                //remove the old node and replace it with the updated one
517
                                if(pos != -1){
518
                                        possibleNodes.remove(pos);
519
                                }
520
                                possibleNodes.add(server);
521
                                setServerList(possibleNodes);
522
                        } else {
523
                                String name = getNameFromIp(node.getAddress());
524
                                if(name.equals("External Node")){
525
                                        showAlert("Error", "This IP has already been added as an external node, please edit " +
526
                                        "it from the list.");
527
                                } else {
528
                                        showAlert("Error", "This IP belongs to a cloud server: \"" + getNameFromIp(node.getAddress()) 
529
                                                        + "\", please edit it from the list.");
530
                                }
531
                        }
532
                }
533
                printTheNodes();
534
        }
535

    
536
        private void printTheNodes(){
537
                for(Node n: nodes){
538
                        Log.d("info", "address: " + n.getAddress() + " Port: " + n.getPort() + " Cond: " + n.getCondition());
539
                }
540
                Log.d("info", " SPACE ");
541
        }
542

    
543
}