Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / AddMoreNodesActivity.java @ 403bb53b

History | View | Annotate | Download (13.1 kB)

1
package com.rackspacecloud.android;
2

    
3
import java.util.ArrayList;
4

    
5
import org.apache.http.HttpResponse;
6

    
7
import com.rackspace.cloud.loadbalancer.api.client.LoadBalancer;
8
import com.rackspace.cloud.loadbalancer.api.client.Node;
9
import com.rackspace.cloud.loadbalancer.api.client.NodeManager;
10
import com.rackspace.cloud.servers.api.client.CloudServersException;
11
import com.rackspace.cloud.servers.api.client.Server;
12
import com.rackspace.cloud.servers.api.client.ServerManager;
13
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
14

    
15
import android.app.Activity;
16
import android.content.Intent;
17
import android.os.AsyncTask;
18
import android.os.Bundle;
19
import android.util.Log;
20
import android.view.LayoutInflater;
21
import android.view.View;
22
import android.view.View.OnClickListener;
23
import android.view.ViewGroup;
24
import android.widget.ArrayAdapter;
25
import android.widget.Button;
26
import android.widget.CheckBox;
27
import android.widget.CompoundButton;
28
import android.widget.LinearLayout;
29
import android.widget.ListView;
30
import android.widget.CompoundButton.OnCheckedChangeListener;
31
import android.widget.TextView;
32

    
33
public class AddMoreNodesActivity extends CloudListActivity {
34

    
35
        private static final int ADD_NODE_CODE = 178;
36
        private static final int ADD_EXTERNAL_NODE_CODE = 188;
37
        private ArrayList<Server> servers; 
38
        private int lastCheckedPos;
39
        private ArrayList<Node> nodes;
40
        private ArrayList<Node> nodesToAdd;
41
        private LoadBalancer loadBalancer;
42

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

    
53
        @Override
54
        protected void onSaveInstanceState(Bundle outState) {
55
                super.onSaveInstanceState(outState);
56

    
57
                outState.putSerializable("nodes", nodes);
58
                outState.putSerializable("loadBalancer", loadBalancer);
59
                outState.putSerializable("nodesToAdd", nodesToAdd);
60
                outState.putSerializable("servers", servers);
61
        }
62

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

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

    
74
                if (state != null && state.containsKey("loadBalancer")){
75
                        loadBalancer = (LoadBalancer) state.getSerializable("loadBalancer");
76
                        if(loadBalancer == null){
77
                                loadBalancer = new LoadBalancer();
78
                        }
79
                }
80

    
81
                if (state != null && state.containsKey("nodesToAdd")){
82
                        nodesToAdd = (ArrayList<Node>) state.getSerializable("nodesToAdd");
83
                }
84
                else{
85
                        nodesToAdd = new ArrayList<Node>();
86
                }
87

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

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

    
103
                        @Override
104
                        public void onClick(View v) {
105
                                if(nodesToAdd.size() == 0){
106
                                        finish();
107
                                } else {
108
                                        new AddNodesTask().execute();
109
                                }
110
                        }
111
                });
112

    
113
                Button addExternalNode = (Button) findViewById(R.id.add_external_node);
114
                addExternalNode.setOnClickListener(new OnClickListener() {
115

    
116
                        @Override
117
                        public void onClick(View v) {
118
                                Intent viewIntent = new Intent(getContext(), AddExternalNodeActivity.class);
119
                                viewIntent.putExtra("weighted", false);
120
                                startActivityForResult(viewIntent, ADD_EXTERNAL_NODE_CODE);
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 ArrayList<Server>();
158

    
159
                for(int i = 0; i < servers.size(); i++){
160
                        serverNames[i] = servers.get(i).getName();
161
                        this.servers.add(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
        // * Adapter/
208
        class ServerAdapter extends ArrayAdapter<Server> {
209
                ServerAdapter() {
210
                        super(AddMoreNodesActivity.this, R.layout.listservernodecell, servers);
211
                }
212

    
213
                public View getView(int position, View convertView, ViewGroup parent) {
214

    
215
                        final Server server = servers.get(position);
216
                        LayoutInflater inflater = getLayoutInflater();
217
                        View row = inflater.inflate(R.layout.listservernodecell, parent, false);
218

    
219
                        TextView label = (TextView) row.findViewById(R.id.label);
220
                        label.setText(server.getName());
221

    
222
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
223
                        if(server.getName().equals("External Node")){
224
                                sublabel.setText(server.getPrivateIpAddresses()[0]);
225
                        } else {
226
                                sublabel.setText(server.getFlavor().getName() + " - " + server.getImage().getName());
227
                        }
228

    
229
                        String[] publicIp = server.getPublicIpAddresses();
230
                        String[] privateIp = server.getPrivateIpAddresses();
231

    
232
                        if(publicIp == null){
233
                                publicIp = new String[0];
234
                        }
235

    
236
                        if(privateIp == null){
237
                                privateIp = new String[0];
238
                        }
239

    
240
                        ArrayList<String> ipAddressList = new ArrayList<String>();
241
                        for(int i = 0; i < privateIp.length; i++){
242
                                if(!nodeHasAddress(privateIp[i])){
243
                                        ipAddressList.add(privateIp[i]);
244
                                }
245
                        }
246
                        for(int i = 0; i < publicIp.length; i++){
247
                                if(!nodeHasAddress(publicIp[i])){
248
                                        ipAddressList.add(publicIp[i]);
249
                                }
250
                        }
251

    
252
                        final String[] ipAddresses = ipAddressList.toArray(new String[ipAddressList.size()]);
253
                        final int pos = position;
254
                        CheckBox add = (CheckBox) row.findViewById(R.id.add_node_checkbox);
255

    
256
                        if(inToAddList(server)){
257
                                add.setChecked(true);
258
                        }
259

    
260
                        add.setOnCheckedChangeListener(new OnCheckedChangeListener() {
261

    
262
                                @Override
263
                                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
264
                                        if(isChecked){
265
                                                lastCheckedPos = pos;
266
                                                Intent viewIntent = new Intent(getContext(), AddNodeActivity.class);
267
                                                viewIntent.putExtra("ipAddresses", ipAddresses);
268
                                                viewIntent.putExtra("name", server.getName());
269
                                                viewIntent.putExtra("weighted", loadBalancer.getAlgorithm().contains("WEIGHTED"));
270
                                                startActivityForResult(viewIntent, ADD_NODE_CODE);
271
                                        }
272
                                        else{
273
                                                removeNodeFromList(server);
274
                                                if(server.getName().equals("External Node")){
275
                                                        servers.remove(server);
276
                                                        setServerList(servers);
277
                                                }
278
                                        }
279
                                }
280
                        });
281

    
282
                        return(row);
283
                }
284

    
285
                /*
286
                 *  need to remove by id because that is 
287
                 *  what is unique
288
                 */
289
                private void removeNodeFromList(Server server){
290
                        for(int i = 0; i < nodesToAdd.size(); i++){
291
                                Node node = nodesToAdd.get(i);
292
                                if(serverHasIp(server, node.getAddress())){
293
                                        nodesToAdd.remove(i);
294
                                        break;
295
                                }
296
                        }
297
                }
298
        }
299
        private boolean serverHasIp(Server server, String address){
300
                String[] addresses = server.getPrivateIpAddresses();
301
                for(int i = 0; i < addresses.length; i++){
302
                        Log.d("info", "server address: " + addresses[i] + " node address: " + address);
303
                        if(addresses[i].equals(address)){
304
                                return true;
305
                        }
306
                }
307
                addresses = server.getPublicIpAddresses();
308
                for(int i = 0; i < addresses.length; i++){
309
                        if(addresses[i].equals(address)){
310
                                return true;
311
                        }
312
                }
313
                return false;
314
        }
315

    
316
        private boolean inToAddList(Server server){
317
                for(Node node : nodesToAdd){
318
                        if(serverHasIp(server, node.getAddress())){
319
                                return true;
320
                        }
321
                }
322
                return false;
323
        }
324

    
325

    
326
        private class AddNodesTask extends AsyncTask<Void, Void, HttpBundle> {
327
                private CloudServersException exception;
328

    
329
                protected void onPreExecute(){
330
                        showDialog();
331
                }
332

    
333
                @Override
334
                protected HttpBundle doInBackground(Void... arg0) {
335
                        HttpBundle bundle = null;
336
                        try {
337
                                bundle = (new NodeManager(getContext())).add(loadBalancer, nodesToAdd);
338
                        } catch (CloudServersException e) {
339
                                exception = e;
340
                        }
341
                        return bundle;
342
                }
343

    
344
                @Override
345
                protected void onPostExecute(HttpBundle bundle) {
346
                        hideDialog();
347
                        HttpResponse response = bundle.getResponse();
348
                        if (response != null) {
349
                                int statusCode = response.getStatusLine().getStatusCode();
350
                                if (statusCode == 202) {
351
                                        setResult(Activity.RESULT_OK);
352
                                        finish();
353
                                } else {
354
                                        CloudServersException cse = parseCloudServersException(response);
355
                                        if ("".equals(cse.getMessage())) {
356
                                                showError("There was a problem creating your load balancer.", bundle);
357
                                        } else {
358
                                                //if container with same name already exists
359
                                                showError("There was a problem creating your load balancer: " + cse.getMessage() + "\n See details for more information", bundle);
360
                                        }
361
                                }
362
                        } else if (exception != null) {
363
                                showError("There was a problem creating your container: " + exception.getMessage()+"\n See details for more information.", bundle);                                
364
                        }
365
                        finish();
366
                }
367
        }
368

    
369
        private class LoadServersTask extends AsyncTask<Void, Void, ArrayList<Server>> {
370
                private CloudServersException exception;
371

    
372
                @Override
373
                protected void onPreExecute(){
374
                        showDialog();
375
                }
376

    
377
                @Override
378
                protected ArrayList<Server> doInBackground(Void... arg0) {
379
                        ArrayList<Server> servers = null;
380
                        try {
381
                                servers = (new ServerManager()).createList(true, getContext());
382
                        } catch (CloudServersException e) {
383
                                exception = e;                                
384
                        } 
385
                        return servers;
386
                }
387

    
388
                @Override
389
                protected void onPostExecute(ArrayList<Server> result) {
390
                        hideDialog();
391
                        if (exception != null) {
392
                                showAlert("Error", exception.getMessage());
393
                        }
394
                        setServerList(result);
395
                }
396
        }
397

    
398
        private String getNameFromIp(String address){
399
                for(Server s: servers){
400
                        if(serverHasIp(s, address)){
401
                                return s.getName();
402
                        }
403
                }
404
                return "";
405
        }
406

    
407
        private boolean isCloudServerIp(String address){
408
                for(Server s : servers){
409
                        if(serverHasIp(s, address)){
410
                                return true;
411
                        }
412
                }
413
                return false;
414
        }
415

    
416
        protected void onActivityResult(int requestCode, int resultCode, Intent data){
417
                int pos = lastCheckedPos;
418
                if(requestCode == ADD_NODE_CODE && resultCode == RESULT_OK){
419
                        Node node = new Node();
420
                        node.setAddress(data.getStringExtra("nodeIp"));
421
                        node.setCondition(data.getStringExtra("nodeCondition"));
422
                        node.setName(servers.get(pos).getName());
423
                        node.setPort(data.getStringExtra("nodePort"));
424
                        Log.d("info", "setting the weight in addmore to " + data.getStringExtra("nodeWeight"));
425
                        node.setWeight(data.getStringExtra("nodeWeight"));
426
                        nodesToAdd.add(node);
427
                }
428
                else if(requestCode == ADD_NODE_CODE && resultCode == RESULT_CANCELED){
429
                        //uncheck the node at lastCheckedPos
430
                        LinearLayout linear = (LinearLayout) findViewById(R.id.nodes_linear_layout); 
431
                        ListView serversList = (ListView) linear.findViewById(android.R.id.list);
432
                        View row = serversList.getChildAt(pos);
433
                        CheckBox checkBox = (CheckBox)row.findViewById(R.id.add_node_checkbox);
434
                        checkBox.setChecked(false);
435
                }
436
                else if(requestCode == ADD_EXTERNAL_NODE_CODE && resultCode == RESULT_OK){
437
                        Node node = new Node();
438
                        node.setAddress(data.getStringExtra("nodeIp"));
439
                        node.setCondition(data.getStringExtra("nodeCondition"));
440
                        node.setName("External Node");
441
                        node.setPort(data.getStringExtra("nodePort"));
442
                        node.setWeight(data.getStringExtra("nodeWeight"));
443

    
444
                        /*
445
                         * If the ip is from a cloud server, alert to user
446
                         * so they can select it from there
447
                         */        
448
                        if(!isCloudServerIp(node.getAddress())){
449
                                nodesToAdd.add(node);
450
                                //Add it to server list so it display in the listview
451
                                Server server = new Server();
452
                                server.setName("External Node");
453
                                String[] ip = {data.getStringExtra("nodeIp")};
454
                                server.setPrivateIpAddresses(ip);
455
                                servers.add(server);
456
                                setServerList(servers);
457
                        } else {
458
                                showAlert("Error", "This IP belongs to a cloud server: \"" + getNameFromIp(node.getAddress()) 
459
                                                + "\", please select it from the list.");
460
                        }
461
                }
462
        }
463
}