From 91b0d72a60a64dd304494ec760550aa654002be5 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Wed, 8 Apr 2015 22:35:18 -0700 Subject: [PATCH] GUAC-1126 Add caching of GET requests in REST API services. --- .../webapp/app/rest/services/cacheService.js | 59 +++++++++++++++++++ .../rest/services/connectionGroupService.js | 29 +++++++-- .../app/rest/services/connectionService.js | 26 ++++++-- .../app/rest/services/permissionService.js | 23 ++++++-- .../app/rest/services/protocolService.js | 12 +++- .../webapp/app/rest/services/userService.js | 40 ++++++++++--- 6 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 guacamole/src/main/webapp/app/rest/services/cacheService.js diff --git a/guacamole/src/main/webapp/app/rest/services/cacheService.js b/guacamole/src/main/webapp/app/rest/services/cacheService.js new file mode 100644 index 000000000..7da8bcba6 --- /dev/null +++ b/guacamole/src/main/webapp/app/rest/services/cacheService.js @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Service which contains all REST API response caches. + */ +angular.module('rest').factory('cacheService', ['$injector', + function cacheService($injector) { + + // Required services + var $cacheFactory = $injector.get('$cacheFactory'); + + // Return service containing all caches + return { + + /** + * Shared cache used by both connectionGroupService and + * connectionService. + * + * @type $cacheFactory.Cache + */ + connections : $cacheFactory('API-CONNECTIONS'), + + /** + * Cache used by protocolService. + * + * @type $cacheFactory.Cache + */ + protocols : $cacheFactory('API-PROTOCOLS'), + + /** + * Shared cache used by both userService and permissionService. + * + * @type $cacheFactory.Cache + */ + users : $cacheFactory('API-USER') + + }; + +}]); diff --git a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js index 1f959b38e..d43c58f52 100644 --- a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js +++ b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js @@ -23,9 +23,17 @@ /** * Service for operating on connection groups via the REST API. */ -angular.module('rest').factory('connectionGroupService', ['$http', 'authenticationService', 'ConnectionGroup', - function connectionGroupService($http, authenticationService, ConnectionGroup) { - +angular.module('rest').factory('connectionGroupService', ['$injector', + function connectionGroupService($injector) { + + // Required services + var $http = $injector.get('$http'); + var authenticationService = $injector.get('authenticationService'); + var cacheService = $injector.get('cacheService'); + + // Required types + var ConnectionGroup = $injector.get('ConnectionGroup'); + var service = {}; /** @@ -65,6 +73,7 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati // Retrieve connection group return $http({ + cache : cacheService.connections, method : 'GET', url : 'api/connectionGroups/' + encodeURIComponent(connectionGroupID) + '/tree', params : httpParameters @@ -97,6 +106,7 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati // Retrieve connection group return $http({ + cache : cacheService.connections, method : 'GET', url : 'api/connectionGroups/' + encodeURIComponent(connectionGroupID), params : httpParameters @@ -133,9 +143,10 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati data : connectionGroup }) - // Set the identifier on the new connection group + // Set the identifier on the new connection group and clear the cache .success(function connectionGroupCreated(identifier){ connectionGroup.identifier = identifier; + cacheService.connections.removeAll(); }); } @@ -146,6 +157,11 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati url : 'api/connectionGroups/' + encodeURIComponent(connectionGroup.identifier), params : httpParameters, data : connectionGroup + }) + + // Clear the cache + .success(function connectionGroupUpdated(){ + cacheService.connections.removeAll(); }); } @@ -173,6 +189,11 @@ angular.module('rest').factory('connectionGroupService', ['$http', 'authenticati method : 'DELETE', url : 'api/connectionGroups/' + encodeURIComponent(connectionGroup.identifier), params : httpParameters + }) + + // Clear the cache + .success(function connectionGroupDeleted(){ + cacheService.connections.removeAll(); }); }; diff --git a/guacamole/src/main/webapp/app/rest/services/connectionService.js b/guacamole/src/main/webapp/app/rest/services/connectionService.js index c655404e4..2afba2489 100644 --- a/guacamole/src/main/webapp/app/rest/services/connectionService.js +++ b/guacamole/src/main/webapp/app/rest/services/connectionService.js @@ -23,9 +23,14 @@ /** * Service for operating on connections via the REST API. */ -angular.module('rest').factory('connectionService', ['$http', 'authenticationService', - function connectionService($http, authenticationService) { - +angular.module('rest').factory('connectionService', ['$injector', + function connectionService($injector) { + + // Required services + var $http = $injector.get('$http'); + var authenticationService = $injector.get('authenticationService'); + var cacheService = $injector.get('cacheService'); + var service = {}; /** @@ -52,6 +57,7 @@ angular.module('rest').factory('connectionService', ['$http', 'authenticationSer // Retrieve connection return $http({ + cache : cacheService.connections, method : 'GET', url : 'api/connections/' + encodeURIComponent(id), params : httpParameters @@ -108,6 +114,7 @@ angular.module('rest').factory('connectionService', ['$http', 'authenticationSer // Retrieve connection parameters return $http({ + cache : cacheService.connections, method : 'GET', url : 'api/connections/' + encodeURIComponent(id) + '/parameters', params : httpParameters @@ -144,9 +151,10 @@ angular.module('rest').factory('connectionService', ['$http', 'authenticationSer data : connection }) - // Set the identifier on the new connection + // Set the identifier on the new connection and clear the cache .success(function connectionCreated(identifier){ connection.identifier = identifier; + cacheService.connections.removeAll(); }); } @@ -157,6 +165,11 @@ angular.module('rest').factory('connectionService', ['$http', 'authenticationSer url : 'api/connections/' + encodeURIComponent(connection.identifier), params : httpParameters, data : connection + }) + + // Clear the cache + .success(function connectionUpdated(){ + cacheService.connections.removeAll(); }); } @@ -184,6 +197,11 @@ angular.module('rest').factory('connectionService', ['$http', 'authenticationSer method : 'DELETE', url : 'api/connections/' + encodeURIComponent(connection.identifier), params : httpParameters + }) + + // Clear the cache + .success(function connectionDeleted(){ + cacheService.connections.removeAll(); }); }; diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js index 803afcf8e..c60bfd2dc 100644 --- a/guacamole/src/main/webapp/app/rest/services/permissionService.js +++ b/guacamole/src/main/webapp/app/rest/services/permissionService.js @@ -23,11 +23,19 @@ /** * Service for operating on user permissions via the REST API. */ -angular.module('rest').factory('permissionService', ['$http', 'authenticationService', 'PermissionPatch', - function permissionService($http, authenticationService, PermissionPatch) { - - var service = {}; +angular.module('rest').factory('permissionService', ['$injector', + function permissionService($injector) { + + // Required services + var $http = $injector.get('$http'); + var authenticationService = $injector.get('authenticationService'); + var cacheService = $injector.get('cacheService'); + // Required types + var PermissionPatch = $injector.get('PermissionPatch'); + + var service = {}; + /** * Makes a request to the REST API to get the list of permissions for a * given user, returning a promise that provides an array of @@ -49,6 +57,7 @@ angular.module('rest').factory('permissionService', ['$http', 'authenticationSer // Retrieve user permissions return $http({ + cache : cacheService.users, method : 'GET', url : 'api/users/' + encodeURIComponent(userID) + '/permissions', params : httpParameters @@ -211,8 +220,12 @@ angular.module('rest').factory('permissionService', ['$http', 'authenticationSer url : 'api/users/' + encodeURIComponent(userID) + '/permissions', params : httpParameters, data : permissionPatch + }) + + // Clear the cache + .success(function permissionsPatched(){ + cacheService.users.removeAll(); }); - }; return service; diff --git a/guacamole/src/main/webapp/app/rest/services/protocolService.js b/guacamole/src/main/webapp/app/rest/services/protocolService.js index b03acd53b..3306f8b1a 100644 --- a/guacamole/src/main/webapp/app/rest/services/protocolService.js +++ b/guacamole/src/main/webapp/app/rest/services/protocolService.js @@ -23,9 +23,14 @@ /** * Service for operating on protocol metadata via the REST API. */ -angular.module('rest').factory('protocolService', ['$http', 'authenticationService', - function protocolService($http, authenticationService) { - +angular.module('rest').factory('protocolService', ['$injector', + function protocolService($injector) { + + // Required services + var $http = $injector.get('$http'); + var authenticationService = $injector.get('authenticationService'); + var cacheService = $injector.get('cacheService'); + var service = {}; /** @@ -46,6 +51,7 @@ angular.module('rest').factory('protocolService', ['$http', 'authenticationServi // Retrieve available protocols return $http({ + cache : cacheService.protocols, method : 'GET', url : 'api/protocols', params : httpParameters diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js index 07dd87453..a81916e19 100644 --- a/guacamole/src/main/webapp/app/rest/services/userService.js +++ b/guacamole/src/main/webapp/app/rest/services/userService.js @@ -26,13 +26,14 @@ angular.module('rest').factory('userService', ['$injector', function userService($injector) { + // Required services + var $http = $injector.get('$http'); + var authenticationService = $injector.get('authenticationService'); + var cacheService = $injector.get('cacheService'); + // Get required types var UserPasswordUpdate = $injector.get("UserPasswordUpdate"); - // Get required services - var $http = $injector.get("$http"); - var authenticationService = $injector.get("authenticationService"); - var service = {}; /** @@ -63,6 +64,7 @@ angular.module('rest').factory('userService', ['$injector', // Retrieve users return $http({ + cache : cacheService.users, method : 'GET', url : 'api/users', params : httpParameters @@ -90,6 +92,7 @@ angular.module('rest').factory('userService', ['$injector', // Retrieve user return $http({ + cache : cacheService.users, method : 'GET', url : 'api/users/' + encodeURIComponent(username), params : httpParameters @@ -115,13 +118,19 @@ angular.module('rest').factory('userService', ['$injector', token : authenticationService.getCurrentToken() }; - // Retrieve user + // Delete user return $http({ method : 'DELETE', url : 'api/users/' + encodeURIComponent(user.username), params : httpParameters + }) + + // Clear the cache + .success(function userDeleted(){ + cacheService.users.removeAll(); }); + }; /** @@ -142,12 +151,17 @@ angular.module('rest').factory('userService', ['$injector', token : authenticationService.getCurrentToken() }; - // Retrieve user + // Create user return $http({ method : 'POST', url : 'api/users', params : httpParameters, data : user + }) + + // Clear the cache + .success(function userCreated(){ + cacheService.users.removeAll(); }); }; @@ -170,12 +184,17 @@ angular.module('rest').factory('userService', ['$injector', token : authenticationService.getCurrentToken() }; - // Retrieve user + // Update user return $http({ method : 'PUT', url : 'api/users/' + encodeURIComponent(user.username), params : httpParameters, data : user + }) + + // Clear the cache + .success(function userUpdated(){ + cacheService.users.removeAll(); }); }; @@ -205,7 +224,7 @@ angular.module('rest').factory('userService', ['$injector', token : authenticationService.getCurrentToken() }; - // Retrieve user + // Update user password return $http({ method : 'PUT', url : 'api/users/' + encodeURIComponent(username) + '/password', @@ -214,6 +233,11 @@ angular.module('rest').factory('userService', ['$injector', oldPassword : oldPassword, newPassword : newPassword }) + }) + + // Clear the cache + .success(function passwordChanged(){ + cacheService.users.removeAll(); }); };