Path: blob/develop/awscli/customizations/datapipeline/translator.py
1567 views
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12import json13from awscli.clidriver import CLIOperationCaller141516class PipelineDefinitionError(Exception):17def __init__(self, msg, definition):18full_msg = (19"Error in pipeline definition: %s\n" % msg)20super(PipelineDefinitionError, self).__init__(full_msg)21self.msg = msg22self.definition = definition232425# Method to convert the dictionary input to a string26# This is required for escaping27def dict_to_string(dictionary, indent=2):28return json.dumps(dictionary, indent=indent)293031# Method to parse the arguments to get the region value32def get_region(session, parsed_globals):33region = parsed_globals.region34if region is None:35region = session.get_config_variable('region')36return region373839# Method to display the response for a particular CLI operation40def display_response(session, operation_name, result, parsed_globals):41cli_operation_caller = CLIOperationCaller(session)42# Calling a private method. Should be changed after the functionality43# is moved outside CliOperationCaller.44cli_operation_caller._display_response(45operation_name, result, parsed_globals)464748def api_to_definition(definition):49# When we're translating from api_response -> definition50# we have to be careful *not* to mutate the existing51# response as other code might need to the original52# api_response.53if 'pipelineObjects' in definition:54definition['objects'] = _api_to_objects_definition(55definition.pop('pipelineObjects'))56if 'parameterObjects' in definition:57definition['parameters'] = _api_to_parameters_definition(58definition.pop('parameterObjects'))59if 'parameterValues' in definition:60definition['values'] = _api_to_values_definition(61definition.pop('parameterValues'))62return definition636465def definition_to_api_objects(definition):66if 'objects' not in definition:67raise PipelineDefinitionError('Missing "objects" key', definition)68api_elements = []69# To convert to the structure expected by the service,70# we convert the existing structure to a list of dictionaries.71# Each dictionary has a 'fields', 'id', and 'name' key.72for element in definition['objects']:73try:74element_id = element.pop('id')75except KeyError:76raise PipelineDefinitionError('Missing "id" key of element: %s' %77json.dumps(element), definition)78api_object = {'id': element_id}79# If a name is provided, then we use that for the name,80# otherwise the id is used for the name.81name = element.pop('name', element_id)82api_object['name'] = name83# Now we need the field list. Each element in the field list is a dict84# with a 'key', 'stringValue'|'refValue'85fields = []86for key, value in sorted(element.items()):87fields.extend(_parse_each_field(key, value))88api_object['fields'] = fields89api_elements.append(api_object)90return api_elements919293def definition_to_api_parameters(definition):94if 'parameters' not in definition:95return None96parameter_objects = []97for element in definition['parameters']:98try:99parameter_id = element.pop('id')100except KeyError:101raise PipelineDefinitionError('Missing "id" key of parameter: %s' %102json.dumps(element), definition)103parameter_object = {'id': parameter_id}104# Now we need the attribute list. Each element in the attribute list105# is a dict with a 'key', 'stringValue'106attributes = []107for key, value in sorted(element.items()):108attributes.extend(_parse_each_field(key, value))109parameter_object['attributes'] = attributes110parameter_objects.append(parameter_object)111return parameter_objects112113114def definition_to_parameter_values(definition):115if 'values' not in definition:116return None117parameter_values = []118for key in definition['values']:119parameter_values.extend(120_convert_single_parameter_value(key, definition['values'][key]))121122return parameter_values123124125def _parse_each_field(key, value):126values = []127if isinstance(value, list):128for item in value:129values.append(_convert_single_field(key, item))130else:131values.append(_convert_single_field(key, value))132return values133134135def _convert_single_field(key, value):136field = {'key': key}137if isinstance(value, dict) and list(value.keys()) == ['ref']:138field['refValue'] = value['ref']139else:140field['stringValue'] = value141return field142143144def _convert_single_parameter_value(key, values):145parameter_values = []146if isinstance(values, list):147for each_value in values:148parameter_value = {'id': key, 'stringValue': each_value}149parameter_values.append(parameter_value)150else:151parameter_value = {'id': key, 'stringValue': values}152parameter_values.append(parameter_value)153return parameter_values154155156def _api_to_objects_definition(api_response):157pipeline_objects = []158for element in api_response:159current = {160'id': element['id'],161'name': element['name']162}163for field in element['fields']:164key = field['key']165if 'stringValue' in field:166value = field['stringValue']167else:168value = {'ref': field['refValue']}169_add_value(key, value, current)170pipeline_objects.append(current)171return pipeline_objects172173174def _api_to_parameters_definition(api_response):175parameter_objects = []176for element in api_response:177current = {178'id': element['id']179}180for attribute in element['attributes']:181_add_value(attribute['key'], attribute['stringValue'], current)182parameter_objects.append(current)183return parameter_objects184185186def _api_to_values_definition(api_response):187pipeline_values = {}188for element in api_response:189_add_value(element['id'], element['stringValue'], pipeline_values)190return pipeline_values191192193def _add_value(key, value, current_map):194if key not in current_map:195current_map[key] = value196elif isinstance(current_map[key], list):197# Dupe keys result in values aggregating198# into a list.199current_map[key].append(value)200else:201converted_list = [current_map[key], value]202current_map[key] = converted_list203204205