Skip to content

Commit

Permalink
Update: Custom Backend REST APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
BLasan committed Sep 9, 2024
1 parent eb6e555 commit 2f211b8
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ public enum ExceptionCodes implements ErrorHandler {
"Required attributes(s) %s for api policy specification %s are either missing or empty"),
OPERATION_POLICY_NOT_FOUND(902010, "API Policy Not Found", 404,
"Requested api policy with id '%s' not found"),
CUSTOM_BACKEND_NOT_FOUND(903250, "Custom Backend not found",
404, "Requested Custom Backend with id '%s' not found"),

OPERATION_POLICY_ALREADY_EXISTS(903001, "The API Policy already exists.", 409, "An Operation Policy with name '%s' and version '%s' already exists"),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,71 @@ paths:
-H "Content-Type: application/json" -d @data.json
"https://127.0.0.1:9443/api/am/publisher/v4/apis/7a2298c4-c905-403f-8fac-38c73301631f/topics"'

/apis/{apiId}/custom-backend/{customBackendId}/content:
get:
tags:
- APIs
summary: Get Sequence of Custom Backend
description: This operation can be used to get Sequence of the Custom Backend
operationId: getCustomBackendDataContent
parameters:
- name: type
in: query
description: |
Type of the Endpoint.
SANDBOX or PRODUCTION
required: true
schema:
maxLength: 15
type: string
- $ref: '#/components/parameters/customBackendId'
- $ref: '#/components/parameters/apiId'
responses:
200:
description: |
OK.
Requested API Custom Backend is returned
headers:
ETag:
description: |
Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future).
schema:
type: string
Last-Modified:
description: |
Date and time the resource has been modifed the last time.
Used by caches, or in conditional requests (Will be supported in future).
schema:
type: string
Content-Type:
description: |
The content type of the body.
schema:
type: string
content:
application/zip:
schema:
type: string
format: binary
304:
description: |
Not Modified.
Empty body because the client has already the latest version of the requested resource (Will be supported in future).
content: {}
404:
$ref: '#/components/responses/NotFound'
406:
$ref: '#/components/responses/NotAcceptable'
security:
- OAuth2Security:
- apim:api_view
- apim:api_manage
- apim:api_import_export
- apim:api_product_import_export
x-code-samples:
- lang: Curl
source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8"
"https://127.0.0.1:9443/api/am/publisher/v4/apis/7a2298c4-c905-403f-8fac-38c73301631f/custom-backend/7a2298c4-c915-483f-8fac-38c73301631f/content"'

/apis/{apiId}/custom-backend/{customBackendId}:
get:
Expand All @@ -496,6 +561,15 @@ paths:
description: This operation can be used to get Custom Backend data of the API
operationId: getCustomBackendData
parameters:
- name: type
in: query
description: |
Type of the Endpoint.
SANDBOX or PRODUCTION
required: true
schema:
maxLength: 15
type: string
- $ref: '#/components/parameters/customBackendId'
- $ref: '#/components/parameters/apiId'
responses:
Expand Down Expand Up @@ -550,6 +624,15 @@ paths:
description: This operation can be used to remove the Custom Backend of the API
operationId: customBackendDelete
parameters:
- name: type
in: query
description: |
Type of the Endpoint.
SANDBOX or PRODUCTION
required: true
schema:
maxLength: 15
type: string
- $ref: '#/components/parameters/apiId'
- $ref: '#/components/parameters/If-Match'
- $ref: '#/components/parameters/customBackendId'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ public Response createNewAPIVersion( @NotNull @Size(max=30) @ApiParam(value = "V
@ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class),
@ApiResponse(code = 409, message = "Conflict. Specified resource already exists.", response = ErrorDTO.class),
@ApiResponse(code = 412, message = "Precondition Failed. The request has not been performed because one of the preconditions is not met.", response = ErrorDTO.class) })
public Response customBackendDelete(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "Custom Backend ID ",required=true) @PathParam("customBackendId") String customBackendId, @ApiParam(value = "Validator for conditional requests; based on ETag. " )@HeaderParam("If-Match") String ifMatch) throws APIManagementException{
return delegate.customBackendDelete(apiId, customBackendId, ifMatch, securityContext);
public Response customBackendDelete( @NotNull @Size(max=15) @ApiParam(value = "Type of the Endpoint. SANDBOX or PRODUCTION ",required=true) @QueryParam("type") String type, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "Custom Backend ID ",required=true) @PathParam("customBackendId") String customBackendId, @ApiParam(value = "Validator for conditional requests; based on ETag. " )@HeaderParam("If-Match") String ifMatch) throws APIManagementException{
return delegate.customBackendDelete(type, apiId, customBackendId, ifMatch, securityContext);
}

@PUT
Expand Down Expand Up @@ -1349,8 +1349,29 @@ public Response getAuditReportOfAPI(@ApiParam(value = "**API ID** consisting of
@ApiResponse(code = 304, message = "Not Modified. Empty body because the client has already the latest version of the requested resource (Will be supported in future). ", response = Void.class),
@ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class),
@ApiResponse(code = 406, message = "Not Acceptable. The requested media type is not supported.", response = ErrorDTO.class) })
public Response getCustomBackendData(@ApiParam(value = "Custom Backend ID ",required=true) @PathParam("customBackendId") String customBackendId, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId) throws APIManagementException{
return delegate.getCustomBackendData(customBackendId, apiId, securityContext);
public Response getCustomBackendData( @NotNull @Size(max=15) @ApiParam(value = "Type of the Endpoint. SANDBOX or PRODUCTION ",required=true) @QueryParam("type") String type, @ApiParam(value = "Custom Backend ID ",required=true) @PathParam("customBackendId") String customBackendId, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId) throws APIManagementException{
return delegate.getCustomBackendData(type, customBackendId, apiId, securityContext);
}

@GET
@Path("/{apiId}/custom-backend/{customBackendId}/content")

@Produces({ "application/zip", "application/json" })
@ApiOperation(value = "Get Sequence of Custom Backend", notes = "This operation can be used to get Sequence of the Custom Backend", response = File.class, authorizations = {
@Authorization(value = "OAuth2Security", scopes = {
@AuthorizationScope(scope = "apim:api_view", description = "View API"),
@AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"),
@AuthorizationScope(scope = "apim:api_import_export", description = "Import and export APIs related operations"),
@AuthorizationScope(scope = "apim:api_product_import_export", description = "Import and export API Products related operations")
})
}, tags={ "APIs", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. Requested API Custom Backend is returned ", response = File.class),
@ApiResponse(code = 304, message = "Not Modified. Empty body because the client has already the latest version of the requested resource (Will be supported in future). ", response = Void.class),
@ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class),
@ApiResponse(code = 406, message = "Not Acceptable. The requested media type is not supported.", response = ErrorDTO.class) })
public Response getCustomBackendDataContent( @NotNull @Size(max=15) @ApiParam(value = "Type of the Endpoint. SANDBOX or PRODUCTION ",required=true) @QueryParam("type") String type, @ApiParam(value = "Custom Backend ID ",required=true) @PathParam("customBackendId") String customBackendId, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId) throws APIManagementException{
return delegate.getCustomBackendDataContent(type, customBackendId, apiId, securityContext);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public interface ApisApiService {
public Response createAPI(APIDTO APIDTO, String openAPIVersion, MessageContext messageContext) throws APIManagementException;
public Response createAPIRevision(String apiId, APIRevisionDTO apIRevisionDTO, MessageContext messageContext) throws APIManagementException;
public Response createNewAPIVersion(String newVersion, String apiId, Boolean defaultVersion, String serviceVersion, MessageContext messageContext) throws APIManagementException;
public Response customBackendDelete(String apiId, String customBackendId, String ifMatch, MessageContext messageContext) throws APIManagementException;
public Response customBackendDelete(String type, String apiId, String customBackendId, String ifMatch, MessageContext messageContext) throws APIManagementException;
public Response customBackendUpdate(String apiId, String ifMatch, InputStream sequenceInputStream, Attachment sequenceDetail, String type, MessageContext messageContext) throws APIManagementException;
public Response deleteAPI(String apiId, String ifMatch, MessageContext messageContext) throws APIManagementException;
public Response deleteAPIClientCertificateByAlias(String alias, String apiId, MessageContext messageContext) throws APIManagementException;
Expand Down Expand Up @@ -128,7 +128,8 @@ public interface ApisApiService {
public Response getAmazonResourceNamesOfAPI(String apiId, MessageContext messageContext) throws APIManagementException;
public Response getAuditReportOfAPI(String apiId, String accept, MessageContext messageContext) throws APIManagementException;
public Response getCommentOfAPI(String commentId, String apiId, String xWSO2Tenant, String ifNoneMatch, Boolean includeCommenterInfo, Integer replyLimit, Integer replyOffset, MessageContext messageContext) throws APIManagementException;
public Response getCustomBackendData(String customBackendId, String apiId, MessageContext messageContext) throws APIManagementException;
public Response getCustomBackendData(String type, String customBackendId, String apiId, MessageContext messageContext) throws APIManagementException;
public Response getCustomBackendDataContent(String type, String customBackendId, String apiId, MessageContext messageContext) throws APIManagementException;
public Response getGeneratedMockScriptsOfAPI(String apiId, String ifNoneMatch, MessageContext messageContext) throws APIManagementException;
public Response getGraphQLPolicyComplexityOfAPI(String apiId, MessageContext messageContext) throws APIManagementException;
public Response getGraphQLPolicyComplexityTypesOfAPI(String apiId, MessageContext messageContext) throws APIManagementException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,32 +163,51 @@ public Response getAllAPIs(Integer limit, Integer offset, String sortBy, String
return null;
}

@Override public Response getCustomBackendData(String customBackendId, String apiId, MessageContext messageContext)
throws APIManagementException {
@Override public Response getCustomBackendData(String type, String customBackendId, String apiId,
MessageContext messageContext) throws APIManagementException {
APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider();

//validate if api exists
CommonUtils.validateAPIExistence(apiId);
String type = "SANDBOX";

Map<String, Object> endpointConfig = apiProvider.getCustomBackendOfAPIByUUID(customBackendId, apiId, type,
true);
false);

if(endpointConfig != null) {
throw new APIMgtResourceNotFoundException("Couldn't retrieve an existing Custom Backend with ID: "
+ customBackendId + " for API " + apiId,
ExceptionCodes.from(ExceptionCodes.CUSTOM_BACKEND_NOT_FOUND, customBackendId));
}
CustomBackendDTO backendDTO = new CustomBackendDTO();
backendDTO.setSequenceName(endpointConfig.get("sequence_name").toString());
backendDTO.setSequenceId(endpointConfig.get("sequence_id").toString());
backendDTO.setSequenceType(endpointConfig.get("type").toString());
return Response.ok().entity(backendDTO).build();
}
@Override
public Response getCustomBackendDataContent(String type, String customBackendId, String apiId, MessageContext messageContext) throws APIManagementException {
APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider();
CommonUtils.validateAPIExistence(apiId);

InputStream seq = apiProvider.getCustomBackendSequenceOfAPIByUUID(apiId, customBackendId, type);
if(seq != null) {
throw new APIMgtResourceNotFoundException("Couldn't retrieve an existing Custom Backend with ID: "
+ customBackendId + " for API " + apiId,
ExceptionCodes.from(ExceptionCodes.CUSTOM_BACKEND_NOT_FOUND, customBackendId));
}
String seqName = APIUtil.getCustomBackendName(apiId, type);
File file = RestApiPublisherUtils.exportCustomBackendData(seq, seqName);
return Response.ok(file).header(RestApiConstants.HEADER_CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getName() + "\"").build();
}

@Override public Response customBackendDelete(String apiId, String customBackendId, String ifMatch,
@Override public Response customBackendDelete(String type, String apiId, String customBackendId, String ifMatch,
MessageContext messageContext) throws APIManagementException {
APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider();

//validate if api exists
CommonUtils.validateAPIExistence(apiId);
String type = "SANDBOX";
apiProvider.deleteCustomBackendByID(apiId, customBackendId, type);
return Response.ok().entity(null).build();
return Response.ok().build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.common.mappings.PublisherCommonUtils;
import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil;
import org.wso2.carbon.utils.FileUtil;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

Expand Down Expand Up @@ -277,6 +278,24 @@ public static String getContentType(Attachment fileDetail) {
return fileContentType;
}

public static File exportCustomBackendData(InputStream seq, String seqName) throws APIManagementException {
File exportFolder = null;
try {
exportFolder = CommonUtil.createTempDirectoryFromName(seqName + "_" + "Custom-Backend");
String exportCustomBackendBasePath = exportFolder.toString();
String archivePath = exportCustomBackendBasePath.concat(File.separator + seqName);
CommonUtil.createDirectory(archivePath);
String customBackendName =
archivePath + File.separator + seqName + APIConstants.SYNAPSE_POLICY_DEFINITION_EXTENSION_XML;
CommonUtil.writeFile(customBackendName, IOUtils.toString(seq));
CommonUtil.archiveDirectory(exportCustomBackendBasePath);
FileUtils.deleteQuietly(new File(exportCustomBackendBasePath));
return new File(exportCustomBackendBasePath + APIConstants.ZIP_FILE_EXTENSION);
} catch (APIImportExportException | IOException ex) {
throw new APIManagementException("Error when exporting Custom Backend: " + seqName, ex);
}
}

public static File exportOperationPolicyData(OperationPolicyData policyData, String format)
throws APIManagementException {

Expand Down
Loading

0 comments on commit 2f211b8

Please sign in to comment.