OLD | NEW |
1 'use strict'; | 1 'use strict'; |
2 | 2 |
| 3 // A global. |
| 4 var noLogin; |
| 5 |
3 YUI.add('juju-env', function(Y) { | 6 YUI.add('juju-env', function(Y) { |
4 | 7 |
5 function Environment(config) { | 8 function Environment(config) { |
6 // Invoke Base constructor, passing through arguments | 9 // Invoke Base constructor, passing through arguments |
7 Environment.superclass.constructor.apply(this, arguments); | 10 Environment.superclass.constructor.apply(this, arguments); |
8 } | 11 } |
9 | 12 |
10 | 13 |
11 Environment.NAME = 'env'; | 14 Environment.NAME = 'env'; |
12 Environment.ATTRS = { | 15 Environment.ATTRS = { |
13 'socket_url': {}, | 16 'socket_url': {}, |
14 'conn': {}, | 17 'conn': {}, |
| 18 'user': {}, |
| 19 'password': {}, |
15 'connected': {value: false}, | 20 'connected': {value: false}, |
16 'debug': {value: false} | 21 'debug': {value: false} |
17 }; | 22 }; |
18 | 23 |
19 Y.extend(Environment, Y.Base, { | 24 Y.extend(Environment, Y.Base, { |
20 // Prototype methods for your new class | 25 // Prototype methods for your new class |
21 | 26 |
22 initializer: function() { | 27 initializer: function() { |
23 console.log('Env Init'); | 28 console.log('Env Init'); |
24 // Define custom events | 29 // Define custom events |
25 this.publish('msg', { | 30 this.publish('msg', { |
26 emitFacade: true, | 31 emitFacade: true, |
27 defaultFn: this.dispatch_result | 32 defaultFn: this.dispatch_result |
28 }); | 33 }); |
29 // txn-id sequence | 34 // txn-id sequence |
30 this._counter = 0; | 35 this._counter = 0; |
31 // mapping txn-id callback if any. | 36 // mapping txn-id callback if any. |
32 this._txn_callbacks = {}; | 37 this._txn_callbacks = {}; |
| 38 // Consider the user unauthenticated until proven otherwise. |
| 39 this.userIsAuthenticated = false; |
| 40 // When the server tells us the outcome of a login attempt we record |
| 41 // the result. |
| 42 this.on('login', this.handleLoginEvent, this); |
33 }, | 43 }, |
34 | 44 |
35 destructor: function() { | 45 destructor: function() { |
36 this.ws.close(); | 46 this.ws.close(); |
37 this._txn_callbacks = {}; | 47 this._txn_callbacks = {}; |
38 }, | 48 }, |
39 | 49 |
40 connect: function() { | 50 connect: function() { |
41 console.log('Env Connect'); | 51 console.log('Env Connect'); |
42 // Allow an external websocket to be passed in. | 52 // Allow an external websocket to be passed in. |
43 var conn = this.get('conn'); | 53 var conn = this.get('conn'); |
44 console.log('ext ws', conn); | 54 console.log('ext ws', conn); |
45 if (conn) { | 55 if (conn) { |
46 this.ws = conn; | 56 this.ws = conn; |
47 } else { | 57 } else { |
48 console.log('Creating new websocket', this.get('socket_url')); | 58 console.log('Creating new websocket', this.get('socket_url')); |
49 this.ws = new Y.ReconnectingWebSocket(this.get('socket_url')); | 59 this.ws = new Y.ReconnectingWebSocket(this.get('socket_url')); |
50 } | 60 } |
51 this.ws.debug = this.get('debug'); | 61 this.ws.debug = this.get('debug'); |
52 this.ws.onmessage = Y.bind(this.on_message, this); | 62 this.ws.onmessage = Y.bind(this.on_message, this); |
53 this.ws.onopen = Y.bind(this.on_open, this); | 63 this.ws.onopen = Y.bind(this.on_open, this); |
54 this.ws.onclose = Y.bind(this.on_close, this); | 64 this.ws.onclose = Y.bind(this.on_close, this); |
55 this.on('msg', this.dispatch_event); | 65 this.on('msg', this.dispatch_event); |
56 return this; | 66 return this; |
57 }, | 67 }, |
58 | 68 |
59 on_open: function(data) { | 69 on_open: function(data) { |
60 console.log('Env: Connected'); | 70 console.log('Env: Connected'); |
61 this.set('connected', true); | |
62 }, | 71 }, |
63 | 72 |
64 on_close: function(data) { | 73 on_close: function(data) { |
65 console.log('Env: Disconnect'); | 74 console.log('Env: Disconnect'); |
66 this.set('connected', false); | 75 this.set('connected', false); |
67 }, | 76 }, |
68 | 77 |
69 on_message: function(evt) { | 78 on_message: function(evt) { |
70 console.log('Env: Receive', evt.data); | 79 console.log('Env: Receive', evt.data); |
71 | |
72 var msg = Y.JSON.parse(evt.data); | 80 var msg = Y.JSON.parse(evt.data); |
| 81 // The "ready" attribute indicates that this is a server's initial |
| 82 // greeting. It provides a few initial values that we care about. |
73 if (msg.ready) { | 83 if (msg.ready) { |
74 // The "ready" attribute indicates that this is a server's initial | 84 console.log('Env: Handshake Complete'); |
75 // greeting. It provides a few initial values that we care about. | 85 this.set('connected', true); |
76 this.set('providerType', msg.provider_type); | 86 this.set('providerType', msg.provider_type); |
77 this.set('defaultSeries', msg.default_series); | 87 this.set('defaultSeries', msg.default_series); |
78 } | |
79 if (msg.version === 0) { | |
80 console.log('Env: Handshake Complete'); | |
81 return; | 88 return; |
82 } | 89 } |
83 this.fire('msg', msg); | 90 this.fire('msg', msg); |
84 }, | 91 }, |
85 | 92 |
| 93 /** |
| 94 * React to the results of sending a login message to the server. |
| 95 * |
| 96 * @method handleLoginEvent |
| 97 * @param {Object} evt The event to which we are responding. |
| 98 * @return {undefined} Nothing. |
| 99 */ |
| 100 handleLoginEvent: function(evt) { |
| 101 // We are only interested in the responses to login events. |
| 102 this.userIsAuthenticated = !!evt.data.result; |
| 103 this.waiting = false; |
| 104 // If the credentials were rejected remove them. |
| 105 if (!this.userIsAuthenticated) { |
| 106 this.set('user', undefined); |
| 107 this.set('password', undefined); |
| 108 } |
| 109 }, |
| 110 |
86 dispatch_result: function(data) { | 111 dispatch_result: function(data) { |
87 console.log('Env: Dispatch Result', data); | 112 console.log('Env: Dispatch Result', data); |
88 this._dispatch_rpc_result(data); | 113 this._dispatch_rpc_result(data); |
89 this._dispatch_event(data); | 114 this._dispatch_event(data); |
90 }, | 115 }, |
91 | 116 |
92 _dispatch_event: function(evt) { | 117 _dispatch_event: function(evt) { |
93 if (!('op' in evt)) { | 118 if (!('op' in evt)) { |
94 console.warn('Env: Unknown evt kind', evt); | 119 console.warn('Env: Unknown evt kind', evt); |
95 return; | 120 return; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 config_raw: config_raw, | 192 config_raw: config_raw, |
168 charm_url: charm_url, | 193 charm_url: charm_url, |
169 num_units: num_units}, | 194 num_units: num_units}, |
170 callback); | 195 callback); |
171 }, | 196 }, |
172 | 197 |
173 expose: function(service, callback) { | 198 expose: function(service, callback) { |
174 this._send_rpc({'op': 'expose', 'service_name': service}, callback); | 199 this._send_rpc({'op': 'expose', 'service_name': service}, callback); |
175 }, | 200 }, |
176 | 201 |
| 202 /** |
| 203 * Attempt to log the user in. Credentials must have been previously |
| 204 * stored on the environment. If not, this method will schedule a call to |
| 205 * itself in the future in order to try again. |
| 206 * |
| 207 * @return {undefined} Nothing. |
| 208 */ |
| 209 login: function() { |
| 210 // If the user is already authenticated there is nothing to do. |
| 211 if (this.userIsAuthenticated) { |
| 212 return; |
| 213 } |
| 214 var user = this.get('user'); |
| 215 var password = this.get('password'); |
| 216 this._send_rpc({op: 'login', user: user, password: password}); |
| 217 }, |
| 218 |
177 unexpose: function(service, callback) { | 219 unexpose: function(service, callback) { |
178 this._send_rpc({'op': 'unexpose', 'service_name': service}, callback); | 220 this._send_rpc({'op': 'unexpose', 'service_name': service}, callback); |
179 }, | 221 }, |
180 | 222 |
181 status: function(callback) { | 223 status: function(callback) { |
182 this._send_rpc({'op': 'status'}, callback); | 224 this._send_rpc({'op': 'status'}, callback); |
183 }, | 225 }, |
184 | 226 |
185 remove_relation: function(endpoint_a, endpoint_b, callback) { | 227 remove_relation: function(endpoint_a, endpoint_b, callback) { |
186 this._send_rpc({ | 228 this._send_rpc({ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 | 278 |
237 }, '0.1.0', { | 279 }, '0.1.0', { |
238 requires: [ | 280 requires: [ |
239 'io', | 281 'io', |
240 'json-parse', | 282 'json-parse', |
241 'json-stringify', | 283 'json-stringify', |
242 'base', | 284 'base', |
243 'reconnecting-websocket' | 285 'reconnecting-websocket' |
244 ] | 286 ] |
245 }); | 287 }); |
OLD | NEW |