Skip to content

Commit

Permalink
Merge pull request #328 from thilinicooray/1.9.x
Browse files Browse the repository at this point in the history
Added modifications to api-import-export tool
  • Loading branch information
nuwand committed Aug 17, 2015
2 parents 53a56a3 + c552775 commit b631096
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public final class APIImportExportConstants {
public static final String TEMP_DIR = "java.io.tmpdir";
//name of the uploaded zip file
public static final String UPLOAD_FILE_NAME = "APIArchive.zip";
//Always use '/' as archive path separator despite the OS dependent path separator
public static final char ARCHIVE_PATH_SEPARATOR = '/';
//location of the api JSON file
public static final String JSON_FILE_LOCATION = DIRECTORY_SEPARATOR + "Meta-information" + DIRECTORY_SEPARATOR +
"api.json";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@
import org.wso2.carbon.apimgt.api.APIDefinition;
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.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.APIStatus;
import org.wso2.carbon.apimgt.api.model.Documentation;
import org.wso2.carbon.apimgt.api.model.*;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerFactory;
import org.wso2.carbon.apimgt.impl.definitions.APIDefinitionFromSwagger20;
Expand Down Expand Up @@ -64,10 +61,7 @@
import java.io.OutputStream;
import java.io.StringReader;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
* This is the util class which consists of all the functions for exporting API
Expand Down Expand Up @@ -582,6 +576,8 @@ private static void exportMetaInformation(API apiToReturn, Registry registry) th
apiToReturn.getId().getVersion());

createDirectory(archivePath + File.separator + "Meta-information");
//Remove unnecessary data from exported Api
cleanApiDataToExport(apiToReturn);

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String apiInJson = gson.toJson(apiToReturn);
Expand All @@ -605,6 +601,20 @@ private static void exportMetaInformation(API apiToReturn, Registry registry) th
}
}

/**
* Clean api by removing unnecessary details
*
* @param api api to be exported
*/
private static void cleanApiDataToExport(API api) {
// Thumbnail will be set according to the importing environment. Therefore current URL is removed
api.setThumbnailUrl(null);
// Swagger.json contains complete details about scopes and URI templates. Therefore scope and URI template
// details are removed from api.json
api.setScopes(new TreeSet<Scope>());
api.setUriTemplates(new TreeSet<URITemplate>());
}

/**
* Write content to file
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.wso2.carbon.apimgt.api.APIDefinition;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIProvider;
import org.wso2.carbon.apimgt.api.FaultGatewaysException;
import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.Documentation;
import org.wso2.carbon.apimgt.api.model.Icon;
import org.wso2.carbon.apimgt.api.model.Tier;
import org.wso2.carbon.apimgt.api.model.*;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.definitions.APIDefinitionFromSwagger20;
import org.wso2.carbon.apimgt.impl.handlers.ScopesIssuer;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;

import org.wso2.carbon.registry.api.Registry;
Expand Down Expand Up @@ -146,7 +145,8 @@ public static String extractArchive(File sourceFile, String destination) throws

//This index variable is used to get the extracted folder name; that is root directory
if (index == 0) {
archiveName = currentEntry.substring(0, currentEntry.indexOf(File.separatorChar));
archiveName =
currentEntry.substring(0, currentEntry.indexOf(APIImportExportConstants.ARCHIVE_PATH_SEPARATOR));
--index;
}

Expand Down Expand Up @@ -255,14 +255,14 @@ public static void importAPI(String pathToArchive, String currentUser, boolean i
}

try{
int tenantId = APIUtil.getTenantId(currentUser);
provider.addAPI(importedApi);
addSwaggerDefinition(importedApi.getId(), pathToArchive);
addSwaggerDefinition(importedApi, pathToArchive, tenantId);
} catch (APIManagementException e){
//Error is logged and APIImportException is thrown because adding API and swagger are mandatory steps
log.error("Error in adding API to the provider. ", e);
throw new APIImportException("Error in adding API to the provider. " + e.getMessage());
}

//Since Image, documents, sequences and WSDL are optional, exceptions are logged and ignored in implementation
addAPIImage(pathToArchive, importedApi);
addAPIDocuments(pathToArchive, importedApi);
Expand Down Expand Up @@ -528,26 +528,69 @@ private static void addAPIWsdl(String pathToArchive, API importedApi, String cur
/**
* This method adds Swagger API definition to registry
*
* @param apiId Identifier of the imported API
* @param importedApi Imported API
* @param archivePath File path where API archive stored
* @param tenantId Id of the current tenant
* @throws APIImportException if there is an error occurs when adding Swagger definition
*/
private static void addSwaggerDefinition(APIIdentifier apiId, String archivePath)
private static void addSwaggerDefinition(API importedApi, String archivePath, int tenantId)
throws APIImportException {

try {
String swaggerContent = FileUtils.readFileToString(
new File(archivePath + APIImportExportConstants.SWAGGER_DEFINITION_LOCATION));
provider.saveSwagger20Definition(apiId, swaggerContent);

updateApiResourcesFromSwagger(importedApi, swaggerContent, tenantId);
provider.updateAPI(importedApi);
provider.saveSwagger20Definition(importedApi.getId(), swaggerContent);
} catch (APIManagementException e) {
log.error("Error in adding Swagger definition for the API. ", e);
throw new APIImportException("Error in adding Swagger definition for the API. " + e.getMessage());
} catch (IOException e) {
log.error("Error in importing Swagger definition for the API. ", e);
throw new APIImportException("Error in importing Swagger definition for the API. " + e.getMessage());
} catch (FaultGatewaysException e) {
log.error("Failed to update API after adding resources and scopes. ", e);
throw new APIImportException("Failed to update API after adding resources and scopes. " + e.getMessage());
}
}

/**
* Add URI templates and scopes retrieved from swagger.json to the imported API
* @param importedApi Imported API
* @param swaggerContent Content of swagger.json
* @param tenantId Current tenant ID
* @throws APIManagementException If an error occurs while adding resources to the imported api
*/
private static void updateApiResourcesFromSwagger(API importedApi, String swaggerContent, int tenantId)
throws APIManagementException {

APIDefinition definitionFromSwagger20 = new APIDefinitionFromSwagger20();
//retrieve URI templates
Set<URITemplate> uriTemplates = definitionFromSwagger20.getURITemplates(importedApi, swaggerContent);

//retrieve scopes
Set<Scope> scopes = definitionFromSwagger20.getScopes(String.valueOf(swaggerContent));

//Check whether scopes of importing api are already assigned by another API
//If so, import process gets halted by throwing an exception
for (Scope scope : scopes) {
if (scope != null && !(ScopesIssuer.getInstance().isWhiteListedScope(scope.getKey()))) {
if (provider.isScopeKeyExist(scope.getKey(), tenantId)) {
log.error("Unable to assign scope! " + scope.getKey() + " is already assigned by another API");
provider.deleteAPI(importedApi.getId());
throw new APIManagementException("Unable to assign scope! " + scope.getKey() +
" is already assigned by another API");
}
}
}

//set URI templates and scopes to the imported API
importedApi.setUriTemplates(uriTemplates);
importedApi.setScopes(scopes);
}


/**
* This method checks whether a given file exists in a given location
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package apim.restful.importexport.utils;

import apim.restful.importexport.APIExportException;
import apim.restful.importexport.APIImportExportConstants;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -127,6 +128,8 @@ private static void addToArchive(File directoryToZip, File file, ZipOutputStream
// Get relative path from archive directory to the specific file
String zipFilePath = file.getCanonicalPath()
.substring(directoryToZip.getCanonicalPath().length() + 1, file.getCanonicalPath().length());
if (File.separatorChar != '/')
zipFilePath = zipFilePath.replace(File.separatorChar, APIImportExportConstants.ARCHIVE_PATH_SEPARATOR);
ZipEntry zipEntry = new ZipEntry(zipFilePath);
zipOutputStream.putNextEntry(zipEntry);

Expand Down

0 comments on commit b631096

Please sign in to comment.