Ejemplo n.º 1
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                ?s a proms:ExternalReport .
                ?s proms:startingActivity ?sa .
                ?s proms:endingActivity ?sa .
            }
            ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report does not contain a single Activity indicated as both the starting and ending Activity'
            )

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Single Activity',
            'The Report has the same starting & ending Activity',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 2
0
    def __init__(self, request):
        self.passed = True
        self.fail_reasons = []

        body = request.data  # don't use request.content as Flask can't handle the text/uri-list mimetype

        # if content-length zero, don't allow content
        if int(request.headers.get('Content-Length')) == 0 and len(str(body).strip()) > 0:
            self.fail_reasons.append(
                'The Content-Length header indicates no content and yet there is body content')

        # if content, it needs to be a linbreak list of URIs only
        for line in body.split('\n'):
            if not self.is_a_uri(line.strip()):
                self.fail_reasons.append(
                    'The line {} is not a valid URI'.format(line))

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'PROV-AQ Body',
            'The pingback must have a valid PROV-AQ-specified body',
            'PROV-AQ',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 3
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        # to get to this rule, the PingbackDeclaration Rule must already have passed which means that there is at least
        # one Entity which has a prov:pingback property
        q = '''
        PREFIX prov: <http://www.w3.org/ns/prov#>
        ASK
        WHERE {
            ?e prov:pingback ?pb .
            {?a prov:generated ?e . }
            UNION
            {?e prov:wasGeneratedBy ?a . }
        }
        '''
        qres = g.query(q)
        if bool(qres):
            self.passed = False
            self.fail_reasons.append(
                'R3: Pingbacks cannot be sent for Entities declared as prov:wasGeneratedBy or prov:wasDerivedFrom in '
                'the pingbacked graph')

        Rule.__init__(
            self,
            'Pingback Declaration',
            'Entities being pingbacked for must be prov:used in the pingback graph',
            'PROV-AQ',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 4
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            ASK
            WHERE {
                ?s a proms:InternalReport .
                ?s proms:startingActivity ?sa .
                ?s proms:endingActivity ?ea .
                FILTER (?sa != ?ea)
            }
            ''')

        if not bool(q):
            self.fail_reasons.append(
                'The Report does not contain at least two different Activities '
                'indicated by the starting and ending Activity')

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Single Activity',
            'The Report has the different starting & ending Activities',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 5
0
    def __init__(self, g, pingback_endpoint):
        self.passed = True
        self.fail_reasons = []
        q = '''
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                ?e  a prov:Entity ;
                    prov:pingback <%s> .
            }
        ''' % pingback_endpoint

        qres = g.query(q)
        if not bool(qres):
            self.passed = False
            self.fail_reasons.append(
                'R2: No prov:Entity contains a prov:pingback property pointing to {}'
                .format(pingback_endpoint))

        Rule.__init__(
            self,
            'Pingback Declaration',
            'At least one prov:Entity (or subclass) must declare a prov:pingback property with the pingback target URI '
            'as its range value (object).',
            'PROV-AQ',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 6
0
    def __init__(self, report_graph):
        self.passed = True
        self.fail_reasons = []
        self.components_total_count = 1
        self.components_failed_count = 0

        q = ''' PREFIX proms: <http://promsns.org/def/proms#>
                PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
                ASK
                WHERE {
                    ?s  a           proms:ReportingSystem .
                    ?s  rdfs:label  ?t .
                }
            '''
        qr = report_graph.query(q)
        if not bool(qr):
            self.passed = False
            self.fail_reasons.append(
                'The Reporting System class does not contain an rdfs:label')

        # Rule constructor
        Rule.__init__(
            self, 'Has a Label', 'PROMS-O',
            'Reporting System must have a label, as defined in the PROMS ontology',
            self.passed, self.fail_reasons, 1, 0)
Ejemplo n.º 7
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                { ?s  a            proms:Report .}
                UNION
                { ?s  a            proms:BasicReport .}
                UNION
                { ?s  a            proms:ExternalReport .}
                UNION
                { ?s  a            proms:InternalReport .}
                ?s  proms:startingActivity  ?rs .
                ?rs a prov:Activity .
            }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not contain a proms:startingActivity')

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                { ?s  a            proms:Report .}
                UNION
                { ?s  a            proms:BasicReport .}
                UNION
                { ?s  a            proms:ExternalReport .}
                UNION
                { ?s  a            proms:InternalReport .}
                ?s  proms:endingActivity  ?rs .
                ?rs a prov:Activity .
            }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not contain a proms:endingActivity')

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Start End Activities',
            'The report has starting & ending Activities',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            2,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 8
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                ?s a proms:ExternalReport .
                ?s proms:startingActivity ?act .
                ?act prov:used ?e1.
                ?e1 a prov:Entity.
            }
            ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report\'s Activity does not use any Entities')

        q = g.query('''
            PREFIX proms: <http://promsns.org/def/proms#>
            PREFIX prov: <http://www.w3.org/ns/prov#>
            ASK
            WHERE {
                ?s a proms:ExternalReport .
                ?s proms:startingActivity ?act .
                ?act prov:generated ?e1.
                ?e1 a prov:Entity.
            }
            ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report\'s Activity does not generate any Entities')

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Activity Entities',
            'The report\'s Activity has at least one prov:used and one prov:generated Entity',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            2,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 9
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []
        reporting_system_uri = None

        # get the ReportingSystem URI
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        SELECT ?rs
        WHERE {
            ?r proms:wasReportedBy ?rs .
        }
        ''')
        for r in q:
            reporting_system_uri = str(r['rs'])

        # check to see if this ReportingSystem already exists in the provenance _database
        q = '''
            PREFIX proms: <http://promsns.org/def/proms#>
            ASK
            WHERE { GRAPH ?g {
                <%(reporting_system_uri)s> ?p proms:ReportingSystem .
            }}
        ''' % {
            'reporting_system_uri': reporting_system_uri
        }
        if not queries.query(q)['boolean']:
            self.fail_reasons.append(
                'The Report does not refer to an existing ReportingSystem within the '
                'provenance _database')
            self.passed = False

        Rule.__init__(
            self,
            'Report\'s Reporting System',
            'Reports can only be lodged for ReportingSystems already in the provenance _database',
            'PROMS system',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 10
0
    def __init__(self, request):
        self.passed = True
        self.fail_reasons = []

        # not valid if Content-Type not set to text/uri-list
        if request.headers.get('Content-Type') != 'text/uri-list':
            self.fail_reasons.append(
                'The pingback message must have a content-type of \'text/uri-list\' defined in the HTTP header'
            )

        # not valid if no Link header set and Content-Length == 0
        if not request.headers.get('Link') and int(
                request.headers.get('Content-Length')) == 0:
            self.fail_reasons.append(
                'The pingback message must have either a non-zero Content-Length or a Link header set'
            )

        # validate each PROV-AQ Link header
        if request.headers.get('Link'):
            for link_header in request.headers.get('Link').split(','):
                link_header_valid = self.valid_provaq_link_header(
                    link_header.strip())
                if not link_header_valid[0]:
                    self.fail_reasons.append(
                        'The Link header "{}" is not valid: {}'.format(
                            link_header, ', '.join(link_header_valid[1])))

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'PROV-AQ Header',
            'The pingback must have a valid PROV-AQ-specified header',
            'PROV-AQ',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 11
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        qres = g.query('''
            PREFIX prov: <http://www.w3.org/ns/prov#>
            PREFIX proms: <http://promsns.org/def/proms#>
            ASK
            WHERE {
                ?s a proms:InternalReport .
                ?s proms:startingActivity ?sa .
                ?sa prov:startedAtTime ?sasat .
                ?s proms:endingActivity ?ea .
                ?ea prov:startedAtTime ?easat .
                FILTER (?sasat < ?easat)
            }
            ''')

        if not bool(qres):
            self.fail_reasons.append(
                'The Report\'s starting Activity doesn\'t start before its ending Activity starts'
            )

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Starting Ending Activity',
            'The starting Activity of the Report must start before the Ending Activity starts',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 12
0
    def __init__(self, request):
        self.passed = True
        self.fail_reasons = []

        # must be an RDF content type
        rdf_content_types = [
            'text/turtle', 'text/ntriples', 'text/n3', 'application/rdf+xml',
            'application/ld+json'
        ]
        if request.headers.get('Content-Type') not in rdf_content_types:
            self.passed = False
            self.fail_reasons.append(
                'PROMS pingback messages must have an RDF Content-Type')

        Rule.__init__(
            self,
            'PROMS pingback header',
            'The pingback must have a valid PROMS-specified header',
            'PROVMS-O Pingbacks',
            self.passed,
            self.fail_reasons,
            1,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )
Ejemplo n.º 13
0
    def __init__(self, g):
        self.passed = True
        self.fail_reasons = []

        # has a Report class
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        SELECT ?s
        WHERE {
            { ?s  a            proms:Report .}
            UNION
            { ?s  a            proms:BasicReport .}
            UNION
            { ?s  a            proms:ExternalReport .}
            UNION
            { ?s  a            proms:InternalReport .}
        }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The report does not contain a Report class or subclass')

        # has a label
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
        SELECT ?s
        WHERE {
            { ?s  a            proms:Report .}
            UNION
            { ?s  a            proms:BasicReport .}
            UNION
            { ?s  a            proms:ExternalReport .}
            UNION
            { ?s  a            proms:InternalReport .}
            ?s  rdfs:label     ?label .
        }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not contain an rdfs:label')

        # has a nativeId
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        SELECT ?s
        WHERE {
            { ?s  a            proms:Report .}
            UNION
            { ?s  a            proms:BasicReport .}
            UNION
            { ?s  a            proms:ExternalReport .}
            UNION
            { ?s  a            proms:InternalReport .}
            ?s  proms:nativeId  ?j .
        }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not contain a proms:nativeId')

        # has a ReportingSystem
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        SELECT ?s
        WHERE {
            { ?s  a            proms:Report .}
            UNION
            { ?s  a            proms:BasicReport .}
            UNION
            { ?s  a            proms:ExternalReport .}
            UNION
            { ?s  a            proms:InternalReport .}
            ?s  proms:wasReportedBy  ?rs .
        }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not indicate which ReportingSystem reported it with a '
                'proms:wasReportedBy property')

        # has a generatedAtTime
        q = g.query('''
        PREFIX proms: <http://promsns.org/def/proms#>
        PREFIX prov: <http://www.w3.org/ns/prov#>
        ASK
        WHERE {
            { ?s  a            proms:Report .}
            UNION
            { ?s  a            proms:BasicReport .}
            UNION
            { ?s  a            proms:ExternalReport .}
            UNION
            { ?s  a            proms:InternalReport .}
            ?s prov:generatedAtTime ?t .
        }
        ''')
        if not bool(q):
            self.fail_reasons.append(
                'The Report class does not contain a prov:generatedAtTime value'
            )

        # determine passed due to any fail_reasons
        # if there are any failure reasons it means it's failed
        if self.fail_reasons:
            self.passed = False

        Rule.__init__(
            self,
            'Report Class properties',
            'Reports Class objects must contain certain properties set out in the PROMS Ontology',
            'PROMS Ontology',
            self.passed,
            self.fail_reasons,
            5,  # the number of individual tests
            len(self.fail_reasons)  # the number of tests failed
        )