From 02453da7b005272a1efa8161d2bf13295cba2464 Mon Sep 17 00:00:00 2001 From: Ashera Silva Date: Fri, 22 Mar 2024 01:53:20 +0530 Subject: [PATCH 1/4] Add devportal rest api changes for API Chat feature --- .../carbon/apimgt/api/ExceptionCodes.java | 6 +- .../wso2/carbon/apimgt/impl/APIConstants.java | 8 + .../carbon/apimgt/impl/utils/APIUtil.java | 72 ++++++ .../src/main/resources/devportal-api.yaml | 232 ++++++++++++++++++ .../apimgt/rest/api/publisher/v1/ApisApi.java | 3 +- .../apimgt/rest/api/store/v1/ApisApi.java | 39 +++ .../rest/api/store/v1/ApisApiService.java | 5 + .../dto/ApiChatExecuteRequestApiSpecDTO.java | 107 ++++++++ .../v1/dto/ApiChatExecuteRequestDTO.java | 126 ++++++++++ .../dto/ApiChatExecuteRequestResponseDTO.java | 147 +++++++++++ .../v1/dto/ApiChatExecuteResponseDTO.java | 158 ++++++++++++ .../ApiChatExecuteResponseResourceDTO.java | 125 ++++++++++ .../v1/dto/ApiChatPreparationResponseDTO.java | 110 +++++++++ .../api/store/v1/dto/EnrichedAPISpecDTO.java | 108 ++++++++ .../rest/api/store/v1/dto/HttpToolDTO.java | 227 +++++++++++++++++ .../rest/api/store/v1/dto/SampleQueryDTO.java | 105 ++++++++ .../rest/api/store/v1/dto/SettingsDTO.java | 46 +++- .../api/store/v1/impl/ApisApiServiceImpl.java | 76 +++++- .../v1/mappings/SettingsMappingUtil.java | 2 + .../src/main/resources/devportal-api.yaml | 232 ++++++++++++++++++ .../repository/conf/api-manager.xml.j2 | 28 +++ .../src/main/resources/config/api-manager.xml | 28 +++ 22 files changed, 1985 insertions(+), 5 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestApiSpecDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestResponseDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseResourceDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatPreparationResponseDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/EnrichedAPISpecDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/HttpToolDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SampleQueryDTO.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java index 5b9d2ff2859d..ef13a401622d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java @@ -548,7 +548,11 @@ public enum ExceptionCodes implements ErrorHandler { KEY_MANAGER_RESTRICTED_FOR_USER(902013, "Unauthorized Access to Key Manager", 403, "Key Manager is Restricted for this user"), // Admin portal get apis and api provider change related errors CHANGE_API_PROVIDER_FAILED(903011, "Error while changing the API provider", 500, "Error while changing the API provider in the registry or DB"), - GET_SEARCH_APIS_IN_ADMIN_FAILED(903012, "Error while getting the apis", 500, "Error while getting/searching the apis from registry"); + GET_SEARCH_APIS_IN_ADMIN_FAILED(903012, "Error while getting the apis", 500, "Error while getting/searching the apis from registry"), + + // AI service invocation related exceptions + AI_SERVICE_INVALID_RESPONSE(903100, "Invalid response from AI service", 500, "Error while invoking AI service. %s", false), + AI_SERVICE_INVALID_ACCESS_TOKEN(900906, "Invalid access token provided for AI service", 401, "Invalid access token provided for AI service"); private final long errorCode; private final String errorMessage; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 54025328e251..92a23a675f2f 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -501,6 +501,14 @@ public final class APIConstants { public static final String DIGEST = "x5t#S256"; public static final String CNF = "cnf"; + // Constants related to AI features: API chat and Marketplace Assistant + public static final String API_CHAT = "APIChat."; + public static final String API_CHAT_ENABLED = API_CHAT + "Enabled"; + public static final String API_CHAT_AUTH_TOKEN = API_CHAT + "AuthToken"; + public static final String API_CHAT_ENDPOINT = API_CHAT + "Endpoint"; + public static final String API_CHAT_PREPARE_RESOURCE = "/prepare"; // "/api-chat/prepare" + public static final String API_CHAT_EXECUTE_RESOURCE = "/chat"; // "/api-chat/chat" + //documentation rxt public static final String DOC_NAME = "overview_name"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java index 6a43f7b4444d..8cf1d483a15f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java @@ -10371,4 +10371,76 @@ public static String getScopesAsString(Set scopes) { } return scopesStringBuilder.toString().trim(); } + + /** + * Check whether API Chat feature is enabled + * + * @return returns true if API Chat feature is enabled, false if disabled. + */ + public static boolean isApiChatEnabled() { + + APIManagerConfiguration config = ServiceReferenceHolder.getInstance(). + getAPIManagerConfigurationService().getAPIManagerConfiguration(); + String isApiChatEnabled = config.getFirstProperty(APIConstants.API_CHAT_ENABLED); + if (isApiChatEnabled == null) { + return false; + } + + return Boolean.parseBoolean(isApiChatEnabled); + } + + /** + * Checks whether an auth token is provided for AI features to use. This token is utilized for authentication and + * throttling purposes. + * + * @return returns true if a valid auth token is found, false otherwise. + */ + public static boolean isAuthTokenProvidedForAIFeatures() { + APIManagerConfiguration config = ServiceReferenceHolder.getInstance(). + getAPIManagerConfigurationService().getAPIManagerConfiguration(); + String authToken = config.getFirstProperty(APIConstants.API_CHAT_AUTH_TOKEN); + if (authToken == null || authToken.equals("")) { + return false; + } + return true; + } + + public static String invokeAIService(String endpointConfigName, String authTokenConfigName, + String resource, String payload, String requestId) throws APIManagementException { + + APIManagerConfiguration config = ServiceReferenceHolder.getInstance(). + getAPIManagerConfigurationService().getAPIManagerConfiguration(); + String endpoint = config.getFirstProperty(endpointConfigName); + String authToken = config.getFirstProperty(authTokenConfigName); + try { + HttpPost preparePost = new HttpPost(endpoint + resource); + preparePost.setHeader(HttpHeaders.AUTHORIZATION, APIConstants.AUTHORIZATION_BEARER + authToken); + preparePost.setHeader(HttpHeaders.CONTENT_TYPE, APIConstants.APPLICATION_JSON_MEDIA_TYPE); + preparePost.setHeader("x-request-id", requestId); + StringEntity requestEntity = new StringEntity(payload, ContentType.APPLICATION_JSON); + preparePost.setEntity(requestEntity); + + URL url = new URL(endpoint); + int port = url.getPort(); + String protocol = url.getProtocol(); + HttpClient httpClient = APIUtil.getHttpClient(port, protocol); + + CloseableHttpResponse response = executeHTTPRequest(preparePost, httpClient); + int statusCode = response.getStatusLine().getStatusCode(); + String responseStr = EntityUtils.toString(response.getEntity()); + if (statusCode == HttpStatus.SC_CREATED) { + return responseStr; + } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) { + throw new APIManagementException("Unexpected response detected from the AI service." + responseStr, + ExceptionCodes.AI_SERVICE_INVALID_ACCESS_TOKEN); + } else { + throw new APIManagementException("Unexpected response detected from the AI service." + responseStr, + ExceptionCodes.AI_SERVICE_INVALID_RESPONSE); + } + } catch (MalformedURLException e) { + throw new APIManagementException("Invalid/malformed URL encountered. URL: " + endpoint, e); + } catch (APIManagementException | IOException e) { + throw new APIManagementException("Error encountered while connecting to service", e); + } + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/devportal-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/devportal-api.yaml index 26019f4337fe..f4e954d339ad 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/devportal-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/devportal-api.yaml @@ -3575,6 +3575,89 @@ paths: - lang: Curl source: curl -k "https://localhost:9443/api/am/devportal/v3/apis/e93fb282-b456-48fc-8981-003fb89086ae/graphql-policies/complexity/types" + ###################################################### + # The "API Chat Feature" resource APIs + ###################################################### + /apis/{apiId}/api-chat/prepare: + + #----------------------------------------------------- + # Prepare API Chat for user queries by feeding spec + #----------------------------------------------------- + post: + security: + - OAuth2Security: + - apim:subscribe + summary: Prepare API Chat service by feeding the OpenAPI specification of the API to be tested + description: | + Processing the OpenAPI specification to extract the API endpoint definitions and generate sample queries + operationId: apiChatPrepare + parameters: + - $ref: '#/components/parameters/apiId' + - $ref: '#/components/parameters/apiChatRequestId' + tags: + - API Chat + responses: + 201: + description: | + Created. + API Chat preparation completed. Successful response with enriched API specification and sample queries. + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatPreparationResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while preparing the API Chat service. + + /apis/{apiId}/api-chat/execute: + + #----------------------------------------------------- + # Execute test specified via API Chat + #----------------------------------------------------- + post: + security: + - OAuth2Security: + - apim:subscribe + summary: Execute a single API test case while caching the progress + description: | + Executes a test scenario against an API; which iteratively provide resources that need to be + invoked alongside the inputs such as parameters, payloads, etc. while caching the progress. + operationId: apiChatExecute + parameters: + - $ref: '#/components/parameters/apiId' + - $ref: '#/components/parameters/apiChatRequestId' + requestBody: + description: | + API Chat execute request payload + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatExecuteRequest' + tags: + - API Chat + responses: + 201: + description: | + Created. + API Chat execute response payload. + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatExecuteResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while executing test using API Chat service. + ###################################################### # User resource APIs ###################################################### @@ -5319,6 +5402,14 @@ components: properties too will affect the maximum password length allowed and an intersection of all conditions will be considered finally to validate the password. + isApiChatEnabled: + type: boolean + description: Specifies whether API Chat feature is enabled. + default: true + isAIFeatureAuthTokenProvided: + type: boolean + description: Checks if the auth token is provided for AI service usage. + default: false ApplicationAttribute: title: Application attributes type: object @@ -5747,6 +5838,140 @@ components: type: array items: type: string + ApiChatPreparationResponse: + title: API Chat preparation response + required: + - apiSpec + - queries + properties: + apiSpec: + type: object + title: Enriched API spec + required: + - tools + properties: + serviceUrl: + type: string + description: Extracted service URL from the OpenAPI specification if there is any + tools: + type: array + description: Extracted Http tools from the OpenAPI specification + items: + $ref: '#/components/schemas/HttpTool' + queries: + type: array + description: list of sample queries + items: + $ref: '#/components/schemas/SampleQuery' + SampleQuery: + title: API Chat sample query record + required: + - scenario + - query + properties: + scenario: + type: string + description: scenario + query: + type: string + description: generated query + HttpTool: + title: HTTP tool + required: + - description + - method + - name + - path + properties: + name: + type: string + description: Name of the Http resource tool + description: + type: string + description: Description of the Http resource tool used by the LLM + method: + type: string + description: Http method type (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) + enum: + - OPTIONS + - HEAD + - PATCH + - PUT + - DELETE + - POST + - GET + path: + type: string + description: Path of the Http resource + parameters: + type: object + requestBody: + type: object + ApiChatExecuteRequest: + title: API Chat execute request + properties: + command: + type: string + description: | + User specified testcase to be tested against the API + example: "Get pet with id 123" + apiSpec: + type: object + properties: + serviceUrl: + type: string + description: Service URL of API if any + tools: + type: array + description: Extracted Http tools from the OpenAPI specification + items: + $ref: '#/components/schemas/HttpTool' + response: + type: object + properties: + code: + type: integer + description: HTTP status code of the response + example: 201 + path: + type: string + description: HTTP path url with encoded parameters + example: "/order/123" + headers: + type: object + description: Response headers + body: + type: object + description: Response payload + ApiChatExecuteResponse: + title: API Chat execution response + required: + - taskStatus + properties: + taskStatus: + type: string + description: Task status (IN_PROGRESS, TERMINATED or COMPLETED) + enum: + - IN_PROGRESS + - TERMINATED + - COMPLETED + example: COMPLETED + resource: + type: object + properties: + method: + type: string + description: HTTP method of the resource + path: + type: string + description: Path of the resource + inputs: + type: object + description: Input parameters for the resource + result: + type: string + description: completion result + example: "The pet with ID 123 is available. Here are the details: - ID: 123 - Name: asd - Status: available" responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -6090,6 +6315,13 @@ components: required: true schema: type: string + apiChatRequestId: + name: apiChatRequestId + in: header + description: | + Request ID + schema: + type: string securitySchemes: OAuth2Security: type: oauth2 diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index 88c06e182eaf..fef871764b3a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -462,7 +462,8 @@ public Response deleteAPIRevision(@ApiParam(value = "**API ID** consisting of th @ApiOperation(value = "Delete Pending Revision Deployment Workflow Tasks", notes = "This operation can be used to remove pending revision deployment requests that are in pending state ", response = Void.class, authorizations = { @Authorization(value = "OAuth2Security", scopes = { @AuthorizationScope(scope = "apim:api_publish", description = "Publish API"), - @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations") + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:api_create", description = "Create API") }) }, tags={ "API Revisions", }) @ApiResponses(value = { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApi.java index 0d4f45982881..7572fb7f5902 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApi.java @@ -2,6 +2,9 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.dto.APIDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.APIListDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteRequestDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatPreparationResponseDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.CommentDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.CommentListDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.DocumentDTO; @@ -69,6 +72,42 @@ public Response addCommentToAPI(@ApiParam(value = "**API ID** consisting of the return delegate.addCommentToAPI(apiId, postRequestBodyDTO, replyTo, securityContext); } + @POST + @Path("/{apiId}/api-chat/execute") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Execute a single API test case while caching the progress", notes = "Executes a test scenario against an API; which iteratively provide resources that need to be invoked alongside the inputs such as parameters, payloads, etc. while caching the progress. ", response = ApiChatExecuteResponseDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:subscribe", description = "Subscribe API") + }) + }, tags={ "API Chat", }) + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Created. API Chat execute response payload. ", response = ApiChatExecuteResponseDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 401, message = "Unauthorized. The user is not authorized.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error. An error occurred while executing test using API Chat service. ", response = Void.class) }) + public Response apiChatExecute(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "Request ID " )@HeaderParam("apiChatRequestId") String apiChatRequestId, @ApiParam(value = "API Chat execute request payload " ) ApiChatExecuteRequestDTO apiChatExecuteRequestDTO) throws APIManagementException{ + return delegate.apiChatExecute(apiId, apiChatRequestId, apiChatExecuteRequestDTO, securityContext); + } + + @POST + @Path("/{apiId}/api-chat/prepare") + + @Produces({ "application/json" }) + @ApiOperation(value = "Prepare API Chat service by feeding the OpenAPI specification of the API to be tested", notes = "Processing the OpenAPI specification to extract the API endpoint definitions and generate sample queries ", response = ApiChatPreparationResponseDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:subscribe", description = "Subscribe API") + }) + }, tags={ "API Chat", }) + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Created. API Chat preparation completed. Successful response with enriched API specification and sample queries. ", response = ApiChatPreparationResponseDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 401, message = "Unauthorized. The user is not authorized.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error. An error occurred while preparing the API Chat service. ", response = Void.class) }) + public Response apiChatPrepare(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "Request ID " )@HeaderParam("apiChatRequestId") String apiChatRequestId) throws APIManagementException{ + return delegate.apiChatPrepare(apiId, apiChatRequestId, securityContext); + } + @GET @Path("/{apiId}/async-api-specification") diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApiService.java index ca91af87db9e..8440e46a060c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/ApisApiService.java @@ -11,6 +11,9 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.dto.APIDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.APIListDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteRequestDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatPreparationResponseDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.CommentDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.CommentListDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.DocumentDTO; @@ -35,6 +38,8 @@ public interface ApisApiService { public Response addCommentToAPI(String apiId, PostRequestBodyDTO postRequestBodyDTO, String replyTo, MessageContext messageContext) throws APIManagementException; + public Response apiChatExecute(String apiId, String apiChatRequestId, ApiChatExecuteRequestDTO apiChatExecuteRequestDTO, MessageContext messageContext) throws APIManagementException; + public Response apiChatPrepare(String apiId, String apiChatRequestId, MessageContext messageContext) throws APIManagementException; public Response apisApiIdAsyncApiSpecificationGet(String apiId, String environmentName, String ifNoneMatch, String xWSO2Tenant, MessageContext messageContext) throws APIManagementException; public Response apisApiIdDocumentsDocumentIdContentGet(String apiId, String documentId, String xWSO2Tenant, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; public Response apisApiIdDocumentsDocumentIdGet(String apiId, String documentId, String xWSO2Tenant, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestApiSpecDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestApiSpecDTO.java new file mode 100644 index 000000000000..b698882b83c2 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestApiSpecDTO.java @@ -0,0 +1,107 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.HttpToolDTO; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatExecuteRequestApiSpecDTO { + + private String serviceUrl = null; + private List tools = new ArrayList(); + + /** + * Service URL of API if any + **/ + public ApiChatExecuteRequestApiSpecDTO serviceUrl(String serviceUrl) { + this.serviceUrl = serviceUrl; + return this; + } + + + @ApiModelProperty(value = "Service URL of API if any") + @JsonProperty("serviceUrl") + public String getServiceUrl() { + return serviceUrl; + } + public void setServiceUrl(String serviceUrl) { + this.serviceUrl = serviceUrl; + } + + /** + * Extracted Http tools from the OpenAPI specification + **/ + public ApiChatExecuteRequestApiSpecDTO tools(List tools) { + this.tools = tools; + return this; + } + + + @ApiModelProperty(value = "Extracted Http tools from the OpenAPI specification") + @Valid + @JsonProperty("tools") + public List getTools() { + return tools; + } + public void setTools(List tools) { + this.tools = tools; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatExecuteRequestApiSpecDTO apiChatExecuteRequestApiSpec = (ApiChatExecuteRequestApiSpecDTO) o; + return Objects.equals(serviceUrl, apiChatExecuteRequestApiSpec.serviceUrl) && + Objects.equals(tools, apiChatExecuteRequestApiSpec.tools); + } + + @Override + public int hashCode() { + return Objects.hash(serviceUrl, tools); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatExecuteRequestApiSpecDTO {\n"); + + sb.append(" serviceUrl: ").append(toIndentedString(serviceUrl)).append("\n"); + sb.append(" tools: ").append(toIndentedString(tools)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestDTO.java new file mode 100644 index 000000000000..bea6aed85149 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestDTO.java @@ -0,0 +1,126 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteRequestApiSpecDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteRequestResponseDTO; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatExecuteRequestDTO { + + private String command = null; + private ApiChatExecuteRequestApiSpecDTO apiSpec = null; + private ApiChatExecuteRequestResponseDTO response = null; + + /** + * User specified testcase to be tested against the API + **/ + public ApiChatExecuteRequestDTO command(String command) { + this.command = command; + return this; + } + + + @ApiModelProperty(example = "Get pet with id 123", value = "User specified testcase to be tested against the API ") + @JsonProperty("command") + public String getCommand() { + return command; + } + public void setCommand(String command) { + this.command = command; + } + + /** + **/ + public ApiChatExecuteRequestDTO apiSpec(ApiChatExecuteRequestApiSpecDTO apiSpec) { + this.apiSpec = apiSpec; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("apiSpec") + public ApiChatExecuteRequestApiSpecDTO getApiSpec() { + return apiSpec; + } + public void setApiSpec(ApiChatExecuteRequestApiSpecDTO apiSpec) { + this.apiSpec = apiSpec; + } + + /** + **/ + public ApiChatExecuteRequestDTO response(ApiChatExecuteRequestResponseDTO response) { + this.response = response; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("response") + public ApiChatExecuteRequestResponseDTO getResponse() { + return response; + } + public void setResponse(ApiChatExecuteRequestResponseDTO response) { + this.response = response; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatExecuteRequestDTO apiChatExecuteRequest = (ApiChatExecuteRequestDTO) o; + return Objects.equals(command, apiChatExecuteRequest.command) && + Objects.equals(apiSpec, apiChatExecuteRequest.apiSpec) && + Objects.equals(response, apiChatExecuteRequest.response); + } + + @Override + public int hashCode() { + return Objects.hash(command, apiSpec, response); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatExecuteRequestDTO {\n"); + + sb.append(" command: ").append(toIndentedString(command)).append("\n"); + sb.append(" apiSpec: ").append(toIndentedString(apiSpec)).append("\n"); + sb.append(" response: ").append(toIndentedString(response)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestResponseDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestResponseDTO.java new file mode 100644 index 000000000000..5a0417c9855e --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteRequestResponseDTO.java @@ -0,0 +1,147 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatExecuteRequestResponseDTO { + + private Integer code = null; + private String path = null; + private Object headers = null; + private Object body = null; + + /** + * HTTP status code of the response + **/ + public ApiChatExecuteRequestResponseDTO code(Integer code) { + this.code = code; + return this; + } + + + @ApiModelProperty(example = "201", value = "HTTP status code of the response") + @JsonProperty("code") + public Integer getCode() { + return code; + } + public void setCode(Integer code) { + this.code = code; + } + + /** + * HTTP path url with encoded parameters + **/ + public ApiChatExecuteRequestResponseDTO path(String path) { + this.path = path; + return this; + } + + + @ApiModelProperty(example = "/order/123", value = "HTTP path url with encoded parameters") + @JsonProperty("path") + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + /** + * Response headers + **/ + public ApiChatExecuteRequestResponseDTO headers(Object headers) { + this.headers = headers; + return this; + } + + + @ApiModelProperty(value = "Response headers") + @Valid + @JsonProperty("headers") + public Object getHeaders() { + return headers; + } + public void setHeaders(Object headers) { + this.headers = headers; + } + + /** + * Response payload + **/ + public ApiChatExecuteRequestResponseDTO body(Object body) { + this.body = body; + return this; + } + + + @ApiModelProperty(value = "Response payload") + @Valid + @JsonProperty("body") + public Object getBody() { + return body; + } + public void setBody(Object body) { + this.body = body; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatExecuteRequestResponseDTO apiChatExecuteRequestResponse = (ApiChatExecuteRequestResponseDTO) o; + return Objects.equals(code, apiChatExecuteRequestResponse.code) && + Objects.equals(path, apiChatExecuteRequestResponse.path) && + Objects.equals(headers, apiChatExecuteRequestResponse.headers) && + Objects.equals(body, apiChatExecuteRequestResponse.body); + } + + @Override + public int hashCode() { + return Objects.hash(code, path, headers, body); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatExecuteRequestResponseDTO {\n"); + + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" headers: ").append(toIndentedString(headers)).append("\n"); + sb.append(" body: ").append(toIndentedString(body)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseDTO.java new file mode 100644 index 000000000000..6e930e87166f --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseDTO.java @@ -0,0 +1,158 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ApiChatExecuteResponseResourceDTO; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatExecuteResponseDTO { + + + @XmlType(name="TaskStatusEnum") + @XmlEnum(String.class) + public enum TaskStatusEnum { + IN_PROGRESS("IN_PROGRESS"), + TERMINATED("TERMINATED"), + COMPLETED("COMPLETED"); + private String value; + + TaskStatusEnum (String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TaskStatusEnum fromValue(String v) { + for (TaskStatusEnum b : TaskStatusEnum.values()) { + if (String.valueOf(b.value).equals(v)) { + return b; + } + } +return null; + } + } + private TaskStatusEnum taskStatus = null; + private ApiChatExecuteResponseResourceDTO resource = null; + private String result = null; + + /** + * Task status (IN_PROGRESS, TERMINATED or COMPLETED) + **/ + public ApiChatExecuteResponseDTO taskStatus(TaskStatusEnum taskStatus) { + this.taskStatus = taskStatus; + return this; + } + + + @ApiModelProperty(example = "COMPLETED", required = true, value = "Task status (IN_PROGRESS, TERMINATED or COMPLETED)") + @JsonProperty("taskStatus") + @NotNull + public TaskStatusEnum getTaskStatus() { + return taskStatus; + } + public void setTaskStatus(TaskStatusEnum taskStatus) { + this.taskStatus = taskStatus; + } + + /** + **/ + public ApiChatExecuteResponseDTO resource(ApiChatExecuteResponseResourceDTO resource) { + this.resource = resource; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("resource") + public ApiChatExecuteResponseResourceDTO getResource() { + return resource; + } + public void setResource(ApiChatExecuteResponseResourceDTO resource) { + this.resource = resource; + } + + /** + * completion result + **/ + public ApiChatExecuteResponseDTO result(String result) { + this.result = result; + return this; + } + + + @ApiModelProperty(example = "The pet with ID 123 is available. Here are the details: - ID: 123 - Name: asd - Status: available", value = "completion result") + @JsonProperty("result") + public String getResult() { + return result; + } + public void setResult(String result) { + this.result = result; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatExecuteResponseDTO apiChatExecuteResponse = (ApiChatExecuteResponseDTO) o; + return Objects.equals(taskStatus, apiChatExecuteResponse.taskStatus) && + Objects.equals(resource, apiChatExecuteResponse.resource) && + Objects.equals(result, apiChatExecuteResponse.result); + } + + @Override + public int hashCode() { + return Objects.hash(taskStatus, resource, result); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatExecuteResponseDTO {\n"); + + sb.append(" taskStatus: ").append(toIndentedString(taskStatus)).append("\n"); + sb.append(" resource: ").append(toIndentedString(resource)).append("\n"); + sb.append(" result: ").append(toIndentedString(result)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseResourceDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseResourceDTO.java new file mode 100644 index 000000000000..4333b52e1a33 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatExecuteResponseResourceDTO.java @@ -0,0 +1,125 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatExecuteResponseResourceDTO { + + private String method = null; + private String path = null; + private Object inputs = null; + + /** + * HTTP method of the resource + **/ + public ApiChatExecuteResponseResourceDTO method(String method) { + this.method = method; + return this; + } + + + @ApiModelProperty(value = "HTTP method of the resource") + @JsonProperty("method") + public String getMethod() { + return method; + } + public void setMethod(String method) { + this.method = method; + } + + /** + * Path of the resource + **/ + public ApiChatExecuteResponseResourceDTO path(String path) { + this.path = path; + return this; + } + + + @ApiModelProperty(value = "Path of the resource") + @JsonProperty("path") + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + /** + * Input parameters for the resource + **/ + public ApiChatExecuteResponseResourceDTO inputs(Object inputs) { + this.inputs = inputs; + return this; + } + + + @ApiModelProperty(value = "Input parameters for the resource") + @Valid + @JsonProperty("inputs") + public Object getInputs() { + return inputs; + } + public void setInputs(Object inputs) { + this.inputs = inputs; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatExecuteResponseResourceDTO apiChatExecuteResponseResource = (ApiChatExecuteResponseResourceDTO) o; + return Objects.equals(method, apiChatExecuteResponseResource.method) && + Objects.equals(path, apiChatExecuteResponseResource.path) && + Objects.equals(inputs, apiChatExecuteResponseResource.inputs); + } + + @Override + public int hashCode() { + return Objects.hash(method, path, inputs); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatExecuteResponseResourceDTO {\n"); + + sb.append(" method: ").append(toIndentedString(method)).append("\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" inputs: ").append(toIndentedString(inputs)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatPreparationResponseDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatPreparationResponseDTO.java new file mode 100644 index 000000000000..3ff79c596df1 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ApiChatPreparationResponseDTO.java @@ -0,0 +1,110 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.EnrichedAPISpecDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.SampleQueryDTO; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class ApiChatPreparationResponseDTO { + + private EnrichedAPISpecDTO apiSpec = null; + private List queries = new ArrayList(); + + /** + **/ + public ApiChatPreparationResponseDTO apiSpec(EnrichedAPISpecDTO apiSpec) { + this.apiSpec = apiSpec; + return this; + } + + + @ApiModelProperty(required = true, value = "") + @Valid + @JsonProperty("apiSpec") + @NotNull + public EnrichedAPISpecDTO getApiSpec() { + return apiSpec; + } + public void setApiSpec(EnrichedAPISpecDTO apiSpec) { + this.apiSpec = apiSpec; + } + + /** + * list of sample queries + **/ + public ApiChatPreparationResponseDTO queries(List queries) { + this.queries = queries; + return this; + } + + + @ApiModelProperty(required = true, value = "list of sample queries") + @Valid + @JsonProperty("queries") + @NotNull + public List getQueries() { + return queries; + } + public void setQueries(List queries) { + this.queries = queries; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ApiChatPreparationResponseDTO apiChatPreparationResponse = (ApiChatPreparationResponseDTO) o; + return Objects.equals(apiSpec, apiChatPreparationResponse.apiSpec) && + Objects.equals(queries, apiChatPreparationResponse.queries); + } + + @Override + public int hashCode() { + return Objects.hash(apiSpec, queries); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ApiChatPreparationResponseDTO {\n"); + + sb.append(" apiSpec: ").append(toIndentedString(apiSpec)).append("\n"); + sb.append(" queries: ").append(toIndentedString(queries)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/EnrichedAPISpecDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/EnrichedAPISpecDTO.java new file mode 100644 index 000000000000..7e1441a19db3 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/EnrichedAPISpecDTO.java @@ -0,0 +1,108 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.HttpToolDTO; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class EnrichedAPISpecDTO { + + private String serviceUrl = null; + private List tools = new ArrayList(); + + /** + * Extracted service URL from the OpenAPI specification if there is any + **/ + public EnrichedAPISpecDTO serviceUrl(String serviceUrl) { + this.serviceUrl = serviceUrl; + return this; + } + + + @ApiModelProperty(value = "Extracted service URL from the OpenAPI specification if there is any") + @JsonProperty("serviceUrl") + public String getServiceUrl() { + return serviceUrl; + } + public void setServiceUrl(String serviceUrl) { + this.serviceUrl = serviceUrl; + } + + /** + * Extracted Http tools from the OpenAPI specification + **/ + public EnrichedAPISpecDTO tools(List tools) { + this.tools = tools; + return this; + } + + + @ApiModelProperty(required = true, value = "Extracted Http tools from the OpenAPI specification") + @Valid + @JsonProperty("tools") + @NotNull + public List getTools() { + return tools; + } + public void setTools(List tools) { + this.tools = tools; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EnrichedAPISpecDTO enrichedAPISpec = (EnrichedAPISpecDTO) o; + return Objects.equals(serviceUrl, enrichedAPISpec.serviceUrl) && + Objects.equals(tools, enrichedAPISpec.tools); + } + + @Override + public int hashCode() { + return Objects.hash(serviceUrl, tools); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class EnrichedAPISpecDTO {\n"); + + sb.append(" serviceUrl: ").append(toIndentedString(serviceUrl)).append("\n"); + sb.append(" tools: ").append(toIndentedString(tools)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/HttpToolDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/HttpToolDTO.java new file mode 100644 index 000000000000..8b29147ac91c --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/HttpToolDTO.java @@ -0,0 +1,227 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class HttpToolDTO { + + private String name = null; + private String description = null; + + @XmlType(name="MethodEnum") + @XmlEnum(String.class) + public enum MethodEnum { + OPTIONS("OPTIONS"), + HEAD("HEAD"), + PATCH("PATCH"), + PUT("PUT"), + DELETE("DELETE"), + POST("POST"), + GET("GET"); + private String value; + + MethodEnum (String v) { + value = v; + } + + public String value() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static MethodEnum fromValue(String v) { + for (MethodEnum b : MethodEnum.values()) { + if (String.valueOf(b.value).equals(v)) { + return b; + } + } +return null; + } + } + private MethodEnum method = null; + private String path = null; + private Object parameters = null; + private Object requestBody = null; + + /** + * Name of the Http resource tool + **/ + public HttpToolDTO name(String name) { + this.name = name; + return this; + } + + + @ApiModelProperty(required = true, value = "Name of the Http resource tool") + @JsonProperty("name") + @NotNull + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + * Description of the Http resource tool used by the LLM + **/ + public HttpToolDTO description(String description) { + this.description = description; + return this; + } + + + @ApiModelProperty(required = true, value = "Description of the Http resource tool used by the LLM") + @JsonProperty("description") + @NotNull + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + /** + * Http method type (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) + **/ + public HttpToolDTO method(MethodEnum method) { + this.method = method; + return this; + } + + + @ApiModelProperty(required = true, value = "Http method type (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)") + @JsonProperty("method") + @NotNull + public MethodEnum getMethod() { + return method; + } + public void setMethod(MethodEnum method) { + this.method = method; + } + + /** + * Path of the Http resource + **/ + public HttpToolDTO path(String path) { + this.path = path; + return this; + } + + + @ApiModelProperty(required = true, value = "Path of the Http resource") + @JsonProperty("path") + @NotNull + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + /** + **/ + public HttpToolDTO parameters(Object parameters) { + this.parameters = parameters; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("parameters") + public Object getParameters() { + return parameters; + } + public void setParameters(Object parameters) { + this.parameters = parameters; + } + + /** + **/ + public HttpToolDTO requestBody(Object requestBody) { + this.requestBody = requestBody; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("requestBody") + public Object getRequestBody() { + return requestBody; + } + public void setRequestBody(Object requestBody) { + this.requestBody = requestBody; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HttpToolDTO httpTool = (HttpToolDTO) o; + return Objects.equals(name, httpTool.name) && + Objects.equals(description, httpTool.description) && + Objects.equals(method, httpTool.method) && + Objects.equals(path, httpTool.path) && + Objects.equals(parameters, httpTool.parameters) && + Objects.equals(requestBody, httpTool.requestBody); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, method, path, parameters, requestBody); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class HttpToolDTO {\n"); + + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" method: ").append(toIndentedString(method)).append("\n"); + sb.append(" path: ").append(toIndentedString(path)).append("\n"); + sb.append(" parameters: ").append(toIndentedString(parameters)).append("\n"); + sb.append(" requestBody: ").append(toIndentedString(requestBody)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SampleQueryDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SampleQueryDTO.java new file mode 100644 index 000000000000..dcda2162199d --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SampleQueryDTO.java @@ -0,0 +1,105 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.*; + + +import io.swagger.annotations.*; +import java.util.Objects; + +import javax.xml.bind.annotation.*; +import org.wso2.carbon.apimgt.rest.api.common.annotations.Scope; +import com.fasterxml.jackson.annotation.JsonCreator; + +import javax.validation.Valid; + + + +public class SampleQueryDTO { + + private String scenario = null; + private String query = null; + + /** + * scenario + **/ + public SampleQueryDTO scenario(String scenario) { + this.scenario = scenario; + return this; + } + + + @ApiModelProperty(required = true, value = "scenario") + @JsonProperty("scenario") + @NotNull + public String getScenario() { + return scenario; + } + public void setScenario(String scenario) { + this.scenario = scenario; + } + + /** + * generated query + **/ + public SampleQueryDTO query(String query) { + this.query = query; + return this; + } + + + @ApiModelProperty(required = true, value = "generated query") + @JsonProperty("query") + @NotNull + public String getQuery() { + return query; + } + public void setQuery(String query) { + this.query = query; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SampleQueryDTO sampleQuery = (SampleQueryDTO) o; + return Objects.equals(scenario, sampleQuery.scenario) && + Objects.equals(query, sampleQuery.query); + } + + @Override + public int hashCode() { + return Objects.hash(scenario, query); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SampleQueryDTO {\n"); + + sb.append(" scenario: ").append(toIndentedString(scenario)).append("\n"); + sb.append(" query: ").append(toIndentedString(query)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SettingsDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SettingsDTO.java index a5a69be8330b..282c6893324e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SettingsDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/SettingsDTO.java @@ -39,6 +39,8 @@ public class SettingsDTO { private String passwordPolicyPattern = null; private Integer passwordPolicyMinLength = null; private Integer passwordPolicyMaxLength = null; + private Boolean isApiChatEnabled = true; + private Boolean isAIFeatureAuthTokenProvided = false; /** **/ @@ -317,6 +319,42 @@ public void setPasswordPolicyMaxLength(Integer passwordPolicyMaxLength) { this.passwordPolicyMaxLength = passwordPolicyMaxLength; } + /** + * Specifies whether API Chat feature is enabled. + **/ + public SettingsDTO isApiChatEnabled(Boolean isApiChatEnabled) { + this.isApiChatEnabled = isApiChatEnabled; + return this; + } + + + @ApiModelProperty(value = "Specifies whether API Chat feature is enabled.") + @JsonProperty("isApiChatEnabled") + public Boolean isIsApiChatEnabled() { + return isApiChatEnabled; + } + public void setIsApiChatEnabled(Boolean isApiChatEnabled) { + this.isApiChatEnabled = isApiChatEnabled; + } + + /** + * Checks if the auth token is provided for AI service usage. + **/ + public SettingsDTO isAIFeatureAuthTokenProvided(Boolean isAIFeatureAuthTokenProvided) { + this.isAIFeatureAuthTokenProvided = isAIFeatureAuthTokenProvided; + return this; + } + + + @ApiModelProperty(value = "Checks if the auth token is provided for AI service usage.") + @JsonProperty("isAIFeatureAuthTokenProvided") + public Boolean isIsAIFeatureAuthTokenProvided() { + return isAIFeatureAuthTokenProvided; + } + public void setIsAIFeatureAuthTokenProvided(Boolean isAIFeatureAuthTokenProvided) { + this.isAIFeatureAuthTokenProvided = isAIFeatureAuthTokenProvided; + } + @Override public boolean equals(java.lang.Object o) { @@ -342,12 +380,14 @@ public boolean equals(java.lang.Object o) { Objects.equals(userStorePasswordPattern, settings.userStorePasswordPattern) && Objects.equals(passwordPolicyPattern, settings.passwordPolicyPattern) && Objects.equals(passwordPolicyMinLength, settings.passwordPolicyMinLength) && - Objects.equals(passwordPolicyMaxLength, settings.passwordPolicyMaxLength); + Objects.equals(passwordPolicyMaxLength, settings.passwordPolicyMaxLength) && + Objects.equals(isApiChatEnabled, settings.isApiChatEnabled) && + Objects.equals(isAIFeatureAuthTokenProvided, settings.isAIFeatureAuthTokenProvided); } @Override public int hashCode() { - return Objects.hash(grantTypes, scopes, applicationSharingEnabled, mapExistingAuthApps, apiGatewayEndpoint, monetizationEnabled, recommendationEnabled, isUnlimitedTierPaid, identityProvider, isAnonymousModeEnabled, isPasswordChangeEnabled, isJWTEnabledForLoginTokens, userStorePasswordPattern, passwordPolicyPattern, passwordPolicyMinLength, passwordPolicyMaxLength); + return Objects.hash(grantTypes, scopes, applicationSharingEnabled, mapExistingAuthApps, apiGatewayEndpoint, monetizationEnabled, recommendationEnabled, isUnlimitedTierPaid, identityProvider, isAnonymousModeEnabled, isPasswordChangeEnabled, isJWTEnabledForLoginTokens, userStorePasswordPattern, passwordPolicyPattern, passwordPolicyMinLength, passwordPolicyMaxLength, isApiChatEnabled, isAIFeatureAuthTokenProvided); } @Override @@ -371,6 +411,8 @@ public String toString() { sb.append(" passwordPolicyPattern: ").append(toIndentedString(passwordPolicyPattern)).append("\n"); sb.append(" passwordPolicyMinLength: ").append(toIndentedString(passwordPolicyMinLength)).append("\n"); sb.append(" passwordPolicyMaxLength: ").append(toIndentedString(passwordPolicyMaxLength)).append("\n"); + sb.append(" isApiChatEnabled: ").append(toIndentedString(isApiChatEnabled)).append("\n"); + sb.append(" isAIFeatureAuthTokenProvided: ").append(toIndentedString(isAIFeatureAuthTokenProvided)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java index 1b73b466d5cd..f3b82cffbe70 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java @@ -50,8 +50,10 @@ import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.store.v1.ApisApiService; - +import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -265,6 +267,78 @@ public Response addCommentToAPI(String apiId, PostRequestBodyDTO postRequestBody return null; } + @Override + public Response apiChatExecute(String apiId, String apiChatRequestId, + ApiChatExecuteRequestDTO apiChatExecuteRequestDTO, MessageContext messageContext) + throws APIManagementException { + if (StringUtils.isEmpty(apiChatRequestId)) { + String errorMessage = "Error executing the API Chat service. Request UUID is a required parameter"; + RestApiUtil.handleBadRequest(errorMessage, log); + return null; + } + + // Determine whether the request body is valid. Request should either initialize test or provide + // test execution progress. + boolean isTestInitializationRequest = !StringUtils.isEmpty(apiChatExecuteRequestDTO.getCommand()) && apiChatExecuteRequestDTO.getApiSpec() != null; + boolean isTestExecutionRequest = apiChatExecuteRequestDTO.getResponse() != null; + if (!(isTestInitializationRequest || isTestExecutionRequest)) { + String errorMessage = "Payload is badly formatted. Expected to have either 'command' and 'apiSpec' " + + "or 'response'"; + RestApiUtil.handleBadRequest(errorMessage, log); + return null; + } + + try { + if (APIUtil.isApiChatEnabled()) { + String payload = new Gson().toJson(apiChatExecuteRequestDTO); + String response = APIUtil.invokeAIService(APIConstants.API_CHAT_ENDPOINT, + APIConstants.API_CHAT_AUTH_TOKEN, APIConstants.API_CHAT_EXECUTE_RESOURCE, payload, + apiChatRequestId); + ObjectMapper objectMapper = new ObjectMapper(); + ApiChatExecuteResponseDTO executeResponseDTO = objectMapper.readValue(response, + ApiChatExecuteResponseDTO.class); + return Response.status(Response.Status.CREATED).entity(executeResponseDTO).build(); + } + } catch (APIManagementException | IOException e) { + String errorMessage = "Error encountered while executing the API Chat service to accomodate the " + + "specified testing requirement"; + RestApiUtil.handleInternalServerError(errorMessage, e, log); + } + return null; + } + + @Override + public Response apiChatPrepare(String apiId, String apiChatRequestId, MessageContext messageContext) + throws APIManagementException { + if (StringUtils.isEmpty(apiChatRequestId) || StringUtils.isEmpty(apiId)) { + String errorMessage = "Error while executing the prepare statement. Both API ID and request ID are " + + "required parameters"; + RestApiUtil.handleBadRequest(errorMessage, log); + return null; + } + try { + if (APIUtil.isApiChatEnabled()) { + String organization = RestApiUtil.getValidatedOrganization(messageContext); + APIConsumer apiConsumer = RestApiCommonUtil.getLoggedInUserConsumer(); + String swaggerDefinition = apiConsumer.getOpenAPIDefinition(apiId, organization); + String payload = "{\"openapi\": " + swaggerDefinition + "}"; + + String response = APIUtil.invokeAIService(APIConstants.API_CHAT_ENDPOINT, + APIConstants.API_CHAT_AUTH_TOKEN, APIConstants.API_CHAT_PREPARE_RESOURCE, payload, + apiChatRequestId); + + ObjectMapper objectMapper = new ObjectMapper(); + ApiChatPreparationResponseDTO preparationResponseDTO = objectMapper.readValue(response, + ApiChatPreparationResponseDTO.class); + return Response.status(Response.Status.CREATED).entity(preparationResponseDTO).build(); + } + } catch (APIManagementException | IOException e) { + String errorMessage = "Error encountered while executing the prepare statement of API Chat service"; + RestApiUtil.handleInternalServerError(errorMessage, e, log); + } + return null; + } + /** * Retrieves the async api specification document of an API * diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/mappings/SettingsMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/mappings/SettingsMappingUtil.java index b8b2febfa20f..cfb49aef4df2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/mappings/SettingsMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/mappings/SettingsMappingUtil.java @@ -125,6 +125,8 @@ public SettingsDTO fromSettingstoDTO(Boolean isUserAvailable, Boolean moneatizat settingsDTO.setPasswordPolicyPattern(passwordPolicyPattern); settingsDTO.setPasswordPolicyMinLength(passwordPolicyMinLength); settingsDTO.setPasswordPolicyMaxLength(passwordPolicyMaxLength); + settingsDTO.setIsApiChatEnabled(APIUtil.isApiChatEnabled()); + settingsDTO.setIsAIFeatureAuthTokenProvided(APIUtil.isAuthTokenProvidedForAIFeatures()); if (isUserAvailable) { settingsDTO.setGrantTypes(APIUtil.getGrantTypes()); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/resources/devportal-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/resources/devportal-api.yaml index 26019f4337fe..f4e954d339ad 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/resources/devportal-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/resources/devportal-api.yaml @@ -3575,6 +3575,89 @@ paths: - lang: Curl source: curl -k "https://localhost:9443/api/am/devportal/v3/apis/e93fb282-b456-48fc-8981-003fb89086ae/graphql-policies/complexity/types" + ###################################################### + # The "API Chat Feature" resource APIs + ###################################################### + /apis/{apiId}/api-chat/prepare: + + #----------------------------------------------------- + # Prepare API Chat for user queries by feeding spec + #----------------------------------------------------- + post: + security: + - OAuth2Security: + - apim:subscribe + summary: Prepare API Chat service by feeding the OpenAPI specification of the API to be tested + description: | + Processing the OpenAPI specification to extract the API endpoint definitions and generate sample queries + operationId: apiChatPrepare + parameters: + - $ref: '#/components/parameters/apiId' + - $ref: '#/components/parameters/apiChatRequestId' + tags: + - API Chat + responses: + 201: + description: | + Created. + API Chat preparation completed. Successful response with enriched API specification and sample queries. + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatPreparationResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while preparing the API Chat service. + + /apis/{apiId}/api-chat/execute: + + #----------------------------------------------------- + # Execute test specified via API Chat + #----------------------------------------------------- + post: + security: + - OAuth2Security: + - apim:subscribe + summary: Execute a single API test case while caching the progress + description: | + Executes a test scenario against an API; which iteratively provide resources that need to be + invoked alongside the inputs such as parameters, payloads, etc. while caching the progress. + operationId: apiChatExecute + parameters: + - $ref: '#/components/parameters/apiId' + - $ref: '#/components/parameters/apiChatRequestId' + requestBody: + description: | + API Chat execute request payload + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatExecuteRequest' + tags: + - API Chat + responses: + 201: + description: | + Created. + API Chat execute response payload. + content: + application/json: + schema: + $ref: '#/components/schemas/ApiChatExecuteResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while executing test using API Chat service. + ###################################################### # User resource APIs ###################################################### @@ -5319,6 +5402,14 @@ components: properties too will affect the maximum password length allowed and an intersection of all conditions will be considered finally to validate the password. + isApiChatEnabled: + type: boolean + description: Specifies whether API Chat feature is enabled. + default: true + isAIFeatureAuthTokenProvided: + type: boolean + description: Checks if the auth token is provided for AI service usage. + default: false ApplicationAttribute: title: Application attributes type: object @@ -5747,6 +5838,140 @@ components: type: array items: type: string + ApiChatPreparationResponse: + title: API Chat preparation response + required: + - apiSpec + - queries + properties: + apiSpec: + type: object + title: Enriched API spec + required: + - tools + properties: + serviceUrl: + type: string + description: Extracted service URL from the OpenAPI specification if there is any + tools: + type: array + description: Extracted Http tools from the OpenAPI specification + items: + $ref: '#/components/schemas/HttpTool' + queries: + type: array + description: list of sample queries + items: + $ref: '#/components/schemas/SampleQuery' + SampleQuery: + title: API Chat sample query record + required: + - scenario + - query + properties: + scenario: + type: string + description: scenario + query: + type: string + description: generated query + HttpTool: + title: HTTP tool + required: + - description + - method + - name + - path + properties: + name: + type: string + description: Name of the Http resource tool + description: + type: string + description: Description of the Http resource tool used by the LLM + method: + type: string + description: Http method type (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) + enum: + - OPTIONS + - HEAD + - PATCH + - PUT + - DELETE + - POST + - GET + path: + type: string + description: Path of the Http resource + parameters: + type: object + requestBody: + type: object + ApiChatExecuteRequest: + title: API Chat execute request + properties: + command: + type: string + description: | + User specified testcase to be tested against the API + example: "Get pet with id 123" + apiSpec: + type: object + properties: + serviceUrl: + type: string + description: Service URL of API if any + tools: + type: array + description: Extracted Http tools from the OpenAPI specification + items: + $ref: '#/components/schemas/HttpTool' + response: + type: object + properties: + code: + type: integer + description: HTTP status code of the response + example: 201 + path: + type: string + description: HTTP path url with encoded parameters + example: "/order/123" + headers: + type: object + description: Response headers + body: + type: object + description: Response payload + ApiChatExecuteResponse: + title: API Chat execution response + required: + - taskStatus + properties: + taskStatus: + type: string + description: Task status (IN_PROGRESS, TERMINATED or COMPLETED) + enum: + - IN_PROGRESS + - TERMINATED + - COMPLETED + example: COMPLETED + resource: + type: object + properties: + method: + type: string + description: HTTP method of the resource + path: + type: string + description: Path of the resource + inputs: + type: object + description: Input parameters for the resource + result: + type: string + description: completion result + example: "The pet with ID 123 is available. Here are the details: - ID: 123 - Name: asd - Status: available" responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -6090,6 +6315,13 @@ components: required: true schema: type: string + apiChatRequestId: + name: apiChatRequestId + in: header + description: | + Request ID + schema: + type: string securitySchemes: OAuth2Security: type: oauth2 diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index 11248a7067b8..d8fcc2d3f512 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -353,6 +353,34 @@ + + + + {{apim.ai.enable}} + + {{apim.ai.token}} + + {{apim.ai.endpoint}} + + + + + + + {{apim.ai.enable}} + + {{apim.ai.token}} + + {{apim.ai.endpoint}} + + + + + + true + + abc + + https://test.com + + + + + + + true + + abc + + https://test.com + + + true - abc + - https://test.com + http://localhost:9090 @@ -206,9 +206,9 @@ true - abc + - https://test.com + http://localhost:9090