def find_user_info_by_subject(self, subject=''):
     # Find UserCredentials
     objects, matches = self.clients.resource_registry.find_resources(
         RT.UserCredentials, None, subject, id_only=False)
     if not objects:
         raise NotFound("UserCredentials with subject %s does not exist" %
                        subject)
     if len(objects) > 1:
         raise Inconsistent(
             "Multiple UserCredentials with subject %s exist" % subject)
     user_credentials_id = objects[0]._id
     subjects, assocs = self.clients.resource_registry.find_subjects(
         RT.ActorIdentity, PRED.hasCredentials, user_credentials_id)
     if not subjects or len(subjects) == 0:
         raise NotFound(
             "ActorIdentity to UserCredentials association for subject %s does not exist"
             % subject)
     if len(subjects) > 1:
         raise Inconsistent(
             "Multiple ActorIdentity to UserCredentials associations for subject %s exist"
             % subject)
     actor_identity_id = subjects[0]._id
     # Look up UserInfo via association with ActorIdentity
     objects, assocs = self.clients.resource_registry.find_objects(
         actor_identity_id, PRED.hasInfo, RT.UserInfo)
     if not objects:
         raise NotFound("UserInfo for subject %s does not exist" % subject)
     if len(objects) > 1:
         raise Inconsistent("Multiple UserInfos for subject %s exist" %
                            subject)
     user_info = objects[0]
     return user_info
Пример #2
0
    def handle_incoming_message(self, invocation):
        receiver = invocation.get_message_receiver()
        op = invocation.get_header_value('op', 'Unknown')
        actor_id = invocation.get_header_value(MSG_HEADER_ACTOR, 'anonymous')

        # Raise Inconsistent message if conversation interceptor found a problem
        # TODO - May just want to drop this message instead of returning in case of DOS attack
        if GovernanceDispatcher.CONVERSATION__STATUS_ANNOTATION in invocation.message_annotations and \
           invocation.message_annotations[GovernanceDispatcher.CONVERSATION__STATUS_ANNOTATION] == GovernanceDispatcher.STATUS_REJECT:
            if GovernanceDispatcher.CONVERSATION__STATUS_REASON_ANNOTATION in invocation.message_annotations:
                raise Inconsistent(
                    "The message from user %s for operation %s(%s) has an error: %s"
                    % (actor_id, receiver, op, invocation.message_annotations[
                        GovernanceDispatcher.
                        CONVERSATION__STATUS_REASON_ANNOTATION]))
            else:
                raise Inconsistent(
                    "The message from user %s for operation %s(%s) is inconsistent with the specified protocol"
                    % (actor_id, receiver, op))

        # Raise Unauthorized exception if policy denies access.
        if GovernanceDispatcher.POLICY__STATUS_ANNOTATION in invocation.message_annotations and \
           invocation.message_annotations[GovernanceDispatcher.POLICY__STATUS_ANNOTATION] == GovernanceDispatcher.STATUS_REJECT:

            if GovernanceDispatcher.POLICY__STATUS_REASON_ANNOTATION in invocation.message_annotations:
                raise Unauthorized(invocation.message_annotations[
                    GovernanceDispatcher.POLICY__STATUS_REASON_ANNOTATION])

            raise Unauthorized(
                "The request from user %s for operation %s(%s) has been denied"
                % (actor_id, receiver, op))

        return invocation
Пример #3
0
    def _analyze_objects(self, resources_objs):
        for obj_id, key, obj in resources_objs:
            if obj_id.startswith("_design"):
                continue
            if not isinstance(obj, dict):
                raise Inconsistent("Object of bad type found: %s" % type(obj))
            obj_type = obj.get("type_", None)
            if obj_type == "Association":
                self._associations[obj_id] = obj
            elif obj_type == "DirEntry":
                self._directory[obj_id] = obj
            elif obj_type:
                self._resources[obj_id] = obj
                if obj_type not in self._res_by_type:
                    self._res_by_type[obj_type] = []
                self._res_by_type[obj_type].append(obj_id)
                for attr, value in obj.iteritems():
                    if obj_type not in self._attr_by_type:
                        self._attr_by_type[obj_type] = set()
                    self._attr_by_type[obj_type].add(attr)
            else:
                raise Inconsistent("Object with no type_ found: %s" % obj)

        for assoc in self._associations.values():
            key = (assoc['s'], assoc['p'])
            if key not in self._assoc_by_sub:
                self._assoc_by_sub[key] = []
            self._assoc_by_sub[key].append(assoc['o'])
Пример #4
0
    def create_transform_process(self, data_process_definition_id,
                                 data_process_input_dp_id, stream_name):

        data_process_definition = self.rrclient.read(
            data_process_definition_id)

        # Find the link between the output Stream Definition resource and the Data Process Definition resource
        stream_ids, _ = self.rrclient.find_objects(data_process_definition._id,
                                                   PRED.hasStreamDefinition,
                                                   RT.StreamDefinition,
                                                   id_only=True)
        if not stream_ids:
            raise Inconsistent(
                "The data process definition %s is missing an association to an output stream definition"
                % data_process_definition._id)
        process_output_stream_def_id = stream_ids[0]

        #Concatenate the name of the workflow and data process definition for the name of the data product output
        data_process_name = data_process_definition.name

        # Create the output data product of the transform

        tdom, sdom = time_series_domain()

        transform_dp_obj = IonObject(
            RT.DataProduct,
            name=data_process_name,
            description=data_process_definition.description,
            temporal_domain=tdom.dump(),
            spatial_domain=sdom.dump())

        transform_dp_id = self.dataproductclient.create_data_product(
            transform_dp_obj, process_output_stream_def_id)

        self.dataproductclient.activate_data_product_persistence(
            data_product_id=transform_dp_id)

        #last one out of the for loop is the output product id
        output_data_product_id = transform_dp_id

        # Create the  transform data process
        log.debug("create data_process and start it")
        data_process_id = self.dataprocessclient.create_data_process(
            data_process_definition._id, [data_process_input_dp_id],
            {stream_name: transform_dp_id})
        self.dataprocessclient.activate_data_process(data_process_id)

        #Find the id of the output data stream
        stream_ids, _ = self.rrclient.find_objects(transform_dp_id,
                                                   PRED.hasStream, None, True)
        if not stream_ids:
            raise Inconsistent(
                "The data process %s is missing an association to an output stream"
                % data_process_id)

        return data_process_id, output_data_product_id
Пример #5
0
    def execute_replay(self):
        '''
        @brief Spawns a greenlet to take care of the query and work
        '''
        if not hasattr(self, 'output'):
            raise Inconsistent(
                'The replay process requires an output stream publisher named output. Invalid configuration!'
            )

        datastore_name = self.datastore_name
        key_id = self.key_id

        view_name = self.view_name

        opts = {
            'start_key': [key_id, 0],
            'end_key': [key_id, 2],
            'include_docs': True
        }

        g = Greenlet(self._query,
                     datastore_name=datastore_name,
                     view_name=view_name,
                     opts=opts,
                     callback=lambda results: self._publish_query(results))
        g.start()
Пример #6
0
    def create_policy(self, policy=None):
        """Persists the provided Policy object The id string returned
        is the internal id by which Policy will be identified in the data store.

        @param policy    Policy
        @retval policy_id    str
        @throws BadRequest    if object passed has _id or _rev attribute
        """

        if not policy:
            raise BadRequest("The policy parameter is missing")

        if not is_basic_identifier(policy.name):
            raise BadRequest(
                "The policy name '%s' can only contain alphanumeric and underscore characters"
                % policy.name)

        try:
            #If there is a policy_rule field then try to add the policy name and decription to the rule text
            if hasattr(policy.policy_type, 'policy_rule'):
                policy.policy_type.policy_rule = policy.policy_type.policy_rule % (
                    policy.name, policy.description)

        except Exception, e:
            raise Inconsistent(
                "Missing the elements in the policy rule to set the description: "
                + e.message)
Пример #7
0
 def read_subject(self,
                  subject_type="",
                  predicate="",
                  object="",
                  assoc="",
                  id_only=False):
     if assoc:
         if type(assoc) is str:
             assoc = self.read(assoc)
         return assoc.s if id_only else self.read(assoc.s)
     else:
         sub_list, assoc_list = self.find_subjects(
             subject_type=subject_type,
             predicate=predicate,
             object=object,
             id_only=True)
         if not sub_list:
             raise NotFound(
                 "No subject found for subject_type=%s, predicate=%s, object=%s"
                 % (subject_type, predicate, object))
         elif len(sub_list) > 1:
             raise Inconsistent(
                 "More than one subject found for subject_type=%s, predicate=%s, object=%s: count=%s"
                 % (subject_type, predicate, object, len(sub_list)))
         return sub_list[0] if id_only else self.read(sub_list[0])
    def _find_org_roles_by_user(self, org=None, user=None):

        if org is None:
            raise BadRequest("The org parameter is missing")

        if user is None:
            raise BadRequest("The user parameter is missing")

        role_list, _ = self.clients.resource_registry.find_objects(
            user, PRED.hasRole, RT.UserRole)

        #Iterate the list of roles associated with user and filter by the org_id. TODO - replace this when
        #better indexing/views are available in couch
        ret_list = []
        for role in role_list:
            if role.org_id == org._id:
                ret_list.append(role)

        #Because a user is enrolled with an Org then the membership role is implied - so add it to the list
        member_role = self._find_role(org._id, MEMBER_ROLE)
        if member_role is None:
            raise Inconsistent('The %s User Role is not found.' % MEMBER_ROLE)

        ret_list.append(member_role)

        return ret_list
def set_object_field(obj, field, field_val):
    if isinstance(field_val, dict) and field != 'kwargs':
        sub_obj = getattr(obj, field)

        if isinstance(sub_obj, IonObjectBase):

            if field_val.has_key(
                    'type_') and field_val['type_'] != sub_obj.type_:

                if issubtype(field_val['type_'], sub_obj.type_):
                    sub_obj = IonObject(field_val['type_'])
                    setattr(obj, field, sub_obj)
                else:
                    raise Inconsistent(
                        "Unable to walk the field %s as an IonObject since the types don't match: %s %s"
                        % (field, sub_obj.type_, field_val['type_']))

            for sub_field in field_val:
                set_object_field(sub_obj, sub_field, field_val.get(sub_field))

        elif isinstance(sub_obj, dict):
            setattr(obj, field, field_val)

        else:
            for sub_field in field_val:
                set_object_field(sub_obj, sub_field, field_val.get(sub_field))
    else:
        # type_ already exists in the class.
        if field != "type_":
            setattr(obj, field, field_val)
Пример #10
0
 def find_user_info_by_name(self, name=''):
     objects, matches = self.clients.resource_registry.find_resources(RT.UserInfo, None, name, id_only=False)
     if not objects:
         raise NotFound("UserInfo with name %s does not exist" % name)
     if len(objects) > 1:
         raise Inconsistent("Multiple UserInfo objects with name %s exist" % name)
     return objects[0]
Пример #11
0
        def test_find_fun(self):
            """
            self is an instance of the tester class
            """
            # get objects
            svc = self._rimi_getservice()
            myimpl = getattr(svc, impl_attr)                 

            # put in 2 objects
            sr = sample_resource()
            sample_resource_id = myimpl.create_one(sr)

            sr2 = sample_resource()
            sr2.name = "NOT A DUPE"
            sample_resource_id2 = myimpl.create_one(sr2)

            resources = myimpl.find_some({})
            self.assertIsInstance(resources, list)
            self.assertNotEqual(0, len(resources))
            self.assertNotEqual(1, len(resources))

            resource_ids = []
            for r in resources:
                if not "_id" in r:
                    raise Inconsistent("'_id' field not found in resource! got: %s" % str(r))
                resource_ids.append(r._id)
            self.assertIn(sample_resource_id, resource_ids)
            self.assertIn(sample_resource_id2, resource_ids)

            if all_in_one: 
                myimpl.delete_one(sample_resource_id)
                myimpl.delete_one(sample_resource_id2)
Пример #12
0
    def dump_dicts_as_xlsx(self, objects, filename=None):
        self._clear()
        """Dumps a dict of dicts. Tab names will be the names of keys in the objects dict"""
        self._wb = xlwt.Workbook()
        self._worksheets = {}

        for cat_name, cat_objects in objects.iteritems():
            for obj_id, obj in cat_objects.iteritems():
                if not isinstance(obj, dict):
                    raise Inconsistent("Object of bad type found: %s" %
                                       type(obj))
                self._resources[obj_id] = obj
                if cat_name not in self._res_by_type:
                    self._res_by_type[cat_name] = []
                self._res_by_type[cat_name].append(obj_id)
                for attr, value in obj.iteritems():
                    if cat_name not in self._attr_by_type:
                        self._attr_by_type[cat_name] = set()
                    self._attr_by_type[cat_name].add(attr)

        for restype in sorted(self._res_by_type.keys()):
            self._dump_resource_type(restype)

        dtstr = datetime.datetime.today().strftime('%Y%m%d_%H%M%S')
        path = filename or "interface/objects_%s.xls" % dtstr
        self._wb.save(path)
            def ret_fn(obj_id, subj_id):
                log.info("Dynamically creating association %s -> %s -> (1)%s",
                         isubj, ipred, iobj)

                # see if there are any other objects of this type and pred on this subject
                existing_objs, _ = self.RR.find_objects(subj_id,
                                                        ipred,
                                                        iobj,
                                                        id_only=True)

                if len(existing_objs) > 1:
                    raise Inconsistent(
                        "Multiple %s-%s objects found with the same %s subject with id='%s'"
                        % (ipred, iobj, isubj, subj_id))

                if len(existing_objs) > 0:
                    try:
                        log.debug("get_association gives")
                        log.debug(
                            self.RR.get_association(subj_id, ipred, obj_id))
                    except NotFound:
                        raise BadRequest(
                            "Attempted to add a second %s-%s association to a %s with id='%s'"
                            % (ipred, iobj, isubj, subj_id))
                    else:
                        log.debug(
                            "Create %s Association (single object): ALREADY EXISTS",
                            ipred)
                        return

                self.RR.create_association(subj_id, ipred, obj_id)
Пример #14
0
def get_predicate_type_list():
    Predicates.clear()
    assoc_defs = Config(["res/config/associations.yml"]).data['AssociationDefinitions']
    for ad in assoc_defs:
        if ad['predicate'] in Predicates:
            raise Inconsistent('Predicate %s defined multiple times in associations.yml' % ad['predicate'])
        Predicates[ad['predicate']] = ad
    return Predicates.keys()
    def add_process_operation_precondition_policy(self, process_name='', op='', policy_content=''):
        """Helper operation for adding a precondition policy for a specific process operation; could be a service or agent.
        The id string returned is the internal id by which Policy will be identified in the data store. The precondition
        method must return a tuple (boolean, string).

        @param process_name    str
        @param op    str
        @param policy_content    str
        @retval policy_id    str
        @throws BadRequest    If any of the parameters are not set.
        """
        if not process_name:
            raise BadRequest("The process_name parameter is missing")

        if not op:
            raise BadRequest("The op parameter is missing")

        if not policy_content:
            raise BadRequest("The policy_content parameter is missing")

        policy_name = process_name + "_" + op + "_Precondition_Policies"

        policies,_ = self.clients.resource_registry.find_resources(restype=RT.Policy, name=policy_name)
        if policies:
            #Update existing policy by adding to list
            if len(policies) > 1:
                raise Inconsistent('There should only be one Policy object per process_name operation')

            if policies[0].policy_type.op != op or  policies[0].policy_type.type_ != OT.ProcessOperationPreconditionPolicy:
                raise Inconsistent('There Policy object %s does not match the requested process operation %s: %s' % ( policies[0].name, process_name, op ))

            policies[0].policy_type.preconditions.append(policy_content)

            self.update_policy(policies[0])

            return policies[0]._id

        else:
            #Create a new policy object

            op_policy_obj = IonObject(OT.ProcessOperationPreconditionPolicy,  process_name=process_name, op=op)
            op_policy_obj.preconditions.append(policy_content)

            policy_obj = IonObject(RT.Policy, name=policy_name, policy_type=op_policy_obj, description='List of operation precondition policies for ' + process_name)

            return self.create_policy(policy_obj)
Пример #16
0
    def generic_association_script(self, assign_obj_to_subj_fn, find_subj_fn,
                                   find_obj_fn, subj_id, obj_id):
        """
        create an association and test that it went properly

        @param assign_obj_to_subj_fn the service method that takes (obj, subj) and associates them
        @param find_subj_fn the service method that returns a list of subjects given an object
        @param find_obj_fn the service method that returns a list of objects given a subject
        @param subj_id the subject id to associate
        @param obj_id the object id to associate
        """
        initial_subj_count = len(find_subj_fn(obj_id))
        initial_obj_count = len(find_obj_fn(subj_id))

        log.debug("Creating association")
        if not ("str" == type(subj_id).__name__ == type(obj_id).__name__):
            raise NotImplementedError(
                "%s='%s' to %s='%s'" %
                (type(subj_id), str(subj_id), type(obj_id), str(obj_id)))
        if not (subj_id and obj_id):
            raise NotImplementedError(
                "%s='%s' to %s='%s'" %
                (type(subj_id), str(subj_id), type(obj_id), str(obj_id)))
        assign_obj_to_subj_fn(obj_id, subj_id)

        log.debug("Verifying find-subj-by-obj")
        subjects = find_subj_fn(obj_id)
        self.assertEqual(initial_subj_count + 1, len(subjects))
        subject_ids = []
        for x in subjects:
            if not "_id" in x:
                raise Inconsistent(
                    "'_id' field not found in resource! got: %s" % str(x))
            subject_ids.append(x._id)
        self.assertIn(subj_id, subject_ids)

        log.debug("Verifying find-obj-by-subj")
        objects = find_obj_fn(subj_id)
        self.assertEqual(initial_obj_count + 1, len(objects))
        object_ids = []
        for x in objects:
            if not "_id" in x:
                raise Inconsistent(
                    "'_id' field not found in resource! got: %s" % str(x))
            object_ids.append(x._id)
        self.assertIn(obj_id, object_ids)
Пример #17
0
    def create_negotiation(self, sap=None):

        if sap is None or ( sap.type_ != OT.ServiceAgreementProposal and not issubtype(sap.type_, OT.ServiceAgreementProposal)):
            raise BadRequest('The sap parameter must be a valid Service Agreement Proposal object')

        if sap.proposal_status != ProposalStatusEnum.INITIAL or sap.sequence_num != 0:
            raise Inconsistent('The specified Service Agreement Proposal has inconsistent status fields')

        if sap.negotiation_id != '':
            raise Inconsistent('The specified Service Agreement Proposal cannot have a negotiation_id for an initial proposal')

        if self.negotiation_rules.has_key(sap.type_):
            #validate preconditions before creating
            for pc in self.negotiation_rules[sap.type_]['pre_conditions']:
                if pc.startswith('not '):
                    pre_condition_met = not eval("self.service_provider." + pc.lstrip('not ')) #Strip off the 'not ' part
                else:
                    pre_condition_met = eval("self.service_provider."+pc)

                if not pre_condition_met:
                    raise BadRequest("A precondition for this request has not been satisfied: %s" % pc)

        #Should be able to determine the negotiation type based on the intial originator
        neg_type = NegotiationTypeEnum.REQUEST
        if sap.originator == ProposalOriginatorEnum.PROVIDER:
            neg_type = NegotiationTypeEnum.INVITATION
        elif sap.originator == ProposalOriginatorEnum.BROKER:
            neg_type = NegotiationTypeEnum.BROKERED

        neg_obj = IonObject(RT.Negotiation, negotiation_type=neg_type)

        #If there is a description in the initial proposal, then set the negotiation description with it.
        if sap.description != '':
            neg_obj.description = sap.description

        neg_id,_ = self.service_provider.clients.resource_registry.create(neg_obj)

        #Create associations between the parties
        self.service_provider.clients.resource_registry.create_association(sap.consumer, PRED.hasNegotiation, neg_id)
        self.service_provider.clients.resource_registry.create_association(sap.provider, PRED.hasNegotiation, neg_id)
        if sap.broker != "":
            self.service_provider.clients.resource_registry.create_association(sap.broker, PRED.hasNegotiation, neg_id)


        return neg_id
Пример #18
0
    def __init__(self, headers, process=None, resource_id_required=True):
        """
        Helpers for retrieving governance related values: op, actor_id, actor_roles, resource_id from the message header
        @param headers:
        @param resource_id_required: True if the message header must have a resource-id field and value.
        """
        if not headers or not isinstance(headers, dict):
            raise BadRequest("The headers parameter is not a valid message header dictionary")

        self._op = headers.get(MSG_HEADER_OP, "Unknown-Operation")

        if process is not None and hasattr(process, 'name'):
            self._process_name = process.name
        else:
            if 'process' in headers:
                if getattr(headers['process'], 'name'):
                    self._process_name = headers['process'].name
                else:
                    self._process_name = "Unknown-Process"
            else:
                self._process_name = "Unknown-Process"


        # The self.name references below should be provided by the running ION process (service, agent, etc),
        # which will be using this class.
        if MSG_HEADER_ACTOR in headers:
            self._actor_id = headers[MSG_HEADER_ACTOR]
        else:
            raise Inconsistent('%s(%s) has been denied since the ion-actor-id can not be found in the message headers' % (self._process_name, self._op))

        if MSG_HEADER_ROLES in headers:
            self._actor_roles = headers[MSG_HEADER_ROLES]
        else:
            raise Inconsistent('%s(%s) has been denied since the ion-actor-roles can not be found in the message headers' % (self._process_name, self._op))

        if MSG_HEADER_RESOURCE_ID in headers:
            self._resource_id = headers[MSG_HEADER_RESOURCE_ID]
        else:
            if resource_id_required:
                raise Inconsistent('%s(%s) has been denied since the resource-id can not be found in the message headers' % (self._process_name, self._op))
            self._resource_id = ''

        self._user_context_id = headers.get(MSG_HEADER_USER_CONTEXT_ID, None)
Пример #19
0
    def _find_having_single(self, association_predicate, some_object):
        """
        enforces exclusivity: 0 or 1 association allowed
        """
        ret = self._find_having(association_predicate, some_object)

        if 1 < len(ret):
            raise Inconsistent(
                "More than one %s point to %s '%s'" %
                (association_predicate, self.iontype, some_object))
        return ret
Пример #20
0
    def read_attachment(self, attachment_id=''):
        attachment = self.read(attachment_id)
        if not isinstance(attachment, Attachment):
            raise Inconsistent("Object in datastore must be Attachment, not %s" % type(attachment))

        if attachment.attachment_type == AttachmentType.BLOB:
            if type(attachment.content) is not str:
                raise BadRequest("Attachment content must be str")
            attachment.content = base64.decodestring(attachment.content)

        return attachment
Пример #21
0
 def get_association(self, subject="", predicate="", object="", assoc_type=None, id_only=False):
     if predicate:
         assoc_type = assoc_type or AT.H2H
     assoc = self.rr_store.find_associations(subject, predicate, object, assoc_type, id_only=id_only)
     if not assoc:
         raise NotFound("Association for subject/predicate/object/type %s/%s/%s/%s not found" % (
             str(subject),str(predicate),str(object),str(assoc_type)))
     elif len(assoc) > 1:
         raise Inconsistent("Duplicate associations found for subject/predicate/object/type %s/%s/%s/%s" % (
             str(subject),str(predicate),str(object),str(assoc_type)))
     return assoc[0]
Пример #22
0
    def create_resources_snapshot(self, persist=False, filename=None):
        ds = CouchDataStore(DataStore.DS_RESOURCES,
                            profile=DataStore.DS_PROFILE.RESOURCES,
                            config=CFG,
                            scope=self.sysname)
        all_objs = ds.find_docs_by_view("_all_docs", None, id_only=False)

        log.info("Found %s objects in datastore resources", len(all_objs))

        resources = {}
        associations = {}
        snapshot = dict(resources=resources, associations=associations)

        for obj_id, key, obj in all_objs:
            if obj_id.startswith("_design"):
                continue
            if not isinstance(obj, dict):
                raise Inconsistent("Object of bad type found: %s" % type(obj))
            obj_type = obj.get("type_", None)
            if obj_type == "Association":
                associations[obj_id] = obj.get("ts", None)
            elif obj_type:
                resources[obj_id] = obj.get("ts_updated", None)
            else:
                raise Inconsistent("Object with no type_ found: %s" % obj)

        if persist:
            dtstr = datetime.datetime.today().strftime('%Y%m%d_%H%M%S')
            path = filename or "interface/rrsnapshot_%s.json" % dtstr
            snapshot_json = json.dumps(snapshot)
            with open(path, "w") as f:
                #yaml.dump(snapshot, f, default_flow_style=False)
                f.write(snapshot_json)

        log.debug(
            "Created resource registry snapshot. %s resources, %s associations",
            len(resources), len(associations))

        return snapshot
Пример #23
0
    def update_negotiation(self, sap=None, reason=None):

        #Find the Negotiation resource associated with this proposal
        if sap is None or sap.negotiation_id == '':
            raise Inconsistent('The Service Agreement Proposal must have a negotiation resource id associated with it')

        neg_obj = self.service_provider.clients.resource_registry.read(sap.negotiation_id)

        if sap.sequence_num != len(neg_obj.proposals):
            raise Inconsistent('The Service Agreement Proposal does not have the correct sequence_num value (%d) for this negotiation (%d)' % (sap.sequence_num, len(neg_obj.proposals)))


        #Synchronize negotiation status based on proposals
        if sap.proposal_status == ProposalStatusEnum.REJECTED:
            neg_obj.negotiation_status = NegotiationStatusEnum.REJECTED
        elif sap.proposal_status == ProposalStatusEnum.ACCEPTED:
            #Look for an previously Accepted proposal from the other party
            for prop in neg_obj.proposals:
                if prop.proposal_status == ProposalStatusEnum.ACCEPTED and prop.originator != sap.originator:
                    neg_obj.negotiation_status = NegotiationStatusEnum.ACCEPTED

        if reason is not None:
            neg_obj.reason = reason

        #Add the current proposal to the Negotiation object to keep a record of it - then save it
        neg_obj.proposals.append(sap)

        neg_id,_ = self.service_provider.clients.resource_registry.update(neg_obj)

        self._publish_status_event(neg_obj)

        if neg_obj.negotiation_status == NegotiationStatusEnum.ACCEPTED:
            self._execute_accept_action(neg_obj.proposals[-1])
            #Publish request granted notification
            self._publish_status_event(neg_obj, ProposalStatusEnum.GRANTED)


        return neg_id
Пример #24
0
    def find_actor_identity_by_name(self, name=''):
        """Return the ActorIdentity object whose name attribute matches the passed value.

        @param name    str
        @retval user_info    ActorIdentity
        @throws NotFound    failed to find ActorIdentity
        @throws Inconsistent    Multiple ActorIdentity objects matched name
        """
        objects, matches = self.clients.resource_registry.find_resources(RT.ActorIdentity, None, name, id_only=False)
        if not objects:
            raise NotFound("ActorIdentity with name %s does not exist" % name)
        if len(objects) > 1:
            raise Inconsistent("Multiple ActorIdentity objects with name %s exist" % name)
        return objects[0]
Пример #25
0
    def _find_stemming_single(self, primary_object_id, association_predicate,
                              some_object_type):
        """
        enforces exclusivity: 0 or 1 association allowed
        """

        ret = self._find_stemming(primary_object_id, association_predicate,
                                  some_object_type)

        if 1 < len(ret):
            raise Inconsistent("%s '%s' has more than one %s:" %
                               (self.iontype, primary_object_id,
                                association_predicate, some_object_type))
        return ret
Пример #26
0
    def create_extended_resource_container_list(self, extended_resource_type, resource_id_list,
                                                computed_resource_type=None,
                                                ext_associations=None, ext_exclude=None, **kwargs):
        """
        Returns a list of extended resource containers for given list of resource_ids.
        """
        if not isinstance(resource_id_list, types.ListType):
            raise Inconsistent("The parameter resource_id_list is not a list of resource_ids")

        ret = list()
        for res_id in resource_id_list:
            ext_res = self.create_extended_resource_container(extended_resource_type, res_id, computed_resource_type,
                ext_associations, ext_exclude )
            ret.append(ext_res)

        return ret
    def find_object(self, subject, predicate, object_type, id_only=False):
        subject_id, subject_type = self._extract_id_and_type(subject)

        objs, _ = self.RR.find_objects(subject=subject_id,
                                       predicate=predicate,
                                       object_type=object_type,
                                       id_only=id_only)

        if 1 == len(objs):
            return objs[0]
        elif 1 < len(objs):
            raise Inconsistent(
                "Expected 1 %s as object of %s '%s', got %d" %
                (object_type, subject_type, str(subject_id), len(objs)))
        else:
            raise NotFound("Expected 1 %s as object of %s '%s'" %
                           (object_type, subject_type, str(subject_id)))
Пример #28
0
    def _link_resources_single_subject(self,
                                       subject_id='',
                                       association_type='',
                                       object_id='',
                                       raise_exn=True):
        """
        create an association where only one subject at a time can exist
         if there is an existing association, the choice is left to the user whether to raise exception
         or quietly remove/replace the existing one.

        @param subject_id the resource ID of the predefined type
        @param association_type the predicate
        @param object_id the resource ID of the type to be joined
        @param raise_exn whether a BadRequest error should be raised if a duplicate is attempted
        @todo check for errors: does RR check for bogus ids?
        """

        # see if there are any other objects of this type and pred on this subject
        obj_type = self._get_resource_type_by_id(object_id)
        existing_links = self._find_having(association_type, object_id)

        if len(existing_links) > 1:
            raise Inconsistent(
                "Multiple %s-%s subjects found on the same %s object with id='%s'"
                % (self.iontype, association_type, obj_type, object_id))

        if len(existing_links) > 0:
            if self._resource_link_exists(subject_id, association_type,
                                          object_id):
                log.debug(
                    "Create %s Association (single subject) from '%s': ALREADY EXISTS"
                    %
                    (self._assn_name(association_type), self._toplevel_call()))
                return None

            if raise_exn:
                raise BadRequest(
                    "Attempted to add a duplicate %s-%s association on a %s object with id='%s'"
                    % (self.iontype, association_type, obj_type, subject_id))

            self._unlink_resources(self, subject_id, association_type,
                                   existing_links[0])

        return self._link_resources_lowlevel(subject_id, association_type,
                                             object_id, False)
Пример #29
0
    def _read_by_path(self, path, orgname=None):
        """
        Given a qualified path, find entry in directory and return DirEntry
        document or None if not found
        """
        if path is None:
            raise BadRequest("Illegal arguments")
        orgname = orgname or self.orgname
        parent, key = path.rsplit("/", 1)
        parent = parent or "/"
        find_key = [orgname, key, parent]
        view_res = self.datastore.find_docs_by_view('directory', 'by_key', key=find_key, id_only=True)

        if len(view_res) > 1:
            raise Inconsistent("More than one directory entry found for key %s" % path)
        elif view_res:
            return view_res[0][2]  # First value
        return None
Пример #30
0
    def read_attachment(self, attachment_id='', include_content=False):
        """
        Returns the metadata of an attachment. Unless indicated otherwise the content returned
        is only a name to the actual attachment content.
        """
        attachment = self.read(attachment_id)
        if not isinstance(attachment, Attachment):
            raise Inconsistent(
                "Object in datastore must be Attachment, not %s" %
                type(attachment))

        if include_content:
            attachment.content = self.rr_store.read_attachment(
                attachment_id, attachment_name=self.DEFAULT_ATTACHMENT_NAME)
            if attachment.attachment_type == AttachmentType.BLOB:
                if type(attachment.content) is not str:
                    raise BadRequest("Attachment content must be str")

        return attachment