示例#1
0
    def process_action(self, context, service_name, api_version, action_name,
                       action_params):
        service_capabilities = self.capabilities.get(service_name, None)

        if service_capabilities is None:
            raise exception.BadRequestException(
                "Service '%s' isn't supported" % service_name)

        target_capabilities = service_capabilities.get(api_version, None)

        if target_capabilities is None:
            raise (
                exception.BadRequestException(
                    "Service '%s' doesn't support API version '%s'" %
                    (service_name, api_version))
            )

        action = target_capabilities.get(action_name, None)

        if action is None:
            raise (
                exception.ValidationException(
                    "Service '%s', API version '%s' "
                    "doesn't support action '%s'" %
                    (service_name, api_version, action_name))
            )

        return action.perform(context, action_params)
示例#2
0
def validate_params(schema, params):
    assert isinstance(params, dict)

    validator = jsonschema.Draft4Validator(schema)
    if not validator.is_valid(params):
        errors = sorted(validator.iter_errors(params), key=lambda e: e.path)
        error_msg = format_validation_msg(errors)
        LOG.info(error_msg)
        raise exception.ValidationException(error_msg)
示例#3
0
    def process_request(self, req, body):
        target = req.environ['HTTP_X_AMZ_TARGET']

        if not target:
            raise (
                exception.ValidationException(
                    "'x-amz-target' header wasn't found")
            )

        matcher = re.match("(\w+)_(\w+)\.(\w+)", target)

        if not matcher:
            raise (
                exception.ValidationException(
                    "'x-amz-target' header wasn't recognized (actual: %s, "
                    "expected format: <<serviceName>>_<<API version>>."
                    "<<operationName>>")
            )
        service_name = matcher.group(1)
        api_version = matcher.group(2)
        action_name = matcher.group(3)

        return self.process_action(req.context, service_name, api_version,
                                   action_name, body)
示例#4
0
    def __call__(self):

        table_name = self.action_params.get(Props.TABLE_NAME, None)

        if not table_name:
            raise exception.ValidationException(
                message='Table name is not defined')

        try:
            table_meta = storage.describe_table(self.context, table_name)

            result = {
                Props.TABLE: {
                    Props.ATTRIBUTE_DEFINITIONS:
                    (Parser.format_attribute_definitions(
                        table_meta.schema.attribute_type_map)),
                    Props.CREATION_DATE_TIME:
                    0,
                    Props.ITEM_COUNT:
                    0,
                    Props.KEY_SCHEMA: (Parser.format_key_schema(
                        table_meta.schema.key_attributes)),
                    Props.PROVISIONED_THROUGHPUT:
                    (Values.PROVISIONED_THROUGHPUT_DUMMY),
                    Props.TABLE_NAME:
                    table_name,
                    Props.TABLE_STATUS:
                    (Parser.format_table_status(table_meta.status)),
                    Props.TABLE_SIZE_BYTES:
                    0
                }
            }

            if table_meta.schema.index_def_map:
                table_def = result[Props.TABLE]
                table_def[Props.LOCAL_SECONDARY_INDEXES] = (
                    Parser.format_local_secondary_indexes(
                        table_meta.schema.key_attributes[0],
                        table_meta.schema.index_def_map))
            return result

        except exception.TableNotExistsException as e:
            raise exception.ResourceNotFoundException(e.message)
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
示例#5
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # get attributes_to_get
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)

            select_type = (models.SelectType.all()
                           if attributes_to_get is None else
                           models.AttributeToGet.specified(attributes_to_get))

            # parse key_attributes
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get  to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            # format conditions to get item
            indexed_condition_map = {
                name: [models.IndexedCondition.eq(value)]
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            # get item
            result = storage.select_item(self.context,
                                         table_name,
                                         indexed_condition_map,
                                         select_type=select_type,
                                         limit=2,
                                         consistent=consistent_read)

            # format response
            if result.count == 0:
                return {}

            assert result.count == 1

            response = {
                parser.Props.ITEM:
                parser.Parser.format_item_attributes(result.items[0])
            }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
示例#6
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})))

            # parse item
            item_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.ITEM])

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE)

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)
        except Exception:
            raise exception.ValidationException()

        try:
            # put item
            result = storage.put_item(
                self.context,
                models.PutItemRequest(table_name, item_attributes),
                if_not_exist=False,
                expected_condition_map=expected_item_conditions)

            if not result:
                raise exception.AWSErrorResponseException()

            # format response
            response = {}

            if return_values != parser.Values.RETURN_VALUES_NONE:
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(item_attributes))

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key"))
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse expected item conditions
            expected_item_conditions = (
                parser.Parser.parse_expected_attribute_conditions(
                    self.action_params.get(parser.Props.EXPECTED, {})))

            #parse attribute updates
            attribute_updates = parser.Parser.parse_attribute_updates(
                self.action_params.get(parser.Props.ATTRIBUTE_UPDATES, {}))

            # parse key
            key_attributes = parser.Parser.parse_item_attributes(
                self.action_params[parser.Props.KEY])

            # parse return_values param
            return_values = self.action_params.get(
                parser.Props.RETURN_VALUES, parser.Values.RETURN_VALUES_NONE)

            # parse return_item_collection_metrics
            return_item_collection_metrics = self.action_params.get(
                parser.Props.RETURN_ITEM_COLLECTION_METRICS,
                parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            select_result = None

            indexed_condition_map_for_select = {
                name: models.IndexedCondition.eq(value)
                for name, value in key_attributes.iteritems()
            }
        except Exception:
            raise exception.ValidationException()

        try:
            if return_values in (parser.Values.RETURN_VALUES_UPDATED_OLD,
                                 parser.Values.RETURN_VALUES_ALL_OLD):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # update item
            result = storage.update_item(
                self.context,
                table_name,
                key_attribute_map=key_attributes,
                attribute_action_map=attribute_updates,
                expected_condition_map=expected_item_conditions)

            if not result:
                raise exception.AWSErrorResponseException()

            if return_values in (parser.Values.RETURN_VALUES_UPDATED_NEW,
                                 parser.Values.RETURN_VALUES_ALL_NEW):

                select_result = storage.select_item(
                    self.context, table_name, indexed_condition_map_for_select)

            # format response
            response = {}

            if return_values != parser.Values.RETURN_VALUES_NONE:
                response[parser.Props.ATTRIBUTES] = (
                    parser.Parser.format_item_attributes(
                        select_result.items[0]))

            if (return_item_collection_metrics !=
                    parser.Values.RETURN_ITEM_COLLECTION_METRICS_NONE):
                response[parser.Props.ITEM_COLLECTION_METRICS] = {
                    parser.Props.ITEM_COLLECTION_KEY: {
                        parser.Parser.format_item_attributes(
                            models.AttributeValue(models.ATTRIBUTE_TYPE_STRING,
                                                  "key"))
                    },
                    parser.Props.SIZE_ESTIMATED_RANGE_GB: [0]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
示例#8
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            # parse select_type
            attributes_to_get = self.action_params.get(
                parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get is not None:
                attributes_to_get = frozenset(attributes_to_get)

            select = self.action_params.get(parser.Props.SELECT, None)

            index_name = self.action_params.get(parser.Props.INDEX_NAME, None)

            select_type = parser.Parser.parse_select_type(
                select, attributes_to_get, index_name)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes = self.action_params.get(
                parser.Props.EXCLUSIVE_START_KEY, None)
            if exclusive_start_key_attributes is not None:
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes))

            # parse indexed_condition_map
            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                self.action_params.get(parser.Props.KEY_CONDITIONS, None))

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = self.action_params.get(
                parser.Props.CONSISTENT_READ, False)

            limit = self.action_params.get(parser.Props.LIMIT, None)

            return_consumed_capacity = self.action_params.get(
                parser.Props.RETURN_CONSUMED_CAPACITY,
                parser.Values.RETURN_CONSUMED_CAPACITY_NONE)

            order_asc = self.action_params.get(parser.Props.SCAN_INDEX_FORWARD,
                                               None)

            order_type = (None if order_asc is None else models.ORDER_TYPE_ASC
                          if order_asc else models.ORDER_TYPE_DESC)
        except Exception:
            raise exception.ValidationException()

        try:
            # select item
            result = storage.select_item(
                self.context,
                table_name,
                indexed_condition_map,
                select_type=select_type,
                index_name=index_name,
                limit=limit,
                consistent=consistent_read,
                order_type=order_type,
                exclusive_start_key=exclusive_start_key_attributes)

            # format response
            if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
                response = {parser.Props.COUNT: result.count}
            else:
                response = {
                    parser.Props.COUNT:
                    result.count,
                    parser.Props.ITEMS: [
                        parser.Parser.format_item_attributes(row)
                        for row in result.items
                    ]
                }

            if (return_consumed_capacity !=
                    parser.Values.RETURN_CONSUMED_CAPACITY_NONE):
                response[parser.Props.CONSUMED_CAPACITY] = (
                    parser.Parser.format_consumed_capacity(
                        return_consumed_capacity, None))

            if limit == result.count:
                response[parser.Props.LAST_EVALUATED_KEY] = (
                    parser.Parser.format_item_attributes(
                        result.last_evaluated_key))
            return response
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()
示例#9
0
    def __call__(self):
        try:
            table_name = self.action_params.get(parser.Props.TABLE_NAME, None)

            #parse table attributes
            attribute_definitions = parser.Parser.parse_attribute_definitions(
                self.action_params.get(parser.Props.ATTRIBUTE_DEFINITIONS, {})
            )

            #parse table key schema
            key_attrs = parser.Parser.parse_key_schema(
                self.action_params.get(parser.Props.KEY_SCHEMA, [])
            )

            #parse table indexed field list
            indexed_def_map = parser.Parser.parse_local_secondary_indexes(
                self.action_params.get(
                    parser.Props.LOCAL_SECONDARY_INDEXES, [])
            )

            #prepare table_schema structure
            table_schema = models.TableSchema(
                attribute_definitions, key_attrs, indexed_def_map
            )

        except Exception:
            raise exception.ValidationException()

        try:
            # creating table
            table_meta = storage.create_table(
                self.context, table_name, table_schema
            )

            result = {
                parser.Props.TABLE_DESCRIPTION: {
                    parser.Props.ATTRIBUTE_DEFINITIONS: (
                        parser.Parser.format_attribute_definitions(
                            table_meta.schema.attribute_type_map
                        )
                    ),
                    parser.Props.CREATION_DATE_TIME: 0,
                    parser.Props.ITEM_COUNT: 0,
                    parser.Props.KEY_SCHEMA: (
                        parser.Parser.format_key_schema(
                            table_meta.schema.key_attributes
                        )
                    ),
                    parser.Props.PROVISIONED_THROUGHPUT: (
                        parser.Values.PROVISIONED_THROUGHPUT_DUMMY
                    ),
                    parser.Props.TABLE_NAME: table_name,
                    parser.Props.TABLE_STATUS: (
                        parser.Parser.format_table_status(table_meta.status)
                    ),
                    parser.Props.TABLE_SIZE_BYTES: 0
                }
            }

            if table_meta.schema.index_def_map:
                table_def = result[parser.Props.TABLE_DESCRIPTION]
                table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                    parser.Parser.format_local_secondary_indexes(
                        table_meta.schema.key_attributes[0],
                        table_meta.schema.index_def_map
                    )
                )

            return result
        except exception.TableAlreadyExistsException:
            raise exception.ResourceInUseException()
        except exception.AWSErrorResponseException as e:
            raise e
        except Exception:
            raise exception.AWSErrorResponseException()