From 02453da7b005272a1efa8161d2bf13295cba2464 Mon Sep 17 00:00:00 2001 From: Ashera Silva Date: Fri, 22 Mar 2024 01:53:20 +0530 Subject: [PATCH 01/11] 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 From 5ad1ec62fc9dcc6f1d98546433cd4983b27ddce7 Mon Sep 17 00:00:00 2001 From: Thenujan-Nagaratnam Date: Sat, 23 Mar 2024 19:25:11 +0530 Subject: [PATCH 05/11] Added marketplace chat backend service --- .../wso2/carbon/apimgt/impl/APIConstants.java | 39 ++++ .../apimgt/impl/APIManagerConfiguration.java | 53 ++++++ .../carbon/apimgt/impl/APIProviderImpl.java | 2 +- .../MarketplaceAssistantConfigurationDto.java | 72 +++++++ .../impl/internal/APIManagerComponent.java | 7 +- ...ketplaceAssistantApiPublisherNotifier.java | 180 ++++++++++++++++++ .../apimgt/impl/notifier/events/APIEvent.java | 76 +++++++- .../carbon/apimgt/impl/utils/APIUtil.java | 96 +++++++++- .../apimgt/impl/utils/LifeCycleUtils.java | 9 +- .../swagger.json | 4 +- .../src/main/resources/devportal-api.yaml | 161 ++++++++++++++++ .../src/main/resources/publisher-api.yaml | 2 +- .../api/store/v1/MarketplaceAssistantApi.java | 69 +++++++ .../v1/MarketplaceAssistantApiService.java | 28 +++ .../rest/api/store/v1/dto/ChatMessageDTO.java | 105 ++++++++++ ...rketplaceAssistantApiCountResponseDTO.java | 105 ++++++++++ .../v1/dto/MarketplaceAssistantApiDTO.java | 127 ++++++++++++ .../dto/MarketplaceAssistantRequestDTO.java | 108 +++++++++++ .../dto/MarketplaceAssistantResponseDTO.java | 107 +++++++++++ .../MarketplaceAssistantApiServiceImpl.java | 131 +++++++++++++ .../src/main/resources/devportal-api.yaml | 161 ++++++++++++++++ .../src/main/webapp/WEB-INF/beans.xml | 1 + .../org.wso2.carbon.apimgt.core.default.json | 7 + .../repository/conf/api-manager.xml.j2 | 22 +++ .../src/main/resources/config/api-manager.xml | 22 +++ .../resources/runtimes/cxf3/snakeyaml-2.2.jar | Bin 0 -> 334352 bytes 26 files changed, 1680 insertions(+), 14 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/ai/MarketplaceAssistantConfigurationDto.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.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/MarketplaceAssistantApi.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/MarketplaceAssistantApiService.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/ChatMessageDTO.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/MarketplaceAssistantApiCountResponseDTO.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/MarketplaceAssistantApiDTO.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/MarketplaceAssistantRequestDTO.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/MarketplaceAssistantResponseDTO.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java create mode 100644 features/apimgt/org.wso2.carbon.apimgt.rest.api.service.catalog.feature/src/main/resources/runtimes/cxf3/snakeyaml-2.2.jar 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 8a68c03fef79..37a1b667b5b7 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 @@ -548,6 +548,17 @@ private AI() { public static final String FIRST_NAME = DEFAULT_CARBON_DIALECT + "/givenname"; public static final String LAST_NAME = DEFAULT_CARBON_DIALECT + "/lastname"; + // constants for marketplace assistant + public static final String MARKETPLACE_ASSISTANT = "MarketplaceAssistant"; + public static final String MARKETPLACE_ASSISTANT_ENABLED = "Enabled"; + public static final String MARKETPLACE_ASSISTANT_AUTH_TOKEN = "AuthToken"; + public static final String MARKETPLACE_ASSISTANT_ENDPOINT = "Endpoint"; + public static final String MARKETPLACE_ASSISTANT_CHAT_RESOURCE = "ChatResource"; + public static final String MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE = "ApiPublishResource"; + public static final String MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE = "ApiDeleteResource"; + public static final String MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE = "ApiCountResource"; + + //Overview constants for CORS configuration public static final String API_OVERVIEW_CORS_CONFIGURATION = "overview_corsConfiguration"; //Registry lifecycle related info @@ -1695,6 +1706,34 @@ private ConfigParameters() { public static final String API_DATA_URL = "url"; public static final String API_UUID = "apiUUID"; + + public static final String UUID = "uuid"; + public static final String API_SPEC_TYPE = "api_type"; + public static final String API_SPEC_NAME = "api_name"; + public static final String TENANT_DOMAIN = "tenant_domain"; + public static final String QUERY = "query"; + public static final String HISTORY = "history"; + public static final String VERSION = "version"; + public static final String DESCRIPTION = "description"; + + public static final String DEMOTE_TO_CREATED= "Demote to Created"; + public static final String BLOCK = "Block"; + public static final String DEPRECATE = "Deprecate"; + public static final String PUBLISH = "Publish"; + public static final String DEPLOY_AS_A_PROTOTYPE = "Deploy as a Prototype"; + public static final String REPUBLISH = "Re-Publish"; + + public static final String API_SPEC_TYPE_REST = "api_spec"; + public static final String API_SPEC_TYPE_GRAPHQL = "sdl_schema"; + public static final String API_SPEC_TYPE_ASYNC = "async_spec"; + public static final String API_TYPE_HTTP = "HTTP"; + public static final String API_TYPE_WEBHOOK = "WEBHOOK"; + + public static final String API_TYPE_REST = "REST"; + + public static final String API_TYPE_GRAPHQL = "GRAPHQL"; + public static final String API_TYPE_ASYNC = "ASYNC"; + public static final String TRANSPORT_URL_IN = "TransportInURL"; // mock response generation diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java index 62861606fb0e..3cb3cdb86ca7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java @@ -34,6 +34,7 @@ import org.wso2.carbon.apimgt.api.model.Environment; import org.wso2.carbon.apimgt.api.model.VHost; import org.wso2.carbon.apimgt.common.gateway.configdto.HttpClientConfigurationDTO; +import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto; import org.wso2.carbon.apimgt.common.gateway.dto.ClaimMappingDto; import org.wso2.carbon.apimgt.common.gateway.dto.JWKSConfigurationDTO; import org.wso2.carbon.apimgt.common.gateway.dto.TokenIssuerDto; @@ -107,6 +108,7 @@ public class APIManagerConfiguration { private JSONArray applicationAttributes = new JSONArray(); private CacheInvalidationConfiguration cacheInvalidationConfiguration; + private HttpClientConfigurationDTO httpClientConfiguration; private RecommendationEnvironment recommendationEnvironment; @@ -116,6 +118,8 @@ public class APIManagerConfiguration { private boolean initialized; private ThrottleProperties throttleProperties = new ThrottleProperties(); private ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto(); + private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto = new MarketplaceAssistantConfigurationDto(); + private WorkflowProperties workflowProperties = new WorkflowProperties(); private Map apiGatewayEnvironments = new LinkedHashMap(); private static Properties realtimeNotifierProperties; @@ -160,6 +164,11 @@ public static boolean isTokenRevocationEnabled() { return !tokenRevocationClassName.isEmpty(); } + public MarketplaceAssistantConfigurationDto getMarketplaceAssistantConfigurationDto() { + + return marketplaceAssistantConfigurationDto; + } + private Set externalAPIStores = new HashSet(); private EventHubConfigurationDto eventHubConfigurationDto; private MonetizationConfigurationDto monetizationConfigurationDto = new MonetizationConfigurationDto(); @@ -624,6 +633,8 @@ private void readChildElements(OMElement serverConfig, jsonObject.put(APIConstants.CustomPropertyAttributes.REQUIRED, isRequired); customProperties.add(jsonObject); } + } else if (APIConstants.MARKETPLACE_ASSISTANT.equals(localName)) { + setMarketplaceAssistantConfiguration(element); } readChildElements(element, nameStack); nameStack.pop(); @@ -2326,4 +2337,46 @@ public HttpClientConfigurationDTO getHttpClientConfiguration() { public void setHttpClientConfiguration(HttpClientConfigurationDTO httpClientConfiguration) { this.httpClientConfiguration = httpClientConfiguration; } + + public void setMarketplaceAssistantConfiguration(OMElement omElement){ + OMElement marketplaceAssistantEnableElement = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_ENABLED)); + if (marketplaceAssistantEnableElement != null) { + marketplaceAssistantConfigurationDto.setEnabled(Boolean.parseBoolean(marketplaceAssistantEnableElement.getText())); + } + if (marketplaceAssistantConfigurationDto.isEnabled()) { + OMElement marketplaceAssistantEndpoint = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_ENDPOINT)); + if (marketplaceAssistantEndpoint != null) { + marketplaceAssistantConfigurationDto.setEndpoint(marketplaceAssistantEndpoint.getText()); + } + OMElement marketplaceAssistantToken = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_AUTH_TOKEN)); + + if (marketplaceAssistantToken != null) { + String AccessToken = MiscellaneousUtil.resolve(marketplaceAssistantToken, secretResolver); + marketplaceAssistantConfigurationDto.setAccessToken(AccessToken); + } + OMElement marketplaceAssistantApiCountResource = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE)); + if (marketplaceAssistantApiCountResource != null) { + marketplaceAssistantConfigurationDto.setApiCountResource(marketplaceAssistantApiCountResource.getText()); + } + OMElement marketplaceAssistantApiDeleteResource = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE)); + if (marketplaceAssistantApiDeleteResource != null) { + marketplaceAssistantConfigurationDto.setApiDeleteResource(marketplaceAssistantApiDeleteResource.getText()); + } + OMElement marketplaceAssistantApiPublishResource = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE)); + if (marketplaceAssistantApiPublishResource != null) { + marketplaceAssistantConfigurationDto.setApiPublishResource(marketplaceAssistantApiPublishResource.getText()); + } + OMElement marketplaceAssistantChatResource = + omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_CHAT_RESOURCE)); + if (marketplaceAssistantChatResource != null) { + marketplaceAssistantConfigurationDto.setChatResource(marketplaceAssistantChatResource.getText()); + } + } + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java index 0a1c430b8ccd..2ff2f27784fa 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java @@ -2336,7 +2336,7 @@ public void deleteAPI(String apiUuid, String organization) throws APIManagementE APIConstants.EventType.API_DELETE.name(), tenantId, organization, api.getId().getApiName(), apiId, api.getUuid(), api.getId().getVersion(), api.getType(), api.getContext(), APIUtil.replaceEmailDomainBack(api.getId().getProviderName()), - api.getStatus(), api.getApiSecurity()); + api.getStatus(), api.getApiSecurity(), api.getStatus(), api.getVisibility()); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); } else { log.debug("Event has not published to gateways due to API id has failed to retrieve from DB for API " diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/ai/MarketplaceAssistantConfigurationDto.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/ai/MarketplaceAssistantConfigurationDto.java new file mode 100644 index 000000000000..841de6f08083 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/ai/MarketplaceAssistantConfigurationDto.java @@ -0,0 +1,72 @@ +package org.wso2.carbon.apimgt.impl.ai; + +public class MarketplaceAssistantConfigurationDto { + + private String AccessToken; + private String Endpoint; + private String ApiPublishResource; + private String ChatResource; + private String ApiDeleteResource; + private String ApiCountResource; + private boolean isEnabled; + + + + public String getAccessToken() { + return AccessToken; + } + + public void setAccessToken(String AccessToken) { + this.AccessToken = AccessToken; + } + + public String getEndpoint() { + return Endpoint; + } + + public void setEndpoint(String Endpoint) { + this.Endpoint = Endpoint; + } + + public String getApiPublishResource() { + return ApiPublishResource; + } + + public void setApiPublishResource(String ApiPublishResource) { + this.ApiPublishResource = ApiPublishResource; + } + + public String getChatResource() { + return ChatResource; + } + + public void setChatResource(String ChatResource) { + this.ChatResource = ChatResource; + } + + public String getApiDeleteResource() { + return ApiDeleteResource; + } + + public void setApiDeleteResource(String ApiDeleteResource) { + this.ApiDeleteResource = ApiDeleteResource; + } + + public String getApiCountResource() { + return ApiCountResource; + } + + public void setApiCountResource(String ApiCountResource) { + this.ApiCountResource = ApiCountResource; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean Enabled) { + this.isEnabled = Enabled; + } + + +} \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java index 6c679cc5acdf..70edf8cf0a47 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java @@ -89,6 +89,7 @@ import org.wso2.carbon.apimgt.impl.notifier.ScopesNotifier; import org.wso2.carbon.apimgt.impl.notifier.SubscriptionsNotifier; import org.wso2.carbon.apimgt.impl.notifier.KeyTemplateNotifier; +import org.wso2.carbon.apimgt.impl.notifier.MarketplaceAssistantApiPublisherNotifier; import org.wso2.carbon.apimgt.impl.observers.APIStatusObserverList; import org.wso2.carbon.apimgt.impl.observers.CommonConfigDeployer; import org.wso2.carbon.apimgt.impl.observers.KeyMgtConfigDeployer; @@ -201,6 +202,8 @@ protected void activate(ComponentContext componentContext) throws Exception { String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); configuration.load(filePath); + boolean isMarketplaceAssistantEnabled = configuration.getMarketplaceAssistantConfigurationDto().isEnabled(); + //Registering Notifiers bundleContext.registerService(Notifier.class.getName(), new SubscriptionsNotifier(), null); bundleContext.registerService(Notifier.class.getName(), new ApisNotifier(), null); @@ -216,6 +219,9 @@ protected void activate(ComponentContext componentContext) throws Exception { bundleContext.registerService(Notifier.class.getName(),new KeyTemplateNotifier(), null); bundleContext.registerService(Notifier.class.getName(), new CorrelationConfigNotifier(), null); bundleContext.registerService(Notifier.class.getName(), new GatewayPolicyNotifier(), null); + if (isMarketplaceAssistantEnabled) { + bundleContext.registerService(Notifier.class.getName(), new MarketplaceAssistantApiPublisherNotifier(), null); + } APIManagerConfigurationServiceImpl configurationService = new APIManagerConfigurationServiceImpl(configuration); ServiceReferenceHolder.getInstance().setAPIManagerConfigurationService(configurationService); APIMgtDBUtil.initialize(); @@ -1097,4 +1103,3 @@ protected void unsetWorkflowTaskService(WorkflowTaskService workflowTaskService) ServiceReferenceHolder.getInstance().setWorkflowTaskService(null); } } - diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java new file mode 100644 index 000000000000..6b19417b418f --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.apimgt.impl.notifier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.json.simple.JSONObject; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.api.APIProvider; +import org.wso2.carbon.apimgt.api.model.API; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; +import org.wso2.carbon.apimgt.impl.APIManagerFactory; +import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto; +import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; +import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; +import org.wso2.carbon.apimgt.impl.notifier.events.APIEvent; +import org.wso2.carbon.apimgt.impl.notifier.events.Event; +import org.wso2.carbon.apimgt.impl.notifier.exceptions.NotifierException; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; + + +/** + * The default API notification service implementation in which API creation, update, delete and LifeCycle change + * events are published to gateway. + */ +public class MarketplaceAssistantApiPublisherNotifier extends ApisNotifier{ + protected ApiMgtDAO apiMgtDAO; + private static final Log log = LogFactory.getLog(MarketplaceAssistantApiPublisherNotifier.class); + private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto = new MarketplaceAssistantConfigurationDto(); + + @Override + public boolean publishEvent(Event event) throws NotifierException { + APIManagerConfiguration configuration = ServiceReferenceHolder. + getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); + + if (configuration == null) { + log.error("API Manager configuration is not initialized."); + } else { + marketplaceAssistantConfigurationDto = configuration.getMarketplaceAssistantConfigurationDto(); + + if (marketplaceAssistantConfigurationDto.isEnabled()) { + process(event); + } + } + return true; + } + + /** + * Add or Delete APIs from external DB when life cycle state changes + * + * @param event APIEvent to undeploy APIs from external gateway + * @return + * @throws NotifierException if error occurs + */ + private void process (Event event) throws NotifierException { + APIEvent apiEvent; + apiEvent = (APIEvent) event; + + if (!APIConstants.API_GLOBAL_VISIBILITY.equals(apiEvent.getApiVisibility())) { + return; + } + + // [ **Publish**, **Deploy as a Prototype**, **Demote to Created**, **Block**, **Deprecate**, **Re-Publish**, **Retire** ] + if (APIConstants.EventType.API_LIFECYCLE_CHANGE.name().equals(event.getType())) { + String lifecycleEvent = apiEvent.getLifecycleEvent(); + String currentStatus = apiEvent.getCurrentStatus().toUpperCase(); + switch (lifecycleEvent) { + case APIConstants.DEMOTE_TO_CREATED: + case APIConstants.BLOCK: + deleteRequest(apiEvent); + break; + case APIConstants.DEPRECATE: + if (APIConstants.PUBLISHED.equals(currentStatus)){ + deleteRequest(apiEvent); + break; + } + case APIConstants.PUBLISH: + case APIConstants.DEPLOY_AS_A_PROTOTYPE: + if (APIConstants.CREATED.equals(currentStatus)) { + postRequest(apiEvent); + } + break; + case APIConstants.REPUBLISH: + postRequest(apiEvent); + break; + default: + break; + } + } else if (APIConstants.EventType.API_DELETE.name().equals(event.getType())) { + String currentStatus = apiEvent.getApiStatus().toUpperCase(); + switch (currentStatus) { + case APIConstants.PROTOTYPED: + case APIConstants.PUBLISHED: + deleteRequest(apiEvent); + break; + default: + break; + } + } + } + + private void postRequest(APIEvent apiEvent) throws NotifierException { + apiMgtDAO = ApiMgtDAO.getInstance(); + String apiId = apiEvent.getUuid(); + + try { + APIProvider apiProvider = APIManagerFactory.getInstance().getAPIProvider(CarbonContext. + getThreadLocalCarbonContext().getUsername()); + API api = apiProvider.getAPIbyUUID(apiId, apiMgtDAO.getOrganizationByAPIUUID(apiId)); + + + String api_type = api.getType(); + + JSONObject payload = new JSONObject(); + + switch (api_type) { + case APIConstants.API_TYPE_GRAPHQL: + payload.put(APIConstants.API_SPEC_TYPE_GRAPHQL, api.getGraphQLSchema()); + payload.put(APIConstants.API_SPEC_TYPE, APIConstants.API_TYPE_GRAPHQL); + break; + case APIConstants.API_TYPE_ASYNC: + case APIConstants.API_TYPE_WS: + case APIConstants.API_TYPE_WEBSUB: + case APIConstants.API_TYPE_SSE: + case APIConstants.API_TYPE_WEBHOOK: + payload.put(APIConstants.API_SPEC_TYPE_ASYNC, api.getAsyncApiDefinition()); + payload.put(APIConstants.API_SPEC_TYPE, APIConstants.API_TYPE_ASYNC); + break; + case APIConstants.API_TYPE_HTTP: + case APIConstants.API_TYPE_SOAP: + case APIConstants.API_TYPE_SOAPTOREST: + payload.put(APIConstants.API_SPEC_TYPE_REST, api.getSwaggerDefinition()); + payload.put(APIConstants.API_SPEC_TYPE, APIConstants.API_TYPE_REST); + break; + default: + break; + } + + payload.put(APIConstants.UUID, api.getUuid()); + payload.put(APIConstants.DESCRIPTION, api.getDescription()); + payload.put(APIConstants.API_SPEC_NAME, api.getId().getApiName()); + payload.put(APIConstants.TENANT_DOMAIN, apiEvent.getTenantDomain()); + payload.put(APIConstants.VERSION, apiEvent.getApiVersion()); + APIUtil.MarketplaceAssistantPostService(marketplaceAssistantConfigurationDto.getEndpoint(), + marketplaceAssistantConfigurationDto.getAccessToken(), marketplaceAssistantConfigurationDto.getApiPublishResource(), payload.toString()); + } catch (APIManagementException e) { + String errorMessage = "Error encountered while Uploading the API to the vector database"; + log.error(errorMessage); + } + } + + private void deleteRequest(APIEvent apiEvent) throws NotifierException { + + try { + String uuid = apiEvent.getUuid(); + APIUtil.DeleteApi(marketplaceAssistantConfigurationDto.getEndpoint(), + marketplaceAssistantConfigurationDto.getAccessToken(), marketplaceAssistantConfigurationDto.getApiDeleteResource(), uuid); + } catch (APIManagementException e) { + String errorMessage = "Error encountered while Deleting the API from the vector database"; + log.error(errorMessage); + } + } +} \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java index 9c8dd27e395e..39ef0b503a81 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java @@ -40,9 +40,12 @@ public class APIEvent extends Event { private String resourcePath; private APIConstants.EventAction action; private String securityScheme; + private String currentStatus; + private String apiVisibility; + private String lifecycleEvent; public APIEvent(String uuid, String logLevel, String type, String apiContext, String resourceMethod, - String resourcePath) { + String resourcePath) { this.uuid = uuid; this.logLevel = logLevel; this.type = type; @@ -82,6 +85,27 @@ public APIEvent(String eventId, long timestamp, String type, int tenantId, Strin this.securityScheme = securityScheme; } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, + int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, + String apiStatus, String securityScheme, String currentStatus, String apiVisibility) { + this.eventId = eventId; + this.timeStamp = timestamp; + this.type = type; + this.tenantId = tenantId; + this.apiId = apiId; + this.uuid = uuid; + this.apiVersion = apiVersion; + this.apiName = apiName; + this.apiType = apiType; + this.apiContext = apiContext; + this.apiProvider = apiProvider; + this.apiStatus = apiStatus; + this.tenantDomain = tenantDomain; + this.securityScheme = securityScheme; + this.currentStatus = currentStatus; + this.apiVisibility = apiVisibility; + } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, String apiStatus, APIConstants.EventAction action, String securityScheme) { @@ -102,6 +126,28 @@ public APIEvent(String eventId, long timestamp, String type, int tenantId, Strin this.securityScheme = securityScheme; } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, + int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, + String apiStatus, String securityScheme, String action, String currentStatus, String apiVisibility) { + this.eventId = eventId; + this.timeStamp = timestamp; + this.type = type; + this.tenantId = tenantId; + this.apiId = apiId; + this.uuid = uuid; + this.apiVersion = apiVersion; + this.apiName = apiName; + this.apiType = apiType; + this.apiContext = apiContext; + this.apiProvider = apiProvider; + this.apiStatus = apiStatus; + this.tenantDomain = tenantDomain; + this.securityScheme = securityScheme; + this.lifecycleEvent = action; + this.currentStatus = currentStatus; + this.apiVisibility = apiVisibility; + } + @Override public String toString() { @@ -248,4 +294,30 @@ public String getSecurityScheme() { public void setSecurityScheme(String securityScheme) { this.securityScheme = securityScheme; } -} + + public String getCurrentStatus() { + return currentStatus; + } + + public String getLifecycleEvent() { + return lifecycleEvent; + } + + public void setLifecycleEvent(String lifecycleEvent) { + this.lifecycleEvent = lifecycleEvent; + } + + + public void setCurrentStatus(String currentStatus) { + this.currentStatus = currentStatus; + } + + + public String getApiVisibility() { + return apiVisibility; + } + + public void setApiVisibility(String apiVisibility) { + this.apiVisibility = apiVisibility; + } +} \ No newline at end of file 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 e8ed26b189b4..5bb0204ca529 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 @@ -58,9 +58,7 @@ import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.methods.*; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; @@ -10454,4 +10452,96 @@ public static String invokeAIService(String endpointConfigName, String authToken throw new APIManagementException("Error encountered while connecting to service", e); } } + + /** + * This method is used for AI Service health check purposes. This will be utilized by API-Chat feature and + * Marketplace-Assistant feature + * + * @param endpoint Config name to retrieve the AI Service URL + * @param resource Resource that we should forward the request to + * @return CloseableHttpResponse of the GET call + * @throws APIManagementException + */ + public static CloseableHttpResponse getMarketplaceChatApiCount(String endpoint, String resource) + throws APIManagementException { + + try{ + HttpGet apiCountGet = new HttpGet(endpoint + resource); + URL url = new URL(endpoint); + int port = url.getPort(); + String protocol = url.getProtocol(); + HttpClient httpClient = APIUtil.getHttpClient(port, protocol); + return executeHTTPRequest(apiCountGet, httpClient); + } 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); + } + } + + public static String MarketplaceAssistantPostService(String endpoint, String authToken, + String resource, String payload) throws APIManagementException { + + try { + HttpPost preparePost = new HttpPost(endpoint + resource); + preparePost.setHeader(HttpHeaders.AUTHORIZATION, authToken); + preparePost.setHeader(HttpHeaders.CONTENT_TYPE, APIConstants.APPLICATION_JSON_MEDIA_TYPE); + 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) { + return null; + } else { + throw new APIManagementException("Unexpected response detected from the AI service." + responseStr); + } + } 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); + } + } + + + public static void DeleteApi(String endpoint, String authToken, + String resource, String uuid) throws APIManagementException { + + try { + String resourceWithPathParam = endpoint + resource + "/{uuid}"; + resourceWithPathParam = resourceWithPathParam.replace("{uuid}", uuid); + + HttpDelete prepareDelete = new HttpDelete(resourceWithPathParam); + prepareDelete.setHeader(HttpHeaders.AUTHORIZATION, authToken); + + URL url = new URL(endpoint); + int port = url.getPort(); + String protocol = url.getProtocol(); + HttpClient httpClient = APIUtil.getHttpClient(port, protocol); + + CloseableHttpResponse response = executeHTTPRequest(prepareDelete, httpClient); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) { + if (log.isDebugEnabled()) { + log.debug("Successfully completed the Marketplace Chat API publisher delete call with status code: " + statusCode); + } + } else { + String errorMessage = "Error encountered while Deleting the API from the vector database service to accommodate the " + + "Marketplace assistant"; + log.error(errorMessage); + } + } 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.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java index a0c2bfc6e7dd..bbce60b8a3c5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java @@ -61,6 +61,7 @@ public static void changeLifecycle(String user, APIProvider apiProvider, String String apiContext = apiTypeWrapper.getContext(); String uuid = apiTypeWrapper.getUuid(); String currentStatus = apiTypeWrapper.getStatus(); + String apiVisibility = apiTypeWrapper.getVisibility(); targetStatus = LCManagerFactory.getInstance().getLCManager().getStateForTransition(action); // Update lifecycle state in the registry @@ -77,7 +78,7 @@ public static void changeLifecycle(String user, APIProvider apiProvider, String // Add LC state change event to the event queue sendLCStateChangeNotification(apiName, apiType, apiContext, apiTypeWrapper.getId().getVersion(), targetStatus, apiTypeWrapper.getId().getProviderName(), apiTypeWrapper.getId().getId(), uuid, orgId, - apiTypeWrapper.getApi() != null ? apiTypeWrapper.getApi().getApiSecurity() : null); + apiTypeWrapper.getApi() != null ? apiTypeWrapper.getApi().getApiSecurity() : null, action, currentStatus, apiVisibility); // Remove revisions and subscriptions after API retire if (!apiTypeWrapper.isAPIProduct()) { @@ -393,12 +394,12 @@ private static void addLCStateChangeInDatabase(String user, ApiTypeWrapper apiTy */ private static void sendLCStateChangeNotification(String apiName, String apiType, String apiContext, String apiVersion, String targetStatus, String provider, int apiOrApiProductId, - String uuid, String organization, String securityScheme) throws + String uuid, String organization, String securityScheme, String action, String currentStatus, String apiVisibility) throws APIManagementException { APIEvent apiEvent = new APIEvent(UUID.randomUUID().toString(), System.currentTimeMillis(), APIConstants.EventType.API_LIFECYCLE_CHANGE.name(), APIUtil.getInternalOrganizationId(organization), organization, apiName, apiOrApiProductId, - uuid, apiVersion, apiType, apiContext, APIUtil.replaceEmailDomainBack(provider), targetStatus, securityScheme); + uuid, apiVersion, apiType, apiContext, APIUtil.replaceEmailDomainBack(provider), targetStatus, securityScheme, action, currentStatus, apiVisibility); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); } @@ -696,4 +697,4 @@ private static void handleException(String msg, Exception e) throws APIManagemen throw new APIManagementException(msg, e); } -} +} \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json index 8040e385bd35..a7fa59630d63 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json @@ -1354,8 +1354,8 @@ "type" : "string", "example" : "EXCHANGED", "description" : "The type of the tokens to be used (exchanged or without exchanged). Accepted values are EXCHANGED, DIRECT or BOTH.", - "default" : "DIRECT", - "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ] + "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ], + "default" : "DIRECT" } } }, 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 93b071249bc4..121a13640033 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 @@ -3651,6 +3651,80 @@ paths: source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -H "Content-Type: application/json" -X POST -d @data.json "https://localhost:9443/api/am/devportal/v3/me/change-password"' + + ###################################################### + # The "Marketplace Assistant Feature" resource APIs + ###################################################### + '/marketplace-assistant/api-count': + + #----------------------------------------------------- + # Get No of apis in the VectorDB + #----------------------------------------------------- + get: + summary: API Count endpoint. + description: | + Get the api count of Marketplace Assistant AI service. + operationId: getMarketplaceAssistantApiCount + tags: + - Marketplace Assistant + responses: + 200: + description: | + OK. + Api Count is returned. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantApiCountResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while checking the health status of API Chat service. + + '/marketplace-assistant/chat': + + #----------------------------------------------------- + # Chat with Marketplace Assistant + #----------------------------------------------------- + post: + summary: Marketplace Assistant Chat Endpoint. + description: | + Send a single query to the service and get the response. + operationId: marketplaceAssistantExecute + requestBody: + description: | + Marketplace Assistant chat request payload. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantRequest' + tags: + - Marketplace Assistant + responses: + 201: + description: | + Created. + Marketplace Assistant chat response payload. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 429: + $ref: '#/components/responses/TooManyRequests' + 500: + description: | + Internal Server Error. + An error occurred while executing test using Marketplace Chat service. + + components: schemas: APIList: @@ -5944,6 +6018,81 @@ components: query: type: string description: generated query + ChatMessage: + required: + - content + - role + type: object + properties: + role: + type: string + description: user or assistant role of a chat message. + example: "assistant" + content: + type: string + description: content of the message. + example: "Hi, How can I help you?" + MarketplaceAssistantRequest: + required: + - query + - history + type: object + properties: + query: + type: string + description: natural langugae query given by the user. + example: "Hi" + history: + type: array + items: + $ref: '#/components/schemas/ChatMessage' + MarketplaceAssistantApi: + required: + - apiId + - apiName + - version + type: object + properties: + apiId: + type: string + description: Uuid of the api. + example: "1sbdhsjd-121n-nknsjkd-1213njb" + apiName: + type: string + description: name of the api. + example: "PizzaShackAPI" + version: + type: string + description: version of the api. + example: "1.0.0" + MarketplaceAssistantResponse: + required: + - response + type: object + properties: + response: + type: string + description: natural language response by the llm. + example: "Hi, How can I help you?" + apis: + type: array + items: + $ref: '#/components/schemas/MarketplaceAssistantApi' + MarketplaceAssistantApiCountResponse: + required: + - count + - limit + type: object + properties: + count: + type: integer + description: no of apis stored in the vectordb. + example: "100" + limit: + type: integer + description: maximum no of apis allowed for an org. + example: "1000" + responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -6045,6 +6194,18 @@ components: description: The entity of the request was not in a supported format moreInfo: "" error: [] + TooManyRequests: + description: Too many requests. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: 429 + message: TooManyRequests + description: The user has exceeded the rate limit + moreInfo: "" + error: [ ] parameters: parentCommentID: name: replyTo diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index aaf9ca9c34fc..7f13e3215e27 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -6626,7 +6626,7 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/api-products/copy-api-products?newVersion=2.0&defaultVersion=false&apiproductId=2fd14eb8-b828-4013-b448-0739d2e76bf7"' + "https://127.0.0.1:9443/api/am/publisher/v4/api-products/copy-api-products?newVersion=2.0&defaultVersion=false&apiProductId=2fd14eb8-b828-4013-b448-0739d2e76bf7"' operationId: createNewAPIProductVersion /api-products/export: diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java new file mode 100644 index 000000000000..869d54c5cd0c --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java @@ -0,0 +1,69 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1; + +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ErrorDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantApiCountResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.MarketplaceAssistantApiService; +import org.wso2.carbon.apimgt.rest.api.store.v1.impl.MarketplaceAssistantApiServiceImpl; +import org.wso2.carbon.apimgt.api.APIManagementException; + +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import javax.inject.Inject; + +import io.swagger.annotations.*; +import java.io.InputStream; + +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; + +import java.util.Map; +import java.util.List; +import javax.validation.constraints.*; +@Path("/marketplace-assistant") + +@Api(description = "the marketplace-assistant API") + + + + +public class MarketplaceAssistantApi { + + @Context MessageContext securityContext; + +MarketplaceAssistantApiService delegate = new MarketplaceAssistantApiServiceImpl(); + + + @GET + @Path("/api-count") + + @Produces({ "application/json" }) + @ApiOperation(value = "API Count endpoint.", notes = "Get the api count of Marketplace Assistant AI service. ", response = MarketplaceAssistantApiCountResponseDTO.class, tags={ "Marketplace Assistant", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. Api Count is returned. ", response = MarketplaceAssistantApiCountResponseDTO.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 checking the health status of API Chat service. ", response = Void.class) }) + public Response getMarketplaceAssistantApiCount() throws APIManagementException{ + return delegate.getMarketplaceAssistantApiCount(securityContext); + } + + @POST + @Path("/chat") + @Consumes({ "application/json" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Marketplace Assistant Chat Endpoint.", notes = "Send a single query to the service and get the response. ", response = MarketplaceAssistantResponseDTO.class, tags={ "Marketplace Assistant" }) + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Created. Marketplace Assistant chat response payload. ", response = MarketplaceAssistantResponseDTO.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 = 429, message = "Too many requests.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error. An error occurred while executing test using Marketplace Chat service. ", response = Void.class) }) + public Response marketplaceAssistantExecute(@ApiParam(value = "Marketplace Assistant chat request payload. " ) MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO) throws APIManagementException{ + return delegate.marketplaceAssistantExecute(marketplaceAssistantRequestDTO, securityContext); + } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java new file mode 100644 index 000000000000..c9ec95dea707 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java @@ -0,0 +1,28 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1; + +import org.wso2.carbon.apimgt.rest.api.store.v1.*; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.*; + +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; + +import org.wso2.carbon.apimgt.api.APIManagementException; + +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ErrorDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantApiCountResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; + +import java.util.List; + +import java.io.InputStream; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + + +public interface MarketplaceAssistantApiService { + public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException; + public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, 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/ChatMessageDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/ChatMessageDTO.java new file mode 100644 index 000000000000..11934dd05edb --- /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/ChatMessageDTO.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 ChatMessageDTO { + + private String role = null; + private String content = null; + + /** + * user or assistant role of a chat message. + **/ + public ChatMessageDTO role(String role) { + this.role = role; + return this; + } + + + @ApiModelProperty(example = "assistant", required = true, value = "user or assistant role of a chat message.") + @JsonProperty("role") + @NotNull + public String getRole() { + return role; + } + public void setRole(String role) { + this.role = role; + } + + /** + * content of the message. + **/ + public ChatMessageDTO content(String content) { + this.content = content; + return this; + } + + + @ApiModelProperty(example = "Hi, How can I help you?", required = true, value = "content of the message.") + @JsonProperty("content") + @NotNull + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ChatMessageDTO chatMessage = (ChatMessageDTO) o; + return Objects.equals(role, chatMessage.role) && + Objects.equals(content, chatMessage.content); + } + + @Override + public int hashCode() { + return Objects.hash(role, content); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ChatMessageDTO {\n"); + + sb.append(" role: ").append(toIndentedString(role)).append("\n"); + sb.append(" content: ").append(toIndentedString(content)).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/MarketplaceAssistantApiCountResponseDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/MarketplaceAssistantApiCountResponseDTO.java new file mode 100644 index 000000000000..5d74191a9701 --- /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/MarketplaceAssistantApiCountResponseDTO.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 MarketplaceAssistantApiCountResponseDTO { + + private Integer count = null; + private Integer limit = null; + + /** + * no of apis stored in the vectordb. + **/ + public MarketplaceAssistantApiCountResponseDTO count(Integer count) { + this.count = count; + return this; + } + + + @ApiModelProperty(example = "100", required = true, value = "no of apis stored in the vectordb.") + @JsonProperty("count") + @NotNull + public Integer getCount() { + return count; + } + public void setCount(Integer count) { + this.count = count; + } + + /** + * maximum no of apis allowed for an org. + **/ + public MarketplaceAssistantApiCountResponseDTO limit(Integer limit) { + this.limit = limit; + return this; + } + + + @ApiModelProperty(example = "1000", required = true, value = "maximum no of apis allowed for an org.") + @JsonProperty("limit") + @NotNull + public Integer getLimit() { + return limit; + } + public void setLimit(Integer limit) { + this.limit = limit; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarketplaceAssistantApiCountResponseDTO marketplaceAssistantApiCountResponse = (MarketplaceAssistantApiCountResponseDTO) o; + return Objects.equals(count, marketplaceAssistantApiCountResponse.count) && + Objects.equals(limit, marketplaceAssistantApiCountResponse.limit); + } + + @Override + public int hashCode() { + return Objects.hash(count, limit); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarketplaceAssistantApiCountResponseDTO {\n"); + + sb.append(" count: ").append(toIndentedString(count)).append("\n"); + sb.append(" limit: ").append(toIndentedString(limit)).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/MarketplaceAssistantApiDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/MarketplaceAssistantApiDTO.java new file mode 100644 index 000000000000..a1c2e2563f14 --- /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/MarketplaceAssistantApiDTO.java @@ -0,0 +1,127 @@ +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 MarketplaceAssistantApiDTO { + + private String apiId = null; + private String apiName = null; + private String version = null; + + /** + * Uuid of the api. + **/ + public MarketplaceAssistantApiDTO apiId(String apiId) { + this.apiId = apiId; + return this; + } + + + @ApiModelProperty(example = "1sbdhsjd-121n-nknsjkd-1213njb", required = true, value = "Uuid of the api.") + @JsonProperty("apiId") + @NotNull + public String getApiId() { + return apiId; + } + public void setApiId(String apiId) { + this.apiId = apiId; + } + + /** + * name of the api. + **/ + public MarketplaceAssistantApiDTO apiName(String apiName) { + this.apiName = apiName; + return this; + } + + + @ApiModelProperty(example = "PizzaShackAPI", required = true, value = "name of the api.") + @JsonProperty("apiName") + @NotNull + public String getApiName() { + return apiName; + } + public void setApiName(String apiName) { + this.apiName = apiName; + } + + /** + * version of the api. + **/ + public MarketplaceAssistantApiDTO version(String version) { + this.version = version; + return this; + } + + + @ApiModelProperty(example = "1.0.0", required = true, value = "version of the api.") + @JsonProperty("version") + @NotNull + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarketplaceAssistantApiDTO marketplaceAssistantApi = (MarketplaceAssistantApiDTO) o; + return Objects.equals(apiId, marketplaceAssistantApi.apiId) && + Objects.equals(apiName, marketplaceAssistantApi.apiName) && + Objects.equals(version, marketplaceAssistantApi.version); + } + + @Override + public int hashCode() { + return Objects.hash(apiId, apiName, version); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarketplaceAssistantApiDTO {\n"); + + sb.append(" apiId: ").append(toIndentedString(apiId)).append("\n"); + sb.append(" apiName: ").append(toIndentedString(apiName)).append("\n"); + sb.append(" version: ").append(toIndentedString(version)).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/MarketplaceAssistantRequestDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/MarketplaceAssistantRequestDTO.java new file mode 100644 index 000000000000..d8165aab24d8 --- /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/MarketplaceAssistantRequestDTO.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.ChatMessageDTO; +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 MarketplaceAssistantRequestDTO { + + private String query = null; + private List history = new ArrayList(); + + /** + * natural langugae query given by the user. + **/ + public MarketplaceAssistantRequestDTO query(String query) { + this.query = query; + return this; + } + + + @ApiModelProperty(example = "Hi", required = true, value = "natural langugae query given by the user.") + @JsonProperty("query") + @NotNull + public String getQuery() { + return query; + } + public void setQuery(String query) { + this.query = query; + } + + /** + **/ + public MarketplaceAssistantRequestDTO history(List history) { + this.history = history; + return this; + } + + + @ApiModelProperty(required = true, value = "") + @Valid + @JsonProperty("history") + @NotNull + public List getHistory() { + return history; + } + public void setHistory(List history) { + this.history = history; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarketplaceAssistantRequestDTO marketplaceAssistantRequest = (MarketplaceAssistantRequestDTO) o; + return Objects.equals(query, marketplaceAssistantRequest.query) && + Objects.equals(history, marketplaceAssistantRequest.history); + } + + @Override + public int hashCode() { + return Objects.hash(query, history); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarketplaceAssistantRequestDTO {\n"); + + sb.append(" query: ").append(toIndentedString(query)).append("\n"); + sb.append(" history: ").append(toIndentedString(history)).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/MarketplaceAssistantResponseDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/dto/MarketplaceAssistantResponseDTO.java new file mode 100644 index 000000000000..f438306a7c02 --- /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/MarketplaceAssistantResponseDTO.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.MarketplaceAssistantApiDTO; +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 MarketplaceAssistantResponseDTO { + + private String response = null; + private List apis = new ArrayList(); + + /** + * natural language response by the llm. + **/ + public MarketplaceAssistantResponseDTO response(String response) { + this.response = response; + return this; + } + + + @ApiModelProperty(example = "Hi, How can I help you?", required = true, value = "natural language response by the llm.") + @JsonProperty("response") + @NotNull + public String getResponse() { + return response; + } + public void setResponse(String response) { + this.response = response; + } + + /** + **/ + public MarketplaceAssistantResponseDTO apis(List apis) { + this.apis = apis; + return this; + } + + + @ApiModelProperty(value = "") + @Valid + @JsonProperty("apis") + public List getApis() { + return apis; + } + public void setApis(List apis) { + this.apis = apis; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MarketplaceAssistantResponseDTO marketplaceAssistantResponse = (MarketplaceAssistantResponseDTO) o; + return Objects.equals(response, marketplaceAssistantResponse.response) && + Objects.equals(apis, marketplaceAssistantResponse.apis); + } + + @Override + public int hashCode() { + return Objects.hash(response, apis); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class MarketplaceAssistantResponseDTO {\n"); + + sb.append(" response: ").append(toIndentedString(response)).append("\n"); + sb.append(" apis: ").append(toIndentedString(apis)).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/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java new file mode 100644 index 000000000000..9274cca8f484 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java @@ -0,0 +1,131 @@ +package org.wso2.carbon.apimgt.rest.api.store.v1.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; +import org.json.simple.JSONObject; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; +import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto; +import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; +import org.wso2.carbon.apimgt.rest.api.store.v1.*; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.*; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.MessageContext; + +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.ErrorDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantApiCountResponseDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; +import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; +import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; + +import java.io.IOException; +import java.util.List; + +import java.io.InputStream; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; + + +public class MarketplaceAssistantApiServiceImpl implements MarketplaceAssistantApiService { + + private static final Log log = LogFactory.getLog(MarketplaceAssistantApiServiceImpl.class); + + private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto; + + @Override + public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, + MessageContext messageContext) throws APIManagementException { + APIManagerConfiguration configuration = ServiceReferenceHolder. + getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); + + if (configuration == null) { + log.error("API Manager configuration is not initialized."); + } else { + marketplaceAssistantConfigurationDto = configuration.getMarketplaceAssistantConfigurationDto(); + } + try { + if (marketplaceAssistantConfigurationDto.isEnabled()) { + + boolean isChatQueryEmpty = StringUtils.isEmpty(marketplaceAssistantRequestDTO.getQuery()); + if (isChatQueryEmpty) { + String errorMessage = "Payload is badly formatted. Expected to have 'query'"; + RestApiUtil.handleBadRequest(errorMessage, log); + return null; + } + + String organization = RestApiUtil.getValidatedOrganization(messageContext); + + JSONObject payload = new JSONObject(); + String history = new Gson().toJson(marketplaceAssistantRequestDTO.getHistory()); + + payload.put(APIConstants.QUERY, marketplaceAssistantRequestDTO.getQuery()); + payload.put(APIConstants.HISTORY, history); + payload.put(APIConstants.TENANT_DOMAIN, organization); + + String response = APIUtil. + MarketplaceAssistantPostService(marketplaceAssistantConfigurationDto.getEndpoint(), + marketplaceAssistantConfigurationDto.getAccessToken(), + marketplaceAssistantConfigurationDto.getChatResource(), payload.toString()); + + ObjectMapper objectMapper = new ObjectMapper(); + MarketplaceAssistantResponseDTO executeResponseDTO = objectMapper.readValue(response, + MarketplaceAssistantResponseDTO.class); + return Response.status(Response.Status.CREATED).entity(executeResponseDTO).build(); + } + } catch (APIManagementException | IOException e) { + String errorMessage = "Error encountered while executing the execute statement of Marketplace Assistant service"; + RestApiUtil.handleInternalServerError(errorMessage, e, log); + } + return null; + } + + @Override + public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException { + APIManagerConfiguration configuration = ServiceReferenceHolder. + getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); + + if (configuration == null) { + log.error("API Manager configuration is not initialized."); + } else { + marketplaceAssistantConfigurationDto = configuration.getMarketplaceAssistantConfigurationDto(); + } + try { + if (marketplaceAssistantConfigurationDto.isEnabled()) { + + CloseableHttpResponse response = APIUtil. + getMarketplaceChatApiCount(marketplaceAssistantConfigurationDto.getEndpoint(), + marketplaceAssistantConfigurationDto.getApiCountResource()); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) { + String responseStr = EntityUtils.toString(response.getEntity()); + if (log.isDebugEnabled()) { + log.debug("Successfully completed the Marketplace Assistant api count call with status code: " + statusCode); + } + ObjectMapper objectMapper = new ObjectMapper(); + MarketplaceAssistantApiCountResponseDTO executeResponseDTO = objectMapper.readValue(responseStr, + MarketplaceAssistantApiCountResponseDTO.class); + return Response.status(Response.Status.OK).entity(executeResponseDTO).build(); + } else { + String errorMessage = "Error encountered while executing the Marketplace Assistant service to accomodate the " + + "specified testing requirement"; + log.error(errorMessage); + RestApiUtil.handleInternalServerError(errorMessage, log); + } + } + } catch (APIManagementException | IOException e) { + String errorMessage = "Error encountered while executing the execute statement of Marketplace Assistant service"; + RestApiUtil.handleInternalServerError(errorMessage, e, log); + } + return null; + } +} 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 93b071249bc4..121a13640033 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 @@ -3651,6 +3651,80 @@ paths: source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -H "Content-Type: application/json" -X POST -d @data.json "https://localhost:9443/api/am/devportal/v3/me/change-password"' + + ###################################################### + # The "Marketplace Assistant Feature" resource APIs + ###################################################### + '/marketplace-assistant/api-count': + + #----------------------------------------------------- + # Get No of apis in the VectorDB + #----------------------------------------------------- + get: + summary: API Count endpoint. + description: | + Get the api count of Marketplace Assistant AI service. + operationId: getMarketplaceAssistantApiCount + tags: + - Marketplace Assistant + responses: + 200: + description: | + OK. + Api Count is returned. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantApiCountResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 500: + description: | + Internal Server Error. + An error occurred while checking the health status of API Chat service. + + '/marketplace-assistant/chat': + + #----------------------------------------------------- + # Chat with Marketplace Assistant + #----------------------------------------------------- + post: + summary: Marketplace Assistant Chat Endpoint. + description: | + Send a single query to the service and get the response. + operationId: marketplaceAssistantExecute + requestBody: + description: | + Marketplace Assistant chat request payload. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantRequest' + tags: + - Marketplace Assistant + responses: + 201: + description: | + Created. + Marketplace Assistant chat response payload. + content: + application/json: + schema: + $ref: '#/components/schemas/MarketplaceAssistantResponse' + 400: + $ref: '#/components/responses/BadRequest' + 401: + $ref: '#/components/responses/Unauthorized' + 429: + $ref: '#/components/responses/TooManyRequests' + 500: + description: | + Internal Server Error. + An error occurred while executing test using Marketplace Chat service. + + components: schemas: APIList: @@ -5944,6 +6018,81 @@ components: query: type: string description: generated query + ChatMessage: + required: + - content + - role + type: object + properties: + role: + type: string + description: user or assistant role of a chat message. + example: "assistant" + content: + type: string + description: content of the message. + example: "Hi, How can I help you?" + MarketplaceAssistantRequest: + required: + - query + - history + type: object + properties: + query: + type: string + description: natural langugae query given by the user. + example: "Hi" + history: + type: array + items: + $ref: '#/components/schemas/ChatMessage' + MarketplaceAssistantApi: + required: + - apiId + - apiName + - version + type: object + properties: + apiId: + type: string + description: Uuid of the api. + example: "1sbdhsjd-121n-nknsjkd-1213njb" + apiName: + type: string + description: name of the api. + example: "PizzaShackAPI" + version: + type: string + description: version of the api. + example: "1.0.0" + MarketplaceAssistantResponse: + required: + - response + type: object + properties: + response: + type: string + description: natural language response by the llm. + example: "Hi, How can I help you?" + apis: + type: array + items: + $ref: '#/components/schemas/MarketplaceAssistantApi' + MarketplaceAssistantApiCountResponse: + required: + - count + - limit + type: object + properties: + count: + type: integer + description: no of apis stored in the vectordb. + example: "100" + limit: + type: integer + description: maximum no of apis allowed for an org. + example: "1000" + responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -6045,6 +6194,18 @@ components: description: The entity of the request was not in a supported format moreInfo: "" error: [] + TooManyRequests: + description: Too many requests. + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + code: 429 + message: TooManyRequests + description: The user has exceeded the rate limit + moreInfo: "" + error: [ ] parameters: parentCommentID: name: replyTo diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/beans.xml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/beans.xml index 16f95295ab6c..071c143fd1b5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/beans.xml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/beans.xml @@ -29,6 +29,7 @@ + diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json index 585fd7d161e8..26d436826223 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/org.wso2.carbon.apimgt.core.default.json @@ -43,6 +43,13 @@ "apim.cache.restapi_token.expiry_time" : "300s", "apim.cache.restapi_cache_control_headers.max_age" : "86400s", "apim.analytics.enable": false, + "apim.ai.enable": false, + "apim.ai.token": "abc", + "apim.ai.endpoint": "http://test.com", + "apim.ai.marketplace_assistant_chat_resource": "/ai/marketplace-assistant/chat", + "apim.ai.marketplace_assistant_publish_api_resource": "/ai/spec-populator/publish-api", + "apim.ai.marketplace_assistant_remove_api_resource": "/ai/spec-populator/remove-api", + "apim.ai.marketplace_assistant_api_count_resource": "/ai/spec-populator/api-count", "apim.api_quota_limit.enable": false, "apim.http_client.max_total": "100", "apim.http_client.default_max_per_route": "50", 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 ae324c00dc8f..dea7d9fa0f07 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 @@ -389,6 +389,28 @@ {{apim.api_quota_limit.enable}} + + + + {{apim.ai.enable}} + + {{apim.ai.token}} + + {{apim.ai.endpoint}} + + {{apim.ai.marketplace_assistant_chat_resource}} + + {{apim.ai.marketplace_assistant_publish_api_resource}} + + {{apim.ai.marketplace_assistant_remove_api_resource}} + + {{apim.ai.marketplace_assistant_api_count_resource}} + + + + + + true + + abc + + https://test.com + + /AI/marketplace-assistant/chat + + /AI/spec-populator/publish-api + + /AI/spec-populator/remove-api + + /AI/spec-populator/api-count + + + diff --git a/features/apimgt/org.wso2.carbon.apimgt.rest.api.service.catalog.feature/src/main/resources/runtimes/cxf3/snakeyaml-2.2.jar b/features/apimgt/org.wso2.carbon.apimgt.rest.api.service.catalog.feature/src/main/resources/runtimes/cxf3/snakeyaml-2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..275dd5700a389ba1902a02d49e465157942368ce GIT binary patch literal 334352 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%0A#Y`S^=~1(K=}tKgF|!NqMRXC~#~yJ^ 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
X?OY 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 Wm_M?y39}2c^Hbm|%RCr+v;7aOr7may literal 0 HcmV?d00001 From da1fcc5bb1954ccd600901f4ef2aaeb58f20c59d Mon Sep 17 00:00:00 2001 From: Thenujan-Nagaratnam Date: Sat, 23 Mar 2024 19:30:29 +0530 Subject: [PATCH 06/11] changed marketplace-assistant to ai --- .../src/main/resources/devportal-api.yaml | 4 ++-- ...MarketplaceAssistantApi.java => AiApi.java} | 12 ++++++------ ...istantApiService.java => AiApiService.java} | 2 +- ...iServiceImpl.java => AiApiServiceImpl.java} | 18 +++++++++--------- .../src/main/resources/devportal-api.yaml | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/{MarketplaceAssistantApi.java => AiApi.java} (89%) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/{MarketplaceAssistantApiService.java => AiApiService.java} (95%) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/{MarketplaceAssistantApiServiceImpl.java => AiApiServiceImpl.java} (89%) 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 121a13640033..fa185612f220 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 @@ -3655,7 +3655,7 @@ paths: ###################################################### # The "Marketplace Assistant Feature" resource APIs ###################################################### - '/marketplace-assistant/api-count': + '/ai/api-count': #----------------------------------------------------- # Get No of apis in the VectorDB @@ -3685,7 +3685,7 @@ paths: Internal Server Error. An error occurred while checking the health status of API Chat service. - '/marketplace-assistant/chat': + '/ai/chat': #----------------------------------------------------- # Chat with Marketplace Assistant diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java similarity index 89% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java index 869d54c5cd0c..1fce2dfe3a15 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java @@ -4,8 +4,8 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantApiCountResponseDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; -import org.wso2.carbon.apimgt.rest.api.store.v1.MarketplaceAssistantApiService; -import org.wso2.carbon.apimgt.rest.api.store.v1.impl.MarketplaceAssistantApiServiceImpl; +import org.wso2.carbon.apimgt.rest.api.store.v1.AiApiService; +import org.wso2.carbon.apimgt.rest.api.store.v1.impl.AiApiServiceImpl; import org.wso2.carbon.apimgt.api.APIManagementException; import javax.ws.rs.*; @@ -24,18 +24,18 @@ import java.util.Map; import java.util.List; import javax.validation.constraints.*; -@Path("/marketplace-assistant") +@Path("/ai") -@Api(description = "the marketplace-assistant API") +@Api(description = "the ai API") -public class MarketplaceAssistantApi { +public class AiApi { @Context MessageContext securityContext; -MarketplaceAssistantApiService delegate = new MarketplaceAssistantApiServiceImpl(); +AiApiService delegate = new AiApiServiceImpl(); @GET diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java similarity index 95% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java index c9ec95dea707..a90cebe47e16 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java @@ -22,7 +22,7 @@ import javax.ws.rs.core.SecurityContext; -public interface MarketplaceAssistantApiService { +public interface AiApiService { public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException; public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, MessageContext messageContext) throws APIManagementException; } 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/MarketplaceAssistantApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/AiApiServiceImpl.java similarity index 89% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/AiApiServiceImpl.java index 9274cca8f484..d7464bd75e7b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/AiApiServiceImpl.java @@ -36,15 +36,15 @@ import javax.ws.rs.core.SecurityContext; -public class MarketplaceAssistantApiServiceImpl implements MarketplaceAssistantApiService { +public class AiApiServiceImpl implements AiApiService { - private static final Log log = LogFactory.getLog(MarketplaceAssistantApiServiceImpl.class); + private static final Log log = LogFactory.getLog(AiApiServiceImpl.class); - private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto; + private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto; - @Override - public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, - MessageContext messageContext) throws APIManagementException { + @Override + public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, + MessageContext messageContext) throws APIManagementException { APIManagerConfiguration configuration = ServiceReferenceHolder. getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); @@ -89,8 +89,8 @@ public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marke return null; } - @Override - public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException { + @Override + public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException { APIManagerConfiguration configuration = ServiceReferenceHolder. getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration(); @@ -104,7 +104,7 @@ public Response getMarketplaceAssistantApiCount(MessageContext messageContext) t CloseableHttpResponse response = APIUtil. getMarketplaceChatApiCount(marketplaceAssistantConfigurationDto.getEndpoint(), - marketplaceAssistantConfigurationDto.getApiCountResource()); + marketplaceAssistantConfigurationDto.getApiCountResource()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { String responseStr = EntityUtils.toString(response.getEntity()); 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 121a13640033..fa185612f220 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 @@ -3655,7 +3655,7 @@ paths: ###################################################### # The "Marketplace Assistant Feature" resource APIs ###################################################### - '/marketplace-assistant/api-count': + '/ai/api-count': #----------------------------------------------------- # Get No of apis in the VectorDB @@ -3685,7 +3685,7 @@ paths: Internal Server Error. An error occurred while checking the health status of API Chat service. - '/marketplace-assistant/chat': + '/ai/chat': #----------------------------------------------------- # Chat with Marketplace Assistant From 8ef180e7ce1eaa01acc820a4352cf50e5dff8357 Mon Sep 17 00:00:00 2001 From: Thenujan-Nagaratnam Date: Sat, 23 Mar 2024 19:52:44 +0530 Subject: [PATCH 07/11] changed endpoint to marketplace-assistant --- .../v1/{AiApi.java => MarketplaceAssistantApi.java} | 12 ++++++------ ...vice.java => MarketplaceAssistantApiService.java} | 2 +- ....java => MarketplaceAssistantApiServiceImpl.java} | 5 +++-- .../src/main/resources/devportal-api.yaml | 4 ++-- .../src/main/webapp/WEB-INF/web.xml | 3 ++- 5 files changed, 14 insertions(+), 12 deletions(-) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/{AiApi.java => MarketplaceAssistantApi.java} (89%) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/{AiApiService.java => MarketplaceAssistantApiService.java} (95%) rename components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/{AiApiServiceImpl.java => MarketplaceAssistantApiServiceImpl.java} (97%) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java similarity index 89% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java index 1fce2dfe3a15..869d54c5cd0c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java @@ -4,8 +4,8 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantApiCountResponseDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; -import org.wso2.carbon.apimgt.rest.api.store.v1.AiApiService; -import org.wso2.carbon.apimgt.rest.api.store.v1.impl.AiApiServiceImpl; +import org.wso2.carbon.apimgt.rest.api.store.v1.MarketplaceAssistantApiService; +import org.wso2.carbon.apimgt.rest.api.store.v1.impl.MarketplaceAssistantApiServiceImpl; import org.wso2.carbon.apimgt.api.APIManagementException; import javax.ws.rs.*; @@ -24,18 +24,18 @@ import java.util.Map; import java.util.List; import javax.validation.constraints.*; -@Path("/ai") +@Path("/marketplace-assistant") -@Api(description = "the ai API") +@Api(description = "the marketplace-assistant API") -public class AiApi { +public class MarketplaceAssistantApi { @Context MessageContext securityContext; -AiApiService delegate = new AiApiServiceImpl(); +MarketplaceAssistantApiService delegate = new MarketplaceAssistantApiServiceImpl(); @GET diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java similarity index 95% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java index a90cebe47e16..c9ec95dea707 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/AiApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApiService.java @@ -22,7 +22,7 @@ import javax.ws.rs.core.SecurityContext; -public interface AiApiService { +public interface MarketplaceAssistantApiService { public Response getMarketplaceAssistantApiCount(MessageContext messageContext) throws APIManagementException; public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marketplaceAssistantRequestDTO, MessageContext messageContext) throws APIManagementException; } 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/AiApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java similarity index 97% rename from components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/AiApiServiceImpl.java rename to components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java index d7464bd75e7b..e4c2d000970e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/AiApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java @@ -36,9 +36,10 @@ import javax.ws.rs.core.SecurityContext; -public class AiApiServiceImpl implements AiApiService { +public class MarketplaceAssistantApiServiceImpl implements MarketplaceAssistantApiService { - private static final Log log = LogFactory.getLog(AiApiServiceImpl.class); + + private static final Log log = LogFactory.getLog(MarketplaceAssistantApiServiceImpl.class); private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto; 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 fa185612f220..121a13640033 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 @@ -3655,7 +3655,7 @@ paths: ###################################################### # The "Marketplace Assistant Feature" resource APIs ###################################################### - '/ai/api-count': + '/marketplace-assistant/api-count': #----------------------------------------------------- # Get No of apis in the VectorDB @@ -3685,7 +3685,7 @@ paths: Internal Server Error. An error occurred while checking the health status of API Chat service. - '/ai/chat': + '/marketplace-assistant/chat': #----------------------------------------------------- # Chat with Marketplace Assistant diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/web.xml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/web.xml index 704f87cb8b17..a82b26da74e6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/web.xml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/webapp/WEB-INF/web.xml @@ -48,7 +48,8 @@ org.wso2.carbon.apimgt.rest.api.store.v1.RecommendationsApi, org.wso2.carbon.apimgt.rest.api.store.v1.KeyManagersApi, org.wso2.carbon.apimgt.rest.api.store.v1.MeApi, - org.wso2.carbon.apimgt.rest.api.store.v1.WebhooksApi + org.wso2.carbon.apimgt.rest.api.store.v1.WebhooksApi, + org.wso2.carbon.apimgt.rest.api.store.v1.MarketplaceAssistantApi From eeadb5c9fcc5041bf83899e2f61de9ae7ab1eb22 Mon Sep 17 00:00:00 2001 From: Thenujan-Nagaratnam Date: Sat, 23 Mar 2024 20:05:36 +0530 Subject: [PATCH 08/11] changed common api-yaml --- .../src/main/resources/devportal-api.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 fa185612f220..121a13640033 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 @@ -3655,7 +3655,7 @@ paths: ###################################################### # The "Marketplace Assistant Feature" resource APIs ###################################################### - '/ai/api-count': + '/marketplace-assistant/api-count': #----------------------------------------------------- # Get No of apis in the VectorDB @@ -3685,7 +3685,7 @@ paths: Internal Server Error. An error occurred while checking the health status of API Chat service. - '/ai/chat': + '/marketplace-assistant/chat': #----------------------------------------------------- # Chat with Marketplace Assistant From 16dd85ccb0b56de0a667e02917528fe9a558b73e Mon Sep 17 00:00:00 2001 From: Thenujan-Nagaratnam Date: Sat, 23 Mar 2024 20:17:25 +0530 Subject: [PATCH 09/11] changed 2021 to 2024 --- .../impl/notifier/MarketplaceAssistantApiPublisherNotifier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java index 6b19417b418f..becd7da09907 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 5f6c0ca5c6e7d469085702ba392e9b0d87b4b2de Mon Sep 17 00:00:00 2001 From: Ashera Silva Date: Sat, 23 Mar 2024 20:38:44 +0530 Subject: [PATCH 10/11] Fix error flow error message propagate issue --- .../main/java/org/wso2/carbon/apimgt/impl/utils/APIUtil.java | 4 ++-- .../apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) 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 f993c4701583..ec66e1fd0d0d 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 @@ -10426,10 +10426,10 @@ public static String invokeAIService(String endpointConfigName, String authToken if (statusCode == HttpStatus.SC_CREATED) { return responseStr; } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) { - throw new APIManagementException("Unexpected response detected from the AI service." + responseStr, + 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, + throw new APIManagementException("Unexpected response detected from the AI service. " + responseStr, ExceptionCodes.AI_SERVICE_INVALID_RESPONSE); } } catch (MalformedURLException e) { 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 a266766547b4..590f1dc1bd10 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 @@ -293,7 +293,8 @@ public Response apiChatPost(String apiId, String apiChatAction, ApiChatRequestDT ApiChatResponseDTO.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"; + String errorMessage = "Error encountered while executing the prepare statement of API Chat " + + "service. Cause: " + e.getCause().getMessage(); RestApiUtil.handleInternalServerError(errorMessage, e, log); } @@ -360,7 +361,7 @@ public Response apiChatPost(String apiId, String apiChatAction, ApiChatRequestDT return Response.status(Response.Status.CREATED).entity(responseDTO).build(); } catch (APIManagementException | IOException e) { String errorMessage = "Error encountered while executing the API Chat service to accommodate the " + - "specified testing requirement"; + "specified testing requirement. Cause: " + e.getCause().getMessage(); RestApiUtil.handleInternalServerError(errorMessage, e, log); } } else { From f9052eea1b85d6e35e35bfb0c5a8ba69304cba05 Mon Sep 17 00:00:00 2001 From: Ashera Silva Date: Sat, 23 Mar 2024 23:25:32 +0530 Subject: [PATCH 11/11] Fix test failures and address review comments --- .../apimgt/impl/APIManagerConfiguration.java | 1 - ...arketplaceAssistantApiPublisherNotifier.java | 9 +++------ .../apimgt/impl/utils/LifeCycleUtils.java | 14 ++++++++------ .../APIManagerComponentImagePermissionTest.java | 5 +++++ .../impl/internal/APIManagerComponentTest.java | 5 +++++ .../src/main/resources/devportal-api.yaml | 2 +- .../api/store/v1/MarketplaceAssistantApi.java | 2 +- .../api/store/v1/impl/ApisApiServiceImpl.java | 1 + .../MarketplaceAssistantApiServiceImpl.java | 17 +++++++++++++++++ .../src/main/resources/devportal-api.yaml | 2 +- 10 files changed, 42 insertions(+), 16 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java index 3cb3cdb86ca7..b6e289da9843 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java @@ -108,7 +108,6 @@ public class APIManagerConfiguration { private JSONArray applicationAttributes = new JSONArray(); private CacheInvalidationConfiguration cacheInvalidationConfiguration; - private HttpClientConfigurationDTO httpClientConfiguration; private RecommendationEnvironment recommendationEnvironment; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java index becd7da09907..1e923265f390 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java @@ -17,8 +17,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.CloseableHttpResponse; import org.json.simple.JSONObject; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.APIProvider; @@ -77,7 +75,6 @@ private void process (Event event) throws NotifierException { return; } - // [ **Publish**, **Deploy as a Prototype**, **Demote to Created**, **Block**, **Deprecate**, **Re-Publish**, **Retire** ] if (APIConstants.EventType.API_LIFECYCLE_CHANGE.name().equals(event.getType())) { String lifecycleEvent = apiEvent.getLifecycleEvent(); String currentStatus = apiEvent.getCurrentStatus().toUpperCase(); @@ -161,8 +158,8 @@ private void postRequest(APIEvent apiEvent) throws NotifierException { APIUtil.MarketplaceAssistantPostService(marketplaceAssistantConfigurationDto.getEndpoint(), marketplaceAssistantConfigurationDto.getAccessToken(), marketplaceAssistantConfigurationDto.getApiPublishResource(), payload.toString()); } catch (APIManagementException e) { - String errorMessage = "Error encountered while Uploading the API to the vector database"; - log.error(errorMessage); + String errorMessage = "Error encountered while Uploading the API to the vector database" + e.getMessage(); + log.error(errorMessage, e); } } @@ -177,4 +174,4 @@ private void deleteRequest(APIEvent apiEvent) throws NotifierException { log.error(errorMessage); } } -} \ No newline at end of file +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java index bbce60b8a3c5..33377a0ece13 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java @@ -392,14 +392,16 @@ private static void addLCStateChangeInDatabase(String user, ApiTypeWrapper apiTy * @param apiOrApiProductId unique ID of API or API product * @param uuid unique UUID of API or API Product */ - private static void sendLCStateChangeNotification(String apiName, String apiType, String apiContext, String apiVersion, - String targetStatus, String provider, int apiOrApiProductId, - String uuid, String organization, String securityScheme, String action, String currentStatus, String apiVisibility) throws - APIManagementException { + private static void sendLCStateChangeNotification(String apiName, String apiType, String apiContext, + String apiVersion, String targetStatus, String provider, int apiOrApiProductId, String uuid, + String organization, String securityScheme, String action, String currentStatus, String apiVisibility) + throws APIManagementException { APIEvent apiEvent = new APIEvent(UUID.randomUUID().toString(), System.currentTimeMillis(), - APIConstants.EventType.API_LIFECYCLE_CHANGE.name(), APIUtil.getInternalOrganizationId(organization), organization, apiName, apiOrApiProductId, - uuid, apiVersion, apiType, apiContext, APIUtil.replaceEmailDomainBack(provider), targetStatus, securityScheme, action, currentStatus, apiVisibility); + APIConstants.EventType.API_LIFECYCLE_CHANGE.name(), APIUtil.getInternalOrganizationId(organization), + organization, apiName, apiOrApiProductId, uuid, apiVersion, apiType, apiContext, + APIUtil.replaceEmailDomainBack(provider), targetStatus, securityScheme, action, currentStatus, + apiVisibility); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentImagePermissionTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentImagePermissionTest.java index f4af4b012c2e..f15822cb5e89 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentImagePermissionTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentImagePermissionTest.java @@ -25,6 +25,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; +import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto; import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil; import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.base.MultitenantConstants; @@ -68,6 +69,8 @@ public void setup() throws Exception { Registry registry = Mockito.mock(Registry.class); CarbonContext carbonContext = Mockito.mock(CarbonContext.class); APIManagerConfiguration configuration = Mockito.mock(APIManagerConfiguration.class); + MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto = Mockito.mock( + MarketplaceAssistantConfigurationDto.class); Mockito.when(componentContext.getBundleContext()).thenReturn(bundleContext); Mockito.when(realmService.getTenantUserRealm(MultitenantConstants.SUPER_TENANT_ID)).thenReturn(userRealm); @@ -77,6 +80,8 @@ public void setup() throws Exception { Mockito.when(carbonContext.getRegistry(RegistryType.USER_GOVERNANCE)).thenReturn(registry); Mockito.doNothing().when(configuration).load(Mockito.anyString()); Mockito.when(configuration.getFirstProperty(Mockito.anyString())).thenReturn(""); + Mockito.when(configuration.getMarketplaceAssistantConfigurationDto()) + .thenReturn(marketplaceAssistantConfigurationDto); PowerMockito.when(ServiceReferenceHolder.getInstance()).thenReturn(serviceReferenceHolder); PowerMockito.when(APIUtil.getMountedPath(null, "")).thenReturn(""); PowerMockito.when(RegistryUtils.getAbsolutePath(null, null)).thenReturn(""); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentTest.java index 62e6f431fb79..91fcf50cf282 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponentTest.java @@ -30,6 +30,7 @@ import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService; +import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto; import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; import org.wso2.carbon.apimgt.impl.dto.EventHubConfigurationDto; import org.wso2.carbon.apimgt.impl.dto.GatewayArtifactSynchronizerProperties; @@ -79,6 +80,8 @@ public void testShouldActivateWhenAllPrerequisitesMet() throws Exception { UserRealm userRealm = Mockito.mock(UserRealm.class); OutputEventAdapterService adapterService = Mockito.mock(OutputEventAdapterService.class); ThrottleProperties throttleProperties = new ThrottleProperties(); + MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto = Mockito.mock( + MarketplaceAssistantConfigurationDto.class); Mockito.doNothing().when(configuration).load(Mockito.anyString()); Mockito.doNothing().when(authManager) @@ -97,6 +100,8 @@ public void testShouldActivateWhenAllPrerequisitesMet() throws Exception { Mockito.when(realmService.getTenantUserRealm(Mockito.anyInt())).thenReturn(userRealm); Mockito.when(userRealm.getAuthorizationManager()).thenReturn(authManager); Mockito.when(configuration.getThrottleProperties()).thenReturn(throttleProperties); + Mockito.when(configuration.getMarketplaceAssistantConfigurationDto()) + .thenReturn(marketplaceAssistantConfigurationDto); PowerMockito.doNothing().when(APIMgtDBUtil.class, "initialize"); PowerMockito.doNothing().when(APIUtil.class, "loadTenantExternalStoreConfig", Mockito.anyString()); PowerMockito.doNothing().when(AuthorizationUtils.class ,"addAuthorizeRoleListener", 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 121a13640033..ce504bb89217 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 @@ -3683,7 +3683,7 @@ paths: 500: description: | Internal Server Error. - An error occurred while checking the health status of API Chat service. + An error occurred while retrieving the API count. '/marketplace-assistant/chat': diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java index 869d54c5cd0c..993e15fdca4d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/store/v1/MarketplaceAssistantApi.java @@ -47,7 +47,7 @@ public class MarketplaceAssistantApi { @ApiResponse(code = 200, message = "OK. Api Count is returned. ", response = MarketplaceAssistantApiCountResponseDTO.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 checking the health status of API Chat service. ", response = Void.class) }) + @ApiResponse(code = 500, message = "Internal Server Error. An error occurred while retrieving the API count. ", response = Void.class) }) public Response getMarketplaceAssistantApiCount() throws APIManagementException{ return delegate.getMarketplaceAssistantApiCount(securityContext); } 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 a266766547b4..4c4cfbc8e205 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 @@ -55,6 +55,7 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.ApisApiService; import com.fasterxml.jackson.databind.ObjectMapper; + import java.io.File; import java.io.IOException; import java.net.URI; 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/MarketplaceAssistantApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java index e4c2d000970e..5fbb2c74a3ca 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you 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. + */ package org.wso2.carbon.apimgt.rest.api.store.v1.impl; import com.fasterxml.jackson.databind.ObjectMapper; 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 121a13640033..ce504bb89217 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 @@ -3683,7 +3683,7 @@ paths: 500: description: | Internal Server Error. - An error occurred while checking the health status of API Chat service. + An error occurred while retrieving the API count. '/marketplace-assistant/chat':