GEN-1322: API Entity - Remove Beta (#17967)

* GEN-1322: API Entity - Remove Beta

* minor: add doc for the metadata pipeline

* api service refactor

* api service refactor backend changes

* add apiconnection in test service connection

* pytest fix

* fix java file formatting

* Fix casing of REST in ApiServiceRest.spec.ts

* Refactor REST to Rest in API classes

* minor change

* minor change

* minor change

* fix cashing for API to Api

* add playwright test for api service ingestion

* fix: playwright test

---------

Co-authored-by: harshsoni2024 <harshsoni2024@gmail.com>
This commit is contained in:
Sachin Chaurasiya 2024-10-08 14:39:55 +05:30 committed by GitHub
parent 53cdd34391
commit 457f3d919a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 301 additions and 208 deletions

View File

@ -1,9 +1,9 @@
{
"type": "REST",
"type": "rest",
"serviceName": "sample_api_service",
"serviceConnection": {
"config": {
"type": "REST",
"type": "Rest",
"openAPISchemaURL": "https://petstore3.swagger.io/",
"token":"mock_token"
}

View File

@ -1,9 +1,9 @@
{
"type": "REST",
"type": "rest",
"serviceName": "ometa_api_service",
"serviceConnection": {
"config": {
"type": "REST",
"type": "Rest",
"openAPISchemaURL": "https://docs.open-metadata.org/swagger.html",
"token":"token"
}

View File

@ -3,9 +3,9 @@ source:
serviceName: openapi_rest
serviceConnection:
config:
type: REST
type: Rest
openAPISchemaURL: https://docs.open-metadata.org/swagger.json
token: <optional_jwt_token>
# token: <jwt_token>
sourceConfig:
config:
type: ApiMetadata

View File

@ -19,8 +19,8 @@ from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
)
from metadata.generated.schema.entity.services.apiService import (
ApiServiceConnection,
APIServiceType,
ApiConnection,
ApiServiceType,
)
from metadata.generated.schema.entity.services.dashboardService import (
DashboardConnection,
@ -135,7 +135,7 @@ HAS_INNER_CONNECTION = {"Airflow"}
# Build a service type map dynamically from JSON Schema covered types
SERVICE_TYPE_MAP = {
"Backend": PipelineConnection, # For Airflow backend
**{service: ApiServiceConnection for service in APIServiceType.__members__},
**{service: ApiConnection for service in ApiServiceType.__members__},
**{service: DatabaseConnection for service in DatabaseServiceType.__members__},
**{service: DashboardConnection for service in DashboardServiceType.__members__},
**{service: MessagingConnection for service in MessagingServiceType.__members__},
@ -183,7 +183,7 @@ class InvalidWorkflowException(Exception):
def get_service_type(
source_type: str,
) -> Union[
Type[ApiServiceConnection],
Type[ApiConnection],
Type[DashboardConnection],
Type[DatabaseConnection],
Type[MessagingConnection],
@ -233,7 +233,7 @@ def get_source_config_class(
def get_connection_class(
source_type: str,
service_type: Union[
Type[ApiServiceConnection],
Type[ApiConnection],
Type[DashboardConnection],
Type[DatabaseConnection],
Type[MessagingConnection],
@ -557,6 +557,7 @@ def parse_automation_workflow_gracefully(
message="Error parsing the service connection",
)
#
raise ParsingConfigurationError(
"Uncaught error when parsing the Ingestion Pipeline!"
)

View File

@ -26,8 +26,8 @@ from metadata.generated.schema.api.data.createAPIEndpoint import (
from metadata.generated.schema.entity.data.apiCollection import APICollection
from metadata.generated.schema.entity.data.apiEndpoint import APIEndpoint
from metadata.generated.schema.entity.services.apiService import (
ApiConnection,
ApiService,
ApiServiceConnection,
)
from metadata.generated.schema.metadataIngestion.apiServiceMetadataPipeline import (
ApiServiceMetadataPipeline,
@ -112,7 +112,7 @@ class ApiServiceSource(TopologyRunnerMixin, Source, ABC):
source_config: ApiServiceMetadataPipeline
config: WorkflowSource
# Big union of types we want to fetch dynamically
service_connection: ApiServiceConnection.model_fields["config"].annotation
service_connection: ApiConnection.model_fields["config"].annotation
topology = ApiServiceTopology()
context = TopologyContextManager(topology)

View File

@ -20,8 +20,8 @@ from requests.models import Response
from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
)
from metadata.generated.schema.entity.services.connections.apiService.restConnection import (
RESTConnection,
from metadata.generated.schema.entity.services.connections.api.restConnection import (
RestConnection,
)
from metadata.ingestion.connections.test_connections import test_connection_steps
from metadata.ingestion.ometa.ometa_api import OpenMetadata
@ -39,7 +39,7 @@ class InvalidOpenAPISchemaError(Exception):
"""
def get_connection(connection: RESTConnection) -> Response:
def get_connection(connection: RestConnection) -> Response:
"""
Create connection
"""
@ -52,7 +52,7 @@ def get_connection(connection: RESTConnection) -> Response:
def test_connection(
metadata: OpenMetadata,
client: Response,
service_connection: RESTConnection,
service_connection: RestConnection,
automation_workflow: Optional[AutomationWorkflow] = None,
) -> None:
"""

View File

@ -23,8 +23,8 @@ from metadata.generated.schema.api.data.createAPIEndpoint import (
)
from metadata.generated.schema.entity.data.apiCollection import APICollection
from metadata.generated.schema.entity.data.apiEndpoint import ApiRequestMethod
from metadata.generated.schema.entity.services.connections.apiService.restConnection import (
RESTConnection,
from metadata.generated.schema.entity.services.connections.api.restConnection import (
RestConnection,
)
from metadata.generated.schema.entity.services.ingestionPipelines.status import (
StackTraceError,
@ -62,10 +62,10 @@ class RestSource(ApiServiceSource):
cls, config_dict, metadata: OpenMetadata, pipeline_name: Optional[str] = None
):
config: WorkflowSource = WorkflowSource.model_validate(config_dict)
connection: RESTConnection = config.serviceConnection.root.config
if not isinstance(connection, RESTConnection):
connection: RestConnection = config.serviceConnection.root.config
if not isinstance(connection, RestConnection):
raise InvalidSourceException(
f"Expected RESTConnection, but got {connection}"
f"Expected RestConnection, but got {connection}"
)
return cls(config, metadata)

View File

@ -68,7 +68,7 @@ from metadata.generated.schema.metadataIngestion.testSuitePipeline import (
from metadata.generated.schema.metadataIngestion.workflow import SourceConfig
SERVICE_TYPE_REF = {
ServiceType.API.value: "apiService",
ServiceType.Api.value: "apiService",
ServiceType.Database.value: "databaseService",
ServiceType.Dashboard.value: "dashboardService",
ServiceType.Pipeline.value: "pipelineService",

View File

@ -19,6 +19,9 @@ from pydantic import ValidationError
from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
)
from metadata.generated.schema.entity.services.connections.api.restConnection import (
RestConnection,
)
from metadata.generated.schema.entity.services.connections.dashboard.tableauConnection import (
TableauConnection,
)
@ -115,6 +118,10 @@ class TestWorkflowParse(TestCase):
connection = get_connection_class(source_type, get_service_type(source_type))
self.assertEqual(connection, KafkaConnection)
source_type = "Rest"
connection = get_connection_class(source_type, get_service_type(source_type))
self.assertEqual(connection, RestConnection)
def test_get_source_config_class(self):
"""
Check that we can correctly build the connection module ingredients

View File

@ -21,9 +21,9 @@ from metadata.generated.schema.api.data.createAPICollection import (
CreateAPICollectionRequest,
)
from metadata.generated.schema.entity.services.apiService import (
ApiConnection,
ApiService,
ApiServiceConnection,
APIServiceType,
ApiServiceType,
)
from metadata.generated.schema.metadataIngestion.workflow import (
OpenMetadataWorkflowConfig,
@ -43,7 +43,7 @@ mock_rest_config = {
"serviceName": "openapi_rest",
"serviceConnection": {
"config": {
"type": "REST",
"type": "Rest",
"openAPISchemaURL": "https://petstore3.swagger.io/api/v3/openapi.json",
}
},
@ -91,8 +91,8 @@ MOCK_API_SERVICE = ApiService(
id="c3eb265f-5445-4ad3-ba5e-797d3a3071bb",
name="openapi_rest",
fullyQualifiedName=FullyQualifiedEntityName("openapi_rest"),
connection=ApiServiceConnection(),
serviceType=APIServiceType.REST,
connection=ApiConnection(),
serviceType=ApiServiceType.Rest,
)
EXPECTED_COLLECTION_REQUEST = [
Either(

View File

@ -18,7 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jdbi.v3.sqlobject.transaction.Transaction;
import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.entity.data.APICollection;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.Relationship;
@ -108,7 +108,7 @@ public class APICollectionRepository extends EntityRepository<APICollection> {
}
private void populateService(APICollection apiCollection) {
APIService service = Entity.getEntity(apiCollection.getService(), "", Include.NON_DELETED);
ApiService service = Entity.getEntity(apiCollection.getService(), "", Include.NON_DELETED);
apiCollection.setService(service.getEntityReference());
apiCollection.setServiceType(service.getServiceType());
}

View File

@ -1,19 +1,18 @@
package org.openmetadata.service.jdbi3;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.entity.services.ServiceType;
import org.openmetadata.schema.type.APIServiceConnection;
import org.openmetadata.schema.type.ApiConnection;
import org.openmetadata.service.Entity;
import org.openmetadata.service.resources.services.apiservices.APIServiceResource;
public class APIServiceRepository
extends ServiceEntityRepository<APIService, APIServiceConnection> {
public class APIServiceRepository extends ServiceEntityRepository<ApiService, ApiConnection> {
public APIServiceRepository() {
super(
APIServiceResource.COLLECTION_PATH,
Entity.API_SERVICE,
Entity.getCollectionDAO().apiServiceDAO(),
APIServiceConnection.class,
ApiConnection.class,
"",
ServiceType.API);
supportsSearch = true;

View File

@ -98,7 +98,7 @@ import org.openmetadata.schema.entity.domains.DataProduct;
import org.openmetadata.schema.entity.domains.Domain;
import org.openmetadata.schema.entity.events.EventSubscription;
import org.openmetadata.schema.entity.policies.Policy;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.entity.services.DashboardService;
import org.openmetadata.schema.entity.services.DatabaseService;
import org.openmetadata.schema.entity.services.MessagingService;
@ -288,7 +288,7 @@ public interface CollectionDAO {
SearchServiceDAO searchServiceDAO();
@CreateSqlObject
APIServiceDAO apiServiceDAO();
ApiServiceDAO apiServiceDAO();
@CreateSqlObject
ContainerDAO containerDAO();
@ -636,15 +636,15 @@ public interface CollectionDAO {
}
}
interface APIServiceDAO extends EntityDAO<APIService> {
interface ApiServiceDAO extends EntityDAO<ApiService> {
@Override
default String getTableName() {
return "api_service_entity";
}
@Override
default Class<APIService> getEntityClass() {
return APIService.class;
default Class<ApiService> getEntityClass() {
return ApiService.class;
}
@Override

View File

@ -47,11 +47,11 @@ import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.api.data.RestoreEntity;
import org.openmetadata.schema.api.services.CreateAPIService;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.api.services.CreateApiService;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.entity.services.ServiceType;
import org.openmetadata.schema.entity.services.connections.TestConnectionResult;
import org.openmetadata.schema.type.APIServiceConnection;
import org.openmetadata.schema.type.ApiConnection;
import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.MetadataOperation;
@ -75,12 +75,12 @@ import org.openmetadata.service.util.ResultList;
@Consumes(MediaType.APPLICATION_JSON)
@Collection(name = "apiServices")
public class APIServiceResource
extends ServiceEntityResource<APIService, APIServiceRepository, APIServiceConnection> {
extends ServiceEntityResource<ApiService, APIServiceRepository, ApiConnection> {
public static final String COLLECTION_PATH = "v1/services/apiServices/";
static final String FIELDS = "pipelines,owners,tags,domain";
@Override
public APIService addHref(UriInfo uriInfo, APIService service) {
public ApiService addHref(UriInfo uriInfo, ApiService service) {
super.addHref(uriInfo, service);
Entity.withHref(uriInfo, service.getPipelines());
return service;
@ -96,7 +96,7 @@ public class APIServiceResource
return null;
}
public static class APIServiceList extends ResultList<APIService> {
public static class APIServiceList extends ResultList<ApiService> {
/* Required for serde */
}
@ -118,7 +118,7 @@ public class APIServiceResource
org.openmetadata.service.resources.services.apiservices
.APIServiceResource.APIServiceList.class)))
})
public ResultList<APIService> list(
public ResultList<ApiService> list(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(
@ -165,12 +165,12 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class))),
schema = @Schema(implementation = ApiService.class))),
@ApiResponse(
responseCode = "404",
description = "API service for instance {id} is not found")
})
public APIService get(
public ApiService get(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") UUID id,
@ -185,7 +185,7 @@ public class APIServiceResource
@QueryParam("include")
@DefaultValue("non-deleted")
Include include) {
APIService apiService = getInternal(uriInfo, securityContext, id, fieldsParam, include);
ApiService apiService = getInternal(uriInfo, securityContext, id, fieldsParam, include);
return decryptOrNullify(securityContext, apiService);
}
@ -202,12 +202,12 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class))),
schema = @Schema(implementation = ApiService.class))),
@ApiResponse(
responseCode = "404",
description = "API service for instance {id} is not found")
})
public APIService getByName(
public ApiService getByName(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("name") String name,
@ -222,7 +222,7 @@ public class APIServiceResource
@QueryParam("include")
@DefaultValue("non-deleted")
Include include) {
APIService apiService =
ApiService apiService =
getByNameInternal(
uriInfo, securityContext, EntityInterfaceUtil.quoteName(name), fieldsParam, include);
return decryptOrNullify(securityContext, apiService);
@ -241,9 +241,9 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class)))
schema = @Schema(implementation = ApiService.class)))
})
public APIService addTestConnectionResult(
public ApiService addTestConnectionResult(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Id of the service", schema = @Schema(type = "UUID"))
@ -252,7 +252,7 @@ public class APIServiceResource
@Valid TestConnectionResult testConnectionResult) {
OperationContext operationContext = new OperationContext(entityType, MetadataOperation.CREATE);
authorizer.authorize(securityContext, operationContext, getResourceContextById(id));
APIService service = repository.addTestConnectionResult(id, testConnectionResult);
ApiService service = repository.addTestConnectionResult(id, testConnectionResult);
return decryptOrNullify(securityContext, service);
}
@ -283,7 +283,7 @@ public class APIServiceResource
.map(
json -> {
try {
APIService apiService = JsonUtils.readValue((String) json, APIService.class);
ApiService apiService = JsonUtils.readValue((String) json, ApiService.class);
return JsonUtils.pojoToJson(decryptOrNullify(securityContext, apiService));
} catch (Exception e) {
return json;
@ -307,12 +307,12 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class))),
schema = @Schema(implementation = ApiService.class))),
@ApiResponse(
responseCode = "404",
description = "API service for instance {id} and version {version} is not found")
})
public APIService getVersion(
public ApiService getVersion(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "API service Id", schema = @Schema(type = "string")) @PathParam("id")
@ -322,13 +322,13 @@ public class APIServiceResource
schema = @Schema(type = "string", example = "0.1 or 1.1"))
@PathParam("version")
String version) {
APIService apiService = super.getVersionInternal(securityContext, id, version);
ApiService apiService = super.getVersionInternal(securityContext, id, version);
return decryptOrNullify(securityContext, apiService);
}
@POST
@Operation(
operationId = "createAPIService",
operationId = "createApiService",
summary = "Create API service",
description = "Create a new API service.",
responses = {
@ -338,16 +338,16 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class))),
schema = @Schema(implementation = ApiService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response create(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Valid CreateAPIService create) {
APIService service = getService(create, securityContext.getUserPrincipal().getName());
@Valid CreateApiService create) {
ApiService service = getService(create, securityContext.getUserPrincipal().getName());
Response response = create(uriInfo, securityContext, service);
decryptOrNullify(securityContext, (APIService) response.getEntity());
decryptOrNullify(securityContext, (ApiService) response.getEntity());
return response;
}
@ -363,16 +363,16 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class))),
schema = @Schema(implementation = ApiService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response createOrUpdate(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Valid CreateAPIService update) {
APIService service = getService(update, securityContext.getUserPrincipal().getName());
@Valid CreateApiService update) {
ApiService service = getService(update, securityContext.getUserPrincipal().getName());
Response response = createOrUpdate(uriInfo, securityContext, unmask(service));
decryptOrNullify(securityContext, (APIService) response.getEntity());
decryptOrNullify(securityContext, (ApiService) response.getEntity());
return response;
}
@ -504,7 +504,7 @@ public class APIServiceResource
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = APIService.class)))
schema = @Schema(implementation = ApiService.class)))
})
public Response restoreAPIService(
@Context UriInfo uriInfo,
@ -513,20 +513,20 @@ public class APIServiceResource
return restoreEntity(uriInfo, securityContext, restore.getId());
}
private APIService getService(CreateAPIService create, String user) {
private ApiService getService(CreateApiService create, String user) {
return repository
.copy(new APIService(), create, user)
.copy(new ApiService(), create, user)
.withServiceType(create.getServiceType())
.withConnection(create.getConnection());
}
@Override
protected APIService nullifyConnection(APIService service) {
protected ApiService nullifyConnection(ApiService service) {
return service.withConnection(null);
}
@Override
protected String extractServiceType(APIService service) {
protected String extractServiceType(ApiService service) {
return service.getServiceType().value();
}
}

View File

@ -23,15 +23,8 @@ import org.openmetadata.schema.entity.data.Table;
import org.openmetadata.schema.entity.data.Topic;
import org.openmetadata.schema.entity.domains.DataProduct;
import org.openmetadata.schema.entity.domains.Domain;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.entity.services.DashboardService;
import org.openmetadata.schema.entity.services.DatabaseService;
import org.openmetadata.schema.entity.services.MessagingService;
import org.openmetadata.schema.entity.services.MetadataService;
import org.openmetadata.schema.entity.services.MlModelService;
import org.openmetadata.schema.entity.services.PipelineService;
import org.openmetadata.schema.entity.services.SearchService;
import org.openmetadata.schema.entity.services.StorageService;
import org.openmetadata.schema.entity.services.*;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
import org.openmetadata.schema.entity.teams.Team;
import org.openmetadata.schema.entity.teams.User;
@ -118,7 +111,7 @@ public class SearchIndexFactory {
case Entity.MESSAGING_SERVICE -> new MessagingServiceIndex((MessagingService) entity);
case Entity.MLMODEL_SERVICE -> new MlModelServiceIndex((MlModelService) entity);
case Entity.SEARCH_SERVICE -> new SearchServiceIndex((SearchService) entity);
case Entity.API_SERVICE -> new APIServiceIndex((APIService) entity);
case Entity.API_SERVICE -> new APIServiceIndex((ApiService) entity);
case Entity.SEARCH_INDEX -> new SearchEntityIndex(
(org.openmetadata.schema.entity.data.SearchIndex) entity);
case Entity.PIPELINE_SERVICE -> new PipelineServiceIndex((PipelineService) entity);

View File

@ -3,11 +3,11 @@ package org.openmetadata.service.search.indexes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.service.Entity;
import org.openmetadata.service.search.models.SearchSuggest;
public record APIServiceIndex(APIService apiService) implements SearchIndex {
public record APIServiceIndex(org.openmetadata.schema.entity.services.ApiService apiService)
implements SearchIndex {
@Override
public List<SearchSuggest> getSuggest() {

View File

@ -1,5 +1,5 @@
{
"name": "REST",
"name": "Rest",
"displayName": "REST Test Connection",
"description": "This Test Connection validates the schema provided for openapi",
"steps": [

View File

@ -22,23 +22,23 @@ import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.api.services.CreateAPIService;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.api.services.CreateApiService;
import org.openmetadata.schema.entity.services.ApiService;
import org.openmetadata.schema.entity.services.connections.TestConnectionResult;
import org.openmetadata.schema.entity.services.connections.TestConnectionResultStatus;
import org.openmetadata.schema.services.connections.api.RESTConnection;
import org.openmetadata.schema.type.APIServiceConnection;
import org.openmetadata.schema.services.connections.api.RestConnection;
import org.openmetadata.schema.type.ApiConnection;
import org.openmetadata.schema.type.ChangeDescription;
import org.openmetadata.service.Entity;
import org.openmetadata.service.resources.services.apiservices.APIServiceResource;
import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.TestUtils;
public class APIServiceResourceTest extends ServiceResourceTest<APIService, CreateAPIService> {
public class APIServiceResourceTest extends ServiceResourceTest<ApiService, CreateApiService> {
public APIServiceResourceTest() {
super(
Entity.API_SERVICE,
APIService.class,
ApiService.class,
APIServiceResource.APIServiceList.class,
"services/apiServices",
"owners");
@ -47,25 +47,25 @@ public class APIServiceResourceTest extends ServiceResourceTest<APIService, Crea
public void setupAPIService(TestInfo test) throws HttpResponseException {
APIServiceResourceTest apiServiceResourceTest = new APIServiceResourceTest();
CreateAPIService createAPIService =
CreateApiService createApiService =
apiServiceResourceTest
.createRequest(test)
.withName("openmetadata")
.withServiceType(CreateAPIService.APIServiceType.REST)
.withServiceType(CreateApiService.ApiServiceType.Rest)
.withConnection(TestUtils.API_SERVICE_CONNECTION);
APIService omAPIService =
new APIServiceResourceTest().createEntity(createAPIService, ADMIN_AUTH_HEADERS);
ApiService omAPIService =
new APIServiceResourceTest().createEntity(createApiService, ADMIN_AUTH_HEADERS);
OPENMETADATA_API_SERVICE_REFERENCE = omAPIService.getEntityReference();
APIServiceResourceTest sampleAPIServiceResourceTest = new APIServiceResourceTest();
createAPIService =
createApiService =
sampleAPIServiceResourceTest
.createRequest(test)
.withName("sampleAPI")
.withServiceType(CreateAPIService.APIServiceType.REST)
.withServiceType(CreateApiService.ApiServiceType.Rest)
.withConnection(TestUtils.API_SERVICE_CONNECTION);
APIService sampleAPIService =
new APIServiceResourceTest().createEntity(createAPIService, ADMIN_AUTH_HEADERS);
ApiService sampleAPIService =
new APIServiceResourceTest().createEntity(createApiService, ADMIN_AUTH_HEADERS);
SAMPLE_API_SERVICE_REFERENCE = sampleAPIService.getEntityReference();
}
@ -93,26 +93,26 @@ public class APIServiceResourceTest extends ServiceResourceTest<APIService, Crea
@Test
void put_updateService_as_admin_2xx(TestInfo test) throws IOException, URISyntaxException {
APIServiceConnection connection1 =
new APIServiceConnection()
ApiConnection connection1 =
new ApiConnection()
.withConfig(
new RESTConnection()
new RestConnection()
.withOpenAPISchemaURL(
new URI("http://sandbox.open-metadata.org/swagger.json")));
APIService service =
ApiService service =
createAndCheckEntity(
createRequest(test).withDescription(null).withConnection(connection1),
ADMIN_AUTH_HEADERS);
RESTConnection credentials2 =
new RESTConnection()
RestConnection credentials2 =
new RestConnection()
.withOpenAPISchemaURL(new URI("https://localhost:9400"))
.withToken("test");
APIServiceConnection connection2 = new APIServiceConnection().withConfig(credentials2);
ApiConnection connection2 = new ApiConnection().withConfig(credentials2);
// Update APIService description and connection
CreateAPIService update =
CreateApiService update =
createRequest(test).withDescription("description1").withConnection(connection2);
ChangeDescription change = getChangeDescription(service, MINOR_UPDATE);
@ -123,10 +123,10 @@ public class APIServiceResourceTest extends ServiceResourceTest<APIService, Crea
@Test
void put_testConnectionResult_200(TestInfo test) throws IOException {
APIService service = createAndCheckEntity(createRequest(test), ADMIN_AUTH_HEADERS);
ApiService service = createAndCheckEntity(createRequest(test), ADMIN_AUTH_HEADERS);
// By default, we have no result logged in
assertNull(service.getTestConnectionResult());
APIService updatedService =
ApiService updatedService =
putTestConnectionResult(service.getId(), TEST_CONNECTION_RESULT, ADMIN_AUTH_HEADERS);
// Validate that the data got properly stored
assertNotNull(updatedService.getTestConnectionResult());
@ -135,50 +135,50 @@ public class APIServiceResourceTest extends ServiceResourceTest<APIService, Crea
updatedService.getTestConnectionResult().getStatus());
assertEquals(updatedService.getConnection(), service.getConnection());
// Check that the stored data is also correct
APIService stored = getEntity(service.getId(), ADMIN_AUTH_HEADERS);
ApiService stored = getEntity(service.getId(), ADMIN_AUTH_HEADERS);
assertNotNull(stored.getTestConnectionResult());
assertEquals(
TestConnectionResultStatus.SUCCESSFUL, stored.getTestConnectionResult().getStatus());
assertEquals(stored.getConnection(), service.getConnection());
}
public APIService putTestConnectionResult(
public ApiService putTestConnectionResult(
UUID serviceId, TestConnectionResult testConnectionResult, Map<String, String> authHeaders)
throws HttpResponseException {
WebTarget target = getResource(serviceId).path("/testConnectionResult");
return TestUtils.put(target, testConnectionResult, APIService.class, OK, authHeaders);
return TestUtils.put(target, testConnectionResult, ApiService.class, OK, authHeaders);
}
@Override
public CreateAPIService createRequest(String name) {
return new CreateAPIService()
public CreateApiService createRequest(String name) {
return new CreateApiService()
.withName(name)
.withServiceType(CreateAPIService.APIServiceType.REST)
.withServiceType(CreateApiService.ApiServiceType.Rest)
.withConnection(
new APIServiceConnection()
new ApiConnection()
.withConfig(
new RESTConnection()
new RestConnection()
.withOpenAPISchemaURL(
CommonUtil.getUri("http://localhost:8585/swagger.json"))));
}
@Override
public void validateCreatedEntity(
APIService service, CreateAPIService createRequest, Map<String, String> authHeaders) {
ApiService service, CreateApiService createRequest, Map<String, String> authHeaders) {
assertEquals(createRequest.getName(), service.getName());
APIServiceConnection expectedConnection = createRequest.getConnection();
APIServiceConnection actualConnection = service.getConnection();
ApiConnection expectedConnection = createRequest.getConnection();
ApiConnection actualConnection = service.getConnection();
validateConnection(expectedConnection, actualConnection, service.getServiceType());
}
@Override
public void compareEntities(
APIService expected, APIService updated, Map<String, String> authHeaders) {
ApiService expected, ApiService updated, Map<String, String> authHeaders) {
// PATCH operation is not supported by this entity
}
@Override
public APIService validateGetWithDifferentFields(APIService service, boolean byName)
public ApiService validateGetWithDifferentFields(ApiService service, boolean byName)
throws HttpResponseException {
String fields = "";
service =
@ -209,13 +209,13 @@ public class APIServiceResourceTest extends ServiceResourceTest<APIService, Crea
}
private void validateConnection(
APIServiceConnection expectedConnection,
APIServiceConnection actualConnection,
CreateAPIService.APIServiceType serviceType) {
ApiConnection expectedConnection,
ApiConnection actualConnection,
CreateApiService.ApiServiceType serviceType) {
if (expectedConnection != null && actualConnection != null) {
RESTConnection restConnection = (RESTConnection) expectedConnection.getConfig();
RESTConnection actualESConnection =
JsonUtils.convertValue(actualConnection.getConfig(), RESTConnection.class);
RestConnection restConnection = (RestConnection) expectedConnection.getConfig();
RestConnection actualESConnection =
JsonUtils.convertValue(actualConnection.getConfig(), RestConnection.class);
assertEquals(restConnection.getOpenAPISchemaURL(), actualESConnection.getOpenAPISchemaURL());
}
}

View File

@ -67,7 +67,7 @@ import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.entity.type.CustomProperty;
import org.openmetadata.schema.entity.type.Style;
import org.openmetadata.schema.security.credentials.AWSCredentials;
import org.openmetadata.schema.services.connections.api.RESTConnection;
import org.openmetadata.schema.services.connections.api.RestConnection;
import org.openmetadata.schema.services.connections.database.BigQueryConnection;
import org.openmetadata.schema.services.connections.database.MysqlConnection;
import org.openmetadata.schema.services.connections.database.RedshiftConnection;
@ -83,7 +83,7 @@ import org.openmetadata.schema.services.connections.pipeline.GluePipelineConnect
import org.openmetadata.schema.services.connections.search.ElasticSearchConnection;
import org.openmetadata.schema.services.connections.search.OpenSearchConnection;
import org.openmetadata.schema.services.connections.storage.S3Connection;
import org.openmetadata.schema.type.APIServiceConnection;
import org.openmetadata.schema.type.ApiConnection;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.MessagingConnection;
import org.openmetadata.schema.type.MlModelConnection;
@ -183,10 +183,10 @@ public final class TestUtils {
new SearchConnection()
.withConfig(new OpenSearchConnection().withHostPort("http://localhost:9200"));
public static final APIServiceConnection API_SERVICE_CONNECTION =
new APIServiceConnection()
public static final ApiConnection API_SERVICE_CONNECTION =
new ApiConnection()
.withConfig(
new RESTConnection()
new RestConnection()
.withOpenAPISchemaURL(getUri("http://localhost:8585/swagger.json")));
public static final MetadataConnection AMUNDSEN_CONNECTION =

View File

@ -1,10 +1,10 @@
{
"$id": "https://open-metadata.org/schema/api/services/createAPIService.json",
"$id": "https://open-metadata.org/schema/api/services/createApiService.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CreateApiServiceRequest",
"description": "Create API Service entity request",
"type": "object",
"javaType": "org.openmetadata.schema.api.services.CreateAPIService",
"javaType": "org.openmetadata.schema.api.services.CreateApiService",
"javaInterfaces": ["org.openmetadata.schema.CreateEntity"],
"properties": {
@ -21,10 +21,10 @@
"$ref": "../../type/basic.json#/definitions/markdown"
},
"serviceType": {
"$ref": "../../entity/services/apiService.json#/definitions/APIServiceType"
"$ref": "../../entity/services/apiService.json#/definitions/apiServiceType"
},
"connection": {
"$ref": "../../entity/services/apiService.json#/definitions/apiServiceConnection"
"$ref": "../../entity/services/apiService.json#/definitions/apiConnection"
},
"tags": {
"description": "Tags for this API Service.",

View File

@ -9,6 +9,9 @@
"connection": {
"description": "Connection object.",
"oneOf": [
{
"$ref": "../services/apiService.json#/definitions/apiConnection"
},
{
"$ref": "../services/databaseService.json#/definitions/databaseConnection"
},

View File

@ -74,7 +74,7 @@
},
"serviceType": {
"description": "Service type where this API Collection is hosted in.",
"$ref": "../services/apiService.json#/definitions/APIServiceType"
"$ref": "../services/apiService.json#/definitions/apiServiceType"
},
"changeDescription": {
"description": "Change that lead to this version of the entity.",

View File

@ -136,7 +136,7 @@
},
"serviceType": {
"description": "Service type where this API Collection is hosted in.",
"$ref": "../services/apiService.json#/definitions/APIServiceType"
"$ref": "../services/apiService.json#/definitions/apiServiceType"
},
"changeDescription": {
"description": "Change that lead to this version of the entity.",

View File

@ -1,37 +1,37 @@
{
"$id": "https://open-metadata.org/schema/entity/services/apiService.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "API Service",
"title": "Api Service",
"description": "This schema defines the API Service entity, to capture metadata from any REST API Services.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.services.APIService",
"javaType": "org.openmetadata.schema.entity.services.ApiService",
"javaInterfaces": [
"org.openmetadata.schema.EntityInterface",
"org.openmetadata.schema.ServiceEntityInterface"
],
"definitions": {
"APIServiceType": {
"apiServiceType": {
"description": "Type of api service such as REST, Webhook,...",
"javaInterfaces": [
"org.openmetadata.schema.EnumInterface"
],
"type": "string",
"enum": [
"REST",
"Rest",
"WEBHOOK"
],
"javaEnums": [
{
"name": "REST"
"name": "Rest"
},
{
"name": "WEBHOOK"
}
]
},
"apiServiceConnection": {
"apiConnection": {
"type": "object",
"javaType": "org.openmetadata.schema.type.APIServiceConnection",
"javaType": "org.openmetadata.schema.type.ApiConnection",
"description": "API Service Connection.",
"javaInterfaces": [
"org.openmetadata.schema.ServiceConnectionEntityInterface"
@ -41,7 +41,7 @@
"mask": true,
"oneOf": [
{
"$ref": "./connections/apiService/restConnection.json"
"$ref": "./connections/api/restConnection.json"
}
]
}
@ -68,14 +68,14 @@
},
"serviceType": {
"description": "Type of API service such as REST, WEBHOOK..",
"$ref": "#/definitions/APIServiceType"
"$ref": "#/definitions/apiServiceType"
},
"description": {
"description": "Description of a API service instance.",
"$ref": "../../type/basic.json#/definitions/markdown"
},
"connection": {
"$ref": "#/definitions/apiServiceConnection"
"$ref": "#/definitions/apiConnection"
},
"pipelines": {
"description": "References to pipelines deployed for this API service to extract metadata, usage, lineage etc..",

View File

@ -1,24 +1,24 @@
{
"$id": "https://open-metadata.org/schema/entity/services/connections/apiService/restConnection.json",
"$id": "https://open-metadata.org/schema/entity/services/connections/api/restConnection.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "RESTConnection",
"title": "RestConnection",
"description": "REST Connection Config",
"type": "object",
"javaType": "org.openmetadata.schema.services.connections.api.RESTConnection",
"javaType": "org.openmetadata.schema.services.connections.api.RestConnection",
"definitions": {
"RESTAPIType": {
"restType": {
"description": "REST API type",
"type": "string",
"enum": ["REST"],
"default": "REST"
"enum": ["Rest"],
"default": "Rest"
}
},
"properties": {
"type": {
"title": "REST API Type",
"description": "REST API Type",
"$ref": "#/definitions/RESTAPIType",
"default": "REST"
"$ref": "#/definitions/restType",
"default": "Rest"
},
"openAPISchemaURL": {
"expose": true,

View File

@ -9,7 +9,7 @@
"description": "Supported services",
"oneOf": [
{
"$ref": "../apiService.json#/definitions/apiServiceConnection"
"$ref": "../apiService.json#/definitions/apiConnection"
},
{
"$ref": "../dashboardService.json#/definitions/dashboardConnection"

View File

@ -14,7 +14,7 @@
"Pipeline",
"Storage",
"Search",
"API"
"Api"
],
"additionalProperties": false
}

View File

@ -35,7 +35,7 @@ test.describe('API service', () => {
await settingClick(page, GlobalSettingOptions.APIS);
await page.getByTestId('add-service-button').click();
await page.getByTestId('REST').click();
await page.getByTestId('Rest').click();
await page.getByTestId('next-button').click();
// step 1

View File

@ -16,6 +16,7 @@ import { PLAYWRIGHT_INGESTION_TAG_OBJ } from '../../constant/config';
import { MYSQL, POSTGRES, REDSHIFT } from '../../constant/service';
import { GlobalSettingOptions } from '../../constant/settings';
import AirflowIngestionClass from '../../support/entity/ingestion/AirflowIngestionClass';
import ApiIngestionClass from '../../support/entity/ingestion/ApiIngestionClass';
import BigQueryIngestionClass from '../../support/entity/ingestion/BigQueryIngestionClass';
import KafkaIngestionClass from '../../support/entity/ingestion/KafkaIngestionClass';
import MetabaseIngestionClass from '../../support/entity/ingestion/MetabaseIngestionClass';
@ -30,6 +31,7 @@ import { INVALID_NAMES, redirectToHomePage } from '../../utils/common';
import { settingClick, SettingOptionsType } from '../../utils/sidebar';
const services = [
ApiIngestionClass,
S3IngestionClass,
MetabaseIngestionClass,
MysqlIngestionClass,

View File

@ -24,10 +24,10 @@ export class ApiCollectionClass extends EntityClass {
private apiCollectionName = `pw-api-collection-${uuid()}`;
service = {
name: this.serviceName,
serviceType: 'REST',
serviceType: 'Rest',
connection: {
config: {
type: 'REST',
type: 'Rest',
openAPISchemaURL: 'https://sandbox-beta.open-metadata.org/swagger.json',
},
},

View File

@ -23,10 +23,10 @@ export class ApiEndpointClass extends EntityClass {
private apiCollectionName = `pw-api-collection-${uuid()}`;
service = {
name: this.serviceName,
serviceType: 'REST',
serviceType: 'Rest',
connection: {
config: {
type: 'REST',
type: 'Rest',
openAPISchemaURL: 'https://sandbox-beta.open-metadata.org/swagger.json',
},
},

View File

@ -0,0 +1,47 @@
/*
* Copyright 2024 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Page } from '@playwright/test';
import { uuid } from '../../../utils/common';
import {
checkServiceFieldSectionHighlighting,
Services,
} from '../../../utils/serviceIngestion';
import ServiceBaseClass from './ServiceBaseClass';
class ApiIngestionClass extends ServiceBaseClass {
constructor() {
super(Services.API, `pw-api-with-%-${uuid()}`, 'Rest', 'Containers');
}
async createService(page: Page) {
await super.createService(page);
}
async updateService(page: Page) {
await super.updateService(page);
}
async fillConnectionDetails(page: Page) {
const openAPISchemaURL = 'https://docs.open-metadata.org/swagger.json';
await page.locator('#root\\/openAPISchemaURL').fill(openAPISchemaURL);
await checkServiceFieldSectionHighlighting(page, 'openAPISchemaURL');
}
async deleteService(page: Page): Promise<void> {
await super.deleteService(page);
}
}
export default ApiIngestionClass;

View File

@ -21,10 +21,10 @@ import { EntityClass } from '../EntityClass';
export class ApiServiceClass extends EntityClass {
entity = {
name: `pw-api-service-${uuid()}`,
serviceType: 'REST',
serviceType: 'Rest',
connection: {
config: {
type: 'REST',
type: 'Rest',
openAPISchemaURL: 'https://sandbox-beta.open-metadata.org/swagger.json',
},
},

View File

@ -24,6 +24,7 @@ export enum Services {
MLModels = GlobalSettingOptions.MLMODELS,
Storage = GlobalSettingOptions.STORAGES,
Search = GlobalSettingOptions.SEARCH,
API = GlobalSettingOptions.APIS,
}
export const getEntityTypeFromService = (service: Services) => {
@ -42,6 +43,8 @@ export const getEntityTypeFromService = (service: Services) => {
return EntityTypeEndpoint.MlModelService;
case Services.Pipeline:
return EntityTypeEndpoint.PipelineService;
case Services.API:
return EntityTypeEndpoint.ApiService;
default:
return EntityTypeEndpoint.DatabaseService;
}
@ -63,6 +66,8 @@ export const getServiceCategoryFromService = (service: Services) => {
return 'mlmodelService';
case Services.Pipeline:
return 'pipelineService';
case Services.API:
return 'apiService';
default:
return 'databaseService';
}

View File

@ -0,0 +1,44 @@
# Metadata
API Service Metadata Pipeline Configuration.
$$section
### API Collection Filter Pattern $(id="apiCollectionFilterPattern")
API Collection filter patterns to control whether to include API Collections as part of metadata ingestion.
**Include**: Explicitly include API Collections by adding a list of regular expressions to the `Include` field. OpenMetadata will include all API Collections with names matching one or more of the supplied regular expressions. All other API Collections will be excluded.
For example, to include only those API Collections whose name starts with the word `demo`, add the regex pattern in the include field as `^demo.*`.
**Exclude**: Explicitly exclude API Collections by adding a list of regular expressions to the `Exclude` field. OpenMetadata will exclude all API Collections with names matching one or more of the supplied regular expressions. All other API Collections will be included.
For example, to exclude all API Collections with the name containing the word `demo`, add the regex pattern in the exclude field as `.*demo.*`.
Checkout [this](https://docs.open-metadata.org/connectors/ingestion/workflows/metadata/filter-patterns/database#database-filter-pattern) document for further examples on filter patterns.
$$
$$section
### Enable Debug Logs $(id="enableDebugLog")
Set the `Enable Debug Log` toggle to set the logging level of the process to debug. You can check these logs in the Ingestion tab of the service and dig deeper into any errors you might find.
$$
$$section
### Mark Deleted API Collection $(id="markDeletedApiCollections")
Optional configuration to soft delete `API Collections` in OpenMetadata if the source `API Collections` are deleted. After deleting, all the associated entities like lineage, etc., with that `API Collection` will be deleted.
$$
$$section
### Override Metadata $(id="overrideMetadata")
Set the `Override Metadata` toggle to control whether to override the existing metadata in the OpenMetadata server with the metadata fetched from the source.
If the toggle is `enabled`, the metadata fetched from the source will override and replace the existing metadata in the OpenMetadata.
If the toggle is `disabled`, the metadata fetched from the source will not override the existing metadata in the OpenMetadata server. In this case the metadata will only get updated for fields that has no value added in OpenMetadata.
This is applicable for fields like description, tags, owner and displayName
$$

View File

@ -243,13 +243,10 @@ const AddService = ({
{activeServiceStep > 3 && (
<SuccessScreen
showIngestionButton
handleIngestionClick={() => handleAddIngestion(true)}
handleViewServiceClick={handleViewServiceClick}
name={serviceConfig.serviceName}
// API Service does not support ingestion workflows
showIngestionButton={
serviceCategory !== ServiceCategory.API_SERVICES
}
state={FormSubmitType.ADD}
suffix={getServiceCreatedLabel(serviceCategory)}
/>

View File

@ -83,14 +83,16 @@ const ServiceDocPanel: FC<ServiceDocPanelProp> = ({
const fetchRequirement = async () => {
setIsLoading(true);
try {
const supportedServiceType =
serviceType === 'Api' ? 'ApiEntity' : serviceType;
let response = '';
const isEnglishLanguage = i18n.language === SupportedLocales.English;
let filePath = `${i18n.language}/${serviceType}/${serviceName}.md`;
let fallbackFilePath = `${SupportedLocales.English}/${serviceType}/${serviceName}.md`;
let filePath = `${i18n.language}/${supportedServiceType}/${serviceName}.md`;
let fallbackFilePath = `${SupportedLocales.English}/${supportedServiceType}/${serviceName}.md`;
if (isWorkflow && workflowType) {
filePath = `${i18n.language}/${serviceType}/workflows/${workflowType}.md`;
fallbackFilePath = `${SupportedLocales.English}/${serviceType}/workflows/${workflowType}.md`;
filePath = `${i18n.language}/${supportedServiceType}/workflows/${workflowType}.md`;
fallbackFilePath = `${SupportedLocales.English}/${supportedServiceType}/workflows/${workflowType}.md`;
}
const [translation, fallbackTranslation] = await Promise.allSettled([

View File

@ -417,7 +417,6 @@ export const BETA_SERVICES = [
PipelineServiceType.OpenLineage,
PipelineServiceType.Flink,
DatabaseServiceType.Teradata,
APIServiceType.REST,
StorageServiceType.Gcs,
DatabaseServiceType.SapERP,
PipelineServiceType.Flink,

View File

@ -1021,22 +1021,21 @@ const ServiceDetailsPage: FunctionComponent = () => {
});
}
if (serviceCategory !== ServiceCategory.API_SERVICES) {
tabs.push({
tabs.push(
{
name: t('label.ingestion-plural'),
key: EntityTabs.INGESTIONS,
isHidden: !showIngestionTab,
count: ingestionPaging.total,
children: ingestionTab,
});
}
tabs.push({
name: t('label.connection'),
isHidden: !servicePermission.EditAll,
key: EntityTabs.CONNECTION,
children: testConnectionTab,
});
},
{
name: t('label.connection'),
isHidden: !servicePermission.EditAll,
key: EntityTabs.CONNECTION,
children: testConnectionTab,
}
);
return tabs
.filter((tab) => !tab.isHidden)

View File

@ -105,8 +105,7 @@ const ServicesPage = () => {
label: 'Services',
},
]),
// pipelines are not supported for apiServices so don't show pipelines tab for apiServices
...(isAdminUser && serviceName !== 'apiServices'
...(isAdminUser
? [
{
key: 'pipelines',

View File

@ -13,14 +13,14 @@
import { cloneDeep } from 'lodash';
import { COMMON_UI_SCHEMA } from '../constants/Services.constant';
import { APIServiceType } from '../generated/entity/services/apiService';
import RESTConnection from '../jsons/connectionSchemas/connections/apiService/restConnection.json';
import restConnection from '../jsons/connectionSchemas/connections/api/restConnection.json';
export const getAPIConfig = (type: APIServiceType) => {
let schema = {};
const uiSchema = { ...COMMON_UI_SCHEMA };
switch (type) {
case APIServiceType.REST:
schema = RESTConnection;
schema = restConnection;
break;

View File

@ -117,6 +117,16 @@ class GlobalSettingsClassBase {
icon: ServiceIcon,
description: t('message.service-description'),
items: [
{
label: t('label.api-uppercase-plural'),
description: t('message.page-sub-header-for-apis'),
isProtected: userPermissions.hasViewPermissions(
ResourceEntity.API_SERVICE,
permissions
),
key: `${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.APIS}`,
icon: IconAPI,
},
{
label: t('label.database-plural'),
description: t('message.page-sub-header-for-databases'),
@ -197,17 +207,6 @@ class GlobalSettingsClassBase {
key: `${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.METADATA}`,
icon: OpenMetadataIcon,
},
{
label: t('label.api-uppercase-plural'),
description: t('message.page-sub-header-for-apis'),
isProtected: userPermissions.hasViewPermissions(
ResourceEntity.API_SERVICE,
permissions
),
key: `${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.APIS}`,
icon: IconAPI,
isBeta: true,
},
{
label: t('label.data-observability'),
description: t('message.page-sub-header-for-data-observability'),

View File

@ -29,7 +29,6 @@ import { ServiceCategory } from '../enums/service.enum';
import { StorageServiceType } from '../generated/entity/data/container';
import { Database } from '../generated/entity/data/database';
import { MlModelServiceType } from '../generated/entity/data/mlmodel';
import { APIServiceType } from '../generated/entity/services/apiService';
import {
DashboardService,
DashboardServiceType,
@ -100,8 +99,7 @@ export const shouldTestConnection = (serviceType: string) => {
serviceType !== DashboardServiceType.CustomDashboard &&
serviceType !== MlModelServiceType.CustomMlModel &&
serviceType !== PipelineServiceType.CustomPipeline &&
serviceType !== StorageServiceType.CustomStorage &&
serviceType !== APIServiceType.REST
serviceType !== StorageServiceType.CustomStorage
);
};
@ -348,7 +346,7 @@ export const getServiceRouteFromServiceType = (type: ServiceTypes) => {
return GlobalSettingOptions.SEARCH;
}
if (type === 'apiServices') {
if (type === ServiceCategory.API_SERVICES) {
return GlobalSettingOptions.APIS;
}
@ -387,7 +385,6 @@ export const getResourceEntityFromServiceCategory = (
case ServiceCategory.STORAGE_SERVICES:
return ResourceEntity.STORAGE_SERVICE;
case 'apiServices':
case ServiceCategory.API_SERVICES:
return ResourceEntity.API_SERVICE;
}