Skip to content

Commit

Permalink
Merge pull request #12157 from HeshanSudarshana/master-apictl-import-…
Browse files Browse the repository at this point in the history
…issue

Optimize existing API import flows with less update calls
  • Loading branch information
HeshanSudarshana authored Sep 25, 2023
2 parents 892cc63 + ff01047 commit bcf1d23
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -841,14 +841,6 @@ public API updateAPI(API api, API existingAPI) throws APIManagementException {
apiLogObject.put(APIConstants.AuditLogConstants.CONTEXT, api.getContext());
apiLogObject.put(APIConstants.AuditLogConstants.VERSION, api.getId().getVersion());
apiLogObject.put(APIConstants.AuditLogConstants.PROVIDER, api.getId().getProviderName());
try {
api.setCreatedTime(existingAPI.getCreatedTime());
apiPersistenceInstance.updateAPI(new Organization(organization), APIMapper.INSTANCE.toPublisherApi(api));
} catch (APIPersistenceException e) {
throw new APIManagementException("Error while updating API details", e);
}
APIUtil.logAuditMessage(APIConstants.AuditLogConstants.API, apiLogObject.toString(),
APIConstants.AuditLogConstants.UPDATED, this.username);

//Validate Transports
validateAndSetTransports(api);
Expand All @@ -859,7 +851,8 @@ public API updateAPI(API api, API existingAPI) throws APIManagementException {
} catch (APIPersistenceException e) {
throw new APIManagementException("Error while updating API details", e);
}

APIUtil.logAuditMessage(APIConstants.AuditLogConstants.API, apiLogObject.toString(),
APIConstants.AuditLogConstants.UPDATED, this.username);

//notify key manager with API update
registerOrUpdateResourceInKeyManager(api, tenantDomain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ public static API importApi(String extractedFolderPath, APIDTO importedApiDTO, B
setOperationsToDTO(importedApiDTO, validationResponse);
}
targetApi.setOrganization(organization);
importedApi = PublisherCommonUtils
.updateApi(targetApi, importedApiDTO, RestApiCommonUtil.getLoggedInUserProvider(), tokenScopes);
importedApi = PublisherCommonUtils.updateApiAndDefinition(targetApi, importedApiDTO,
RestApiCommonUtil.getLoggedInUserProvider(), tokenScopes, validationResponse);
} else {
if (targetApi == null && Boolean.TRUE.equals(overwrite)) {
log.info("Cannot find : " + importedApiDTO.getName() + "-" + importedApiDTO.getVersion()
Expand All @@ -293,6 +293,14 @@ public static API importApi(String extractedFolderPath, APIDTO importedApiDTO, B
importedApi = PublisherCommonUtils
.addAPIWithGeneratedSwaggerDefinition(importedApiDTO, ImportExportConstants.OAS_VERSION_3,
importedApiDTO.getProvider(), organization);
// Add/update swagger content except for streaming APIs and GraphQL APIs
if (!PublisherCommonUtils.isStreamingAPI(importedApiDTO)
&& !APIConstants.APITransportType.GRAPHQL.toString().equalsIgnoreCase(apiType)) {
// Add the validated swagger separately since the UI does the same procedure
PublisherCommonUtils.updateSwagger(importedApi.getUuid(), validationResponse, false,
organization);
importedApi = apiProvider.getAPIbyUUID(importedApi.getUuid(), currentTenantDomain);
}
} else {
importedApi = PublisherCommonUtils.importAsyncAPIWithDefinition(validationResponse, Boolean.FALSE,
importedApiDTO, null, currentTenantDomain, apiProvider);
Expand All @@ -317,13 +325,6 @@ public static API importApi(String extractedFolderPath, APIDTO importedApiDTO, B
// Retrieving the life cycle actions to do the lifecycle state change explicitly later
lifecycleActions = getLifeCycleActions(currentStatus, targetStatus);

// Add/update swagger content except for streaming APIs and GraphQL APIs
if (!PublisherCommonUtils.isStreamingAPI(importedApiDTO)
&& !APIConstants.APITransportType.GRAPHQL.toString().equalsIgnoreCase(apiType)) {
// Add the validated swagger separately since the UI does the same procedure
PublisherCommonUtils.updateSwagger(importedApi.getUuid(), validationResponse, false, organization);
importedApi = apiProvider.getAPIbyUUID(importedApi.getUuid(), currentTenantDomain);
}
// Add the GraphQL schema
if (APIConstants.APITransportType.GRAPHQL.toString().equalsIgnoreCase(apiType)) {
importedApi.setOrganization(organization);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,36 @@ public class PublisherCommonUtils {

private static final Log log = LogFactory.getLog(PublisherCommonUtils.class);
public static final String SESSION_TIMEOUT_CONFIG_KEY = "sessionTimeOut";

/**
* Update API and API definition.
*
* @param originalAPI existing API
* @param apiDtoToUpdate DTO object with updated API data
* @param apiProvider API Provider
* @param tokenScopes token scopes
* @param response response of the API definition validation
* @return updated API
* @throws APIManagementException If an error occurs while updating the API and API definition
* @throws ParseException If an error occurs while parsing the endpoint configuration
* @throws CryptoException If an error occurs while encrypting the secret key of API
* @throws FaultGatewaysException If an error occurs while updating manage of an existing API
*/
public static API updateApiAndDefinition(API originalAPI, APIDTO apiDtoToUpdate, APIProvider apiProvider,
String[] tokenScopes, APIDefinitionValidationResponse response)
throws APIManagementException, ParseException, CryptoException, FaultGatewaysException {

API apiToUpdate = prepareForUpdateApi(originalAPI, apiDtoToUpdate, apiProvider, tokenScopes);
String organization = RestApiCommonUtil.getLoggedInUserTenantDomain();
if (!PublisherCommonUtils.isStreamingAPI(apiDtoToUpdate) && !APIConstants.APITransportType.GRAPHQL.toString()
.equalsIgnoreCase(apiDtoToUpdate.getType().toString())) {
prepareForUpdateSwagger(originalAPI.getUuid(), response, false, apiProvider, organization,
response.getParser(), apiToUpdate);
}
apiProvider.updateAPI(apiToUpdate, originalAPI);
return apiProvider.getAPIbyUUID(originalAPI.getUuid(), originalAPI.getOrganization());
}

/**
* Update an API.
*
Expand All @@ -127,6 +157,28 @@ public class PublisherCommonUtils {
public static API updateApi(API originalAPI, APIDTO apiDtoToUpdate, APIProvider apiProvider, String[] tokenScopes)
throws ParseException, CryptoException, APIManagementException, FaultGatewaysException {

API apiToUpdate = prepareForUpdateApi(originalAPI, apiDtoToUpdate, apiProvider, tokenScopes);
apiProvider.updateAPI(apiToUpdate, originalAPI);

return apiProvider.getAPIbyUUID(originalAPI.getUuid(), originalAPI.getOrganization());
// TODO use returend api
}

/**
* Prepare for API object before updating the API.
*
* @param originalAPI Existing API
* @param apiDtoToUpdate New API DTO to update
* @param apiProvider API Provider
* @param tokenScopes Scopes of the token
* @throws ParseException If an error occurs while parsing the endpoint configuration
* @throws CryptoException If an error occurs while encrypting the secret key of API
* @throws APIManagementException If an error occurs while updating the API
*/
private static API prepareForUpdateApi(API originalAPI, APIDTO apiDtoToUpdate, APIProvider apiProvider,
String[] tokenScopes)
throws APIManagementException, ParseException, CryptoException {

APIIdentifier apiIdentifier = originalAPI.getId();
// Validate if the USER_REST_API_SCOPES is not set in WebAppAuthenticator when scopes are validated
if (tokenScopes == null) {
Expand Down Expand Up @@ -359,10 +411,7 @@ public static API updateApi(API originalAPI, APIDTO apiDtoToUpdate, APIProvider
}

apiToUpdate.setOrganization(originalAPI.getOrganization());
apiProvider.updateAPI(apiToUpdate, originalAPI);

return apiProvider.getAPIbyUUID(originalAPI.getUuid(), originalAPI.getOrganization());
// TODO use returend api
return apiToUpdate;
}

/**
Expand Down Expand Up @@ -1343,6 +1392,36 @@ public static String updateSwagger(String apiId, APIDefinitionValidationResponse
//this will fail if user does not have access to the API or the API does not exist
API existingAPI = apiProvider.getAPIbyUUID(apiId, organization);
APIDefinition oasParser = response.getParser();
prepareForUpdateSwagger(apiId, response, isServiceAPI, apiProvider, organization, oasParser, existingAPI);

//Update API is called to update URITemplates and scopes of the API
API unModifiedAPI = apiProvider.getAPIbyUUID(apiId, organization);
existingAPI.setStatus(unModifiedAPI.getStatus());
apiProvider.updateAPI(existingAPI, unModifiedAPI);

//retrieves the updated swagger definition
String apiSwagger = apiProvider.getOpenAPIDefinition(apiId, organization); // TODO see why we need to get it
// instead of passing same
return oasParser.getOASDefinitionForPublisher(existingAPI, apiSwagger);
}

/**
* Prepare the API object before updating swagger.
*
* @param apiId API Id
* @param response response of a swagger definition validation call
* @param isServiceAPI whether the API is a service API or not
* @param apiProvider API Provider
* @param organization tenant domain
* @param oasParser OASParser for the API definition
* @param existingAPI existing API
* @throws APIManagementException when error occurred updating swagger
*/
private static void prepareForUpdateSwagger(String apiId, APIDefinitionValidationResponse response,
boolean isServiceAPI, APIProvider apiProvider, String organization,
APIDefinition oasParser, API existingAPI)
throws APIManagementException {

String apiDefinition = response.getJsonContent();
if (isServiceAPI) {
apiDefinition = oasParser.copyVendorExtensions(existingAPI.getSwaggerDefinition(), apiDefinition);
Expand Down Expand Up @@ -1390,20 +1469,10 @@ public static String updateSwagger(String apiId, APIDefinitionValidationResponse
existingAPI.setScopes(scopes);
PublisherCommonUtils.validateScopes(existingAPI);

//Update API is called to update URITemplates and scopes of the API
API unModifiedAPI = apiProvider.getAPIbyUUID(apiId, organization);
existingAPI.setStatus(unModifiedAPI.getStatus());
apiProvider.updateAPI(existingAPI, unModifiedAPI);
SwaggerData swaggerData = new SwaggerData(existingAPI);

String updatedApiDefinition = oasParser.populateCustomManagementInfo(apiDefinition, swaggerData);
apiProvider.saveSwaggerDefinition(existingAPI, updatedApiDefinition, organization);
existingAPI.setSwaggerDefinition(updatedApiDefinition);

//retrieves the updated swagger definition
String apiSwagger = apiProvider.getOpenAPIDefinition(apiId, organization); // TODO see why we need to get it
// instead of passing same
return oasParser.getOASDefinitionForPublisher(existingAPI, apiSwagger);
}

/**
Expand Down

0 comments on commit bcf1d23

Please sign in to comment.