Fix #10382 - Test Connection Definitions, Results and Resource (#10383)

* Prep the skeleton

* Add DAO and tables

* Add Test Connection Definition Resource

* Format

* Add ResourceDescriptors & missing props

* Simplify APIs to scope for GET and LIST
This commit is contained in:
Pere Miquel Brull 2023-03-05 10:17:08 +01:00 committed by GitHub
parent 5208b6f684
commit 1e3652d35e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 655 additions and 4 deletions

View File

@ -50,4 +50,13 @@ CREATE TABLE IF NOT EXISTS objectstore_container_entity (
UNIQUE (fullyQualifiedName)
);
CREATE TABLE IF NOT EXISTS test_connection_definition (
id VARCHAR(36) GENERATED ALWAYS AS (json ->> '$.id') STORED NOT NULL,
name VARCHAR(256) GENERATED ALWAYS AS (json ->> '$.name') NOT NULL,
json JSON NOT NULL,
updatedAt BIGINT UNSIGNED GENERATED ALWAYS AS (json ->> '$.updatedAt') NOT NULL,
updatedBy VARCHAR(256) GENERATED ALWAYS AS (json ->> '$.updatedBy') NOT NULL,
deleted BOOLEAN GENERATED ALWAYS AS (json -> '$.deleted'),
PRIMARY KEY (id),
UNIQUE (name)
);

View File

@ -50,3 +50,13 @@ CREATE TABLE IF NOT EXISTS objectstore_container_entity (
PRIMARY KEY (id),
UNIQUE (fullyQualifiedName)
);
CREATE TABLE IF NOT EXISTS test_connection_definition (
id VARCHAR(36) GENERATED ALWAYS AS (json ->> 'id') STORED NOT NULL,
name VARCHAR(256) GENERATED ALWAYS AS (json ->> 'name') STORED NOT NULL,
json JSONB NOT NULL,
updatedAt BIGINT GENERATED ALWAYS AS ((json ->> 'updatedAt')::bigint) STORED NOT NULL,
updatedBy VARCHAR(256) GENERATED ALWAYS AS (json ->> 'updatedBy') STORED NOT NULL,
deleted BOOLEAN GENERATED ALWAYS AS ((json ->> 'deleted')::boolean) STORED,
UNIQUE (name)
);

View File

@ -101,6 +101,7 @@ public final class Entity {
public static final String CLASSIFICATION = "classification";
public static final String TYPE = "type";
public static final String TEST_DEFINITION = "testDefinition";
public static final String TEST_CONNECTION_DEFINITION = "testConnectionDefinition";
public static final String ALERT_ACTION = "alertAction";
public static final String TEST_SUITE = "testSuite";

View File

@ -85,6 +85,7 @@ import org.openmetadata.schema.entity.services.MlModelService;
import org.openmetadata.schema.entity.services.ObjectStoreService;
import org.openmetadata.schema.entity.services.PipelineService;
import org.openmetadata.schema.entity.services.StorageService;
import org.openmetadata.schema.entity.services.connections.TestConnectionDefinition;
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
import org.openmetadata.schema.entity.teams.Role;
import org.openmetadata.schema.entity.teams.Team;
@ -242,6 +243,9 @@ public interface CollectionDAO {
@CreateSqlObject
TestDefinitionDAO testDefinitionDAO();
@CreateSqlObject
TestConnectionDefinitionDAO testConnectionDefinitionDAO();
@CreateSqlObject
AlertActionDAO alertActionDAO();
@ -368,6 +372,23 @@ public interface CollectionDAO {
}
}
interface TestConnectionDefinitionDAO extends EntityDAO<TestConnectionDefinition> {
@Override
default String getTableName() {
return "test_connection_definition";
}
@Override
default Class<TestConnectionDefinition> getEntityClass() {
return TestConnectionDefinition.class;
}
@Override
default String getNameColumn() {
return "name";
}
}
interface StorageServiceDAO extends EntityDAO<StorageService> {
@Override
default String getTableName() {

View File

@ -0,0 +1,68 @@
package org.openmetadata.service.jdbi3;
import static org.openmetadata.service.Entity.TEST_CONNECTION_DEFINITION;
import java.io.IOException;
import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.entity.services.connections.TestConnectionDefinition;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.service.Entity;
import org.openmetadata.service.resources.services.connections.TestConnectionDefinitionResource;
import org.openmetadata.service.util.EntityUtil;
/*
We won't have any POST/PUT operations on these definitions.
They are created by the server and will be updated, if needed, via migration files.
*/
public class TestConnectionDefinitionRepository extends EntityRepository<TestConnectionDefinition> {
private static final String UPDATE_FIELDS = "";
private static final String PATCH_FIELDS = "";
public TestConnectionDefinitionRepository(CollectionDAO dao) {
super(
TestConnectionDefinitionResource.COLLECTION_PATH,
TEST_CONNECTION_DEFINITION,
TestConnectionDefinition.class,
dao.testConnectionDefinitionDAO(),
dao,
PATCH_FIELDS,
UPDATE_FIELDS);
}
@Override
public TestConnectionDefinition setFields(TestConnectionDefinition entity, EntityUtil.Fields fields)
throws IOException {
return entity.withOwner(fields.contains(Entity.FIELD_OWNER) ? getOwner(entity) : null);
}
@Override
public void prepare(TestConnectionDefinition entity) throws IOException {
// validate steps
if (CommonUtil.nullOrEmpty(entity.getSteps())) {
throw new IllegalArgumentException("Steps must not be empty");
}
}
@Override
public void storeEntity(TestConnectionDefinition entity, boolean update) throws IOException {
EntityReference owner = entity.getOwner();
// Don't store owner, database, href and tags as JSON. Build it on the fly based on relationships
entity.withOwner(null).withHref(null);
store(entity, update);
// Restore the relationships
entity.withOwner(owner);
}
@Override
public void storeRelationships(TestConnectionDefinition entity) throws IOException {
storeOwner(entity, entity.getOwner());
}
@Override
public EntityUpdater getUpdater(
TestConnectionDefinition original, TestConnectionDefinition updated, Operation operation) {
return null;
}
}

View File

@ -233,7 +233,6 @@ public class TestDefinitionResource extends EntityResource<TestDefinition, TestD
})
public TestDefinition getByName(
@Context UriInfo uriInfo,
@Parameter(description = "Id of the test definition", schema = @Schema(type = "UUID")) @PathParam("id") UUID id,
@Parameter(description = "Name of the test definition", schema = @Schema(type = "string")) @PathParam("name")
String name,
@Context SecurityContext securityContext,
@ -309,7 +308,7 @@ public class TestDefinitionResource extends EntityResource<TestDefinition, TestD
operationId = "patchTestDefinition",
summary = "Update a test definition",
tags = "testDefinitions",
description = "Update an existing topic using JsonPatch.",
description = "Update an existing Test Definition using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
public Response updateDescription(
@ -334,7 +333,7 @@ public class TestDefinitionResource extends EntityResource<TestDefinition, TestD
operationId = "createOrUpdateTestDefinition",
summary = "Update test definition",
tags = "testDefinitions",
description = "Create a definition, it it does not exist or update an existing test definition.",
description = "Create a test definition, if it does not exist, or update an existing test definition.",
responses = {
@ApiResponse(
responseCode = "200",

View File

@ -0,0 +1,206 @@
package org.openmetadata.service.resources.services.connections;
import com.google.inject.Inject;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.entity.services.connections.TestConnectionDefinition;
import org.openmetadata.schema.type.Include;
import org.openmetadata.service.Entity;
import org.openmetadata.service.OpenMetadataApplicationConfig;
import org.openmetadata.service.jdbi3.CollectionDAO;
import org.openmetadata.service.jdbi3.ListFilter;
import org.openmetadata.service.jdbi3.TestConnectionDefinitionRepository;
import org.openmetadata.service.resources.Collection;
import org.openmetadata.service.resources.EntityResource;
import org.openmetadata.service.security.Authorizer;
import org.openmetadata.service.util.RestUtil;
import org.openmetadata.service.util.ResultList;
@Slf4j
@Path("/v1/services/testConnectionDefinition")
@Api(value = "Test Connection Definitions collection", tags = "Test Connection Definitions collection")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Collection(name = "TestConnectionDefinitions")
public class TestConnectionDefinitionResource
extends EntityResource<TestConnectionDefinition, TestConnectionDefinitionRepository> {
public static final String COLLECTION_PATH = "/v1/services/testConnectionDefinition";
static final String FIELDS = "owner";
@Override
public TestConnectionDefinition addHref(UriInfo uriInfo, TestConnectionDefinition testConnectionDefinition) {
testConnectionDefinition.withHref(RestUtil.getHref(uriInfo, COLLECTION_PATH, testConnectionDefinition.getId()));
Entity.withHref(uriInfo, testConnectionDefinition.getOwner());
return testConnectionDefinition;
}
@Inject
public TestConnectionDefinitionResource(CollectionDAO dao, Authorizer authorizer) {
super(TestConnectionDefinition.class, new TestConnectionDefinitionRepository(dao), authorizer);
}
@Override
public void initialize(OpenMetadataApplicationConfig config) throws IOException {
List<TestConnectionDefinition> testConnectionDefinitions =
dao.getEntitiesFromSeedData(".*json/data/testConnections/.*\\.json$");
for (TestConnectionDefinition testConnectionDefinition : testConnectionDefinitions) {
dao.initializeEntity(testConnectionDefinition);
}
}
public static class TestConnectionDefinitionList extends ResultList<TestConnectionDefinition> {
@SuppressWarnings("unused")
public TestConnectionDefinitionList() {
// Empty constructor needed for deserialization
}
}
@GET
@Operation(
operationId = "listTestConnectionDefinitions",
summary = "List test connection definitions",
tags = "testConnectionDefinitions",
description =
"Get a list of test connection definitions. Use cursor-based pagination to limit the number "
+ "entries in the list using `limit` and `before` or `after` query params.",
responses = {
@ApiResponse(
responseCode = "200",
description = "List of test connection definitions",
content =
@Content(
mediaType = "application/json",
schema =
@Schema(implementation = TestConnectionDefinitionResource.TestConnectionDefinitionList.class)))
})
public ResultList<TestConnectionDefinition> list(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(
description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields")
String fieldsParam,
@Parameter(
description = "Limit the number test connection definitions returned. (1 to 1000000, default = " + "10)")
@DefaultValue("10")
@QueryParam("limit")
@Min(0)
@Max(1000000)
int limitParam,
@Parameter(
description = "Returns list of test connection definitions before this cursor",
schema = @Schema(type = "string"))
@QueryParam("before")
String before,
@Parameter(
description = "Returns list of test connection definitions after this cursor",
schema = @Schema(type = "string"))
@QueryParam("after")
String after,
@Parameter(
description = "Include all, deleted, or non-deleted entities.",
schema = @Schema(implementation = Include.class))
@QueryParam("include")
@DefaultValue("non-deleted")
Include include)
throws IOException {
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@GET
@Path("/{id}")
@Operation(
summary = "Get a test connection definition by Id",
tags = "testConnectionDefinitions",
description = "Get a Test Connection Definition by `Id`.",
responses = {
@ApiResponse(
responseCode = "200",
description = "The Test Connection definition",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = TestConnectionDefinition.class))),
@ApiResponse(responseCode = "404", description = "Test Connection Definition for instance {id} is not found")
})
public TestConnectionDefinition get(
@Context UriInfo uriInfo,
@Parameter(description = "Id of the test connection definition", schema = @Schema(type = "UUID")) @PathParam("id")
UUID id,
@Context SecurityContext securityContext,
@Parameter(
description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields")
String fieldsParam,
@Parameter(
description = "Include all, deleted, or non-deleted entities.",
schema = @Schema(implementation = Include.class))
@QueryParam("include")
@DefaultValue("non-deleted")
Include include)
throws IOException {
return getInternal(uriInfo, securityContext, id, fieldsParam, include);
}
@GET
@Path("/name/{name}")
@Operation(
operationId = "getTestConnectionDefinitionByName",
summary = "Get a test connection definition by name",
tags = "testConnectionDefinitions",
description = "Get a test connection definition by `name`.",
responses = {
@ApiResponse(
responseCode = "200",
description = "The test connection definition",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = TestConnectionDefinition.class))),
@ApiResponse(responseCode = "404", description = "Test Connection Definition for instance {name} is not found")
})
public TestConnectionDefinition getByName(
@Context UriInfo uriInfo,
@Parameter(description = "Name of the test definition", schema = @Schema(type = "string")) @PathParam("name")
String name,
@Context SecurityContext securityContext,
@Parameter(
description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields")
String fieldsParam,
@Parameter(
description = "Include all, deleted, or non-deleted entities.",
schema = @Schema(implementation = Include.class))
@QueryParam("include")
@DefaultValue("non-deleted")
Include include)
throws IOException {
return getByNameInternal(uriInfo, securityContext, name, fieldsParam, include);
}
}

View File

@ -453,6 +453,14 @@
"ViewAll"
]
},
{
"name" : "testConnectionDefinition",
"operations" : [
"Create",
"Delete",
"ViewAll"
]
},
{
"name" : "type",
"operations" : [

View File

@ -0,0 +1,24 @@
{
"name": "Tableau",
"fullyQualifiedName": "Tableau",
"displayName": "Tableau Test Connection",
"description": "This Test Connection validates the access against the server and basic metadata extraction of workbooks and views.",
"steps": [
{
"name": "ServerInfo",
"description": "Validate that the API can properly reach the server",
"mandatory": true
},
{
"name": "GetWorkbooks",
"description": "List all the workbooks available to the user. We will ingest Workbooks as Dashboards.",
"mandatory": true
},
{
"name": "GetViews",
"description": "List the Views (charts) from a given Workbook.",
"mandatory": false
}
]
}

View File

@ -0,0 +1,24 @@
{
"name": "Mysql",
"fullyQualifiedName": "Mysql",
"displayName": "Mysql Test Connection",
"description": "This Test Connection validates the access against the database and basic metadata extraction of schemas and tables.",
"steps": [
{
"name": "GetSchemas",
"description": "List all the schemas available to the user.",
"mandatory": true
},
{
"name": "GetTables",
"description": "From a given schema, list the tables belonging to that schema. If no schema is specified, we'll list the tables of a random schema.",
"mandatory": true
},
{
"name": "GetViews",
"description": "From a given schema, list the views belonging to that schema. If no schema is specified, we'll list the tables of a random schema.",
"mandatory": false
}
]
}

View File

@ -0,0 +1,39 @@
{
"name": "Redshift",
"fullyQualifiedName": "Redshift",
"displayName": "Redshift Test Connection",
"description": "This Test Connection validates the access against the database and basic metadata extraction of schemas and tables.",
"steps": [
{
"name": "GetDatabases",
"description": "List all the available databases to the user. If all databases option is selected, we will try to go beyond the configured database.",
"mandatory": true
},
{
"name": "GetSchemas",
"description": "List all the possible schemas from the configured database.",
"mandatory": true
},
{
"name": "GetTables",
"description": "From a given schema, list the tables belonging to that schema. If no schema is specified, we'll list the tables of a random schema.",
"mandatory": true
},
{
"name": "GetViews",
"description": "From a given schema, list the views belonging to that schema. If no schema is specified, we'll list the views of a random schema.",
"mandatory": false
},
{
"name": "GetStlQueryText",
"description": "Check that we can properly access the records in stl_querytext. This is required for lineage and usage workflows.",
"mandatory": false
},
{
"name": "GetStlQuery",
"description": "Check that we can properly access the records in stl_query. This is required for lineage and usage workflows.",
"mandatory": false
}
]
}

View File

@ -0,0 +1,56 @@
package org.openmetadata.service.resources.services.connections;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
import java.util.UUID;
import javax.ws.rs.client.WebTarget;
import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.Test;
import org.openmetadata.schema.entity.services.connections.TestConnectionDefinition;
import org.openmetadata.service.OpenMetadataApplicationTest;
import org.openmetadata.service.util.ResultList;
import org.openmetadata.service.util.TestUtils;
/*
This Entity only supports GET, LIST, so we'll validate these endpoints.
*/
public class TestConnectionDefinitionResourceTest extends OpenMetadataApplicationTest {
private static final String TEST_CONNECTION_NAME = "Mysql";
private static final String COLLECTION = "services/testConnectionDefinition";
@Test
public void test_get_test_connection_definition() throws HttpResponseException {
WebTarget target = getResourceByName(TEST_CONNECTION_NAME);
TestConnectionDefinition mysqlTest = TestUtils.get(target, TestConnectionDefinition.class, ADMIN_AUTH_HEADERS);
assertEquals(mysqlTest.getName(), "Mysql");
assertEquals(mysqlTest.getSteps().size(), 3);
WebTarget idTarget = getResourceById(mysqlTest.getId());
TestConnectionDefinition mysqlTestById =
TestUtils.get(idTarget, TestConnectionDefinition.class, ADMIN_AUTH_HEADERS);
assertEquals(mysqlTestById.getName(), "Mysql");
assertEquals(mysqlTestById.getSteps().size(), 3);
}
@Test
public void test_list_test_connection_definition() throws HttpResponseException {
WebTarget target = listResource();
ResultList mysqlTest = TestUtils.get(target, ResultList.class, ADMIN_AUTH_HEADERS);
// Update this number after adding new TestConnectionDefinition to the server
assertEquals(mysqlTest.getData().size(), 3);
}
protected final WebTarget getResourceByName(String name) {
return getResource(COLLECTION).path("/name/" + name);
}
protected final WebTarget getResourceById(UUID id) {
return getResource(COLLECTION).path("/" + id.toString());
}
protected final WebTarget listResource() {
return getResource(COLLECTION).path("/");
}
}

View File

@ -44,6 +44,9 @@
"secretsManagerProvider": {
"$ref": "../../../security/secrets/secretsManagerProvider.json",
"default": "noop"
},
"serviceName": {
"$ref": "../../../entity/type.json#/definitions/entityName"
}
},
"additionalProperties": false

View File

@ -0,0 +1,94 @@
{
"$id": "https://open-metadata.org/schema/entity/services/connections/testConnectionDefinition.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "TestConnectionDefinition",
"description": "TestConnection is the definition that will encapsulate the steps required to test a connection to a specific service.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.services.connections.TestConnectionDefinition",
"javaInterfaces": ["org.openmetadata.schema.EntityInterface"],
"definitions": {
"testConnectionStep": {
"description": "Function that tests one specific element of the service. E.g., listing schemas, lineage, or tags.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.services.connections.TestConnectionStep",
"properties": {
"name": {
"description": "Name of the step being tested",
"type": "string"
},
"description": {
"description": "What is the goal of the step",
"type": "string"
},
"mandatory": {
"description": "Is this step mandatory to be passed?",
"type": "boolean",
"default": true
}
},
"additionalProperties": false,
"required": ["name", "mandatory", "description"]
}
},
"properties": {
"id": {
"description": "Unique identifier of this test case definition instance.",
"$ref": "../../../type/basic.json#/definitions/uuid"
},
"name": {
"description": "Name of the Test Connection Definition. It should be the `type` of the service being tested, e.g., Mysql, or Snowflake.",
"$ref": "../../../type/basic.json#/definitions/entityName"
},
"displayName": {
"description": "Display Name that identifies this test definition.",
"type": "string"
},
"description": {
"description": "Description of the test connection def.",
"$ref": "../../../type/basic.json#/definitions/markdown"
},
"fullyQualifiedName": {
"description": "FullyQualifiedName same as `name`.",
"$ref": "../../../type/basic.json#/definitions/fullyQualifiedEntityName"
},
"steps": {
"description": "Steps to test the connection. Order matters.",
"type": "array",
"items": {
"$ref": "#/definitions/testConnectionStep"
}
},
"owner": {
"description": "Owner of this TestConnection definition.",
"$ref": "../../../type/entityReference.json",
"default": null
},
"version": {
"description": "Metadata version of the entity.",
"$ref": "../../../type/entityHistory.json#/definitions/entityVersion"
},
"updatedAt": {
"description": "Last update time corresponding to the new version of the entity in Unix epoch time milliseconds.",
"$ref": "../../../type/basic.json#/definitions/timestamp"
},
"updatedBy": {
"description": "User who made the update.",
"type": "string"
},
"href": {
"description": "Link to the resource corresponding to this entity.",
"$ref": "../../../type/basic.json#/definitions/href"
},
"changeDescription": {
"description": "Change that lead to this version of the entity.",
"$ref": "../../../type/entityHistory.json#/definitions/changeDescription"
},
"deleted": {
"description": "When `true` indicates the entity has been soft deleted.",
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"required": ["name", "steps"]
}

View File

@ -0,0 +1,61 @@
{
"$id": "https://open-metadata.org/schema/entity/services/connections/testConnectionResult.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "TestConnectionResult",
"description": "TestConnectionResult is the definition that will encapsulate result of running the test connection steps.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.services.connections.TestConnectionResult",
"definitions": {
"testConnectionStepResult": {
"description": "Function that tests one specific element of the service. E.g., listing schemas, lineage, or tags.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.services.connections.TestConnectionStep",
"properties": {
"name": {
"description": "Name of the step being tested",
"type": "string"
},
"mandatory": {
"description": "Is this step mandatory to be passed?",
"type": "boolean",
"default": true
},
"passed": {
"description": "Did the step pass successfully?",
"type": "boolean"
},
"message": {
"description": "Results or exceptions to be shared after running the test.",
"type": "string",
"default": null
}
},
"additionalProperties": false,
"required": ["name", "mandatory", "passed"]
},
"statusType": {
"description": "Enum defining possible Test Connection Result status",
"type": "string",
"enum": ["Successful", "Failed", "Running"]
}
},
"properties": {
"lastUpdatedAt": {
"description": "Last time that the test connection was executed",
"$ref": "../../../type/basic.json#/definitions/timestamp"
},
"status": {
"description": "Test Connection Result computation status.",
"$ref": "#/definitions/statusType"
},
"steps": {
"description": "Steps to test the connection. Order matters.",
"type": "array",
"items": {
"$ref": "#/definitions/testConnectionStepResult"
}
}
},
"additionalProperties": false,
"required": ["steps", "status"]
}

View File

@ -138,6 +138,10 @@
"description": "References to pipelines deployed for this dashboard service.",
"$ref": "../../type/entityReference.json#/definitions/entityReferenceList"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Dashboard Service.",
"type": "array",

View File

@ -271,6 +271,10 @@
"description": "References to pipelines deployed for this database service to extract metadata, usage, lineage etc..",
"$ref": "../../type/entityReference.json#/definitions/entityReferenceList"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Database Service.",
"type": "array",

View File

@ -105,6 +105,10 @@
"description": "References to pipelines deployed for this messaging service to extract topic configs and schemas.",
"$ref": "../../type/entityReference.json#/definitions/entityReferenceList"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Message Service.",
"type": "array",

View File

@ -103,6 +103,10 @@
"description": "User who made the update.",
"type": "string"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Metadata Service.",
"type": "array",

View File

@ -103,6 +103,10 @@
"connection": {
"$ref": "#/definitions/mlModelConnection"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this MlModel Service.",
"type": "array",

View File

@ -91,6 +91,10 @@
"description": "References to pipelines deployed for this object store service to extract metadata, usage, lineage etc..",
"$ref": "../../type/entityReference.json#/definitions/entityReferenceList"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Object Store Service.",
"type": "array",

View File

@ -138,6 +138,10 @@
"description": "User who made the update.",
"type": "string"
},
"testConnectionResult": {
"description": "Last test connection results for this service",
"$ref": "connections/testConnectionResult.json"
},
"tags": {
"description": "Tags for this Pipeline Service.",
"type": "array",