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
« 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.
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
24@base.WatcherObjectRegistry.register
25class Goal(base.WatcherPersistentObject, base.WatcherObject,
26 base.WatcherObjectDictCompat):
27 # Version 1.0: Initial version
28 VERSION = '1.0'
30 dbapi = db_api.get_instance()
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 }
40 @base.remotable_classmethod
41 def get(cls, context, goal_id):
42 """Find a goal based on its id or uuid
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)
60 @base.remotable_classmethod
61 def get_by_id(cls, context, goal_id):
62 """Find a goal based on its integer id
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
77 @base.remotable_classmethod
78 def get_by_uuid(cls, context, uuid):
79 """Find a goal based on uuid
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
94 @base.remotable_classmethod
95 def get_by_name(cls, context, name):
96 """Find a goal based on name
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
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.
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)
132 return [cls._from_db_object(cls(context), obj) for obj in db_goals]
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)
141 def destroy(self):
142 """Delete the :class:`Goal` from the DB"""
143 self.dbapi.destroy_goal(self.id)
144 self.obj_reset_changes()
146 @base.remotable
147 def save(self):
148 """Save updates to this :class:`Goal`.
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()
159 @base.remotable
160 def refresh(self):
161 """Loads updates for this :class:`Goal`.
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)
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)