Beispiel #1
0
class ServiceClassService(BaseService):
    """
    Service to handle ServiceClass objects with mongodb and provide
    all business logic needed to views layer
    """
    def __init__(self):
        self.class_dao = ServiceClassDao()
        self.instance_dao = ServiceInstanceDao()

    def get_all_service_classes(self):
        return list(self.class_dao.find_all())

    def create(self, obj):
        try:
            return self.class_dao.create(obj)
        except DuplicateKeyError:
            raise UnsupportedParameterValueException(obj['_id'],
                                                     'non-existing-class')

    @return_obj_or_raise_not_found
    def get(self, class_name):
        return self.class_dao.find(class_name)

    def update(self, obj):
        # raise not found if not existing class

        if self.class_dao.update(
                obj):  # When OperationFailure, Exception mapper will translate
            return obj
        else:
            raise GenericServiceError('Class update failed')

    def delete(self, class_name):
        class_obj = self.class_dao.find(class_name)
        if class_obj:
            try:
                self.instance_dao.delete_by_class_name(class_name)
            except OperationFailure:
                raise GenericServiceError('The class delete process failed.')
            if self.class_dao.delete(class_name):
                return
            else:
                raise GenericServiceError('The class delete process failed.')

        raise NotFoundException(class_name)
Beispiel #2
0
 def setUp(self):
     self.class_ = {
         '_id': 'test',
         'description': 'Descripcion test',
         'default_version': "1.0"
     }
     self.instance = {
         'uri': 'http://test',
         'version': '1.0',
         'class_name': 'test'
     }
     self.instance_new = {
         'uri': 'http://testNew',
         'version': '1.0',
         'class_name': 'test'
     }
     self.dao = ServiceInstanceDao()
     self.classes_dao = ServiceClassDao()
     self.classes_dao.create(self.class_)
     self.dao.create(self.instance)
     super(InstancesDaoTests, self).setUp()
Beispiel #3
0
class InstancesDaoTests(TestCase):
    def setUp(self):
        self.class_ = {
            '_id': 'test',
            'description': 'Descripcion test',
            'default_version': "1.0"
        }
        self.instance = {
            'uri': 'http://test',
            'version': '1.0',
            'class_name': 'test'
        }
        self.instance_new = {
            'uri': 'http://testNew',
            'version': '1.0',
            'class_name': 'test'
        }
        self.dao = ServiceInstanceDao()
        self.classes_dao = ServiceClassDao()
        self.classes_dao.create(self.class_)
        self.dao.create(self.instance)
        super(InstancesDaoTests, self).setUp()

    def tearDown(self):
        self.dao.delete(self.instance['_id'])
        self.classes_dao.delete(self.class_['_id'])

    def test_add_new_instance_should_work(self):
        self.dao.create(self.instance_new)
        created_instance = self.dao.find(self.instance_new['_id'])
        self.assertEquals(created_instance, self.instance_new)
        # Removing created instance
        self.dao.delete(created_instance['_id'])

    def test_find_existing_instance_should_work(self):
        # _id is an objectId but we convert to str representation
        existing_instance = self.dao.find(str(self.instance['_id']))
        self.assertEquals(existing_instance, self.instance)

    def test_find_instance_by_class_name_and_id_invalid_id_should_return_none(
            self):
        # _id is an objectId but we convert to str representation
        res = self.dao.find_by_class_name_and_id('test', 'invalid_id')
        self.assertEquals(None, res)

    def test_find_all_existing_instance_should_work(self):
        # _id is an objectId but we convert to str representation
        instances_list = self.dao.find_all('test')
        self.assertEquals(1, len(list(instances_list)))

    def test_add_existing_instance_should_raiseException(self):
        """
        We check than uri, version and class_name are unique for instances collection
        """
        # We don't use self.instance as _id will be populated by setUp method
        # We want ton ensure unique index is being managed
        self.assertRaises(DuplicateKeyError, self.dao.create, {
            'uri': 'http://test',
            'version': '1.0',
            'class_name': 'test'
        })

    def test_modify_existing_instance_should_return_true(self):
        self.instance['ob'] = 'oba'
        res = self.dao.update(self.instance)
        self.assertEquals(True, res, 'ob param not added')

    def test_modify_invalid_instance_id_should_return_false(self):
        self.instance_new['_id'] = '8989_nonExisting'
        res = self.dao.update(self.instance_new)
        self.assertEquals(
            False, res, 'Non existing instance was modified and it shouldnt')

    def test_modify_non_existing_instance_should_return_false(self):
        self.instance_new['_id'] = '5555b1d2f26ba3088459ffff'
        res = self.dao.update(self.instance_new)
        self.assertEquals(
            False, res, 'Non existing instance was modified and it shouldnt')

    def test_modify_existing_instance_matching_another_should_return_DuplicateKeyException(
            self):
        instance_new = self.dao.create(self.instance_new)
        instance_new['uri'] = self.instance['uri']
        instance_new['version'] = self.instance['version']
        self.assertRaises(DuplicateKeyError, self.dao.update, instance_new)

    def test_delete_invalid_instance_id_should_return_false(self):
        res = self.dao.delete('non_exitings_id')
        self.assertEquals(res, False,
                          'Delete not existing instance didnt return false')

    def test_delete_unexisting_instance_id_should_return_false(self):
        res = self.dao.delete('5555b1d2f26ba3088459ffff')
        self.assertEquals(res, False,
                          'Delete not existing instance didnt return false')
Beispiel #4
0
 def __init__(self):
     self.binding_dao = BindingDao()
     self.class_dao = ServiceClassDao()
     self.instance_dao = ServiceInstanceDao()
Beispiel #5
0
class BindingService(BaseService):
    """
    Service to handle Bindings objects with mongodb and provide
    all business logic needed to views layer
    """
    def __init__(self):
        self.binding_dao = BindingDao()
        self.class_dao = ServiceClassDao()
        self.instance_dao = ServiceInstanceDao()

    @return_obj_or_raise_not_found
    def get_binding_by_id(self, binding_id):
        return self.binding_dao.find(binding_id)

    def get_all_bindings(self, query_params):
        return self.binding_dao.find_bindings(query_params)

    def create_binding(self, binding):
        if not self.class_dao.find(binding['class_name']):
            raise NotFoundException(binding['class_name'])
        try:
            self.check_binding_rules_in_class(binding)
            return self.binding_dao.create(binding)
        except DuplicateKeyError:
            raise UnsupportedParameterValueException(
                '{0}-{1}'.format(binding['class_name'], binding['origin']),
                'non-duplicated-origin')

    def check_binding_rules_in_class(self, binding):
        for binding_rule in binding['binding_rules']:
            for binding_instance in binding_rule['bindings']:
                if not self.instance_dao.find_by_class_name_and_id(
                        binding['class_name'], binding_instance):
                    raise UnsupportedParameterValueException(
                        binding_instance,
                        "instances of {0}".format(binding['class_name']))

    def update_binding(self, binding):
        if not self.class_dao.find(binding['class_name']):
            raise NotFoundException(binding['class_name'])
        # if not binding is found, not found is already launched in serializers
        try:
            self.check_binding_rules_in_class(binding)
            if self.binding_dao.update_binding(binding):
                return binding
            else:
                raise GenericServiceError('The binding update process failed.')
        except DuplicateKeyError:
            raise UnsupportedParameterValueException(
                '{0}-{1}'.format(binding['class_name'], binding['origin']),
                'non-duplicated-origin')

    def delete_binding(self, binding_id):
        if not self.binding_dao.delete(binding_id, ):
            raise GenericServiceError('The binding delete process failed.')

    def get_binding_instance(self, params):
        try:
            class_name = params.pop('class_name')
        except KeyError:
            raise MissingMandatoryParameterException('class_name')

        class_ = self.class_dao.find(class_name)
        if not class_:
            raise NotFoundException(class_name)

        origin = params.get('origin', 'default')
        binding = self.binding_dao.find_by_class_and_origin(class_name, origin)
        if binding is None:  # when rules are null in database
            rules = ()
        else:
            rules = binding['binding_rules']

        # perform the binding_instance operation
        if rules:
            binding_instances = self.get_binding_instances_by_rules(
                rules, params)
            if binding_instances is None:
                raise NotMatchingRuleException(class_name, origin)
            else:
                # Although we only return one binding_instance, in future this can deal
                # with several bindings and return the first binding alive
                if len(binding_instances) == 0:
                    raise NotBindingInstanceException(class_name, origin)
                binding_instance = self.instance_dao.find(binding_instances[0])
                if binding_instance:
                    return binding_instance
                else:
                    raise DeletedInstanceException(binding_instances[0])
        else:
            # No rules defined for the search
            raise NotBindingDefinedException(class_name, origin)

    def get_binding_instances_by_rules(self, rules, context):
        """
        Performs an ordered search over rules to return a tuple with the binding_instances and
        the input_key_param that first match with the context specified.

        :param rules and ordered array of rules for class_origins, defining also
                     the binding_instances
        :param context The request query parameters to be applied as input of the rules

        :return the (instances, keys) that first match with the rules
                If any rule is matched, ((), ()) will be returned
                If no rules for search are found, None will be returned
        """
        # Apply rules by priority
        for binding_rule in rules:
            # Check rule matches with context params
            matched_rule = True
            for rule in binding_rule['group_rules']:
                if not self.execute_rule(rule, context):
                    matched_rule = False
                    break
            if matched_rule:
                # rule matched, return bindings and keys
                return binding_rule['bindings']

        # No binding_rules found at all
        return None

    def execute_rule(self, rule, context):
        """
        Check if rule applied over context param is executed,
        that means the rule operand applied on the input param
        of context for the rule value is matched:
               input operand value is True
        :param rule a dict with operand, input_context_param and value
        :param context a dict with input context params value

        :return True if the rule can be executed for the context
        """
        try:

            left_operand = context[rule['input_context_param']]
            right_operand = rule['value']
            if rule['operation'] == 'eq':
                left_operand = convert_str_to_type(left_operand,
                                                   type(right_operand[0]))
                return left_operand == right_operand[0]
            elif rule['operation'] == 'regex':
                pattern = re.compile(right_operand[0])
                return pattern.match(left_operand)
            elif rule['operation'] == 'range':
                if type(right_operand[0]) != type(right_operand[1]):
                    logger.error(
                        "Bad rule definition for range, min and max must be of same type"
                    )
                    raise GenericServiceError("Range rule defined is invalid")
                else:
                    left_operand_c = convert_str_to_type(
                        left_operand, type(right_operand[0]))
                    if left_operand_c is None:
                        raise UnsupportedParameterValueException(
                            left_operand, pretty_type(right_operand[0]))
                    return left_operand_c >= right_operand[
                        0] and left_operand_c <= right_operand[1]
            elif rule['operation'] == 'in':
                left_operand_c = convert_str_to_type(left_operand,
                                                     type(right_operand[0]))
                if left_operand_c is None:
                    raise UnsupportedParameterValueException(
                        left_operand, pretty_type(right_operand[0]))
                return left_operand_c in right_operand
            else:
                msg = "Unsupported operand for rule {0}".format(
                    rule['operation'])
                logger.error(msg)
                raise GenericServiceError(msg)

        except (AttributeError, KeyError) as e:
            logger.debug(str(e))

        return False
Beispiel #6
0
class ServiceInstanceService(BaseService):
    """
    Service to handle ServiceInstance objects with mongodb and provide
    all business logic needed to views layer
    """
    def __init__(self):
        self.instance_dao = ServiceInstanceDao()
        self.class_dao = ServiceClassDao()
        self.binding_dao = BindingDao()

    def create(self, obj):
        if not self.class_dao.find(obj['class_name']):
            raise NotFoundException(obj['class_name'])
        try:
            return self.instance_dao.create(obj)
        except DuplicateKeyError:
            raise UnsupportedParameterValueException(
                '{0}-{1}-{2}'.format(obj['class_name'], obj['uri'],
                                     obj['version']),
                'non-duplicated-instance')

    def get_service_instance(self, class_name, instance_id):
        class_obj = self.class_dao.find(class_name)
        if class_obj:
            instance = self.instance_dao.find(instance_id)
            if instance:
                if instance['class_name'] == class_name:
                    return instance
                else:
                    raise UnsupportedParameterValueException(
                        '{0}-{1}'.format(class_name, instance_id),
                        'instances-of-class')
            else:
                raise NotFoundException(instance_id)
        else:
            raise NotFoundException(class_name)

    def update(self, obj):
        # if not instance is found, not found would be raised in serializers
        try:
            if self.instance_dao.update(obj):
                return obj
            else:
                raise GenericServiceError(
                    'The instance update process failed.')
        except DuplicateKeyError:
            raise UnsupportedParameterValueException(
                '{0}-{1}-{2}'.format(obj['class_name'], obj['uri'],
                                     obj['version']),
                'non-duplicated-instance')

    def delete(self, class_name, instance_id):
        class_obj = self.class_dao.find(class_name)
        if class_obj:
            instance = self.instance_dao.find(instance_id)
            if instance:
                if instance['class_name'] == class_name:
                    if self.instance_dao.delete(instance_id):
                        return
                    else:
                        raise GenericServiceError(
                            'The instance delete process failed.')
                else:
                    raise UnsupportedParameterValueException(
                        '{0}-{1}'.format(class_name, instance_id),
                        'instances-of-class')
            else:
                raise NotFoundException(instance_id)
        raise NotFoundException(class_name)

    def discover_service_instances(self, class_name, params):
        if 'class_name' in params:
            raise BadParameterException('class_name')
        class_obj = self.class_dao.find(class_name)
        if not class_obj:
            raise NotFoundException(class_name)
        params['class_name'] = class_name
        return self.instance_dao.find_instances(params)