Class OpenApiSyncPlanner

java.lang.Object
org.mockserver.openapi.OpenApiSyncPlanner

public final class OpenApiSyncPlanner extends Object
Pure-function helper for incremental OpenAPI sync: given the set of existing expectation ids, the set of newly-generated ids, and the namespace prefixes that the new generation covers, determines which existing ids should be pruned.

An existing id is pruned iff it starts with one of the namespace prefixes AND is not in the new id set. This ensures that re-importing a spec updates expectations in place and removes operations no longer present, without affecting expectations from other specs or manually created expectations.

  • Field Details

    • OPENAPI_ID_PREFIX

      public static final String OPENAPI_ID_PREFIX
      Prefix used for all OpenAPI-generated expectation ids.
      See Also:
  • Method Details

    • idsToPrune

      public static Set<String> idsToPrune(Collection<String> existingIds, Collection<String> newIds, Collection<String> namespacePrefixes)
      Computes the set of existing expectation ids that should be removed (pruned) during an incremental OpenAPI sync.
      Parameters:
      existingIds - all currently active expectation ids
      newIds - ids generated from the newly-imported spec(s)
      namespacePrefixes - the "openapi:<specKey>:" prefixes covered by this import batch
      Returns:
      the ids to remove — a subset of existingIds
    • deriveSpecKey

      public static String deriveSpecKey(String title, String specUrlOrPayload)
      Derives a stable, collision-resistant spec key for the OpenAPI namespace.

      The key is <sanitizedTitle>_<shortHash> (or just <shortHash> when the title is blank), where the hash is taken over the spec source identity rather than the human title alone. This is the critical correctness property: two different specs that happen to share the same info.title must never collide into the same namespace, otherwise importing one would prune/overwrite the other's expectations (cross-spec data loss).

      Identity semantics by source kind

      • URL / file reference (OpenAPIParser.isSpecUrl(java.lang.String) is true): the source reference string is the stable identity. Re-importing the same URL yields the same key (so incremental sync keeps pruning removed operations) while a different URL yields a different key.
      • Inline payload: the payload content is the identity. Re-importing the byte-identical payload yields the same key (incremental sync still works for the unchanged-payload case); editing the payload changes the key, so the previous version's stale operations are NOT pruned on edit — they simply become orphaned under the old namespace. This trade-off is deliberate: collision-resistance (no cross-spec deletion) outranks pruning-on-inline-edit. Callers that need clean incremental sync of an evolving spec should reference it by URL/file.
      Parameters:
      title - the parsed openAPI.getInfo().getTitle(), may be null/blank
      specUrlOrPayload - the raw spec URL/file reference or inline payload (the source identity)
      Returns:
      a non-null, collision-resistant spec key safe for use as a namespace token
    • specKeyFromTitle

      public static String specKeyFromTitle(String title)
      Derives the human-readable portion of a spec key from an OpenAPI title. The title is lowercased and every non-alphanumeric character is replaced with '_'.

      NOTE: a title alone is NOT a safe namespace — distinct specs can share a title. Use deriveSpecKey(String, String) for the full collision-resistant key.

      Parameters:
      title - the parsed openAPI.getInfo().getTitle(), may be null/blank
      Returns:
      sanitized key, or null if the title is blank
    • specKeyFromHash

      public static String specKeyFromHash(String specUrlOrPayload)
      Derives a stable spec key by hashing the spec payload/URL source identity. Returns a short 16-character hex hash suitable for use as a namespace token.

      The same input always yields the same hash (so re-importing the same source re-targets the same namespace); different inputs yield different hashes with high probability (so distinct sources get distinct namespaces).

      Parameters:
      specUrlOrPayload - the raw spec URL or inline payload
      Returns:
      a 16-character lowercase hex string
    • namespacePrefix

      public static String namespacePrefix(String specKey)
      Builds the namespace prefix for a given spec key, i.e. "openapi:<specKey>:".
      Parameters:
      specKey - the sanitized spec key (from title or hash)
      Returns:
      the namespace prefix string