PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/dxweb/priv/www/js/nodewatch.models.js

http://github.com/hyperthunk/nodewatch
JavaScript | 265 lines | 215 code | 19 blank | 31 comment | 18 complexity | de911ac7974133a7c667d6210fad3543 MD5 | raw file
  1. //
  2. // Erlang System Monitoring Dashboard: Backbone Application Module
  3. //
  4. // Copyright (c) 2008-2010 Tim Watson (watson.timothy@gmail.com)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. // *static* façade for service calls
  25. Service = {
  26. debuggerTag: 'Service',
  27. loadFragment: function(path, dest) {
  28. return this.get({url: path,
  29. accept: 'application/html',
  30. dataType: 'html'})
  31. .success(function(html) { dest.html(html); });
  32. },
  33. get: function(opts) {
  34. if (typeof(opts) == "string") {
  35. return this.http({ url: opts });
  36. } else {
  37. console.debug('opts:');
  38. console.debug(opts);
  39. return this.http(opts);
  40. }
  41. },
  42. postForm: function(url, data) {
  43. return $.ajax({
  44. async: false,
  45. url: url,
  46. type: 'POST',
  47. data: data
  48. });
  49. },
  50. http: function(opts) {
  51. return $.ajax(
  52. _.defaults(opts, {
  53. async: true,
  54. type: 'GET',
  55. contentType: 'application/json',
  56. crossDomain: true,
  57. processData: false,
  58. dataType: 'json',
  59. }));
  60. }
  61. };
  62. Subscription = Backbone.Model.extend({
  63. debuggerTag: 'Subscription',
  64. defaults: {
  65. id: 'user.node.sensor',
  66. user: 'user',
  67. node: 'nonode@nohost',
  68. sensor: 'none',
  69. mode: 'instrument'
  70. },
  71. parse: function(response) {
  72. var data = response.subscription;
  73. data.id = _.template('${user}-${node}-${sensor}', data);
  74. return data;
  75. }
  76. });
  77. SubscriptionList = Backbone.Collection.extend({
  78. debuggerTag: 'SubscriptionList',
  79. model: Subscription,
  80. initialize: function(models, opts) {
  81. this.url = opts.url;
  82. },
  83. parse: function(response) {
  84. return _.map(response,
  85. function(s) { return s.subscription; });
  86. }
  87. });
  88. //$('#loading').dialog({ autoOpen: false });
  89. Node = Backbone.Model.extend({
  90. debuggerTag: 'Node',
  91. // id is the -name of the node, e.g. Node[foo@bar] => id = foo
  92. defaults: {
  93. id: 'nonode@nohost',
  94. status: 'unknown',
  95. info: []
  96. },
  97. parse: function(response) {
  98. return response.node_info;
  99. }
  100. });
  101. NodeSet = Backbone.Collection.extend({
  102. debuggerTag: 'NodeSet',
  103. url: '/service/nodes',
  104. model: Node,
  105. parse: function(response) {
  106. return _.map(response,
  107. function(ni) { return ni.node_info; });
  108. }
  109. });
  110. SystemStatus = Backbone.Model.extend({});
  111. SystemStats = Backbone.Collection.extend({
  112. debuggerTag: 'SystemStats',
  113. /* NO URL! */
  114. model: SystemStatus,
  115. initialize: function(args, opts) {
  116. _.bindAll(this, 'destroy', 'handleSysEvent', 'render');
  117. this.node = opts.node;
  118. var eventKey = 'event:system:' + this.node;
  119. console.debug('subscribing to ' + eventKey);
  120. _application.bind(eventKey, this.handleSysEvent);
  121. },
  122. handleSysEvent: function(eventData) {
  123. console.debug('adding eventData');
  124. this.add(eventData);
  125. },
  126. destroy: function() {
  127. _application.unbind('event:system:' + this.node);
  128. }
  129. });
  130. // TODO: use backbone's Model#refresh to do all this.....
  131. Session = Backbone.Model.extend({
  132. debuggerTag: 'Session',
  133. defaults: {
  134. version: '0.0.1',
  135. host: document.location.host,
  136. serviceUrl: 'service',
  137. connected: false,
  138. sessionId: ''
  139. },
  140. websocketUrl: function() {
  141. return 'ws://' +
  142. this.get('host') + '/'
  143. + this.get('sessionId');
  144. },
  145. login: function() {
  146. // TODO: make this synchronous or face annoying bugs later on....
  147. var jqXHR = Service.postForm('/service/login', this.toJSON());
  148. if (jqXHR.status != 200) {
  149. this.set({connected: false});
  150. return false;
  151. } else {
  152. // FIXME: this is totally broken since we moved it around...
  153. if ($ === undefined) return false;
  154. this.set({sessionId: $.cookie("sid")});
  155. console.debug(_.template('connecting to ${ws}',
  156. {ws: this.websocketUrl()}));
  157. //$.cookie("nodewatch.user", this.get('username'));
  158. var username = this.get('username');
  159. if (username != undefined) {
  160. $.cookie('nodewatch.user', username, {
  161. expires: 7,
  162. path: '/',
  163. domain: document.domain,
  164. secure: false
  165. });
  166. }
  167. this.websocketConnect();
  168. return true;
  169. }
  170. },
  171. hasCookie: function() {
  172. return $.cookie('sid') != null;
  173. },
  174. websocketConnect: function() {
  175. var ws = new WebSocket(this.websocketUrl());
  176. var self = this;
  177. ws.onopen = function() {
  178. self.set({connected: true});
  179. };
  180. ws.onmessage = function (evt) {
  181. self.trigger("websock:data", evt);
  182. }
  183. ws.onclose = function() {
  184. self.set({connected: false});
  185. }
  186. this.set({websocket: ws});
  187. return this;
  188. },
  189. toJSON: function() {
  190. return {
  191. username: this.get('username'),
  192. password: this.get('password'),
  193. };
  194. }
  195. });
  196. App = Backbone.Model.extend({
  197. debuggerTag: 'App',
  198. defaults: {
  199. session: new Session(),
  200. nodes: new NodeSet([]),
  201. subscriptionStatus: 'off',
  202. subscriptions: new SubscriptionList([])
  203. },
  204. initialize: function() {
  205. var session = this.get('session');
  206. if (session != undefined) {
  207. var self = this;
  208. session.bind("websock:data", function(msg) {
  209. self.publishEvent(msg);
  210. });
  211. }
  212. },
  213. publishEvent: function(msg) {
  214. var ev = JSON.parse(msg.data).event;
  215. if (ev.tag == 'system') {
  216. var info = ev.data[1];
  217. var key = 'event:system:' + info.node;
  218. console.debug('publishing ' + key);
  219. this.trigger(key, info);
  220. } else if (ev.tag == 'process') {
  221. var obj = ev.data[1];
  222. var key = "event:process:" + obj.node;
  223. console.debug('publishing ' + key);
  224. this.trigger(key, obj);
  225. } else {
  226. this.trigger('event:' + ev.tag, ev.data);
  227. }
  228. },
  229. activateSubscriptions: function() {
  230. this.toggleSubscriptions('PUT', 'ON');
  231. },
  232. deactivateSubscriptions: function() {
  233. this.toggleSubscriptions('DELETE', 'OFF');
  234. },
  235. toggleSubscriptions: function(method, status) {
  236. var session = this.get('session');
  237. var uname = session.get('username');
  238. $.ajax({
  239. url: '/service/subscriptions/active/' + uname,
  240. type: method,
  241. data: "",
  242. context: this
  243. }).success(function() { this.set({subscriptionStatus: status}); })
  244. .error(function() { console.debug('Unable to modify event feed!'); });
  245. }
  246. });