Exemplo n.º 1
0
def getSchemaDetails(SchemaType, SchemaURI):
    """
    Find Schema file for given Namespace.

    param SchemaType: Schema Namespace, such as ServiceRoot
    param SchemaURI: uri to grab schema, given LocalOnly is False
    return: (success boolean, a Soup object, origin)
    """
    rst.traverseLogger.debug('getting Schema of {} {}'.format(
        SchemaType, SchemaURI))
    currentService = rst.currentService

    if SchemaType is None:
        return False, None, None

    if currentService is None:
        return getSchemaDetailsLocal(SchemaType, SchemaURI)

    elif currentService.active and getNamespace(
            SchemaType) in currentService.metadata.schema_store:
        result = rst.currentService.metadata.schema_store[getNamespace(
            SchemaType)]
        if result is not None:
            return True, result.soup, result.origin

    if not currentService.config[
            'preferonline'] and '$metadata' not in SchemaURI:
        success, soup, origin = getSchemaDetailsLocal(SchemaType, SchemaURI)
        if success:
            return success, soup, origin

    xml_suffix = currentService.config['schemasuffix']

    config = rst.currentService.config
    LocalOnly, SchemaLocation, ServiceOnly = config['localonlymode'], config[
        'metadatafilepath'], config['servicemode']

    scheme, netloc, path, params, query, fragment = urlparse(SchemaURI)
    inService = scheme is None and netloc is None

    if (SchemaURI is not None
            and not LocalOnly) or (SchemaURI is not None
                                   and '/redfish/v1/$metadata' in SchemaURI):
        # Get our expected Schema file here
        # if success, generate Soup, then check for frags to parse
        #   start by parsing references, then check for the refLink
        if '#' in SchemaURI:
            base_schema_uri, frag = tuple(SchemaURI.rsplit('#', 1))
        else:
            base_schema_uri, frag = SchemaURI, None
        success, data, status, elapsed = rst.callResourceURI(base_schema_uri)
        if success:
            soup = BeautifulSoup(data, "xml")
            # if frag, look inside xml for real target as a reference
            if frag is not None:
                # prefer type over frag, truncated down
                # using frag, check references
                frag = getNamespace(SchemaType)
                frag = frag.split('.', 1)[0]
                refType, refLink = getReferenceDetails(
                    soup, name=base_schema_uri).get(frag, (None, None))
                if refLink is not None:
                    success, linksoup, newlink = getSchemaDetails(
                        refType, refLink)
                    if success:
                        return True, linksoup, newlink
                    else:
                        rst.traverseLogger.error(
                            "SchemaURI couldn't call reference link {} inside {}"
                            .format(frag, base_schema_uri))
                else:
                    rst.traverseLogger.error(
                        "SchemaURI missing reference link {} inside {}".format(
                            frag, base_schema_uri))
                    # error reported; assume likely schema uri to allow continued validation
                    uri = 'http://redfish.dmtf.org/schemas/v1/{}{}'.format(
                        frag, xml_suffix)
                    rst.traverseLogger.info(
                        "Continue assuming schema URI for {} is {}".format(
                            SchemaType, uri))
                    return getSchemaDetails(SchemaType, uri)
            else:
                storeSchemaToLocal(data, base_schema_uri)
                return True, soup, base_schema_uri
        if not inService and ServiceOnly:
            rst.traverseLogger.debug(
                "Nonservice URI skipped: {}".format(base_schema_uri))
        else:
            rst.traverseLogger.debug(
                "SchemaURI called unsuccessfully: {}".format(base_schema_uri))
    if LocalOnly:
        rst.traverseLogger.debug("This program is currently LOCAL ONLY")
    if ServiceOnly:
        rst.traverseLogger.debug("This program is currently SERVICE ONLY")
    if not LocalOnly and not ServiceOnly or (not inService
                                             and config['preferonline']):
        rst.traverseLogger.warning(
            "SchemaURI {} was unable to be called, defaulting to local storage in {}"
            .format(SchemaURI, SchemaLocation))
    return getSchemaDetailsLocal(SchemaType, SchemaURI)
Exemplo n.º 2
0
def checkComparison(val, compareType, target):
    """
    Validate a given comparison option, given a value and a target set
    """
    rsvLogger.info('Testing a comparison \n\t' +
                   str((val, compareType, target)))
    vallist = val if isinstance(val, list) else [val]
    paramPass = False
    if compareType is None:
        rsvLogger.error('CompareType not available in payload')
    if compareType == "AnyOf":
        for item in vallist:
            paramPass = item in target
            if paramPass:
                break
            else:
                continue

    if compareType == "AllOf":
        alltarget = set()
        for item in vallist:
            paramPass = item in target and item not in alltarget
            if paramPass:
                alltarget.add(item)
                if len(alltarget) == len(target):
                    break
            else:
                continue
        paramPass = len(alltarget) == len(target)
    if compareType == "LinkToResource":
        vallink = val.get('@odata.id')
        success, decoded, code, elapsed = rst.callResourceURI(vallink)
        if success:
            ourType = decoded.get('@odata.type')
            if ourType is not None:
                SchemaType = rst.getType(ourType)
                paramPass = SchemaType in target
            else:
                paramPass = False
        else:
            paramPass = False

    if compareType == "Absent":
        paramPass = val == 'DNE'
    if compareType == "Present":
        paramPass = val != 'DNE'

    if isinstance(target, list):
        if len(target) >= 1:
            target = target[0]
        else:
            target = 'DNE'

    if target != 'DNE':
        if compareType == "Equal":
            paramPass = val == target
        if compareType == "NotEqual":
            paramPass = val != target
        if compareType == "GreaterThan":
            paramPass = val > target
        if compareType == "GreaterThanOrEqual":
            paramPass = val >= target
        if compareType == "LessThan":
            paramPass = val < target
        if compareType == "LessThanOrEqual":
            paramPass = val <= target
    rsvLogger.info('\tpass ' + str(paramPass))
    if not paramPass:
        rsvLogger.error('\tNoPass')
    return msgInterop('Comparison', target, compareType, val, paramPass),\
        paramPass
Exemplo n.º 3
0
def validateSingleURI(URI,
                      profile,
                      uriName='',
                      expectedType=None,
                      expectedSchema=None,
                      expectedJson=None,
                      parent=None):
    """
    Validates a single URI that is given, returning its ResourceObject, counts and links
    """
    # rs-assertion: 9.4.1
    # Initial startup here
    lc = setupLoggingCaptures()
    next(lc)

    # Start
    counts = Counter()
    results = OrderedDict()
    messages = []

    results[uriName] = {
        'uri': URI,
        'success': False,
        'counts': counts,
        'messages': messages,
        'errors': '',
        'warns': '',
        'rtime': '',
        'context': '',
        'fulltype': ''
    }

    # check for @odata mandatory stuff
    # check for version numbering problems
    # check id if its the same as URI
    # check @odata.context instead of local.  Realize that @odata is NOT a "property"

    # Attempt to get a list of properties
    if URI is None:
        if parent is not None:
            parentURI = parent.uri
        else:
            parentURI = '...'
        URI = parentURI + '...'
    if expectedJson is None:
        successGet, jsondata, status, rtime = rst.callResourceURI(URI)
    else:
        successGet, jsondata = True, expectedJson

    if jsondata is not None:
        successPayload, odataMessages = rst.ResourceObj.checkPayloadConformance(
            jsondata, URI)

        if not successPayload:
            counts['failPayloadWarn'] += 1
            rsvLogger.verboseout(
                str(URI) + ': payload error, @odata property non-conformant', )

    # Generate dictionary of property info
    try:
        propResourceObj = rst.createResourceObject(uriName, URI, expectedJson,
                                                   expectedType,
                                                   expectedSchema, parent)
        if not propResourceObj:
            counts['problemResource'] += 1
            results[uriName]['warns'], results[uriName]['errors'] = next(lc)
            return False, counts, results, None, None
    except AuthenticationError:
        raise  # re-raise exception
    except Exception:
        rsvLogger.exception("")
        counts['exceptionResource'] += 1
        results[uriName]['warns'], results[uriName]['errors'] = next(lc)
        return False, counts, results, None, None

    counts['passGet'] += 1

    # if URI was sampled, get the notation text from rst.uri_sample_map
    sample_string = rst.uri_sample_map.get(URI)
    sample_string = sample_string + ', ' if sample_string is not None else ''

    results[uriName]['uri'] = (str(URI))
    results[uriName]['samplemapped'] = (str(sample_string))
    results[uriName]['rtime'] = propResourceObj.rtime
    results[uriName]['context'] = propResourceObj.context
    results[uriName]['origin'] = propResourceObj.schemaObj.origin
    results[uriName]['fulltype'] = propResourceObj.typeobj.fulltype
    results[uriName]['success'] = True

    rsvLogger.debug("\t URI {}, Type ({}), GET SUCCESS (time: {})".format(
        URI, propResourceObj.typeobj.stype, propResourceObj.rtime))

    uriName, SchemaFullType, jsondata = propResourceObj.name, propResourceObj.typeobj.fulltype, propResourceObj.jsondata
    SchemaNamespace, SchemaType = rst.getNamespace(
        SchemaFullType), rst.getType(SchemaFullType)

    objRes = profile.get('Resources')

    if SchemaType not in objRes:
        rsvLogger.debug('\nNo Such Type in sample {} {}.{}, skipping'.format(
            URI, SchemaNamespace, SchemaType))
    else:
        rsvLogger.info("\n*** %s, %s", URI, SchemaType)
        rsvLogger.debug("\n*** %s, %s, %s", expectedType, expectedSchema
                        is not None, expectedJson is not None)
        objRes = objRes.get(SchemaType)
        try:
            propMessages, propCounts = commonInterop.validateInteropResource(
                propResourceObj, objRes, jsondata)
            messages = messages.extend(propMessages)
            counts.update(propCounts)
            rsvLogger.info('{} of {} tests passed.'.format(
                counts['pass'] + counts['warn'], counts['totaltests']))
        except Exception:
            rsvLogger.exception("Something went wrong")
            rsvLogger.error(
                'Could not finish validation check on this payload')
            counts['exceptionProfilePayload'] += 1
        rsvLogger.info('%s, %s\n', SchemaFullType, counts)

    # Get all links available
    results[uriName]['warns'], results[uriName]['errors'] = next(lc)

    rsvLogger.debug(propResourceObj.links)
    return True, counts, results, propResourceObj.links, propResourceObj
Exemplo n.º 4
0
def validateSingleURI(URI,
                      uriName='',
                      expectedType=None,
                      expectedSchema=None,
                      expectedJson=None,
                      parent=None):
    # rs-assertion: 9.4.1
    # Initial startup here
    lc = setupLoggingCaptures()
    next(lc)
    # Start
    rsvLogger.verboseout("\n*** %s, %s", uriName, URI)
    rsvLogger.info("\n*** %s", URI)
    rsvLogger.debug("\n*** %s, %s, %s", expectedType, expectedSchema
                    is not None, expectedJson is not None)
    counts = Counter()
    results = OrderedDict()
    messages = OrderedDict()

    results[uriName] = {
        'uri': URI,
        'success': False,
        'counts': counts,
        'messages': messages,
        'errors': '',
        'warns': '',
        'rtime': '',
        'context': '',
        'fulltype': '',
        'rcode': 0,
        'payload': {}
    }

    # check for @odata mandatory stuff
    # check for version numbering problems
    # check id if its the same as URI
    # check @odata.context instead of local.  Realize that @odata is NOT a "property"

    # Attempt to get a list of properties
    if URI is None:
        if parent is not None:
            parentURI = parent.uri
        else:
            parentURI = 'MissingParent'
        URI = parentURI + '/Missing URI Link'
        rsvLogger.warning(
            'Tool appears to be missing vital URI information, replacing URI w/: {}'
            .format(URI))
    # Generate dictionary of property info
    try:
        if expectedJson is None:
            success, jsondata, status, rtime = rst.callResourceURI(URI)
            results[uriName]['payload'] = jsondata
        else:
            results[uriName]['payload'] = expectedJson

        # verify basic odata strings
        if results[uriName]['payload'] is not None:
            successPayload, odataMessages = rst.ResourceObj.checkPayloadConformance(
                results[uriName]['payload'], URI)
            messages.update(odataMessages)

        propResourceObj = rst.createResourceObject(uriName, URI, expectedJson,
                                                   expectedType,
                                                   expectedSchema, parent)
        if not propResourceObj:
            counts['problemResource'] += 1
            results[uriName]['warns'], results[uriName]['errors'] = next(lc)
            return False, counts, results, None, None
    except AuthenticationError as e:
        raise  # re-raise exception
    except Exception as e:
        rsvLogger.debug('Exception caught while creating ResourceObj',
                        exc_info=1)
        rsvLogger.error('Unable to gather property info for URI {}: {}'.format(
            URI, repr(e)))
        counts['exceptionResource'] += 1
        results[uriName]['warns'], results[uriName]['errors'] = next(lc)
        return False, counts, results, None, None
    counts['passGet'] += 1

    # verify odata_id properly resolves to its parent if holding fragment
    odata_id = propResourceObj.jsondata.get('@odata.id', 'void')
    if '#' in odata_id:
        if parent is not None:
            payload_resolve = rst.navigateJsonFragment(parent.jsondata, URI)
            if payload_resolve is None:
                rsvLogger.error(
                    '@odata.id of ReferenceableMember does not contain a valid JSON pointer for this payload: {}'
                    .format(odata_id))
                counts['badOdataIdResolution'] += 1
            elif payload_resolve != propResourceObj.jsondata:
                rsvLogger.error(
                    '@odata.id of ReferenceableMember does not point to the correct object: {}'
                    .format(odata_id))
                counts['badOdataIdResolution'] += 1
        else:
            rsvLogger.warn(
                'No parent found with which to test @odata.id of ReferenceableMember'
            )

    if not successPayload:
        counts['failPayloadError'] += 1
        rsvLogger.error(
            str(URI) + ': payload error, @odata property non-conformant', )

    # if URI was sampled, get the notation text from rst.uri_sample_map
    sample_string = rst.uri_sample_map.get(URI)
    sample_string = sample_string + ', ' if sample_string is not None else ''

    results[uriName]['uri'] = (str(URI))
    results[uriName]['samplemapped'] = (str(sample_string))
    results[uriName]['rtime'] = propResourceObj.rtime
    results[uriName]['rcode'] = propResourceObj.status
    results[uriName]['payload'] = propResourceObj.jsondata
    results[uriName]['context'] = propResourceObj.context
    results[uriName]['origin'] = propResourceObj.schemaObj.origin
    results[uriName]['fulltype'] = propResourceObj.typename
    results[uriName]['success'] = True

    rsvLogger.info("\t Type (%s), GET SUCCESS (time: %s)",
                   propResourceObj.typename, propResourceObj.rtime)

    # If this is an AttributeRegistry, load it for later use
    if isinstance(propResourceObj.jsondata, dict):
        odata_type = propResourceObj.jsondata.get('@odata.type')
        if odata_type is not None:
            namespace = odata_type.split('.')[0]
            type_name = odata_type.split('.')[-1]
            if namespace == '#AttributeRegistry' and type_name == 'AttributeRegistry':
                loadAttributeRegDict(odata_type, propResourceObj.jsondata)

    for prop in propResourceObj.getResourceProperties():
        try:
            if not prop.valid and not prop.exists:
                continue
            propMessages, propCounts = checkPropertyConformance(
                propResourceObj.schemaObj,
                prop.name,
                prop,
                propResourceObj.jsondata,
                parentURI=URI)
            if '@Redfish.Copyright' in propMessages and 'MessageRegistry' not in propResourceObj.typeobj.fulltype:
                modified_entry = list(propMessages['@Redfish.Copyright'])
                modified_entry[-1] = 'FAIL'
                propMessages['@Redfish.Copyright'] = tuple(modified_entry)
                rsvLogger.error(
                    '@Redfish.Copyright is only allowed for mockups, and should not be allowed in official implementations'
                )
            if prop.payloadName != prop.propChild:
                propCounts['invalidName'] += 1
                for propMsg in propMessages:
                    modified_entry = list(propMessages[propMsg])
                    modified_entry[-1] = 'Invalid'
                    propMessages[propMsg] = tuple(modified_entry)
            if not prop.valid:
                rsvLogger.error(
                    'Verifying property that does not belong to this version: {}'
                    .format(prop.name))
                for propMsg in propMessages:
                    propCounts['invalidEntry'] += 1
                    modified_entry = list(propMessages[propMsg])
                    modified_entry[-1] = 'Invalid'
                    propMessages[propMsg] = tuple(modified_entry)

            messages.update(propMessages)
            counts.update(propCounts)
        except AuthenticationError as e:
            raise  # re-raise exception
        except Exception as ex:
            rsvLogger.debug('Exception caught while validating single URI',
                            exc_info=1)
            rsvLogger.error(
                '{}: Could not finish check on this property ({})'.format(
                    prop.name, str(ex)))
            counts['exceptionPropCheck'] += 1

    uriName, SchemaFullType, jsonData = propResourceObj.name, propResourceObj.typeobj.fulltype, propResourceObj.jsondata
    SchemaNamespace, SchemaType = rst.getNamespace(
        SchemaFullType), rst.getType(SchemaFullType)

    # List all items checked and unchecked
    # current logic does not check inside complex types
    fmt = '%-30s%30s'
    rsvLogger.verboseout('%s, %s, %s', uriName, SchemaNamespace, SchemaType)

    for key in jsonData:
        item = jsonData[key]
        rsvLogger.verboseout(fmt % (key, messages[key][3] if key in messages
                                    else 'Exists, no schema check'))

    allowAdditional = propResourceObj.typeobj.additional
    for key in [
            k for k in jsonData
            if k not in messages and k not in propResourceObj.unknownProperties
    ] + propResourceObj.unknownProperties:
        # note: extra messages for "unchecked" properties
        if not allowAdditional:
            rsvLogger.error(
                '{} not defined in schema {} (check version, spelling and casing)'
                .format(key, SchemaNamespace))
            counts['failAdditional'] += 1
            messages[key] = (displayValue(item), '-', '-', 'FAIL')
        else:
            rsvLogger.warn(
                '{} not defined in schema {} (check version, spelling and casing)'
                .format(key, SchemaNamespace))
            counts['unverifiedAdditional'] += 1
            messages[key] = (displayValue(item), '-', '-', 'Additional')

    for key in messages:
        if key not in jsonData:
            rsvLogger.verboseout(fmt % (key, messages[key][3]))

    results[uriName]['warns'], results[uriName]['errors'] = next(lc)

    pass_val = len(results[uriName]['errors']) == 0
    for key in counts:
        if any(x in key for x in ['problem', 'fail', 'bad', 'exception']):
            pass_val = False
            break
    rsvLogger.info("\t {}".format('PASS' if pass_val else ' FAIL...'))

    rsvLogger.verboseout('%s, %s', SchemaFullType, counts)

    # Get all links available

    rsvLogger.debug(propResourceObj.links)

    return True, counts, results, propResourceObj.links, propResourceObj
Exemplo n.º 5
0
def validateActionRequirement(propResourceObj, profile_entry, rf_payload_tuple,
                              actionname):
    """
    Validate Requirements for one action
    """
    rf_payload_item, rf_payload = rf_payload_tuple
    rf_payload_action = None
    counts = Counter()
    msgs = []
    rsvLogger.verboseout('actionRequirement \n\tval: ' + str(
        rf_payload_item if not isinstance(rf_payload_item, dict) else 'dict') +
                         ' ' + str(profile_entry))

    if "ReadRequirement" in profile_entry:
        # problem: if dne, skip
        msg, success = validateRequirement(
            profile_entry.get('ReadRequirement', "Mandatory"), rf_payload_item)
        msgs.append(msg)
        msg.name = actionname + '.' + msg.name

    propDoesNotExist = (rf_payload_item == 'DNE')
    if propDoesNotExist:
        return msgs, counts
    if "@Redfish.ActionInfo" in rf_payload_item:
        vallink = rf_payload_item['@Redfish.ActionInfo']
        success, rf_payload_action, code, elapsed = rst.callResourceURI(
            vallink)
        if not success:
            rf_payload_action = None

    # problem: if dne, skip
    if "Parameters" in profile_entry:
        innerDict = profile_entry["Parameters"]
        # problem: if dne, skip
        # assume mandatory
        for k in innerDict:
            item = innerDict[k]
            values_array = None
            if rf_payload_action is not None:
                action_by_name = rf_payload_action['Parameters']
                my_action = [x for x in action_by_name if x['Name'] == k]
                if my_action:
                    values_array = my_action[0].get('AllowableValues')
            if values_array is None:
                values_array = rf_payload_item.get(
                    str(k) + '@Redfish.AllowableValues', 'DNE')
            msg, success = validateRequirement(
                item.get('ReadRequirement', "Mandatory"), values_array)
            msgs.append(msg)
            msg.name = "{}.{}.{}".format(actionname, k, msg.name)
            if values_array == 'DNE':
                continue
            if "ParameterValues" in item:
                msg, success = validateSupportedValues(item["ParameterValues"],
                                                       values_array)
                msgs.append(msg)
                msg.name = "{}.{}.{}".format(actionname, k, msg.name)
            if "RecommendedValues" in item:
                msg, success = validateSupportedValues(
                    item["RecommendedValues"], values_array)
                msg.name = msg.name.replace('Supported', 'Recommended')
                if config['WarnRecommended'] and not success:
                    rsvLogger.warn(
                        '\tRecommended parameters do not all exist, escalating to WARN'
                    )
                    msg.success = sEnum.WARN
                elif not success:
                    rsvLogger.warn(
                        '\tRecommended parameters do not all exist, but are not Mandatory'
                    )
                    msg.success = sEnum.PASS

                msgs.append(msg)
                msg.name = "{}.{}.{}".format(actionname, k, msg.name)
    # consider requirement before anything else, what if action
    # if the action doesn't exist, you can't check parameters
    # if it doesn't exist, what should not be checked for action
    return msgs, counts
Exemplo n.º 6
0
def validateEntity(name: str,
                   val: dict,
                   propType: str,
                   propCollectionType: str,
                   schemaObj,
                   autoExpand,
                   parentURI=""):
    """
    Validates an entity based on its uri given
    """
    rsvLogger.debug('validateEntity: name = {}'.format(name))

    # check for required @odata.id
    if '@odata.id' not in val:
        if autoExpand:
            default = parentURI + '#/{}'.format(
                name.replace('[', '/').strip(']'))
        else:
            default = parentURI + '/{}'.format(name)
        rsvLogger.error(
            "{}: EntityType resource does not contain required @odata.id property, attempting default {}"
            .format(name, default))
        if parentURI == "":
            return False
        uri = default
    else:
        uri = val['@odata.id']
    # check if the entity is truly what it's supposed to be
    paramPass = False
    # if not autoexpand, we must grab the resource
    if not autoExpand:
        success, data, status, delay = rst.callResourceURI(uri)
    else:
        success, data, status, delay = True, val, 200, 0
    rsvLogger.debug(
        '(success, uri, status, delay) = {}, (propType, propCollectionType) = {}, data = {}'
        .format((success, uri, status, delay), (propType, propCollectionType),
                data))
    # if the reference is a Resource, save us some trouble as most/all basetypes are Resource
    generics = [
        'Resource.ItemOrCollection', 'Resource.ResourceCollection',
        'Resource.Item', 'Resource.Resource'
    ]
    if (propCollectionType in generics or propType in generics) and success:
        return True
    elif success:
        # Attempt to grab an appropriate type to test against and its schema
        # Default lineup: payload type, collection type, property type
        currentType = data.get('@odata.type', propCollectionType)
        if currentType is None:
            currentType = propType
        soup, refs = schemaObj.soup, schemaObj.refs
        baseLink = refs.get(
            rst.getNamespace(propCollectionType
                             if propCollectionType is not None else propType))
        # if schema in current schema, then use it
        #   elif namespace in References, use that
        #   else we have no lead
        if soup.find('Schema',
                     attrs={'Namespace':
                            rst.getNamespace(currentType)}) is not None:
            success, baseObj = True, schemaObj
        elif baseLink is not None:
            baseObj = schemaObj.getSchemaFromReference(
                rst.getNamespaceUnversioned(currentType))
            success = baseObj is not None
        else:
            success = False

        if not success:
            rsvLogger.error(
                "Schema of target {} not referenced in current resource, concluding type {} is not of expected type {}"
                .format(uri, currentType, propType))
        rsvLogger.debug('success = {}, currentType = {}, baseLink = {}'.format(
            success, currentType, baseLink))

        # Recurse through parent types, gather type hierarchy to check against
        if success and currentType is not None and baseObj.getTypeTagInSchema(
                currentType) is None and success:
            rsvLogger.error(
                '{}: Linked resource reports version {} not in Schema {}'.
                format(name.split(':')[-1], currentType, baseObj.origin))

        elif success and currentType is not None:
            currentType = currentType.replace('#', '')
            allTypes = []
            while currentType not in allTypes and success:
                allTypes.append(currentType)
                success, baseObj, currentType = baseObj.getParentType(
                    currentType, 'EntityType')
                rsvLogger.debug('success = {}, currentType = {}'.format(
                    success, currentType))

            rsvLogger.debug(
                'propType = {}, propCollectionType = {}, allTypes = {}'.format(
                    propType, propCollectionType, allTypes))
            paramPass = propType in allTypes or propCollectionType in allTypes
            if not paramPass:
                full_namespace = propCollectionType if propCollectionType is not None else propType
                rsvLogger.error(
                    '{}: Linked resource reports schema version (or namespace): {} not found in typechain'
                    .format(name.split(':')[-1], full_namespace))
        else:
            rsvLogger.error(
                "{}: Could not get schema file for Entity check".format(name))
    else:
        if "OriginOfCondition" in name:
            rsvLogger.verboseout(
                "{}: GET of resource at URI {} returned HTTP {}, but was a temporary resource."
                .format(
                    name, uri, status
                    if isinstance(status, int) and status >= 200 else "error"))
            return True

        else:
            rsvLogger.error(
                "{}: GET of resource at URI {} returned HTTP {}. Check URI.".
                format(
                    name, uri, status
                    if isinstance(status, int) and status >= 200 else "error"))
    return paramPass