Coverage for watcher/objects/goal.py: 91%

60 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-17 12:22 +0000

1# -*- encoding: utf-8 -*- 

2# Copyright 2013 IBM Corp. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 

13# implied. 

14# See the License for the specific language governing permissions and 

15# limitations under the License. 

16 

17from watcher.common import exception 

18from watcher.common import utils 

19from watcher.db import api as db_api 

20from watcher.objects import base 

21from watcher.objects import fields as wfields 

22 

23 

24@base.WatcherObjectRegistry.register 

25class Goal(base.WatcherPersistentObject, base.WatcherObject, 

26 base.WatcherObjectDictCompat): 

27 # Version 1.0: Initial version 

28 VERSION = '1.0' 

29 

30 dbapi = db_api.get_instance() 

31 

32 fields = { 

33 'id': wfields.IntegerField(), 

34 'uuid': wfields.UUIDField(), 

35 'name': wfields.StringField(), 

36 'display_name': wfields.StringField(), 

37 'efficacy_specification': wfields.FlexibleListOfDictField(), 

38 } 

39 

40 @base.remotable_classmethod 

41 def get(cls, context, goal_id): 

42 """Find a goal based on its id or uuid 

43 

44 :param context: Security context. NOTE: This should only 

45 be used internally by the indirection_api. 

46 Unfortunately, RPC requires context as the first 

47 argument, even though we don't use it. 

48 A context should be set when instantiating the 

49 object, e.g.: Goal(context) 

50 :param goal_id: the id *or* uuid of a goal. 

51 :returns: a :class:`Goal` object. 

52 """ 

53 if utils.is_int_like(goal_id): 

54 return cls.get_by_id(context, goal_id) 

55 elif utils.is_uuid_like(goal_id): 55 ↛ 58line 55 didn't jump to line 58 because the condition on line 55 was always true

56 return cls.get_by_uuid(context, goal_id) 

57 else: 

58 raise exception.InvalidIdentity(identity=goal_id) 

59 

60 @base.remotable_classmethod 

61 def get_by_id(cls, context, goal_id): 

62 """Find a goal based on its integer id 

63 

64 :param context: Security context. NOTE: This should only 

65 be used internally by the indirection_api. 

66 Unfortunately, RPC requires context as the first 

67 argument, even though we don't use it. 

68 A context should be set when instantiating the 

69 object, e.g.: Goal(context) 

70 :param goal_id: the id *or* uuid of a goal. 

71 :returns: a :class:`Goal` object. 

72 """ 

73 db_goal = cls.dbapi.get_goal_by_id(context, goal_id) 

74 goal = cls._from_db_object(cls(context), db_goal) 

75 return goal 

76 

77 @base.remotable_classmethod 

78 def get_by_uuid(cls, context, uuid): 

79 """Find a goal based on uuid 

80 

81 :param context: Security context. NOTE: This should only 

82 be used internally by the indirection_api. 

83 Unfortunately, RPC requires context as the first 

84 argument, even though we don't use it. 

85 A context should be set when instantiating the 

86 object, e.g.: Goal(context) 

87 :param uuid: the uuid of a goal. 

88 :returns: a :class:`Goal` object. 

89 """ 

90 db_goal = cls.dbapi.get_goal_by_uuid(context, uuid) 

91 goal = cls._from_db_object(cls(context), db_goal) 

92 return goal 

93 

94 @base.remotable_classmethod 

95 def get_by_name(cls, context, name): 

96 """Find a goal based on name 

97 

98 :param name: the name of a goal. 

99 :param context: Security context 

100 :returns: a :class:`Goal` object. 

101 """ 

102 db_goal = cls.dbapi.get_goal_by_name(context, name) 

103 goal = cls._from_db_object(cls(context), db_goal) 

104 return goal 

105 

106 @base.remotable_classmethod 

107 def list(cls, context, limit=None, marker=None, filters=None, 

108 sort_key=None, sort_dir=None): 

109 """Return a list of :class:`Goal` objects. 

110 

111 :param context: Security context. NOTE: This should only 

112 be used internally by the indirection_api. 

113 Unfortunately, RPC requires context as the first 

114 argument, even though we don't use it. 

115 A context should be set when instantiating the 

116 object, e.g.: Goal(context) 

117 :param filters: dict mapping the filter key to a value. 

118 :param limit: maximum number of resources to return in a single result. 

119 :param marker: pagination marker for large data sets. 

120 :param sort_key: column to sort results by. 

121 :param sort_dir: direction to sort. "asc" or "desc". 

122 :returns: a list of :class:`Goal` object. 

123 """ 

124 db_goals = cls.dbapi.get_goal_list( 

125 context, 

126 filters=filters, 

127 limit=limit, 

128 marker=marker, 

129 sort_key=sort_key, 

130 sort_dir=sort_dir) 

131 

132 return [cls._from_db_object(cls(context), obj) for obj in db_goals] 

133 

134 @base.remotable 

135 def create(self): 

136 """Create a :class:`Goal` record in the DB""" 

137 values = self.obj_get_changes() 

138 db_goal = self.dbapi.create_goal(values) 

139 self._from_db_object(self, db_goal) 

140 

141 def destroy(self): 

142 """Delete the :class:`Goal` from the DB""" 

143 self.dbapi.destroy_goal(self.id) 

144 self.obj_reset_changes() 

145 

146 @base.remotable 

147 def save(self): 

148 """Save updates to this :class:`Goal`. 

149 

150 Updates will be made column by column based on the result 

151 of self.what_changed(). 

152 """ 

153 updates = self.obj_get_changes() 

154 db_obj = self.dbapi.update_goal(self.uuid, updates) 

155 obj = self._from_db_object(self, db_obj, eager=False) 

156 self.obj_refresh(obj) 

157 self.obj_reset_changes() 

158 

159 @base.remotable 

160 def refresh(self): 

161 """Loads updates for this :class:`Goal`. 

162 

163 Loads a goal with the same uuid from the database and 

164 checks for updated attributes. Updates are applied from 

165 the loaded goal column by column, if there are any updates. 

166 """ 

167 current = self.get_by_uuid(self._context, uuid=self.uuid) 

168 self.obj_refresh(current) 

169 

170 @base.remotable 

171 def soft_delete(self): 

172 """Soft Delete the :class:`Goal` from the DB""" 

173 db_obj = self.dbapi.soft_delete_goal(self.uuid) 

174 obj = self._from_db_object( 

175 self.__class__(self._context), db_obj, eager=False) 

176 self.obj_refresh(obj)