Example #1
0
    def set_object_field(self, obj, field, field_val):
        """Recursively set sub object field values.
        TODO: This may be an expensive operation. May also be redundant with object code
        """
        if isinstance(field_val, dict) and field != "kwargs":
            sub_obj = getattr(obj, field)

            if isinstance(sub_obj, IonObjectBase):

                if "type_" in field_val 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 - types don't match: %s %s"
                            % (field, sub_obj.type_, field_val["type_"]))

                for sub_field in field_val:
                    self.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:
                    self.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)
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 'type_' in field_val 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)
Example #3
0
    def check_collection_content(self, key, list_values, content_types):
        split_content_types = []
        if ',' in content_types:
            split_content_types = content_types.split(',')
        else:
            split_content_types.append(content_types)

        for value in list_values:
            match_found = False
            for content_type in split_content_types:
                #First check for valid ION types
                from pyon.core.registry import issubtype
                if isinstance(value, dict) and value.has_key('type_'):
                    if value['type_'] == content_type.strip() or issubtype(
                            value['type_'], content_type.strip()):
                        match_found = True
                        break

                if type(value).__name__ == content_type.strip():
                    match_found = True
                    break
                # Check for inheritance
                if self.check_inheritance_chain(type(value), content_type):
                    match_found = True
                    break

            if not match_found:
                raise AttributeError(
                    'Invalid value type %s in collection field "%s.%s", should be one of "%s"'
                    % (str(list_values), type(self).__name__, key,
                       content_types))
Example #4
0
    def check_collection_content(self, key, list_values, content_types):
        split_content_types = []
        if ',' in content_types:
            split_content_types = content_types.split(',')
        else:
            split_content_types.append(content_types)

        for value in list_values:
            match_found = False
            for content_type in split_content_types:
                #First check for valid ION types
                from pyon.core.registry import issubtype
                if isinstance(value, dict) and value.has_key('type_'):
                    if value['type_'] == content_type.strip() or issubtype(value['type_'], content_type.strip()):
                        match_found = True
                        break

                if type(value).__name__ == content_type.strip():
                    match_found = True
                    break
                # Check for inheritance
                if self.check_inheritance_chain(type(value), content_type):
                    match_found = True
                    break

            if not match_found:
                raise AttributeError('Invalid value type %s in collection field "%s.%s", should be one of "%s"' %
                    (str(list_values), type(self).__name__, key, content_types))
Example #5
0
    def set_object_field(self, obj, field, field_val):
        """Recursively set sub object field values.
        TODO: This may be an expensive operation. May also be redundant with object code
        """
        if isinstance(field_val, dict) and field != "kwargs":
            sub_obj = getattr(obj, field)

            if isinstance(sub_obj, IonObjectBase):

                if "type_" in field_val 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 - types don't match: %s %s"
                            % (field, sub_obj.type_, field_val["type_"])
                        )

                for sub_field in field_val:
                    self.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:
                    self.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)
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)
Example #7
0
    def create_prepare_resource_support(self, resource_id="", prepare_resource_type=None, origin_resource_type=None):

        if not isinstance(resource_id, types.StringType):
            raise Inconsistent("The parameter resource_id is not a single resource id string")

        if not self.service_provider or not self._rr:
            raise Inconsistent("This class is not initialized properly")

        if prepare_resource_type is not None and prepare_resource_type not in getextends(OT.ResourcePrepareSupport):
            raise BadRequest('The requested resource %s is not extended from %s' % (prepare_resource_type, OT.ResourcePrepareSupport))


        resource_data = IonObject(prepare_resource_type)

        # Check to make sure the extended resource decorator raise OriginResourceType matches the type of the resource type
        origin_resource_decorator =  resource_data.get_class_decorator_value('OriginResourceType')
        if origin_resource_decorator is None and origin_resource_type is None:
            raise NotFound('OriginResourceType decorator not found in object specification %s', prepare_resource_type)

        origin_resource_type = origin_resource_type if origin_resource_type is not None else origin_resource_decorator
        if origin_resource_type is None:
            raise NotFound('OriginResourceType decorator not found in object specification %s', prepare_resource_type)


        resource_object = None
        if resource_id:
            resource_object = self._rr.read(resource_id)

            if origin_resource_type != resource_object.type_ and not issubtype(resource_object.type_, origin_resource_type):
                raise Inconsistent('The OriginResourceType decorator of the requested resource %s(%s) does not match the type of the specified resource id(%s).' % (
                    prepare_resource_type, origin_resource_type, resource_object.type_))

            resource_data._id = resource_object._id
        else:
            resource_object = IonObject(origin_resource_type)

        resource_data.resource = resource_object
        resource_data.resource_schema = get_object_schema(origin_resource_type)

        for field in resource_data._schema:

            deco_value = resource_data.get_decorator_value(field, 'AssociatedResources')
            assoc_dict = {}
            if deco_value is not None:
                if deco_value.find(',') == -1:
                    associated_resources = [deco_value]
                else:
                    associated_resources = deco_value.split(',')

                for res in associated_resources:
                    assoc = self.get_associated_resource_info(origin_resource_type, resource_id, res)
                    assoc_dict[assoc.key] = assoc

                setattr(resource_data, field, assoc_dict)
                continue


        return resource_data
Example #8
0
    def read_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 not sap.negotiation_id:
            raise BadRequest('The Service Agreement Proposal object (sap) is missing a negotiation_id value')

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

        return neg_obj
Example #9
0
File: resource.py Project: daf/pyon
    def create_extended_resource_container(self, extended_resource_type, resource_id, computed_resource_type=None,
                                           ext_associations=None, ext_exclude=None):

        overall_start_time = time.time()

        if not isinstance(resource_id, types.StringType):
            raise Inconsistent("The parameter resource_id is not a single resource id string")

        if not self.service_provider or not self._rr:
            raise Inconsistent("This class is not initialized properly")

        if extended_resource_type not in getextends(OT.ResourceContainer):
            raise BadRequest('The requested resource %s is not extended from %s' % (extended_resource_type, OT.ResourceContainer))

        if computed_resource_type and computed_resource_type not in getextends(OT.ComputedAttributes):
            raise BadRequest('The requested resource %s is not extended from %s' % (computed_resource_type, OT.ComputedAttributes))

        resource_object = self._rr.read(resource_id)

        if not resource_object:
            raise NotFound("The Resource %s does not exist" % resource_id)

        res_container = IonObject(extended_resource_type)

        # @TODO - replace with object level decorators and raise exceptions
        if not hasattr(res_container, 'origin_resource_type'):
            log.error('The requested resource %s does not contain a properly set origin_resource_type field.' , extended_resource_type)
            #raise Inconsistent('The requested resource %s does not contain a properly set origin_resource_type field.' % extended_resource_type)

        if hasattr(res_container, 'origin_resource_type') and res_container.origin_resource_type != resource_object.type_\
        and not issubtype(resource_object.type_, res_container.origin_resource_type):
            log.error('The origin_resource_type of the requested resource %s(%s) does not match the type of the specified resource id(%s).' % (
                extended_resource_type, res_container.origin_resource_type, resource_object.type_))
            #raise Inconsistent('The origin_resource_type of the requested resource %s(%s) does not match the type of the specified resource id(%s).' % (extended_resource_type, res_container.origin_resource_type, resource_object.type_))

        res_container._id = resource_object._id
        res_container.resource = resource_object

        self.set_container_lcstate_info(res_container)

        self.set_container_field_values(res_container, ext_exclude)

        self.set_computed_attributes(res_container, computed_resource_type, ext_exclude)

        self.set_extended_associations(res_container, ext_associations, ext_exclude)

        res_container.ts_created = get_ion_ts()

        overall_stop_time = time.time()

        log.debug("Time to process extended resource container %s %f secs", extended_resource_type, overall_stop_time - overall_start_time )

        return res_container
Example #10
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 sap.type_ in self.negotiation_rules:
            # 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
Example #11
0
    def _check_collection_content(self, key, list_values, content_types):
        from pyon.core.registry import issubtype
        split_content_types = {t.strip() for t in content_types.split(',')}

        for value in list_values:
            for content_type in split_content_types:
                # First check for valid ION types
                if isinstance(value, dict) and 'type_' in value:
                    if value['type_'] == content_type or issubtype(value['type_'], content_type):
                        break

                if type(value).__name__ == content_type:
                    break
                # Check for inheritance
                if self._check_inheritance_chain(type(value), content_type):
                    break
            else:
                # No break - no match found
                raise AttributeError("Invalid value type '%s' in collection field '%s.%s', should be one of '%s'" %
                        (value, type(self).__name__, key, content_types))
Example #12
0
 def _validate_resource_id(self, arg_name, resource_id, res_type=None, optional=False, allow_subtype=True):
     """
     Check that the given argument is a resource id (string), by retrieving the resource from the
     resource registry. Additionally, checks type and returns the result object.
     Supports optional argument and subtypes. res_type can be a list of (sub)types.
     """
     if optional and not resource_id:
         return
     if not resource_id:
         raise BadRequest("Argument '%s': missing" % arg_name)
     resource_obj = self.clients.resource_registry.read(resource_id)
     if res_type:
         type_list = res_type
         if not hasattr(res_type, "__iter__"):
             type_list = [res_type]
         from pyon.core.registry import issubtype
         if allow_subtype and not any(map(lambda check_type: issubtype(resource_obj.type_, check_type), type_list)):
             raise BadRequest("Argument '%s': existing resource is not a '%s' -- SPOOFING ALERT" % (arg_name, res_type))
         elif not allow_subtype and not any(map(lambda check_type: resource_obj.type_ == check_type, type_list)):
             raise BadRequest("Argument '%s': existing resource is not a '%s' -- SPOOFING ALERT" % (arg_name, res_type))
     return resource_obj
Example #13
0
 def _validate_resource_id(self,
                           arg_name,
                           resource_id,
                           res_type=None,
                           optional=False,
                           allow_subtype=True,
                           allow_deleted=False):
     """
     Check that the given argument is a resource id (string), by retrieving the resource from the
     resource registry. Additionally, checks type and returns the result object.
     Supports optional argument and subtypes. res_type can be a list of (sub)types.
     """
     if optional and not resource_id:
         return
     if not resource_id and not optional:
         raise BadRequest("Argument '%s': missing" % arg_name)
     resource_obj = self.clients.resource_registry.read(resource_id)
     if resource_obj.lcstate == "DELETED" and not allow_deleted:
         raise NotFound("Object with id %s does not exist." % resource_id)
     if res_type:
         type_list = res_type
         if not hasattr(res_type, "__iter__"):
             type_list = [res_type]
         from pyon.core.registry import issubtype
         if allow_subtype and not any(
                 map(
                     lambda check_type: issubtype(resource_obj.type_,
                                                  check_type), type_list)):
             raise BadRequest(
                 "Argument '%s': existing resource is not a '%s' -- SPOOFING ALERT"
                 % (arg_name, res_type))
         elif not allow_subtype and not any(
                 map(lambda check_type: resource_obj.type_ == check_type,
                     type_list)):
             raise BadRequest(
                 "Argument '%s': existing resource is not a '%s' -- SPOOFING ALERT"
                 % (arg_name, res_type))
     return resource_obj
    def negotiate(self, sap=None):
        """A generic operation for negotiating actions with an Org, such as for enrollment, role request or to acquire a
        resource managed by the Org. The Service Agreement Proposal is used to specify conditions of the proposal as well
        as counter proposals and the Org will create Negotiation Resource to track the history and status of the negotiation.

        @param sap    ServiceAgreementProposal
        @retval sap    ServiceAgreementProposal
        @throws BadRequest    If an SAP is not provided or incomplete
        @throws Inconsistent    If an SAP has inconsistent information
        @throws NotFound    If any of the ids in the SAP do not exist
        """

        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:
            neg_id = self.negotiation_handler.create_negotiation(sap)

            #Synchronize the internal reference for later use
            sap.negotiation_id = neg_id

        #Get the most recent version of the Negotiation resource
        negotiation = self.negotiation_handler.read_negotiation(sap)

        #Update the Negotiation object with the latest SAP
        neg_id = self.negotiation_handler.update_negotiation(sap)

        #Get the most recent version of the Negotiation resource
        negotiation = self.clients.resource_registry.read(neg_id)

        #hardcodng some rules at the moment
        if sap.type_ == OT.EnrollmentProposal or sap.type_ == OT.RequestRoleProposal:
            #Automatically accept for the consumer if the Org Manager as provider accepts the proposal
            if sap.proposal_status == ProposalStatusEnum.ACCEPTED and sap.originator == ProposalOriginatorEnum.PROVIDER:
                consumer_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED)

                #Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(consumer_accept_sap)

                #Get the most recent version of the Negotiation resource
                negotiation = self.clients.resource_registry.read(neg_id)

            elif sap.proposal_status == ProposalStatusEnum.ACCEPTED and sap.originator == ProposalOriginatorEnum.CONSUMER:
                provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED, ProposalOriginatorEnum.PROVIDER)

                #Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap)

                #Get the most recent version of the Negotiation resource
                negotiation = self.clients.resource_registry.read(neg_id)

        elif sap.type_ == OT.AcquireResourceExclusiveProposal:
            if not self.is_resource_acquired_exclusively(None, sap.resource):

                #Automatically reject the proposal if the exipration request is greater than 12 hours from now or 0
                cur_time = int(get_ion_ts())
                expiration = cur_time +  ( 12 * 60 * 60 * 1000 ) # 12 hours from now
                if sap.expiration == 0 or sap.expiration > expiration:
                    #Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.REJECTED, ProposalOriginatorEnum.PROVIDER)

                    rejection_reason = "A proposal to acquire a resource exclusively must be included and be less than 12 hours."

                    #Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap, rejection_reason)

                    #Get the most recent version of the Negotiation resource
                    negotiation = self.clients.resource_registry.read(neg_id)
                else:

                    #Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED, ProposalOriginatorEnum.PROVIDER)

                    #Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap)

                    #Get the most recent version of the Negotiation resource
                    negotiation = self.clients.resource_registry.read(neg_id)

                    consumer_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED)

                    #Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(consumer_accept_sap)

                    #Get the most recent version of the Negotiation resource
                    negotiation = self.clients.resource_registry.read(neg_id)

        #Return the latest proposal
        return negotiation.proposals[-1]
Example #15
0
def is_resource(object):
    """Returns true if the given object is a resource (i.e. a sub-type of Resource)"""
    return issubtype(object.type_, "Resource")
Example #16
0
def is_resource(object):
    """Returns true if the given object is a resource (i.e. a sub-type of Resource)"""
    return issubtype(object.type_, "Resource")
Example #17
0
def is_resource(object):
    return issubtype(object._get_type(), "Resource")
Example #18
0
    def create_extended_resource_container(
        self,
        extended_resource_type,
        resource_id,
        computed_resource_type=None,
        ext_associations=None,
        ext_exclude=None,
        **kwargs
    ):
        """
        Returns an extended resource container for a given resource_id.
        """
        overall_start_time = time.time()
        self.ctx = None  # Clear the context in case this instance gets reused

        if not isinstance(resource_id, types.StringType):
            raise Inconsistent("The parameter resource_id is not a single resource id string")

        if not self.service_provider or not self._rr:
            raise Inconsistent("This class is not initialized properly")

        if extended_resource_type not in getextends(OT.ResourceContainer):
            raise BadRequest(
                "The requested resource %s is not extended from %s" % (extended_resource_type, OT.ResourceContainer)
            )

        if computed_resource_type and computed_resource_type not in getextends(OT.BaseComputedAttributes):
            raise BadRequest(
                "The requested resource %s is not extended from %s"
                % (computed_resource_type, OT.BaseComputedAttributes)
            )

        resource_object = self._rr.read(resource_id)

        if not resource_object:
            raise NotFound("The Resource %s does not exist" % resource_id)

        res_container = IonObject(extended_resource_type)

        # Check to make sure the extended resource decorator raise OriginResourceType matches the type of the resource type
        originResourceType = res_container.get_class_decorator_value("OriginResourceType")
        if originResourceType is None:
            log.error(
                "The requested extended resource %s does not contain an OriginResourceType decorator.",
                extended_resource_type,
            )

        elif originResourceType != resource_object.type_ and not issubtype(resource_object.type_, originResourceType):
            raise Inconsistent(
                "The OriginResourceType decorator of the requested resource %s(%s) does not match the type of the specified resource id(%s)."
                % (extended_resource_type, originResourceType, resource_object.type_)
            )

        res_container._id = resource_object._id
        res_container.resource = resource_object

        # Initialize context object field and load resource associations
        self._prepare_context(resource_object._id)

        # Fill lcstate related resource container fields
        self.set_container_lcstate_info(res_container)

        # Fill resource container info; currently only type_version
        self.set_res_container_info(res_container)

        # Fill resource container fields
        self.set_container_field_values(res_container, ext_exclude, **kwargs)

        # Fill computed attributes
        self.set_computed_attributes(res_container, computed_resource_type, ext_exclude, **kwargs)

        # Fill additional associations
        self.set_extended_associations(res_container, ext_associations, ext_exclude)

        res_container.ts_created = get_ion_ts()

        overall_stop_time = time.time()

        log.debug(
            "Time to process extended resource container %s %f secs",
            extended_resource_type,
            overall_stop_time - overall_start_time,
        )

        # log.info("ResourceContainer: %s" % res_container)

        return res_container
    def negotiate(self, sap=None):
        """A generic operation for negotiating actions with an Org, such as for enrollment, role request or to acquire a
        resource managed by the Org. The Service Agreement Proposal is used to specify conditions of the proposal as well
        as counter proposals and the Org will create Negotiation Resource to track the history and status of the negotiation.

        @param sap    ServiceAgreementProposal
        @retval sap    ServiceAgreementProposal
        @throws BadRequest    If an SAP is not provided or incomplete
        @throws Inconsistent    If an SAP has inconsistent information
        @throws NotFound    If any of the ids in the SAP do not exist
        """

        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:
            neg_id = self.negotiation_handler.create_negotiation(sap)

            org = self.read_org(org_id=sap.provider)

            #Publish an event indicating an Negotiation has been initiated
            self.event_pub.publish_event(event_type=OT.OrgNegotiationInitiatedEvent, origin=org._id, origin_type='Org',
                description=sap.description, org_name=org.name, negotiation_id=neg_id, sub_type=sap.type_ )

            #Synchronize the internal reference for later use
            sap.negotiation_id = neg_id

        #Get the most recent version of the Negotiation resource
        negotiation = self.negotiation_handler.read_negotiation(sap)

        #Update the Negotiation object with the latest SAP
        neg_id = self.negotiation_handler.update_negotiation(sap)

        #Get the most recent version of the Negotiation resource
        negotiation = self.clients.resource_registry.read(neg_id)

        #hardcodng some rules at the moment - could be replaced by a Rules Engine
        if sap.type_ == OT.AcquireResourceExclusiveProposal:

            if self.is_resource_acquired_exclusively(None, sap.resource_id):
                #Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.REJECTED, ProposalOriginatorEnum.PROVIDER)

                rejection_reason = "The resource has already been acquired exclusively"

                #Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap, rejection_reason)

                #Get the most recent version of the Negotiation resource
                negotiation = self.clients.resource_registry.read(neg_id)

            else:

                #Automatically reject the proposal if the exipration request is greater than 12 hours from now or 0
                cur_time = int(get_ion_ts())
                expiration = int(cur_time +  ( 12 * 60 * 60 * 1000 )) # 12 hours from now
                if int(sap.expiration) == 0 or int(sap.expiration) > expiration:
                    #Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.REJECTED, ProposalOriginatorEnum.PROVIDER)

                    rejection_reason = "A proposal to acquire a resource exclusively must be more than 0 and be less than 12 hours."

                    #Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap, rejection_reason)

                    #Get the most recent version of the Negotiation resource
                    negotiation = self.clients.resource_registry.read(neg_id)

                else:

                    #Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED, ProposalOriginatorEnum.PROVIDER)

                    #Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap)

                    #Get the most recent version of the Negotiation resource
                    negotiation = self.clients.resource_registry.read(neg_id)

        #Check to see if the rules allow for auto acceptance of the negotiations - where the second party is assumed to accept if the
        #first party accepts.
        if negotiation_rules[sap.type_]['auto_accept']:

            #Automatically accept for the consumer if the Org Manager as provider accepts the proposal
            latest_sap = negotiation.proposals[-1]

            if latest_sap.proposal_status == ProposalStatusEnum.ACCEPTED and latest_sap.originator == ProposalOriginatorEnum.PROVIDER:
                consumer_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED)

                #Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(consumer_accept_sap)

                #Get the most recent version of the Negotiation resource
                negotiation = self.clients.resource_registry.read(neg_id)

            elif latest_sap.proposal_status == ProposalStatusEnum.ACCEPTED and latest_sap.originator == ProposalOriginatorEnum.CONSUMER:
                provider_accept_sap = Negotiation.create_counter_proposal(negotiation, ProposalStatusEnum.ACCEPTED, ProposalOriginatorEnum.PROVIDER)

                #Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(provider_accept_sap)

                #Get the most recent version of the Negotiation resource
                negotiation = self.clients.resource_registry.read(neg_id)


        #Return the latest proposal
        return negotiation.proposals[-1]
Example #20
0
    def create_prepare_resource_support(self,
                                        resource_id="",
                                        prepare_resource_type=None,
                                        origin_resource_type=None):

        if not isinstance(resource_id, types.StringType):
            raise Inconsistent(
                "The parameter resource_id is not a single resource id string")

        if not self.service_provider or not self._rr:
            raise Inconsistent("This class is not initialized properly")

        if prepare_resource_type is not None and prepare_resource_type not in getextends(
                OT.ResourcePrepareSupport):
            raise BadRequest(
                'The requested resource %s is not extended from %s' %
                (prepare_resource_type, OT.ResourcePrepareSupport))

        resource_data = IonObject(prepare_resource_type)

        # Check to make sure the extended resource decorator raise OriginResourceType matches the type of the resource type
        origin_resource_decorator = resource_data.get_class_decorator_value(
            'OriginResourceType')
        if origin_resource_decorator is None and origin_resource_type is None:
            raise NotFound(
                'OriginResourceType decorator not found in object specification %s',
                prepare_resource_type)

        origin_resource_type = origin_resource_type if origin_resource_type is not None else origin_resource_decorator
        if origin_resource_type is None:
            raise NotFound(
                'OriginResourceType decorator not found in object specification %s',
                prepare_resource_type)

        resource_object = None
        if resource_id:
            resource_object = self._rr.read(resource_id)

            if origin_resource_type != resource_object.type_ and not issubtype(
                    resource_object.type_, origin_resource_type):
                raise Inconsistent(
                    'The OriginResourceType decorator of the requested resource %s(%s) does not match the type of the specified resource id(%s).'
                    % (prepare_resource_type, origin_resource_type,
                       resource_object.type_))

            resource_data._id = resource_object._id
        else:
            resource_object = IonObject(origin_resource_type)

        resource_data.resource = resource_object
        resource_data.resource_schema = get_object_schema(origin_resource_type)

        for field in resource_data._schema:

            deco_value = resource_data.get_decorator_value(
                field, 'AssociatedResources')
            assoc_dict = {}
            if deco_value is not None:
                if deco_value.find(',') == -1:
                    associated_resources = [deco_value]
                else:
                    associated_resources = deco_value.split(',')

                for res in associated_resources:
                    assoc = self.get_associated_resource_info(
                        origin_resource_type, resource_id, res)
                    assoc_dict[assoc.key] = assoc

                setattr(resource_data, field, assoc_dict)
                continue

        return resource_data
Example #21
0
def is_resource(object):
    return issubtype(object._get_type(), "Resource")
Example #22
0
    def negotiate(self, sap=None):
        """A generic operation for negotiating actions with an Org, such as for enrollment, role request
        or to acquire a resource managed by the Org. The ServiceAgreementProposal object is used to
        specify conditions of the proposal as well as counter proposals and the Org will create a
        Negotiation resource to track the history and status of the negotiation.
        """

        if sap is None or (
                sap.type_ != OT.ServiceAgreementProposal
                and not issubtype(sap.type_, OT.ServiceAgreementProposal)):
            raise BadRequest(
                "The sap argument must be a valid ServiceAgreementProposal object"
            )

        if sap.proposal_status == ProposalStatusEnum.INITIAL:
            neg_id = self.negotiation_handler.create_negotiation(sap)

            org = self.read_org(org_id=sap.provider)

            # Publish an event indicating an Negotiation has been initiated
            self.event_pub.publish_event(
                event_type=OT.OrgNegotiationInitiatedEvent,
                origin=org._id,
                origin_type="Org",
                description=sap.description,
                org_name=org.name,
                negotiation_id=neg_id,
                sub_type=sap.type_)

            # Synchronize the internal reference for later use
            sap.negotiation_id = neg_id

        # Get the most recent version of the Negotiation resource
        negotiation = self.negotiation_handler.read_negotiation(sap)

        # Update the Negotiation object with the latest SAP
        neg_id = self.negotiation_handler.update_negotiation(sap)

        # Get the most recent version of the Negotiation resource
        negotiation = self.rr.read(neg_id)

        # hardcoding some rules at the moment - could be replaced by a Rules Engine
        if sap.type_ == OT.AcquireResourceExclusiveProposal:

            if self.is_resource_acquired_exclusively(None, sap.resource_id):
                # Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                provider_accept_sap = Negotiation.create_counter_proposal(
                    negotiation, ProposalStatusEnum.REJECTED,
                    ProposalOriginatorEnum.PROVIDER)

                rejection_reason = "The resource has already been acquired exclusively"

                # Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(
                    provider_accept_sap, rejection_reason)

                # Get the most recent version of the Negotiation resource
                negotiation = self.rr.read(neg_id)

            else:
                # Automatically reject the proposal if the expiration request is greater than 12 hours from now or 0
                cur_time = int(get_ion_ts())
                expiration = int(cur_time +
                                 (12 * 60 * 60 * 1000))  # 12 hours from now
                if int(sap.expiration) == 0 or int(
                        sap.expiration) > expiration:
                    # Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(
                        negotiation, ProposalStatusEnum.REJECTED,
                        ProposalOriginatorEnum.PROVIDER)

                    rejection_reason = "A proposal to acquire a resource exclusively must be more than 0 and be less than 12 hours."

                    # Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(
                        provider_accept_sap, rejection_reason)

                    # Get the most recent version of the Negotiation resource
                    negotiation = self.rr.read(neg_id)

                else:
                    # Automatically accept the proposal for exclusive access if it is not already acquired exclusively
                    provider_accept_sap = Negotiation.create_counter_proposal(
                        negotiation, ProposalStatusEnum.ACCEPTED,
                        ProposalOriginatorEnum.PROVIDER)

                    # Update the Negotiation object with the latest SAP
                    neg_id = self.negotiation_handler.update_negotiation(
                        provider_accept_sap)

                    # Get the most recent version of the Negotiation resource
                    negotiation = self.rr.read(neg_id)

        # Check to see if the rules allow for auto acceptance of the negotiations -
        # where the second party is assumed to accept if the
        # first party accepts.
        if negotiation_rules[sap.type_]["auto_accept"]:
            # Automatically accept for the consumer if the Org Manager as provider accepts the proposal
            latest_sap = negotiation.proposals[-1]

            if latest_sap.proposal_status == ProposalStatusEnum.ACCEPTED and latest_sap.originator == ProposalOriginatorEnum.PROVIDER:
                consumer_accept_sap = Negotiation.create_counter_proposal(
                    negotiation, ProposalStatusEnum.ACCEPTED)

                # Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(
                    consumer_accept_sap)

                # Get the most recent version of the Negotiation resource
                negotiation = self.rr.read(neg_id)

            elif latest_sap.proposal_status == ProposalStatusEnum.ACCEPTED and latest_sap.originator == ProposalOriginatorEnum.CONSUMER:
                provider_accept_sap = Negotiation.create_counter_proposal(
                    negotiation, ProposalStatusEnum.ACCEPTED,
                    ProposalOriginatorEnum.PROVIDER)

                # Update the Negotiation object with the latest SAP
                neg_id = self.negotiation_handler.update_negotiation(
                    provider_accept_sap)

                # Get the most recent version of the Negotiation resource
                negotiation = self.rr.read(neg_id)

        # Return the latest proposal
        return negotiation.proposals[-1]
Example #23
0
    def create_extended_resource_container(self,
                                           extended_resource_type,
                                           resource_id,
                                           computed_resource_type=None,
                                           ext_associations=None,
                                           ext_exclude=None,
                                           **kwargs):
        """
        Returns an extended resource container for a given resource_id.
        """
        overall_start_time = time.time()
        self.ctx = None  # Clear the context in case this instance gets reused

        if not isinstance(resource_id, types.StringType):
            raise Inconsistent(
                "The parameter resource_id is not a single resource id string")

        if not self.service_provider or not self._rr:
            raise Inconsistent("This class is not initialized properly")

        if extended_resource_type not in getextends(OT.ResourceContainer):
            raise BadRequest(
                'The requested resource %s is not extended from %s' %
                (extended_resource_type, OT.ResourceContainer))

        if computed_resource_type and computed_resource_type not in getextends(
                OT.ComputedAttributes):
            raise BadRequest(
                'The requested resource %s is not extended from %s' %
                (computed_resource_type, OT.ComputedAttributes))

        resource_object = self._rr.read(resource_id)

        if not resource_object:
            raise NotFound("The Resource %s does not exist" % resource_id)

        res_container = IonObject(extended_resource_type)

        # @TODO - replace with object level decorators and raise exceptions
        if not hasattr(res_container, 'origin_resource_type'):
            log.error(
                'The requested resource %s does not contain a properly set origin_resource_type field.',
                extended_resource_type)
            #raise Inconsistent('The requested resource %s does not contain a properly set origin_resource_type field.' % extended_resource_type)

        if hasattr(res_container, 'origin_resource_type') and res_container.origin_resource_type != resource_object.type_\
        and not issubtype(resource_object.type_, res_container.origin_resource_type):
            log.error(
                'The origin_resource_type of the requested resource %s(%s) does not match the type of the specified resource id(%s).'
                % (extended_resource_type, res_container.origin_resource_type,
                   resource_object.type_))
            #raise Inconsistent('The origin_resource_type of the requested resource %s(%s) does not match the type of the specified resource id(%s).' % (extended_resource_type, res_container.origin_resource_type, resource_object.type_))

        res_container._id = resource_object._id
        res_container.resource = resource_object

        # Initialize context object field and load resource associations
        self._prepare_context(resource_object._id)

        # Fill lcstate related resource container fields
        self.set_container_lcstate_info(res_container)

        # Fill resource container fields
        self.set_container_field_values(res_container, ext_exclude, **kwargs)

        # Fill computed attributes
        self.set_computed_attributes(res_container, computed_resource_type,
                                     ext_exclude, **kwargs)

        # Fill additional associations
        self.set_extended_associations(res_container, ext_associations,
                                       ext_exclude)

        res_container.ts_created = get_ion_ts()

        overall_stop_time = time.time()

        log.debug("Time to process extended resource container %s %f secs",
                  extended_resource_type,
                  overall_stop_time - overall_start_time)

        #log.info("ResourceContainer: %s" % res_container)

        return res_container
Example #24
0
def is_resource(object):
    return issubtype(object.type_, "Resource")