
Now only required resource values are fetched on calculating effective values. Calculation of effective values optimised to use indexed resource values insead of going throw nested for loop. Test for fetching values and effective values for 500 items (nodes) added. Each resource value contains over than 10000 keys. Logging added to the resource values fetching. Change-Id: Icea7ece8a2bc6957bcb00c9d90d8cf59e5ca1da0 Closes-Bug: #1626147
144 lines
5.9 KiB
Python
144 lines
5.9 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import flask
|
|
from flask import current_app as app
|
|
import flask_restful
|
|
import six
|
|
from sqlalchemy import or_
|
|
|
|
from tuning_box import db
|
|
from tuning_box import library
|
|
from tuning_box.library import hierarchy_levels
|
|
from tuning_box.library import resource_keys_operation
|
|
|
|
|
|
class ResourceValues(flask_restful.Resource):
|
|
|
|
@db.with_transaction
|
|
def put(self, environment_id, levels, resource_id_or_name):
|
|
environment = db.Environment.query.get_or_404(environment_id)
|
|
res_def = library.get_resource_definition(
|
|
resource_id_or_name, environment_id)
|
|
|
|
level_value = hierarchy_levels.get_environment_level_value(
|
|
environment, levels)
|
|
esv = db.get_or_create(
|
|
db.ResourceValues,
|
|
environment=environment,
|
|
resource_definition=res_def,
|
|
level_value=level_value,
|
|
)
|
|
esv.values = flask.request.json
|
|
return None, 204
|
|
|
|
def _calculate_effective_values(self, result, level_value,
|
|
resource_values_idx, show_lookup,
|
|
lookup_path):
|
|
level_value_id = getattr(level_value, 'id', None)
|
|
if level_value_id in resource_values_idx:
|
|
resource_value = resource_values_idx[level_value_id]
|
|
if show_lookup:
|
|
values = ((k, (v, lookup_path)) for k, v in
|
|
six.iteritems(resource_value.values))
|
|
overrides = ((k, (v, lookup_path)) for k, v in
|
|
six.iteritems(resource_value.overrides))
|
|
else:
|
|
values = resource_value.values
|
|
overrides = resource_value.overrides
|
|
result.update(values)
|
|
result.update(overrides)
|
|
|
|
@db.with_transaction
|
|
def get(self, environment_id, resource_id_or_name, levels):
|
|
app.logger.debug("Getting resource value. Env: %s, "
|
|
"resource: %s, levels: %s", environment_id,
|
|
resource_id_or_name, levels)
|
|
environment = db.Environment.query.get_or_404(environment_id)
|
|
res_def = library.get_resource_definition(
|
|
resource_id_or_name, environment_id)
|
|
|
|
level_values = list(hierarchy_levels.iter_environment_level_values(
|
|
environment, levels))
|
|
|
|
level_values_ids = [l.id for l in level_values]
|
|
app.logger.debug("Got level values ids: %s", level_values_ids)
|
|
|
|
if 'effective' in flask.request.args:
|
|
app.logger.debug("Getting effective resource value. Env: %s, "
|
|
"resource: %s, levels: %s", environment_id,
|
|
resource_id_or_name, levels)
|
|
show_lookup = 'show_lookup' in flask.request.args
|
|
resource_values = db.ResourceValues.query.filter(
|
|
or_(
|
|
db.ResourceValues.level_value_id.in_(level_values_ids),
|
|
db.ResourceValues.level_value_id.is_(None)
|
|
),
|
|
db.ResourceValues.resource_definition == res_def,
|
|
db.ResourceValues.environment == environment
|
|
).all()
|
|
app.logger.debug("Processing values for resource: %s, env: %s. "
|
|
"Loaded resource values: %s",
|
|
res_def.id, environment.id, len(resource_values))
|
|
# Creating index of resource_values by level_value_id
|
|
resource_values_idx = {r.level_value_id: r
|
|
for r in resource_values}
|
|
app.logger.debug("Resource values index size: %s",
|
|
len(resource_values_idx))
|
|
|
|
result = {}
|
|
lookup_path = '/'
|
|
self._calculate_effective_values(
|
|
result, None, resource_values_idx, show_lookup,
|
|
lookup_path)
|
|
|
|
for level_value in level_values:
|
|
name = level_value.level.name
|
|
value = level_value.value
|
|
lookup_path += name + '/' + value + '/'
|
|
|
|
self._calculate_effective_values(
|
|
result, level_value, resource_values_idx, show_lookup,
|
|
lookup_path)
|
|
|
|
app.logger.debug("Effective values got for resource: "
|
|
"%s, env: %s", res_def.id, environment.id)
|
|
return result
|
|
else:
|
|
if not level_values:
|
|
level_value = None
|
|
else:
|
|
level_value = level_values[-1]
|
|
resource_values = db.ResourceValues.query.filter_by(
|
|
resource_definition=res_def,
|
|
environment=environment,
|
|
level_value=level_value,
|
|
).one_or_none()
|
|
app.logger.debug("Values got for resource: "
|
|
"%s, env: %s", res_def.id, environment.id)
|
|
if not resource_values:
|
|
return {}
|
|
return resource_values.values
|
|
|
|
|
|
class ResourceValuesKeys(flask_restful.Resource,
|
|
resource_keys_operation.ResourceKeysMixin):
|
|
|
|
def put(self, environment_id, levels, resource_id_or_name, operation):
|
|
return self.patch(environment_id, levels,
|
|
resource_id_or_name, operation)
|
|
|
|
def patch(self, environment_id, levels, resource_id_or_name, operation):
|
|
self._do_update(environment_id, levels, resource_id_or_name,
|
|
operation, 'values')
|
|
return None, 204
|