Skip to content

Commit

Permalink
Added TestExport and SchemaExport to avoid creating unstructured json,
Browse files Browse the repository at this point in the history
fixes #860
  • Loading branch information
stalep committed Feb 6, 2024
1 parent 6ccae8b commit cb16294
Show file tree
Hide file tree
Showing 32 changed files with 836 additions and 542 deletions.
64 changes: 64 additions & 0 deletions docs/site/content/en/docs/Tasks/import-export/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Import and Export Tests and Schemas
date: 2023-11-30
description: How to import and export Tests and Schemas in Horreum
categories: [Tutorial]
weight: 3
---

> **Prerequisites**:
> 1. Horreum is running
> 2. To export you have previously defined a `Schema` for the JSON data you wish to analyze, please see [Define a Schema](/docs/tasks/define-schema-and-views/)
> 3. To export you have previously defined a Test, please see [Create new Test](/docs/tasks/create-new-test/)
## Background

To simplify copying [Tests](https://horreum.hyperfoil.io/docs/concepts/core-concepts/#test) and [Schemas](https://horreum.hyperfoil.io/docs/concepts/core-concepts/#schema) between Horreum instances Horreum provides a simple API to export and import new Tests and Schemas. Horreum also support updating exising Schemas and Tests by importing Tests or Schemas with existing Id's.

## TestExport

The export object for Tests is called [TestExport](https://horreum.hyperfoil.io/openapi/#tag/Test/operation/importTest) and contains a lot of other fields in addition to what's defined in [Test](https://horreum.hyperfoil.io/docs/concepts/core-concepts/#test). This includes, variables, experiments, actions, subscriptions, datastore and missingDataRules. This is to simplify the import/export experience and make sure that all the data related to a Test has a single entrypoint with regards to import and export. Note that secrets defined on [Action](https://horreum.hyperfoil.io/docs/tasks/configure-actions/) are not portable between Horreum instances and there might be security concerns so they are omitted. The apiKey and password attributs defined on the config field in [Datastore](https://horreum.hyperfoil.io/docs/integrations/) are also omitted and will have to be manually added in a separate step.

## TestSchema

The export object for Schemas is called [SchemaExport](https://horreum.hyperfoil.io/openapi/#tag/Schema/operation/importSchema) and contains other fields in addition to what's defined in [Schema](https://horreum.hyperfoil.io/docs/concepts/core-concepts/#schema). This includes, labels, extractors and transformers. This is to simplify the import/export experience and make sure that all the data related to a Schema has a single entrypoint with regards to import and export.

## Import Schemas

```bash
curl 'http://localhost:8080/api/schema/import/' \
-s -X POST -H 'content-type: application/json' \
-H 'Authorization: Bearer '$TOKEN \
-d @/path/to/schema.json
```

If you are unfamiliar with creating the auth token please see [Upload Run](/docs/tasks/upload-new-run/).

## Import Tests

```bash
curl 'http://localhost:8080/api/test/import/' \
-s -X POST -H 'content-type: application/json' \
-H 'Authorization: Bearer '$TOKEN \
-d @/path/to/test.json
```

## Export Schemas

```bash
SCHEMAID='123'
curl 'http://localhost:8080/api/schema/export/?id='$SCHEMAID \
-H 'Authorization: Bearer '$TOKEN \
-O --output-dir /path/to/folder
```

## Export Tests

```bash
TESTID='123'
curl 'http://localhost:8080/api/test/export/?id=$TESTID' \
-s -X POST -H 'content-type: application/json' \
-H 'Authorization: Bearer '$TOKEN \
-O --output-dir /path/to/folder
```
224 changes: 213 additions & 11 deletions docs/site/content/en/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1355,16 +1355,18 @@ paths:
post:
tags:
- Schema
description: Import an previously exported Schema
description: Import an previously exported Schema either as a new Schema or
to update an existing Schema
operationId: importSchema
requestBody:
content:
application/json:
schema:
type: string
$ref: '#/components/schemas/SchemaExport'
required: true
responses:
"201":
description: Created
"204":
description: Import a new Schema or update an existing Schema
/api/schema/{id}:
get:
tags:
Expand Down Expand Up @@ -1449,11 +1451,11 @@ paths:
example: 101
responses:
"200":
description: A JSON representation of the Schema object
description: A JSON representation of the SchemaExport object
content:
application/json:
schema:
type: string
$ref: '#/components/schemas/SchemaExport'
/api/schema/{id}/resetToken:
post:
tags:
Expand Down Expand Up @@ -1780,16 +1782,18 @@ paths:
post:
tags:
- Test
description: Import a previously exported Test
description: Import a previously exported Test either as a new Test or to update
an existing Test
operationId: importTest
requestBody:
content:
application/json:
schema:
type: string
$ref: '#/components/schemas/TestExport'
required: true
responses:
"204":
description: Import a new test
description: Import a new Test or update an existing Test
/api/test/summary:
get:
tags:
Expand Down Expand Up @@ -1898,11 +1902,11 @@ paths:
type: integer
responses:
"200":
description: A Test defintion formatted as json
description: A Test definition formatted as json
content:
application/json:
schema:
type: string
$ref: '#/components/schemas/TestExport'
/api/test/{id}/fingerprint:
get:
tags:
Expand Down Expand Up @@ -2174,6 +2178,41 @@ components:
- PROTECTED
- PRIVATE
type: string
Action:
required:
- id
- event
- type
- config
- testId
- active
- runAlways
type: object
properties:
id:
format: int32
type: integer
event:
type: string
nullable: false
type:
type: string
nullable: false
config:
type: array
nullable: false
testId:
format: int32
type: integer
nullable: false
active:
type: boolean
nullable: false
runAlways:
type: boolean
nullable: false
secrets:
type: array
ActionLog:
description: Action Log
required:
Expand All @@ -2199,6 +2238,21 @@ components:
- SAME
- WORSE
type: string
ChangeDetection:
required:
- id
- model
- config
type: object
properties:
id:
format: int32
type: integer
model:
type: string
config:
type: array
nullable: false
ComparisonResult:
description: Result of performing a Comparison
type: object
Expand Down Expand Up @@ -2551,6 +2605,8 @@ components:
- POSTGRES
- ELASTICSEARCH
type: string
example: ELASTICSEARCH
nullable: false
ElasticsearchDatastoreConfig:
description: Type of backend datastore
required:
Expand Down Expand Up @@ -2981,6 +3037,34 @@ components:
\ array or JSON object"
type: string
example: "1724"
MissingDataRule:
required:
- id
- maxStaleness
- testId
type: object
properties:
id:
format: int32
type: integer
name:
type: string
labels:
type: array
items:
type: string
condition:
type: string
maxStaleness:
format: int64
type: integer
nullable: false
lastNotification:
format: date-time
type: string
testId:
format: int32
type: integer
PersistentLog:
description: Persistent Log
required:
Expand Down Expand Up @@ -3487,6 +3571,23 @@ components:
type: string
example: uri:my-schmea:0.1
nullable: false
SchemaExport:
description: Represents a Schema with all associated data used for export/import
operations.
type: object
allOf:
- $ref: '#/components/schemas/Schema'
properties:
labels:
description: Array of Labels associated with schema
type: array
items:
$ref: '#/components/schemas/Label'
transformers:
description: Array of Transformers associated with schema
type: array
items:
$ref: '#/components/schemas/Transformer'
SchemaQueryResult:
required:
- schemas
Expand Down Expand Up @@ -3964,6 +4065,41 @@ components:
type: boolean
example: true
nullable: false
TestExport:
description: Represents a Test with all associated data used for export/import
operations.
type: object
allOf:
- $ref: '#/components/schemas/Test'
properties:
variables:
description: Array of Variables associated with test
type: array
items:
$ref: '#/components/schemas/Variable'
missingDataRules:
description: Array of MissingDataRules associated with test
type: array
items:
$ref: '#/components/schemas/MissingDataRule'
experiments:
description: Array of ExperimentProfiles associated with test
type: array
items:
$ref: '#/components/schemas/ExperimentProfile'
actions:
description: Array of Actions associated with test
type: array
items:
$ref: '#/components/schemas/Action'
subscriptions:
allOf:
- $ref: '#/components/schemas/Watch'
- description: Watcher object associated with test
datastore:
allOf:
- $ref: '#/components/schemas/Datastore'
- description: Datastore associated with test
TestListing:
type: object
properties:
Expand Down Expand Up @@ -4207,6 +4343,43 @@ components:
allOf:
- $ref: '#/components/schemas/ErrorDetails'
- description: Validation Error Details
Variable:
required:
- id
- testId
- name
- order
- labels
- changeDetection
type: object
properties:
id:
format: int32
type: integer
testId:
format: int32
type: integer
nullable: false
name:
type: string
nullable: false
group:
type: string
order:
format: int32
type: integer
nullable: false
labels:
type: array
items:
type: string
nullable: false
calculation:
type: string
changeDetection:
type: array
items:
$ref: '#/components/schemas/ChangeDetection'
VersionInfo:
required:
- version
Expand All @@ -4223,3 +4396,32 @@ components:
description: Timestamp of server startup
type: integer
example: 2023-10-18 18:00:57
Watch:
required:
- users
- optout
- teams
- testId
type: object
properties:
id:
format: int32
type: integer
users:
type: array
items:
type: string
nullable: false
optout:
type: array
items:
type: string
nullable: false
teams:
type: array
items:
type: string
nullable: false
testId:
format: int32
type: integer
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.validation.constraints.NotNull;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

public class ChangeDetection {
@JsonProperty( required = true )
Expand Down
Loading

0 comments on commit cb16294

Please sign in to comment.