Skip to content

Latest commit

 

History

History

library

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Spec Math Library

A library for performing operations on OpenAPI specifications.

About this document

This document contains information about using the Spec Math Library. For a description of Spec Math itself, please see the README at the root of the repository.

Running tests

Run mvn test to execute all of the tests.

Usage

This library supports performing Spec Math Operations on OpenAPI Specifications represented as YAML strings. The SpecMath class contains static functions which can be called on OpenAPI specifications. The most common use case of this library will be to call the functions provided in the SpecMath class, although more advanced usage is possible by using the underlying classes. For some examples of inputs and outputs to this class, please see The tests for the SpecMath class or the guide below.

Performing Spec Math Operations

For descriptions of these operations, please see the root of the repository.

Union

Of Two or More Specs

The union function can be called on a list of specs or spec fragments. For example:

String spec1 = Files.readString(Path.of("src/test/resources/noConflict1.yaml"));
String spec2 = Files.readString(Path.of("src/test/resources/noConflict2.yaml"));
String spec3 = Files.readString(Path.of("src/test/resources/noConflict3.yaml"));

var listOfSpecs = new ArrayList<String>();
listOfSpecs.add(spec1);
listOfSpecs.add(spec2);
listOfSpecs.add(spec3);

return SpecMath.union(listOfSpecTrees);

There is also a convenient function provided for performing union on just two specs:

String spec1 = Files.readString(Path.of("src/test/resources/noConflict1.yaml"));
String spec2 = Files.readString(Path.of("src/test/resources/noConflict2.yaml"));

SpecMath.union(spec1, spec2)
With UnionOptions

UnionOptions is a way to provide additional options to perform during the union. It is built using the desired options and then provided to the union function as a parameter.

Once you have built your UnionOptions (see the following sections for more details), simply supply it as a second argument to union like so:

UnionOptions unionOptions = //... see following sections for more details
return SpecMath.union(listOfSpecs, unionOptions);

You can use all or some of the options:

defaults

Please feel free to read more about defaults files here.

To build the UnionOptions with your defaults file:

String defaults = Files.readString(Path.of("src/test/resources/conflictDefaults.yaml"));

UnionOptions unionOptions =
    UnionOptions.builder()
        .defaults(defaults)
        .build();

conflictResolutions

If conflicts occurred during the process of the union, there are several ways to resolve them as further described here. One method is to provide a conflictResolutions string (sample) through UnionOptions. If a conflict arises, a UnionConflictException (e) will be thrown. At that point, you may inspect the conflicts with e.getConflicts(). A conflictResolutions file template may be created by simply serializing the result of e.getConflicts():

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();

mapper
  .writerWithDefaultPrettyPrinter()
  .writeValue(new File(conflictsFilename), e.getConflicts());

You will then need to modify the resolvedValue properties for each conflict in the file you just created to indicate your conflict resolutions.

Note: you can also modify the resolvedValues by setting them programmatically in the conflict objects themselves.

Finally, to build the UnionOptions with your conflict resolutions string:

String conflictResolutions = Files.readString(Path.of(conflictsFilename));

UnionOptions unionOptions =
    UnionOptions.builder()
        .conflictResolutions(conflictResolutions)
        .build();

Using multiple options

You may add multiple options by chaining them like so:

String defaults = Files.readString(Path.of("src/test/resources/conflictDefaults.yaml"));
String conflictResolutions = Files.readString(Path.of("src/test/resources/conflictMerged.yaml"));

UnionOptions unionOptions =
    UnionOptions.builder()
        .defaults(defaults)
        .conflictResolutions(conflictResolutions)
        .build();

Overlay

To apply an overlay on top of a spec, just call the applyOverlay function like so:

String spec1String = Files.readString(Path.of("src/test/resources/petstoreMarketing.yaml"));
String overlay = Files.readString(Path.of("src/test/resources/petstoreMetadata.yaml"));
return SpecMath.applyOverlay(overlay, spec1String);

Note that if you would like to overlay a set of metadata to a result spec after a union or a filter, you may also consider using a defaults file through either UnionOptions or FilterOptions instead, discussed above and below.

Filter

The filter operation requires a spec and a filter (either as a file or a list of FilterCriteria objects), with optional FilterOptions.

A filter file contains a list of objects which have some or all of the properties in the FilterCriteria class. The properties to filter on which are currently supported are also described here. You may provide all or some of the properties for each list item of the filter file. Each list item will independently produce a subset of the input spec, and the union of all of these subsets will be returned. For some small examples of filter files, please see the JSON files in this directory.

String specString =
    Files.readString(Path.of("src/test/resources/filtering/filteringMonolithicSpec.yaml"));
String filterCriteria =
    Files.readString(Path.of("src/test/resources/filtering/specificPathFilterCriteria.json"));
return SpecMath.filter(specString, filterCriteria);

Note: instead of having to create a file to perform the filter, you may also provide a list of FilterCriteria objects instead.

With FilterOptions

FilterOptions is a way to provide additional options to perform during or after the filter. It is built using the desired options and then provided to the filter function as a parameter.

Once you have built your FilterOptions (see the following sections for more details), simply supply it as a third argument to filter like so:

FilterOptions filterOptions = //... see following sections for more details
return SpecMath.filter(specString, filterFile, filterOptions);

You can use the following option:

defaults

Please feel free to read more about defaults files here.

To build the FilterOptions with your defaults file:

String defaults = Files.readString(Path.of("src/test/resources/petstoreMetadata.yaml"));
FilterOptions filterOptions = FilterOptions.builder().defaults(defaults).build();