Ejemplo n.º 1
0
    def insert_resp_metadata(self, response):
        """
        @brief Insert metadata from GET-RESP message into internal form.
        @param response Either JSON format dict or JSON format string
                        in format of of GET-RESP metadata.
        @retval None.

        The response is converted to a JSON dictionary and/or checked
        to verify that it is in good shape.

        Can be used either with an 'empty' NetInfMetaData instance
        identified by the 'ni' field being the empty string or with
        a previously populated entry.

        For an empty instance, the header fields ('ni', 'ct' and 'size')
        are populated from the response where possible (may be no 'ct' or 'size'
        in the response).

        The remainder of the information is converted into a new 'details'
        entry which is either used as the first entry or appended to the
        list if there are existing entries.
        
        @raises Exceptions if cannot parse response
        """

        if type(response) == StringType:
            resp_dict = json.loads(response)
        elif type(response) == DictType:
            resp_dict = response
            # Check the response is really a JSON dictionary
            js = json.dumps(response)
        else:
            raise TypeError("Parameter 'response' is not a string or dictionary")

        curr_ni = self.get_ni()
        resp_ni_name = NIname(resp_dict["ni"])
        ret = resp_ni_name.validate_ni_url()
        if ret != ni_errs.niSUCCESS:
            raise InvalidNIname("Response ni field '%s' is not a valid ni URI: %s" %
                                (resp_dict["ni"], ni_errs_txt[ret]))

        if curr_ni == "" :
            # Empty metadata case
            self.json_obj["ni"] = resp_ni_name.get_canonical_ni_url()
            if resp_dict.has_key("ct"):
                self.json_obj["ct"] = resp_dict["ct"]
            if resp_dict.has_key("size"):
                self.json_obj["size"] = resp_dict["size"]
            self.json_obj["details"] = []
        else:
            # The metadata is not empty
            # Create validated NIname for the current metadata
            ni_name = NIname(curr_ni)
            # If this fails the metadata database is corrupt
            assert(ni_name.validate_ni_url() == ni_errs.niSUCCESS)
            if ni_name.cmp(resp_ni_name) == 0:
                # Update with data about same ni name
                if resp_dict.has_key("ct") and (resp_dict["ct"] != ""):
                    if self.json_obj["ct"] == "":
                        self.json_obj["ct"] = resp_dict["ct"]
                    elif self.json_obj["ct"] != resp_dict["ct"]:
                        raise MetadataMismatch("Content Type fields are unmatched")
                if resp_dict.has_key("size") and (resp_dict["size"] >= 0):
                    if self.json_obj["size"] == -1:
                        self.json_obj["size"] = resp_dict["size"]
                    elif self.json_obj["size"] != resp_dict["size"]:
                        raise MetadataMismatch("Size fields are unmatched")
            else:
                raise MetadataMismatch("NI name fields are unmatched curr: %s, got: %s" %
                                       (curr_ni, resp_dict["ni"]))

        new_detail = {}
        new_detail["loc"] = []
        for loc_key in ("loc", "loclist"):
            if resp_dict.has_key(loc_key):
                if type(resp_dict[loc_key]) == ListType:
                    new_detail["loc"] = resp_dict[loc_key]
                else:
                    raise TypeError("Response '%s' value is not a list" %
                                    loc_key)
        auth = resp_ni_name.get_netloc()
        if auth is not None and (auth != ""):
            new_detail["loc"].append(auth)

                
        if resp_dict.has_key("metadata"):
            if type(resp_dict["metadata"]) == DictType:
                new_detail["metadata"] = resp_dict["metadata"]
            else:
                raise TypeError("Response metadata is not an object dictionary")


        if resp_dict.has_key("searches"):
            if not new_detail.has_key("metadata"):
                new_detail["metadata"] = {}
            new_detail["metadata"]["search"] = resp_dict["searches"]

        new_detail["ts"] = self.metadata_timestamp_for_now()
        
        self.json_obj["details"].append(new_detail)
        self.curr_detail = new_detail
        return