Get Started

Get started with CASE using code examples.

Get Started with CASE

The full collection of libraries, tools, and documentation for CASE is available on the CASE GitHub repository. This guide walks through the anatomy of a CASE graph, full CASE example graph, and how to generate, validate, and query CASE graphs.

Disclaimer

Portions of this page contributed by NIST are governed by the following statement:

Participation by NIST in the creation of the documentation of mentioned software is not intended to imply a recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that any specific software is necessarily the best available for the purpose.

Anatomy of a CASE Graph

CASE uses JSON-LD which is JSON with linked relationships between objects within the JSON. It contains two top-level keys, @context and @graph. The @context key is a mapping of aliases and namespaces that point to namespaces within the UCO and CASE ontologies. The @graph key is an array/list of objects that represent the data being exchanged.

Each object within the @graph key is a JSON object (i.e., string-keyed dictionary), which contains at least an @id key that is a unique identifier for the object. The @type key is the aliased type of the object, using a reference for some class within the ontology compacted in line with the @context dictionary’s assistance. The available and required properties are defined in the ontology schema. A mimimal example is:

{
    "@context": {
        "kb": "http://example.org/kb/",
        "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/"
    },
    "@graph": {
        "@id": "kb:location-4511219e-a924-4ba5-aee7-dfad5a2c9c05",
        "@type": "uco-location:Location"
    }
}

This example demonstrates a few aspects of CASE and JSON-LD that are specialized over general JSON:

One characteristic of JSON-LD is that it is a concrete syntax for RDF. There are translation mechanisms that convert between various concrete syntaxes, which can serve as an elementary syntax check of JSON as JSON-LD. The example graph above encodes one statement - that there is a thing with ID kb:location-4511219e-..., and RDF-type uco-location:Location. A graph-consuming application could read a JSON-LD file and translate to confirm statements survive a load-save round-trip. For instance, here is the above graph in various other RDF syntaxes:

Full CASE Example Graph

A full (basic) example of a CASE JSON-LD output is below:

{
    "@context": {
        "@vocab": "http://example.org/local#",
        "kb": "http://example.org/kb/",
        "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
        "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/",
        "xsd": "http://www.w3.org/2001/XMLSchema#"
    },
    "@graph": [
        {
            "@id": "kb:location-4511219e-a924-4ba5-aee7-dfad5a2c9c05",
            "@type": "uco-location:Location",
            "uco-core:hasFacet": [
                {
                    "@id": "kb:simple-address-facet-59334948-00b9-4370-85b0-4dc8e07f5384",
                    "@type": "uco-location:SimpleAddressFacet",
                    "uco-location:locality": "Seattle",
                    "uco-location:region": "WA",
                    "uco-location:postalCode": "98052",
                    "uco-location:street": "20341 Whitworth Institute 405 N. Whitworth"
                }
            ]
        },
        {
            "@id": "kb:location-b579264d-6e30-4055-bf9b-72390364f224",
            "@type": "uco-location:Location",
            "uco-core:hasFacet": [
                {
                    "@id": "kb:simple-address-facet-258f169e-1e9c-4936-ba65-eed0f0c60788",
                    "@type": "uco-location:SimpleAddressFacet",
                    "uco-location:locality": "Paris",
                    "uco-location:country": "France",
                    "uco-location:postalCode": "F-75002",
                    "uco-location:street": "38 Bad Guy Headquarters st."
                },
                {
                    "@id": "kb:lat-long-coordinates-facet-36126f9c-0273-48fe-ad4d-6a4e2848458f",
                    "@type": "uco-location:LatLongCoordinatesFacet",
                    "uco-location:latitude": {
                        "@type": "xsd:decimal",
                        "@value": "48.860346"
                    },
                    "uco-location:longitude": {
                        "@type": "xsd:decimal",
                        "@value": "2.331199"
                    }
                }
            ]
        }
    ]
}

The same graph reads as follows in alternate syntaxes:

Additional examples are available in the CASE-Examples repository. This example was copied from here.

Basic Graph Creation

Validation Tools

CLI

Once the JSON-LD output is generated, it can be validated for syntactic correctness using the case_validate tool. The tool is available as a Python package and can be installed using pip install case-utils.

pip install case-utils

Then the tool can be run on the generated JSON-LD file which will output any errors or warnings.

case_validate case.jsonld

Docker

The case_validate tool is also available as a Docker image on Docker Hub. The container can be run with the following command:

docker run --rm \
	-e CASE_PATH="/opt/case/" \
	-e CASE_VERSION="case-1.3.0" \
	-e CASE_EXTENSION_FILTER="jsonld" \
	-v "/path/to/local:/opt/case" \
	kchason/case-validator:latest

Full usage documentation is available at the kchason/case-validator Docker Hub page.

GitHub Actions

There is a GitHub Action available to validate CASE graphs in a CI/CD pipeline that are wrappers around the case_validate tool which makes it easier to test built graphs from unit and integrated testing frameworks.

- name: CASE Export Validation
  uses: kchason/case-validation-action@v2.9.0
  with:
    case-path: ./output/
    case-version: "case-1.3.0"
    extension-filter: "jsonld"

Full usage documentation is available at the GitHub Action Marketplace page for the CASE Ontology Validator.

GitLab CI Component

There is also GitLab CI component available to validate CASE graphs in a CI/CD pipeline that are wrappers around the case_validate tool which makes it easier to test built graphs from unit and integrated testing frameworks.

include:
  - component: https://gitlab.com/keith.chason/case-validation-example/case-validate@0.1.0
    inputs:
      case-path: tests/data

Full usage documentation is available at the GitLab Repository.

Graph Creation Resources

Several libraries and repositories have been developed to assist in the generation of CASE graphs in various programming languages. These libraries provide a more programmatic way to generate CASE graphs using the language’s native data structures. These have been categorized between “Bindings” and “Mappings”.

Separately, a template repository is available that provides a demonstration command line utility and build system. This template repository happens to use a Python community graph-library instead of language primitives, but if the bindings or mappings are favored by a developer, the template’s build system provides other test infrastructure that is independently assistive.

Bindings

These libraries use RDF graphs to manage the CASE graph data. They provide a more direct mapping to the RDF data model and are more closely aligned with the underlying ontology but can be more resource intensive.

Language Library Repository
C# CipherTech.CASE.Bindings https://github.com/ciphertechsolutions/CASE-Bindings-CSharp

Mappings

These libraries use native data structures to manage the CASE graph data. They provide a more programmatic way to generate CASE graphs using the language’s native data structures and are then serialized into JSON-LD.

Language Library Repository
Python case-mapping https://github.com/casework/CASE-Mapping-Python

Application template

CASE provides a Python application template repository that is one potential style of starting an application. Lessons learned within the CDO community in maintaining Python repositories are implemented in the template.

Full CASE Concepts

The rendered documentation for the CASE Ontology, which contains the list of all classes and properties, is available at https://ontology.caseontology.org.

All of the concepts used in CASE and UCO are identified with IRIs, which redirect to the concept’s documentation when visited in a browser. See for example the location classes used above:

JSON-LD Stubs

Classes in CDO also have “empty” JSON-LD files, sometimes referred to as “stubs,” generated to show the properties available in them. These stubs assist with showing the properties provided by parent classes, and hinting at the available cardinalities (e.g., a property with none following has a maximum cardinality of 1, while a property with an empty array following has an unbounded maximum cardinality). The files are “empty” graphs because each of the statements is incomplete - the none and [] JSON values are absent information as JSON-LD, and thus would not load in an RDF application.

The classes above have these available stubs:

To assist with recalling Facets available to each of the UcoObject subclasses, the stubs also carry Facet suggestions from parent classes. If some Facet happens to have no information available in an application, it is not necessary to specify the Facet.

See for instance:

Query CASE Graphs

A frequent use-case for RDF is graph querying. JSON-LD users have access to querying using the SPARQL query language. For instance, the following query can be used to find all street addresses of locations in the knowledge base. Because these addresses are properties tied to a uco-location:Location object, at times, there may be a linked latitude/longitude pair. This query will find all street addresses, and will optionally find associated latitude/longitude coordinate pairs.

PREFIX uco-location: <https://ontology.unifiedcyberontology.org/uco/location/>
PREFIX uco-core: <https://ontology.unifiedcyberontology.org/uco/core/>

SELECT ?lStreet ?lLatitude ?lLongitude
WHERE
{
    ?nLocation
        a uco-location:Location ;
        uco-core:hasFacet ?nSimpleAddressFacet ;
        .
    ?nSimpleAddressFacet
        a uco-location:SimpleAddressFacet ;
        uco-location:street ?lStreet ;
        .
    
    OPTIONAL {
        ?nLocation uco-core:hasFacet ?nLatLongCoordinatesFacet .
        ?nLatLongCoordinatesFacet
            a uco-location:LatLongCoordinatesFacet ;
            uco-location:latitude ?lLatitude ;
            uco-location:longitude ?lLongitude ;
            .
    }
}
ORDER BY ?lStreet

Run against the example location graph above, this query returns the following results:

  ?lStreet ?lLatitude ?lLongitude
0 20341 Whitworth Institute 405 N. Whitworth    
1 38 Bad Guy Headquarters st. 48.860346 2.331199

CASE provides a command-line tool alongside case_validate, case_sparql_select, which can run a SPARQL query against one or more graph files. The command is documented here. The above table was generated through a command-line session similar to this one:

python3 -m venv venv
source .../venv/bin/activate
pip install case-utils
case_sparql_select out.md query.sparql example.jsonld

Programming languages will often have libraries available to run SPARQL queries against loaded graphs. The following examples show how to load a graph file and run a query similar to the query above, but that just gets the street addresses.

Note that SPARQL’s syntactic similarities with Turtle extend to subject-sharing in statements. Though the queries have a different number of words per line, they achieve the same pattern matching pertaining to finding street addresses.

A full set of examples for querying CASE graphs and converting them to a GeoJSON output format in several programming languages is available in the CASE-Examples-Conversion repository.