diff --git a/config/api-manager.xml b/config/api-manager.xml
index 0312bfa176..c26b3aff54 100644
--- a/config/api-manager.xml
+++ b/config/api-manager.xml
@@ -12,32 +12,6 @@
false
-
-
-
-
-
-
-
-
-
-
-
+ false
+
org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageDataBridgeDataPublisher
+
+
+ {tcp://localhost:7612/}
+
+
+ admin
+
+
+ admin
+
-
+
+
+
+ 4.0.0
+
+ org.wso2.carbon.apimgt
+ api-import-export
+ 1.0-SNAPSHOT
+
+ JAX-RS API Import Export
+ war
+
+
+
+
+ maven-compiler-plugin
+
+
+ 1.5
+
+ 2.3.2
+
+
+ maven-war-plugin
+ 2.2
+
+ WEB-INF/lib/*.jar
+ ${project.artifactId}
+
+
+
+ maven-eclipse-plugin
+ 2.9
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+ org.wso2.developerstudio.eclipse.jaxrs.project.nature
+ org.eclipse.jdt.core.javanature
+
+
+
+
+
+
+
+
+ deploy
+
+ compile
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.7
+
+
+ compile
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ client
+
+ test
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.2.1
+
+
+ test
+
+ java
+
+
+ demo.jaxrs.client.Client
+
+
+ http://localhost:9763/services
+
+
+
+
+
+
+
+
+
+
+
+
+ commons-httpclient
+ commons-httpclient
+ 3.1
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+ 2.6.1
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ 2.6.1
+
+
+ javax.ws.rs
+ jsr311-api
+ 1.1.1
+
+
+ org.wso2.carbon.apimgt
+ org.wso2.carbon.apimgt.impl
+ 1.2.4-SNAPSHOT
+
+
+ org.wso2.carbon.apimgt
+ org.wso2.carbon.apimgt.api
+ 1.2.4-SNAPSHOT
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.8.5
+
+
+ com.google.code.gson
+ gson
+ 1.7.1
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+
+
+ codehaus
+ http://repository.codehaus.org/org/codehaus
+
+
+ wso2-nexus
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/groups/wso2-public/
+
+ true
+ daily
+ warn
+
+
+
+ wso2.releases
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/repositories/releases/
+
+ true
+ daily
+ ignore
+
+
+
+
\ No newline at end of file
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/APIExportException.java b/modules/api-import-export/src/main/java/apim/restful/importexport/APIExportException.java
new file mode 100644
index 0000000000..265e7c459f
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/APIExportException.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport;
+
+/**
+ * This class is used for handling exceptions occur in API export
+ */
+public class APIExportException extends Exception {
+
+ public APIExportException(String msg) {
+ super(msg);
+ }
+
+ public APIExportException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+ public APIExportException(Throwable throwable) {
+ super(throwable);
+ }
+}
+
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportException.java b/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportException.java
new file mode 100644
index 0000000000..4ed47c01fa
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportException.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport;
+
+/**
+ * This is the class to represent APIImportException. This exception is used to indicate the
+ * exceptions that might be occurred during API import process.
+ */
+public class APIImportException extends Exception {
+
+ String errorDescription;
+
+ public APIImportException(String errorMessage) {
+ this.errorDescription = errorMessage;
+ }
+
+ /**
+ * This method returns the error description to the caller.
+ *
+ * @return errorDescription a string which contains the error
+ */
+ public String getErrorDescription() {
+ return this.errorDescription;
+ }
+}
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportExportConstants.java b/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportExportConstants.java
new file mode 100644
index 0000000000..38b0a1f645
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/APIImportExportConstants.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport;
+
+import java.io.File;
+
+/**
+ * This class contains all the constants required for API Import and Export
+ */
+public final class APIImportExportConstants {
+
+ //system dependent default path separator character, represented as a string
+ public static final String DIRECTORY_SEPARATOR = File.separator;
+ //string representing the false state when preserving the provider
+ public static final String STATUS_FALSE = "FALSE";
+ //length of the name of the temporary directory
+ public static final int TEMP_FILENAME_LENGTH = 5;
+ //system property for default temporary directory
+ public static final String TEMP_DIR = "java.io.tmpdir";
+ //name of the uploaded zip file
+ public static final String UPLOAD_FILE_NAME = "APIArchive.zip";
+ //location of the api JSON file
+ public static final String JSON_FILE_LOCATION = DIRECTORY_SEPARATOR + "Meta-information" + DIRECTORY_SEPARATOR +
+ "api.json";
+ //name of the id element tag of the api.json file
+ public static final String ID_ELEMENT = "id";
+ //name of the id element tag of the api.json file
+ public static final String PROVIDER_ELEMENT = "providerName";
+ //location of the api swagger definition file
+ public static final String SWAGGER_DEFINITION_LOCATION = DIRECTORY_SEPARATOR + "Meta-information" +
+ DIRECTORY_SEPARATOR + "swagger.json";
+ //location of the image
+ public static final String IMAGE_FILE_LOCATION = DIRECTORY_SEPARATOR + "Image" + DIRECTORY_SEPARATOR;
+ //name of the image
+ public static final String IMAGE_FILE_NAME = "icon";
+ //location of the documents JSON file
+ public static final String DOCUMENT_FILE_LOCATION = DIRECTORY_SEPARATOR + "Docs" + DIRECTORY_SEPARATOR +
+ "docs.json";
+ //name of the inline file type
+ public static final String INLINE_DOC_TYPE = "INLINE";
+ //name of the url file type
+ public static final String URL_DOC_TYPE = "URL";
+ //name of the physical file type
+ public static final String FILE_DOC_TYPE = "FILE";
+ //location of the in sequence
+ public static final String IN_SEQUENCE_LOCATION = DIRECTORY_SEPARATOR + "Sequences" + DIRECTORY_SEPARATOR +
+ "in-sequence" + DIRECTORY_SEPARATOR;
+ //location of the out sequence
+ public static final String OUT_SEQUENCE_LOCATION = DIRECTORY_SEPARATOR + "Sequences" + DIRECTORY_SEPARATOR +
+ "out-sequence" + DIRECTORY_SEPARATOR;
+ //location of the fault sequence
+ public static final String FAULT_SEQUENCE_LOCATION = DIRECTORY_SEPARATOR + "Sequences" + DIRECTORY_SEPARATOR +
+ "fault-sequence" + DIRECTORY_SEPARATOR;
+ //extension of xml files
+ public static final String XML_EXTENSION = ".xml";
+ //location of the wsdl file
+ public static final String WSDL_LOCATION = DIRECTORY_SEPARATOR + "WSDL" + DIRECTORY_SEPARATOR;
+ //extension of wsdl files
+ public static final String WSDL_EXTENSION = ".wsdl";
+
+}
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/APIService.java b/modules/api-import-export/src/main/java/apim/restful/importexport/APIService.java
new file mode 100644
index 0000000000..71b94afde6
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/APIService.java
@@ -0,0 +1,214 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport;
+
+
+import com.google.gson.Gson;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.POST;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import java.io.File;
+import java.io.InputStream;
+
+import apim.restful.importexport.utils.APIExportUtil;
+import apim.restful.importexport.utils.APIImportUtil;
+import apim.restful.importexport.utils.ArchiveGeneratorUtil;
+import apim.restful.importexport.utils.AuthenticatorUtil;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+
+import org.wso2.carbon.apimgt.api.APIManagementException;
+import org.wso2.carbon.apimgt.api.model.APIIdentifier;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+
+/**
+ * This class provides JAX-RS services for exporting and importing APIs.
+ * These services provides functionality for exporting and importing single API at a time.
+ */
+@Path("/")
+public class APIService {
+
+ private static final Log log = LogFactory.getLog(APIService.class);
+
+ /**
+ * This service exports an API from API Manager for a given API ID
+ * Meta information, API icon, documentation, WSDL and sequences are exported
+ * This service generates a zipped archive which contains all the above mentioned resources
+ * for a given API
+ *
+ * @param name Name of the API that needs to be exported
+ * @param version Version of the API that needs to be exported
+ * @param providerName Provider name of the API that needs to be exported
+ * @return Zipped API as the response to the service call
+ */
+ @GET
+ @Path("/export-api")
+ @Produces("application/zip")
+ public Response exportAPI(@QueryParam("name") String name, @QueryParam("version") String version,
+ @QueryParam("provider") String providerName, @Context HttpHeaders httpHeaders) {
+
+ String userName;
+ if (name == null || version == null || providerName == null) {
+ log.error("Invalid API Information ");
+
+ return Response.status(Response.Status.BAD_REQUEST).entity("Invalid API Information")
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+ log.info("Retrieving API for API-Id : " + name + "-" + version + "-" + providerName);
+ APIIdentifier apiIdentifier;
+ try {
+
+ Response authorizationResponse = AuthenticatorUtil.authorizeUser(httpHeaders);
+ if (!(Response.Status.OK.getStatusCode() == authorizationResponse.getStatus())) {
+ return authorizationResponse;
+ }
+
+ userName = AuthenticatorUtil.getAuthenticatedUserName();
+ //provider names with @ signs are only accepted
+ String apiDomain = MultitenantUtils.getTenantDomain(providerName);
+ String apiRequesterDomain = MultitenantUtils.getTenantDomain(userName);
+ //Allows to export APIs created only in current tenant domain
+ if (!apiDomain.equals(apiRequesterDomain)) {
+ //not authorized to export requested API
+ log.error("Not authorized to " +
+ "export API :" + name + "-" + version + "-" + providerName);
+ return Response.status(Response.Status.FORBIDDEN).entity("Not authorized to export API :" +
+ name + "-" + version + "-" + providerName).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ apiIdentifier = new APIIdentifier(APIUtil.replaceEmailDomain(providerName), name, version);
+
+ //create temp location for storing API data to generate archive
+ String currentDirectory = System.getProperty(APIImportExportConstants.TEMP_DIR);
+ String createdFolders = File.separator + RandomStringUtils.
+ randomAlphanumeric(APIImportExportConstants.TEMP_FILENAME_LENGTH) + File.separator;
+ File exportFolder = new File(currentDirectory + createdFolders);
+ APIExportUtil.createDirectory(exportFolder.getPath());
+ String archiveBasePath = exportFolder.toString();
+
+ APIExportUtil.setArchiveBasePath(archiveBasePath);
+
+ Response apiResourceRetrievalResponse = APIExportUtil.retrieveApiToExport(apiIdentifier, userName);
+
+ //Retrieve resources : thumbnail, meta information, wsdl, sequences and documents
+ // available for the exporting API
+ if (!(Response.Status.OK.getStatusCode() == apiResourceRetrievalResponse.getStatus())) {
+ return apiResourceRetrievalResponse;
+ }
+
+ ArchiveGeneratorUtil.archiveDirectory(archiveBasePath);
+
+ log.info("API" + name + "-" + version + " exported successfully");
+
+ File file = new File(archiveBasePath + ".zip");
+ Response.ResponseBuilder response = Response.ok(file);
+ response.header("Content-Disposition", "attachment; filename=\"" + file.getName() +
+ "\"");
+ return response.build();
+
+ } catch (APIExportException e) {
+ log.error("APIExportException occurred while exporting ", e);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal Server Error")
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ }
+
+ /**
+ * This is the service which is used to import an API. All relevant API data will be included upon the creation of
+ * the API. Depending on the choice of the user, provider of the imported API will be preserved or modified.
+ *
+ * @param uploadedInputStream uploadedInputStream input stream from the REST request
+ * @param defaultProviderStatus user choice to keep or replace the API provider
+ * @param httpHeaders HTTP headers for the authentication mechanism
+ * @return response for the API process
+ */
+ @POST
+ @Path("/import-api")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response importAPI(@Multipart("file") InputStream uploadedInputStream, @QueryParam("preserveProvider")
+ String defaultProviderStatus, @Context HttpHeaders httpHeaders) {
+
+ boolean isProviderPreserved = true;
+
+ //Check if the URL parameter value is specified, otherwise the default value "true" is used
+ if (APIImportExportConstants.STATUS_FALSE.equalsIgnoreCase(defaultProviderStatus)) {
+ isProviderPreserved = false;
+ }
+
+ try {
+ Response authorizationResponse = AuthenticatorUtil.authorizeUser(httpHeaders);
+
+ //Process continues only if the user is authorized
+ if (Response.Status.OK.getStatusCode() == authorizationResponse.getStatus()) {
+
+ String currentUser = AuthenticatorUtil.getAuthenticatedUserName();
+ APIImportUtil.initializeProvider(currentUser);
+
+ //Temporary directory is used to create the required folders
+ String currentDirectory = System.getProperty(APIImportExportConstants.TEMP_DIR);
+ String createdFolders = File.separator +
+ RandomStringUtils.randomAlphanumeric(APIImportExportConstants.TEMP_FILENAME_LENGTH) +
+ File.separator;
+ File importFolder = new File(currentDirectory + createdFolders);
+ boolean folderCreateStatus = importFolder.mkdirs();
+
+ //API import process starts only if the required folder is created successfully
+ if (folderCreateStatus) {
+
+ String uploadFileName = APIImportExportConstants.UPLOAD_FILE_NAME;
+ String absolutePath = currentDirectory + createdFolders;
+ APIImportUtil.transferFile(uploadedInputStream, uploadFileName, absolutePath);
+
+ String extractedFolderName = APIImportUtil.extractArchive(
+ new File(absolutePath + uploadFileName), absolutePath);
+
+ APIImportUtil.importAPI(absolutePath + extractedFolderName, currentUser, isProviderPreserved);
+
+ importFolder.deleteOnExit();
+ return Response.status(Status.CREATED).entity("API imported successfully.\n").build();
+ } else {
+ return Response.status(Status.BAD_REQUEST).build();
+ }
+ } else {
+ return Response.status(Status.UNAUTHORIZED).entity("Not authorized to import API.\n").build();
+ }
+ } catch (APIExportException e) {
+ return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Error in initializing API provider.\n").build();
+ } catch (APIImportException e) {
+ String errorDetail = new Gson().toJson(e.getErrorDescription());
+ return Response.serverError().entity(errorDetail).build();
+ }
+ }
+}
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIExportUtil.java b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIExportUtil.java
new file mode 100644
index 0000000000..e26acf59f9
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIExportUtil.java
@@ -0,0 +1,630 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport.utils;
+
+import apim.restful.importexport.APIExportException;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.axiom.om.OMElement;
+import org.apache.commons.io.IOUtils;
+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.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.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.APIManagerFactory;
+import org.wso2.carbon.apimgt.impl.definitions.APIDefinitionFromSwagger20;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.context.RegistryType;
+import org.wso2.carbon.registry.api.Registry;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.api.Resource;
+import org.wso2.carbon.registry.core.RegistryConstants;
+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This is the util class which consists of all the functions for exporting API
+ */
+public class APIExportUtil {
+
+ private static final Log log = LogFactory.getLog(APIExportUtil.class);
+ private static String archiveBasePath = null;
+
+ private APIExportUtil() {
+ }
+
+ /**
+ * Set base path where exporting archive should be generated
+ *
+ * @param path Temporary directory location
+ */
+ public static void setArchiveBasePath(String path) {
+ archiveBasePath = path;
+ }
+
+ /**
+ * Retrieve API provider
+ *
+ * @param userName User name
+ * @return APIProvider Provider of the supplied user name
+ * @throws APIExportException If an error occurs while retrieving the provider
+ */
+ public static APIProvider getProvider(String userName) throws APIExportException {
+ APIProvider provider;
+ try {
+ provider = APIManagerFactory.getInstance().getAPIProvider(userName);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Current provider retrieved successfully");
+ }
+
+ return provider;
+
+ } catch (APIManagementException e) {
+ log.error("Error while retrieving provider" + e.getMessage());
+ throw new APIExportException("Error while retrieving current provider", e);
+ }
+
+ }
+
+ /**
+ * Retrieve registry for the current tenant
+ *
+ * @param userName user name of the tenant
+ * @return Registry registry of the current tenant
+ */
+ public static Registry getRegistry(String userName) {
+ boolean isTenantFlowStarted = false;
+ String tenantDomain = MultitenantUtils.getTenantDomain(userName);
+ try {
+ if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
+ isTenantFlowStarted = true;
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
+ }
+ Registry registry = CarbonContext.getThreadLocalCarbonContext().
+ getRegistry(RegistryType.SYSTEM_GOVERNANCE);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Registry of logged in user retrieved successfully");
+ }
+ return registry;
+
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+ }
+
+ /**
+ * This method retrieves all meta information and registry resources required for an API to
+ * recreate
+ *
+ * @param apiID Identifier of the exporting API
+ * @param userName User name of the requester
+ * @return HttpResponse indicating whether resource retrieval got succeed or not
+ * @throws APIExportException If an error occurs while retrieving API related resources
+ */
+ public static Response retrieveApiToExport(APIIdentifier apiID, String userName) throws APIExportException {
+
+ API apiToReturn;
+ String archivePath = archiveBasePath.concat(File.separator + apiID.getApiName() + "-" +
+ apiID.getVersion());
+ //initializing provider
+ APIProvider provider = getProvider(userName);
+ //registry for the current user
+ Registry registry = APIExportUtil.getRegistry(userName);
+
+ int tenantId = APIUtil.getTenantId(userName);
+
+ //directory creation
+ APIExportUtil.createDirectory(archivePath);
+
+ try {
+ apiToReturn = provider.getAPI(apiID);
+ } catch (APIManagementException e) {
+ log.error("Unable to retrieve API", e);
+ return Response.status(Response.Status.NOT_FOUND).entity("Unable to retrieve API")
+ .type(MediaType.APPLICATION_JSON).
+ build();
+ }
+
+ //export thumbnail
+ exportAPIThumbnail(apiID, registry);
+
+ //export documents
+ List docList;
+ try {
+ docList = provider.getAllDocumentation(apiID);
+ } catch (APIManagementException e) {
+ log.error("Unable to retrieve API Documentation", e);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal Server Error")
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ if (!docList.isEmpty()) {
+ exportAPIDocumentation(docList, apiID, registry);
+ }
+
+ //export wsdl
+ String wsdlUrl = apiToReturn.getWsdlUrl();
+ if (wsdlUrl != null) {
+ exportWSDL(apiID, registry);
+ }
+
+ //export sequences
+ exportSequences(apiToReturn, apiID, tenantId, registry);
+
+ //set API status to created
+ apiToReturn.setStatus(APIStatus.CREATED);
+
+ //export meta information
+ exportMetaInformation(apiToReturn, registry);
+
+ return Response.ok().build();
+
+ }
+
+ /**
+ * Retrieve thumbnail image for the exporting API and store it in the archive directory
+ *
+ * @param apiIdentifier ID of the requesting API
+ * @param registry Current tenant registry
+ * @throws APIExportException If an error occurs while retrieving image from the registry or
+ * storing in the archive directory
+ */
+ private static void exportAPIThumbnail(APIIdentifier apiIdentifier, Registry registry) throws APIExportException {
+ String thumbnailUrl = APIConstants.API_IMAGE_LOCATION + RegistryConstants.PATH_SEPARATOR +
+ apiIdentifier.getProviderName() + RegistryConstants.PATH_SEPARATOR +
+ apiIdentifier.getApiName() + RegistryConstants.PATH_SEPARATOR +
+ apiIdentifier.getVersion() + RegistryConstants.PATH_SEPARATOR +
+ APIConstants.API_ICON_IMAGE;
+
+ InputStream imageDataStream = null;
+ OutputStream outputStream = null;
+ String archivePath = archiveBasePath.concat(File.separator + apiIdentifier.getApiName() +
+ "-" + apiIdentifier.getVersion());
+ try {
+ if (registry.resourceExists(thumbnailUrl)) {
+ Resource icon = registry.get(thumbnailUrl);
+
+ imageDataStream = icon.getContentStream();
+
+ String mediaType = icon.getMediaType();
+ String extension = getThumbnailFileType(mediaType);
+
+ if (extension != null) {
+ createDirectory(archivePath + File.separator + "Image");
+
+ outputStream = new FileOutputStream(archivePath + File.separator + "Image" + File.separator +
+ "icon." + extension);
+
+ IOUtils.copy(imageDataStream, outputStream);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Thumbnail image retrieved successfully");
+ }
+ }
+ }
+ } catch (IOException e) {
+ //Exception is ignored by logging due to the reason that Thumbnail is not essential for
+ // an API to be recreated
+ log.error("I/O error while writing API Thumbnail to file" + e.getMessage());
+ } catch (RegistryException e) {
+ log.error("Error while retrieving API Thumbnail " + e.getMessage());
+ } finally {
+ IOUtils.closeQuietly(imageDataStream);
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+
+ /**
+ * Retrieve content type of the thumbnail image for setting the exporting file extension
+ *
+ * @param mediaType Media type of the thumbnail registry resource
+ * @return File extension for the exporting image
+ */
+ private static String getThumbnailFileType(String mediaType) {
+ if (("image/png").equals(mediaType)) {
+ return "png";
+ } else if (("image/jpg").equals(mediaType)) {
+ return "jpg";
+ } else if ("image/jpeg".equals(mediaType)) {
+ return "jpeg";
+ } else if (("image/bmp").equals(mediaType)) {
+ return "bmp";
+ } else if (("image/gif").equals(mediaType)) {
+ return "gif";
+ } else {
+ //api gets imported without thumbnail
+ log.error("Unsupported media type for icon " + mediaType);
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve documentation for the exporting API and store it in the archive directory
+ * FILE, INLINE and URL documentations are handled
+ *
+ * @param apiIdentifier ID of the requesting API
+ * @param registry Current tenant registry
+ * @param docList documentation list of the exporting API
+ * @throws APIExportException If an error occurs while retrieving documents from the
+ * registry or storing in the archive directory
+ */
+ public static void exportAPIDocumentation(List docList, APIIdentifier apiIdentifier,
+ Registry registry) throws APIExportException {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ String archivePath = archiveBasePath.concat(File.separator + apiIdentifier.getApiName() + "-" +
+ apiIdentifier.getVersion());
+ createDirectory(archivePath + File.separator + "Docs");
+ InputStream fileInputStream = null;
+ OutputStream outputStream = null;
+ try {
+ for (Documentation doc : docList) {
+ String sourceType = doc.getSourceType().name();
+ if (Documentation.DocumentSourceType.FILE.toString().equalsIgnoreCase(sourceType)) {
+ String fileName = doc.getFilePath().substring(doc.getFilePath().
+ lastIndexOf(RegistryConstants.PATH_SEPARATOR) + 1);
+ String filePath = APIUtil.getDocumentationFilePath(apiIdentifier, fileName);
+
+ //check whether resource exists in the registry
+ Resource docFile = registry.get(filePath);
+ String localFilePath = File.separator + "Docs" + File.separator + fileName;
+ outputStream = new FileOutputStream(archivePath + localFilePath);
+ fileInputStream = docFile.getContentStream();
+
+ IOUtils.copy(fileInputStream, outputStream);
+
+ doc.setFilePath(localFilePath);
+
+ if (log.isDebugEnabled()) {
+ log.debug(fileName + " retrieved successfully");
+ }
+ }
+ }
+
+ String json = gson.toJson(docList);
+ writeFile(archivePath + File.separator + "Docs" + File.separator + "docs.json", json);
+
+ if (log.isDebugEnabled()) {
+ log.debug("API Documentation retrieved successfully");
+ }
+
+ } catch (IOException e) {
+ log.error("I/O error while writing API documentation to file" + e.getMessage());
+ throw new APIExportException("I/O error while writing API documentation to file", e);
+ } catch (RegistryException e) {
+ log.error("Error while retrieving documentation " + e.getMessage());
+ throw new APIExportException("Error while retrieving documentation", e);
+ } finally {
+ IOUtils.closeQuietly(fileInputStream);
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+
+ /**
+ * Retrieve WSDL for the exporting API and store it in the archive directory
+ *
+ * @param apiIdentifier ID of the requesting API
+ * @param registry Current tenant registry
+ * @throws APIExportException If an error occurs while retrieving WSDL from the registry or
+ * storing in the archive directory
+ */
+ public static void exportWSDL(APIIdentifier apiIdentifier, Registry registry) throws APIExportException {
+
+ InputStream wsdlStream = null;
+ OutputStream outputStream = null;
+ String archivePath = archiveBasePath.concat("/" + apiIdentifier.getApiName() + "-" +
+ apiIdentifier.getVersion());
+
+ try {
+ String wsdlPath = APIConstants.API_WSDL_RESOURCE_LOCATION +
+ apiIdentifier.getProviderName() + "--" + apiIdentifier.getApiName() +
+ apiIdentifier.getVersion() + ".wsdl";
+ if (registry.resourceExists(wsdlPath)) {
+ createDirectory(archivePath + File.separator + "WSDL");
+
+ Resource wsdl = registry.get(wsdlPath);
+
+ wsdlStream = wsdl.getContentStream();
+
+ outputStream = new FileOutputStream(archivePath + File.separator + "WSDL" + File.separator +
+ apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + ".wsdl");
+
+ IOUtils.copy(wsdlStream, outputStream);
+
+ if (log.isDebugEnabled()) {
+ log.debug("WSDL file retrieved successfully");
+ }
+ }
+ } catch (IOException e) {
+ log.error("I/O error while writing WSDL to file" + e.getMessage());
+ throw new APIExportException("I/O error while writing WSDL to file", e);
+ } catch (RegistryException e) {
+ log.error("Error while retrieving WSDL " + e.getMessage());
+ throw new APIExportException("Error while retrieving WSDL", e);
+ } finally {
+ IOUtils.closeQuietly(wsdlStream);
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+
+ /**
+ * Retrieve available custom sequences for the exporting API
+ *
+ * @param api exporting API
+ * @param apiIdentifier ID of the requesting API
+ * @param registry current tenant registry
+ * @throws APIExportException If an error occurs while exporting sequences
+ */
+ public static void exportSequences(API api, APIIdentifier apiIdentifier, int tenantId, Registry registry)
+ throws APIExportException {
+
+ Map sequences = new HashMap();
+
+ if (api.getInSequence() != null) {
+ sequences.put(APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN, api.getInSequence());
+ }
+
+ if (api.getOutSequence() != null) {
+ sequences.put(APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT, api.getOutSequence());
+ }
+
+ if (api.getOutSequence() != null) {
+ sequences.put(APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT, api.getFaultSequence());
+ }
+
+ if (!sequences.isEmpty()) {
+ String archivePath = archiveBasePath.concat(File.separator + apiIdentifier.getApiName() + "-" +
+ apiIdentifier.getVersion());
+ createDirectory(archivePath + File.separator + "Sequences");
+
+ String sequenceName;
+ String direction;
+ for (Map.Entry sequence : sequences.entrySet()) {
+ sequenceName = sequence.getValue();
+ direction = sequence.getKey();
+ AbstractMap.SimpleEntry sequenceDetails;
+ if (sequenceName != null) {
+ if (APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN.equalsIgnoreCase(direction)) {
+ sequenceDetails = getCustomSequence(sequenceName, APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN,
+ registry);
+ writeSequenceToFile(sequenceDetails, APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN,
+ apiIdentifier);
+ } else if (APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT.equalsIgnoreCase(direction)) {
+ sequenceDetails = getCustomSequence(sequenceName, APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT,
+ registry);
+ writeSequenceToFile(sequenceDetails, APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT,
+ apiIdentifier);
+ } else {
+ sequenceDetails = getCustomSequence(sequenceName,
+ APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT, registry);
+ writeSequenceToFile(sequenceDetails, APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT,
+ apiIdentifier);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieve custom sequence details from the registry
+ *
+ * @param sequenceName Name of the sequence
+ * @param type Sequence type
+ * @param registry Current tenant registry
+ * @return Registry resource name of the sequence and its content
+ * @throws APIExportException If an error occurs while retrieving registry elements
+ */
+ private static AbstractMap.SimpleEntry getCustomSequence(String sequenceName,
+ String type, Registry registry) throws APIExportException {
+ AbstractMap.SimpleEntry sequenceDetails;
+
+ org.wso2.carbon.registry.api.Collection seqCollection = null;
+
+ try {
+ if (APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN.equals(type)) {
+ seqCollection =
+ (org.wso2.carbon.registry.api.Collection) registry.get(APIConstants.API_CUSTOM_INSEQUENCE_LOCATION);
+ }
+ else if (APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT.equals(type)) {
+ seqCollection =
+ (org.wso2.carbon.registry.api.Collection) registry.get(APIConstants.API_CUSTOM_OUTSEQUENCE_LOCATION);
+ }
+ else if(APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT.equals(type)) {
+ seqCollection =
+ (org.wso2.carbon.registry.api.Collection) registry.get(APIConstants.API_CUSTOM_FAULTSEQUENCE_LOCATION);
+ }
+
+ if (seqCollection != null) {
+ String[] childPaths = seqCollection.getChildren();
+
+ for (int i = 0; i < childPaths.length; i++) {
+ Resource sequence = registry.get(childPaths[i]);
+ OMElement seqElment = APIUtil.buildOMElement(sequence.getContentStream());
+ if (sequenceName.equals(seqElment.getAttributeValue(new QName("name")))) {
+ String sequenceFileName = sequence.getPath().substring(sequence.getPath().lastIndexOf('/'));
+ sequenceDetails = new AbstractMap.SimpleEntry(sequenceFileName, seqElment);
+ return sequenceDetails;
+ }
+ }
+ }
+
+ } catch (RegistryException e) {
+ log.error("Error while retrieving sequence from the registry " + e.getMessage());
+ throw new APIExportException("Error while retrieving sequence from the registry", e);
+ } catch (Exception e ) { //APIUtil.buildOMElement() throws a generic exception
+ log.error("Error while reading sequence content " + e.getMessage());
+ throw new APIExportException("Error while reading sequence content", e);
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Store custom sequences in the archive directory
+ *
+ * @param sequenceDetails Details of the sequence
+ * @param direction Direction of the sequence "in", "out" or "fault"
+ * @param apiIdentifier ID of the requesting API
+ * @throws APIExportException If an error occurs while serializing XML stream or storing in
+ * archive directory
+ */
+ private static void writeSequenceToFile(AbstractMap.SimpleEntry sequenceDetails, String direction,
+ APIIdentifier apiIdentifier) throws APIExportException {
+ OutputStream outputStream = null;
+ String archivePath = archiveBasePath.concat(File.separator + apiIdentifier.getApiName() + "-" +
+ apiIdentifier.getVersion()) + File.separator + "Sequences" + File.separator;
+
+ String pathToExportedSequence = archivePath + direction + "-sequence" + File.separator;
+ String sequenceFileName = sequenceDetails.getKey();
+ OMElement sequenceConfig = sequenceDetails.getValue();
+ String exportedSequenceFile = pathToExportedSequence + sequenceFileName;
+ try {
+ createDirectory(pathToExportedSequence);
+ outputStream = new FileOutputStream(exportedSequenceFile);
+ sequenceConfig.serialize(outputStream);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Sequence retrieved successfully");
+ }
+
+ } catch (FileNotFoundException e) {
+ log.error("Unable to find file" + e.getMessage());
+ throw new APIExportException("Unable to find file: " + exportedSequenceFile, e);
+ } catch (XMLStreamException e) {
+ log.error("Error while processing XML stream" + e.getMessage());
+ throw new APIExportException("Error while processing XML stream", e);
+ } finally {
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+
+ /**
+ * Create directory at the given path
+ *
+ * @param path Path of the directory
+ * @throws APIExportException If directory creation failed
+ */
+ public static void createDirectory(String path) throws APIExportException {
+ if (path != null) {
+ File file = new File(path);
+ if (!file.exists() && !file.mkdirs()) {
+ log.error("Error while creating directory : " + path);
+ throw new APIExportException("Directory creation failed " + path);
+ }
+ }
+ }
+
+ /**
+ * Retrieve meta information of the API to export
+ * URL template information are stored in swagger.json definition while rest of the required
+ * data are in api.json
+ *
+ * @param apiToReturn API to be exported
+ * @param registry Current tenant registry
+ * @throws APIExportException If an error occurs while exporting meta information
+ */
+ private static void exportMetaInformation(API apiToReturn, Registry registry) throws APIExportException {
+ APIDefinition definitionFromSwagger20 = new APIDefinitionFromSwagger20();
+ String archivePath = archiveBasePath.concat(File.separator + apiToReturn.getId().getApiName() + "-" +
+ apiToReturn.getId().getVersion());
+
+ createDirectory(archivePath + File.separator + "Meta-information");
+
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ String apiInJson = gson.toJson(apiToReturn);
+ writeFile(archivePath + File.separator + "Meta-information" + File.separator + "api.json", apiInJson);
+
+ try {
+ String swaggerDefinition = definitionFromSwagger20.getAPIDefinition(apiToReturn.getId(), registry);
+ JsonParser parser = new JsonParser();
+ JsonObject json = parser.parse(swaggerDefinition).getAsJsonObject();
+ String formattedSwaggerJson = gson.toJson(json);
+ writeFile(archivePath + File.separator + "Meta-information" + File.separator + "swagger.json",
+ formattedSwaggerJson);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Meta information retrieved successfully");
+ }
+
+ } catch (APIManagementException e) {
+ log.error("Error while retrieving Swagger definition" + e.getMessage());
+ throw new APIExportException("Error while retrieving Swagger definition", e);
+ }
+ }
+
+ /**
+ * Write content to file
+ *
+ * @param path Location of the file
+ * @param content Content to be written
+ * @throws APIExportException If an error occurs while writing to file
+ */
+ private static void writeFile(String path, String content) throws APIExportException {
+ FileWriter writer = null;
+
+ try {
+ writer = new FileWriter(path);
+ IOUtils.copy(new StringReader(content), writer);
+ } catch (IOException e) {
+ log.error("I/O error while writing to file" + e.getMessage());
+ throw new APIExportException("I/O error while writing to file", e);
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+
+ }
+
+}
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIImportUtil.java b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIImportUtil.java
new file mode 100644
index 0000000000..d0850792b6
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/APIImportUtil.java
@@ -0,0 +1,562 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport.utils;
+
+import apim.restful.importexport.APIExportException;
+import apim.restful.importexport.APIImportExportConstants;
+import apim.restful.importexport.APIImportException;
+import apim.restful.importexport.APIService;
+
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.axiom.om.OMElement;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+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.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+
+import org.wso2.carbon.registry.api.Registry;
+import org.wso2.carbon.registry.core.RegistryConstants;
+import org.wso2.carbon.registry.core.Resource;
+
+import javax.xml.namespace.QName;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import java.util.Enumeration;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * This class provides the functions utilized to import an API from an API archive.
+ */
+public final class APIImportUtil {
+
+ private static final Log log = LogFactory.getLog(APIService.class);
+ static APIProvider provider;
+
+ /**
+ * This method initializes the Provider when there is a direct request to import an API
+ *
+ * @param currentUserName the current logged in user
+ * @throws APIExportException if provider cannot be initialized
+ */
+ public static void initializeProvider(String currentUserName) throws APIExportException {
+ provider = APIExportUtil.getProvider(currentUserName);
+ }
+
+ /**
+ * This method uploads a given file to specified location
+ *
+ * @param uploadedInputStream input stream of the file
+ * @param newFileName name of the file to be created
+ * @param storageLocation destination of the new file
+ * @throws APIImportException if the file transfer fails
+ */
+ public static void transferFile(InputStream uploadedInputStream, String newFileName, String storageLocation)
+ throws APIImportException {
+ FileOutputStream outFileStream = null;
+
+ try {
+ outFileStream = new FileOutputStream(new File(storageLocation, newFileName));
+ int read = 0;
+ byte[] bytes = new byte[1024];
+ while ((read = uploadedInputStream.read(bytes)) != -1) {
+ outFileStream.write(bytes, 0, read);
+ }
+ } catch (IOException e) {
+ log.error("Error in transferring files.", e);
+ throw new APIImportException("Error in transferring archive files. " + e.getMessage());
+ } finally {
+ IOUtils.closeQuietly(outFileStream);
+ }
+ }
+
+ /**
+ * This method decompresses API the archive
+ *
+ * @param sourceFile The archive containing the API
+ * @param destination location of the archive to be extracted
+ * @return Name of the extracted directory
+ * @throws APIImportException If the decompressing fails
+ */
+ public static String extractArchive(File sourceFile, String destination) throws APIImportException {
+
+ BufferedInputStream inputStream = null;
+ InputStream zipInputStream = null;
+ FileOutputStream outputStream = null;
+ ZipFile zip = null;
+ String archiveName = null;
+
+ try {
+ zip = new ZipFile(sourceFile);
+ Enumeration zipFileEntries = zip.entries();
+ int index = 0;
+
+ // Process each entry
+ while (zipFileEntries.hasMoreElements()) {
+
+ // grab a zip file entry
+ ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+ String currentEntry = entry.getName();
+
+ //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));
+ --index;
+ }
+
+ File destinationFile = new File(destination, currentEntry);
+ File destinationParent = destinationFile.getParentFile();
+
+ // create the parent directory structure
+ if (destinationParent.mkdirs()) {
+ log.info("Creation of folder is successful. Directory Name : " + destinationParent.getName());
+ }
+
+ if (!entry.isDirectory()) {
+ zipInputStream = zip.getInputStream(entry);
+ inputStream = new BufferedInputStream(zipInputStream);
+
+ // write the current file to the destination
+ outputStream = new FileOutputStream(destinationFile);
+ IOUtils.copy(inputStream, outputStream);
+ }
+ }
+ return archiveName;
+ } catch (IOException e) {
+ log.error("Failed to extract archive file ", e);
+ throw new APIImportException("Failed to extract archive file. " + e.getMessage());
+ } finally {
+ IOUtils.closeQuietly(zipInputStream);
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(outputStream);
+ }
+ }
+
+ /**
+ * This method imports an API
+ *
+ * @param pathToArchive location of the extracted folder of the API
+ * @param currentUser the current logged in user
+ * @param isDefaultProviderAllowed decision to keep or replace the provider
+ * @throws APIImportException if there is an error in importing an API
+ */
+ public static void importAPI(String pathToArchive, String currentUser, boolean isDefaultProviderAllowed)
+ throws APIImportException {
+
+ API importedApi;
+
+ // If the original provider is preserved,
+ if (isDefaultProviderAllowed) {
+
+ FileInputStream inputStream = null;
+ BufferedReader bufferedReader = null;
+
+ try {
+ inputStream = new FileInputStream(pathToArchive + APIImportExportConstants.JSON_FILE_LOCATION);
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+ importedApi = new Gson().fromJson(bufferedReader, API.class);
+ } catch (FileNotFoundException e) {
+ log.error("Error in locating api.json file. ", e);
+ throw new APIImportException("Error in locating api.json file. " + e.getMessage());
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(bufferedReader);
+ }
+ } else {
+
+ String pathToJSONFile = pathToArchive + APIImportExportConstants.JSON_FILE_LOCATION;
+
+ try {
+ String jsonContent = FileUtils.readFileToString(new File(pathToJSONFile));
+ JsonElement configElement = new JsonParser().parse(jsonContent);
+ JsonObject configObject = configElement.getAsJsonObject();
+
+ //locate the "providerName" within the "id" and set it as the current user
+ JsonObject apiId = configObject.getAsJsonObject(APIImportExportConstants.ID_ELEMENT);
+ apiId.addProperty(APIImportExportConstants.PROVIDER_ELEMENT, APIUtil.replaceEmailDomain(currentUser));
+ importedApi = new Gson().fromJson(configElement, API.class);
+
+ } catch (IOException e) {
+ log.error("Error in setting API provider to logged in user. ", e);
+ throw new APIImportException("Error in setting API provider to logged in user. " + e.getMessage());
+ }
+ }
+
+ Set allowedTiers;
+ Set unsupportedTiersList;
+
+ try{
+ allowedTiers = provider.getTiers();
+ } catch (APIManagementException e) {
+ log.error("Error in retrieving tiers of the provider. ", e);
+ throw new APIImportException("Error in retrieving tiers of the provider. " + e.getMessage());
+ }
+
+ if (!(allowedTiers.isEmpty())){
+ unsupportedTiersList = Sets.difference(importedApi.getAvailableTiers(), allowedTiers);
+
+ //If at least one unsupported tier is found, it should be removed before adding API
+ if (!(unsupportedTiersList.isEmpty())) {
+ for (Tier unsupportedTier : unsupportedTiersList) {
+
+ //Process is continued with a warning and only supported tiers are added to the importer API
+ log.warn("Tier name : " + unsupportedTier.getName() + " is not supported.");
+ }
+
+ //Remove the unsupported tiers before adding the API
+ importedApi.removeAvailableTiers(unsupportedTiersList);
+ }
+ }
+
+ try{
+ provider.addAPI(importedApi);
+ addSwaggerDefinition(importedApi.getId(), pathToArchive);
+ } 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);
+ addAPISequences(pathToArchive, importedApi, currentUser);
+ addAPIWsdl(pathToArchive, importedApi, currentUser);
+
+ }
+
+ /**
+ * This method adds the icon to the API which is to be displayed at the API store.
+ *
+ * @param pathToArchive location of the extracted folder of the API
+ * @param importedApi the imported API object
+ */
+ private static void addAPIImage(String pathToArchive, API importedApi) {
+
+ //Adding image icon to the API if there is any
+ File imageFolder = new File(pathToArchive + APIImportExportConstants.IMAGE_FILE_LOCATION);
+ File[] fileArray = imageFolder.listFiles();
+ FileInputStream inputStream = null;
+
+ try {
+ if (imageFolder.isDirectory() && fileArray != null) {
+
+ //This loop locates the icon of the API
+ for (File imageFile : fileArray) {
+ if (imageFile != null && imageFile.getName().contains(APIImportExportConstants.IMAGE_FILE_NAME)) {
+
+ String mimeType = URLConnection.guessContentTypeFromName(imageFile.getName());
+ inputStream = new FileInputStream(imageFile.getAbsolutePath());
+ Icon apiImage = new Icon(inputStream, mimeType);
+ String thumbPath = APIUtil.getIconPath(importedApi.getId());
+ String thumbnailUrl = provider.addIcon(thumbPath, apiImage);
+
+ importedApi.setThumbnailUrl(APIUtil.prependTenantPrefix(thumbnailUrl,
+ importedApi.getId().getProviderName()));
+ APIUtil.setResourcePermissions(importedApi.getId().getProviderName(), null, null, thumbPath);
+ provider.updateAPI(importedApi);
+
+ //the loop is terminated after successfully locating the icon
+ break;
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ //This is logged and process is continued because icon is optional for an API
+ log.error("Icon for API is not found. ", e);
+ } catch (APIManagementException e){
+ //This is logged and process is continued because icon is optional for an API
+ log.error("Failed to add icon to the API. ", e);
+ } catch (FaultGatewaysException e) {
+ //This is logged and process is continued because icon is optional for an API
+ log.error("Failed to update API after adding icon. ", e);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
+ /**
+ * This method adds the documents to the imported API
+ *
+ * @param pathToArchive location of the extracted folder of the API
+ * @param importedApi the imported API object
+ */
+ private static void addAPIDocuments(String pathToArchive, API importedApi) {
+
+ String docFileLocation = pathToArchive + APIImportExportConstants.DOCUMENT_FILE_LOCATION;
+ FileInputStream inputStream = null;
+ BufferedReader bufferedReader = null;
+ APIIdentifier apiIdentifier = importedApi.getId();
+
+ try {
+ if (checkFileExistence(docFileLocation)) {
+
+ inputStream = new FileInputStream(docFileLocation);
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+ Documentation[] documentations = new Gson().fromJson(bufferedReader, Documentation[].class);
+
+ //For each type of document separate action is performed
+ for (Documentation doc : documentations) {
+
+ if (APIImportExportConstants.INLINE_DOC_TYPE.equalsIgnoreCase(doc.getSourceType().toString())) {
+ provider.addDocumentation(apiIdentifier, doc);
+ provider.addDocumentationContent(importedApi, doc.getName(), doc.getSummary());
+
+ } else if (APIImportExportConstants.URL_DOC_TYPE.equalsIgnoreCase(doc.getSourceType().toString())) {
+ provider.addDocumentation(apiIdentifier, doc);
+
+ } else if (APIImportExportConstants.FILE_DOC_TYPE.
+ equalsIgnoreCase(doc.getSourceType().toString())) {
+ inputStream = new FileInputStream(pathToArchive + doc.getFilePath());
+ String docExtension = FilenameUtils.getExtension(pathToArchive + doc.getFilePath());
+ Icon apiDocument = new Icon(inputStream, docExtension);
+ String visibleRolesList = importedApi.getVisibleRoles();
+ String[] visibleRoles = new String[0];
+
+ if (visibleRolesList != null) {
+ visibleRoles = visibleRolesList.split(",");
+ }
+
+ String filePathDoc = APIUtil.getDocumentationFilePath(apiIdentifier, doc.getName());
+ APIUtil.setResourcePermissions(importedApi.getId().getProviderName(),
+ importedApi.getVisibility(), visibleRoles, filePathDoc);
+ doc.setFilePath(provider.addIcon(filePathDoc, apiDocument));
+ provider.addDocumentation(apiIdentifier, doc);
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ //this error is logged and ignored because documents are optional in an API
+ log.error("Failed to locate the document files of the API.", e);
+ } catch (APIManagementException e){
+ //this error is logged and ignored because documents are optional in an API
+ log.error("Failed to add Documentations to API.", e);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ IOUtils.closeQuietly(bufferedReader);
+ }
+
+ }
+
+ /**
+ * This method adds API sequences to the imported API. If the sequence is a newly defined one, it is added.
+ *
+ * @param pathToArchive location of the extracted folder of the API
+ * @param importedApi the imported API object
+ * @param currentUser current logged in username
+ */
+ private static void addAPISequences(String pathToArchive, API importedApi, String currentUser) {
+
+ Registry registry = APIExportUtil.getRegistry(currentUser);
+ //Adding in-sequence, if any
+ String inSequenceName = importedApi.getInSequence();
+ if (inSequenceName != null && !inSequenceName.isEmpty()) {
+ importAPISequence(inSequenceName, registry, APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN,pathToArchive,
+ APIImportExportConstants.IN_SEQUENCE_LOCATION);
+ }
+
+ //Adding out-sequence, if any
+ String outSequenceName = importedApi.getOutSequence();
+ if (outSequenceName != null && !outSequenceName.isEmpty()) {
+ importAPISequence(outSequenceName, registry, APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT,pathToArchive,
+ APIImportExportConstants.OUT_SEQUENCE_LOCATION);
+ }
+
+ //Adding fault-sequence, if any
+ String faultSequenceName = importedApi.getFaultSequence();
+ if (faultSequenceName != null && !faultSequenceName.isEmpty()) {
+ importAPISequence(faultSequenceName, registry, APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT, pathToArchive,
+ APIImportExportConstants.FAULT_SEQUENCE_LOCATION);
+ }
+ }
+
+ /**
+ * Import custom sequences
+ *
+ * @param sequenceName Name of the sequence
+ * @param registry Tenant registry
+ * @param direction Direction of the sequence
+ * @param pathToArchive Location of the extracted folder of the imported APi archive
+ */
+ private static void importAPISequence(String sequenceName, Registry registry, String direction,
+ String pathToArchive, String sequenceLocation)
+ {
+ String sequenceFileLocation = pathToArchive + sequenceLocation;
+ File sequenceFileFolder = new File(sequenceFileLocation);
+ File[] fileList = sequenceFileFolder.listFiles();
+ String sequenceFileName;
+ InputStream fileInputStream = null;
+ for (final File fileEntry : fileList) {
+ if (fileEntry.isFile()) {
+ try {
+ fileInputStream = new FileInputStream(fileEntry);
+ OMElement seqElement = APIUtil.buildOMElement(fileInputStream);
+ if (sequenceName.equals(seqElement.getAttributeValue(new QName("name")))) {
+ sequenceFileName = FilenameUtils.getName(fileEntry.getName());
+ addSequenceToRegistry(registry, direction, sequenceFileName,
+ sequenceFileLocation + sequenceFileName);
+ }
+ } catch (Exception e) {
+ //this error is logged and ignored because sequences are optional in an API
+ log.error("Failed to retrieve Sequence of imported API.", e);
+ } finally {
+ IOUtils.closeQuietly(fileInputStream);
+ }
+ }
+ }
+ }
+
+ /**
+ * This method adds the sequence files to the registry.
+ *
+ * @param registry the registry instance
+ * @param customSequenceType type of the sequence
+ * @param sequenceFileName name of the sequence
+ * @param sequenceFileLocation location of the sequence file
+ */
+ private static void addSequenceToRegistry(Registry registry, String customSequenceType, String sequenceFileName,
+ String sequenceFileLocation) {
+
+ String regResourcePath = APIConstants.API_CUSTOM_SEQUENCE_LOCATION + RegistryConstants.PATH_SEPARATOR +
+ customSequenceType + RegistryConstants.PATH_SEPARATOR + sequenceFileName;
+ InputStream inSeqStream = null;
+ try {
+ if (registry.resourceExists(regResourcePath)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Defined sequences have already been added to the registry");
+ }
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Adding defined sequences to the registry.");
+ }
+ File sequenceFile = new File(sequenceFileLocation);
+ inSeqStream = new FileInputStream(sequenceFile);
+ byte[] inSeqData = IOUtils.toByteArray(inSeqStream);
+ Resource inSeqResource = (Resource) registry.newResource();
+ inSeqResource.setContent(inSeqData);
+ registry.put(regResourcePath, inSeqResource);
+ }
+ } catch (org.wso2.carbon.registry.api.RegistryException e) {
+ //this is logged and ignored because sequences are optional
+ log.error("Failed to add sequences into the registry: " + customSequenceType, e);
+ } catch (IOException e) {
+ //this is logged and ignored because sequences are optional
+ log.error("I/O error while writing sequence data to the registry, Sequence type: " + customSequenceType, e);
+ } finally {
+ IOUtils.closeQuietly(inSeqStream);
+ }
+ }
+
+ /**
+ * This method adds the WSDL to the registry, if there is a WSDL associated with the API
+ *
+ * @param pathToArchive location of the extracted folder of the API
+ * @param importedApi the imported API object
+ * @param currentUser current logged in username
+ */
+ private static void addAPIWsdl(String pathToArchive, API importedApi, String currentUser) {
+
+ String wsdlFileName = importedApi.getId().getApiName() + "-" + importedApi.getId().getVersion() +
+ APIImportExportConstants.WSDL_EXTENSION;
+ String wsdlPath = pathToArchive + APIImportExportConstants.WSDL_LOCATION + wsdlFileName;
+
+ if (checkFileExistence(wsdlPath)) {
+ try {
+ URL wsdlFileUrl = new File(wsdlPath).toURI().toURL();
+ importedApi.setWsdlUrl(wsdlFileUrl.toString());
+ Registry registry = APIExportUtil.getRegistry(currentUser);
+ APIUtil.createWSDL((org.wso2.carbon.registry.core.Registry) registry, importedApi);
+ } catch (MalformedURLException e) {
+ //this exception is logged and ignored since WSDL is optional for an API
+ log.error("Error in getting WSDL URL. ", e);
+ } catch (org.wso2.carbon.registry.core.exceptions.RegistryException e) {
+ //this exception is logged and ignored since WSDL is optional for an API
+ log.error("Error in putting the WSDL resource to registry. ", e);
+ } catch (APIManagementException e) {
+ //this exception is logged and ignored since WSDL is optional for an API
+ log.error("Error in creating the WSDL resource in the registry. ", e);
+ }
+ }
+ }
+
+ /**
+ * This method adds Swagger API definition to registry
+ *
+ * @param apiId Identifier of the imported API
+ * @param archivePath File path where API archive stored
+ * @throws APIImportException if there is an error occurs when adding Swagger definition
+ */
+ private static void addSwaggerDefinition(APIIdentifier apiId, String archivePath)
+ throws APIImportException {
+
+ try {
+ String swaggerContent = FileUtils.readFileToString(
+ new File(archivePath + APIImportExportConstants.SWAGGER_DEFINITION_LOCATION));
+ provider.saveSwagger20Definition(apiId, 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());
+ }
+ }
+
+ /**
+ * This method checks whether a given file exists in a given location
+ *
+ * @param fileLocation location of the file
+ * @return true if the file exists, false otherwise
+ */
+ private static boolean checkFileExistence(String fileLocation) {
+ File testFile = new File(fileLocation);
+ return testFile.exists();
+ }
+}
+
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/utils/ArchiveGeneratorUtil.java b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/ArchiveGeneratorUtil.java
new file mode 100644
index 0000000000..4ac18fdd57
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/ArchiveGeneratorUtil.java
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport.utils;
+
+import apim.restful.importexport.APIExportException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * This class is used to generate zipped archive files
+ */
+public class ArchiveGeneratorUtil {
+ private static final Log log = LogFactory.getLog(ArchiveGeneratorUtil.class);
+
+ private ArchiveGeneratorUtil() {
+ }
+
+ /**
+ * Archive a provided source directory to a zipped file
+ *
+ * @param sourceDirectory Source directory
+ * @throws APIExportException If an error occurs while generating archive
+ */
+ public static void archiveDirectory(String sourceDirectory) throws APIExportException {
+
+ File directoryToZip = new File(sourceDirectory);
+
+ List fileList = new ArrayList();
+ getAllFiles(directoryToZip, fileList);
+ writeArchiveFile(directoryToZip, fileList);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Archived API generated successfully");
+ }
+
+ }
+
+ /**
+ * Retrieve all the files included in the source directory to be archived
+ *
+ * @param sourceDirectory Source directory
+ * @param fileList List of files
+ */
+ private static void getAllFiles(File sourceDirectory, List fileList) {
+ File[] files = sourceDirectory.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ fileList.add(file);
+ if (file.isDirectory()) {
+ getAllFiles(file, fileList);
+ }
+ }
+ }
+ }
+
+ /**
+ * Generate archive file
+ *
+ * @param directoryToZip Location of the archive
+ * @param fileList List of files to be included in the archive
+ * @throws APIExportException If an error occurs while adding files to the archive
+ */
+ private static void writeArchiveFile(File directoryToZip, List fileList) throws APIExportException {
+
+ FileOutputStream fileOutputStream = null;
+ ZipOutputStream zipOutputStream = null;
+
+ try {
+ fileOutputStream = new FileOutputStream(directoryToZip.getPath() + ".zip");
+ zipOutputStream = new ZipOutputStream(fileOutputStream);
+ for (File file : fileList) {
+ if (!file.isDirectory()) {
+ addToArchive(directoryToZip, file, zipOutputStream);
+ }
+ }
+
+ } catch (IOException e) {
+ log.error("I/O error while adding files to archive" + e.getMessage());
+ throw new APIExportException("I/O error while adding files to archive", e);
+ } finally {
+ IOUtils.closeQuietly(zipOutputStream);
+ IOUtils.closeQuietly(fileOutputStream);
+ }
+ }
+
+ /**
+ * Add files of the directory to the archive
+ *
+ * @param directoryToZip Location of the archive
+ * @param file File to be included in the archive
+ * @param zipOutputStream Output stream
+ * @throws APIExportException If an error occurs while writing files to the archive
+ */
+ private static void addToArchive(File directoryToZip, File file, ZipOutputStream zipOutputStream)
+ throws APIExportException {
+
+ FileInputStream fileInputStream = null;
+ try {
+ fileInputStream = new FileInputStream(file);
+
+ // Get relative path from archive directory to the specific file
+ String zipFilePath = file.getCanonicalPath()
+ .substring(directoryToZip.getCanonicalPath().length() + 1, file.getCanonicalPath().length());
+ ZipEntry zipEntry = new ZipEntry(zipFilePath);
+ zipOutputStream.putNextEntry(zipEntry);
+
+ IOUtils.copy(fileInputStream, zipOutputStream);
+
+ zipOutputStream.closeEntry();
+ } catch (IOException e) {
+ log.error("I/O error while writing files to archive" + e.getMessage());
+ throw new APIExportException("I/O error while writing files to archive", e);
+ } finally {
+ IOUtils.closeQuietly(fileInputStream);
+ }
+ }
+}
+
diff --git a/modules/api-import-export/src/main/java/apim/restful/importexport/utils/AuthenticatorUtil.java b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/AuthenticatorUtil.java
new file mode 100644
index 0000000000..dbde61b102
--- /dev/null
+++ b/modules/api-import-export/src/main/java/apim/restful/importexport/utils/AuthenticatorUtil.java
@@ -0,0 +1,170 @@
+/*
+ *
+ * Copyright (c) 2015, 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 apim.restful.importexport.utils;
+
+import apim.restful.importexport.APIExportException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.api.UserStoreManager;
+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * This class provides authentication facility for importing and exporting APIs
+ * Basic authentication is used for this purpose
+ * Users with admin roles are only eligible for accessing those JAX-RS services
+ */
+public class AuthenticatorUtil {
+
+ private static final String AUTHORIZATION_PROPERTY = "Authorization";
+ private static final String AUTHENTICATION_SCHEME = "Basic";
+ private static final Log log = LogFactory.getLog(AuthenticatorUtil.class);
+ private static String username;
+ private static String password;
+
+ private AuthenticatorUtil() {
+ }
+
+ /**
+ * Checks whether received credentials for accessing API is authorized for exporting and
+ * importing APIs
+ *
+ * @param headers HTTP headers of the received request
+ * @return Response indicating whether authentication and authorization for accessing API got
+ * succeeded
+ * @throws APIExportException If an error occurs while authorizing current user
+ */
+
+ public static Response authorizeUser(HttpHeaders headers) throws APIExportException {
+ if (!isValidCredentials(headers)) {
+ log.error("No username and password is provided for authentication");
+ return Response.status(Response.Status.UNAUTHORIZED)
+ .entity("No username and password is provided for authentication").type(MediaType.APPLICATION_JSON).
+ build();
+
+ }
+
+ try {
+ String tenantDomain = MultitenantUtils.getTenantDomain(username);
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
+
+ UserStoreManager userstoremanager =
+ CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager();
+
+ String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(username);
+
+ //authenticate user provided credentials
+ if (userstoremanager.authenticate(tenantAwareUsername, password)) {
+ log.info(username + " user authenticated successfully");
+ //Get admin role name of the current domain
+ String adminRoleName =
+ CarbonContext.getCurrentContext().getUserRealm().getRealmConfiguration().getAdminRoleName();
+
+ String[] userRoles = userstoremanager.getRoleListOfUser(tenantAwareUsername);
+
+ //user is only authorized for exporting and importing if he is an admin of his
+ // domain
+ if (Arrays.asList(userRoles).contains(adminRoleName)) {
+ log.info(username + " is authorized to import and export APIs");
+ return Response.ok().build();
+ } else {
+ return Response.status(Response.Status.FORBIDDEN).entity("User Authorization " + "Failed")
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ } else {
+ return Response.status(Response.Status.UNAUTHORIZED).entity("User Authentication " + "Failed")
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ } catch (UserStoreException e) {
+ log.error("Error while accessing user configuration" + e.getMessage());
+ throw new APIExportException("Error while accessing user configuration", e);
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+
+ }
+
+ /**
+ * Checks whether user has provided non blank username and password for authentication
+ *
+ * @param headers Http Headers of the request
+ * @return boolean Whether a user name and password has been provided for authentication
+ * @throws APIExportException If an error occurs while extracting username and password from
+ * the header
+ */
+ private static boolean isValidCredentials(HttpHeaders headers) throws APIExportException {
+
+ //Fetch authorization header
+ final List authorization = headers.getRequestHeader(AUTHORIZATION_PROPERTY);
+
+ //If no authorization information present; block access
+ if (authorization == null || authorization.isEmpty()) {
+ return false;
+ }
+
+ //Get encoded username and password
+ final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
+
+ //Decode username and password
+ String usernameAndPassword;
+ usernameAndPassword = StringUtils.newStringUtf8(Base64.decodeBase64(encodedUserPassword.getBytes()));
+
+ if (usernameAndPassword != null) {
+ //Split username and password tokens
+ final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
+
+ if (tokenizer.hasMoreTokens()) {
+ username = tokenizer.nextToken();
+ }
+
+ if (tokenizer.hasMoreTokens()) {
+ password = tokenizer.nextToken();
+ }
+
+ if (username != null && password != null) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieve authenticated user name for the current session
+ *
+ * @return User name
+ */
+ public static String getAuthenticatedUserName() {
+ return username;
+ }
+}
diff --git a/modules/api-import-export/src/main/webapp/META-INF/MANIFEST.MF b/modules/api-import-export/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..274e1a9e53
--- /dev/null
+++ b/modules/api-import-export/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Class-Path: cxf-rt-frontend-jaxrs-2.6.1.jar cxf-api-2.6.1.jar woodstox
+ -core-asl-4.1.2.jar stax2-api-3.1.1.jar xmlschema-core-2.0.2.jar gero
+ nimo-javamail_1.4_spec-1.7.1.jar wsdl4j-1.6.2.jar cxf-rt-core-2.6.1.j
+ ar jaxb-impl-2.1.13.jar jsr311-api-1.1.1.jar cxf-rt-bindings-xml-2.6.
+ 1.jar cxf-rt-transports-http-2.6.1.jar jackson-core-asl-1.8.6.jar jac
+ kson-mapper-asl-1.8.6.jar jackson-jaxrs-1.8.6.jar spring-web-3.0.6.RE
+ LEASE.jar aopalliance-1.0.jar spring-beans-3.0.6.RELEASE.jar spring-c
+ ore-3.0.6.RELEASE.jar spring-asm-3.0.6.RELEASE.jar commons-logging-1.
+ 1.1.jar spring-context-3.0.6.RELEASE.jar spring-aop-3.0.6.RELEASE.jar
+ spring-expression-3.0.6.RELEASE.jar
+
diff --git a/modules/api-import-export/src/main/webapp/META-INF/webapp-classloading.xml b/modules/api-import-export/src/main/webapp/META-INF/webapp-classloading.xml
new file mode 100644
index 0000000000..f9f4993fc3
--- /dev/null
+++ b/modules/api-import-export/src/main/webapp/META-INF/webapp-classloading.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+ false
+
+
+ CXF,Carbon
+
diff --git a/modules/api-import-export/src/main/webapp/WEB-INF/cxf-servlet.xml b/modules/api-import-export/src/main/webapp/WEB-INF/cxf-servlet.xml
new file mode 100644
index 0000000000..5dc831d4da
--- /dev/null
+++ b/modules/api-import-export/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/api-import-export/src/main/webapp/WEB-INF/web.xml b/modules/api-import-export/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..d7bff92bf1
--- /dev/null
+++ b/modules/api-import-export/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+ JAX-WS/JAX-RS Webapp
+
+
+ carbon.enable.saas
+ *
+
+
+
+
+ enable.saml2.sso
+ true
+
+
+
+ JAXServlet
+ JAX-WS/JAX-RS Servlet
+ JAX-WS/JAX-RS Endpoint
+
+ org.apache.cxf.transport.servlet.CXFServlet
+
+
+ service-list-stylesheet
+ servicelist.css
+
+ 1
+
+
+
+ JAXServlet
+ /*
+
+
+
+ 60
+
+
+
+
+ Secured Resources
+ /*
+ GET
+ POST
+ PUT
+ DELETE
+
+
+
+ CONFIDENTIAL
+
+
+
+
+
diff --git a/modules/api-import-export/src/main/webapp/servicelist.css b/modules/api-import-export/src/main/webapp/servicelist.css
new file mode 100644
index 0000000000..bbc4987c0a
--- /dev/null
+++ b/modules/api-import-export/src/main/webapp/servicelist.css
@@ -0,0 +1,117 @@
+@CHARSET "ISO-8859-1";
+
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+html {
+ background: #efefef;
+}
+
+body {
+ line-height: 1;
+ width:960px;
+ margin:auto;
+ background:white;
+ padding:10px;
+ box-shadow:0px 0px 5px #CCC;
+ font-family:"Lucida Grande","Lucida Sans","Microsoft Sans Serif", "Lucida Sans Unicode","Verdana","Sans-serif","trebuchet ms" !important;
+
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+ width:960px;
+ border:solid 1px #ccc;
+}
+
+table a {
+ font-size:12px;
+ color:#1e90ff;
+ padding:7px;
+float:left;
+;
+}
+
+.heading {
+ font-size: 18px;
+ margin-top: 20px;
+ float:left;
+ color:#0067B1;
+ margin-bottom:20px;
+ padding-top:20px;
+}
+
+.field {
+ font-weight: normal;
+ width:120px;
+ font-size:12px;
+ float:left;
+ padding:7px;
+ clear:left;
+}
+.value {
+ font-weight: bold;
+ font-size:12px;
+ float:left;
+ padding:7px;
+ clear:right;
+}
+.porttypename {
+ font-weight: bold;
+ font-size:14px;
+}
+UL {
+ margin-top: 0;
+}
+LI {
+ font-weight: normal;
+ font-size:12px;
+ margin-top:10px;
+}
+
+TD {
+ border:1px solid #ccc;
+ vertical-align: text-top;
+ padding: 5px;
+}
+
+
diff --git a/modules/distribution/product/src/main/assembly/bin.xml b/modules/distribution/product/src/main/assembly/bin.xml
index 03ff046aa2..0736df433f 100644
--- a/modules/distribution/product/src/main/assembly/bin.xml
+++ b/modules/distribution/product/src/main/assembly/bin.xml
@@ -534,6 +534,13 @@
**/patch0011/*.*
+
+ ../../p2-profile/product/target/WSO2-CARBON-PATCH-4.2.0-0012
+ wso2am-${pom.version}/repository/components/patches/
+
+ **/patch0012/*.*
+
+
@@ -602,6 +609,10 @@
../../p2-profile/product/target/WSO2-CARBON-PATCH-4.2.0-0010/lib
wso2am-${pom.version}/lib/
+
+
+ ../../p2-profile/product/target/WSO2-CARBON-PATCH-4.2.0-0012/dbscripts
+ wso2am-${pom.version}/dbscripts
diff --git a/modules/distribution/product/src/main/conf/axis2.xml b/modules/distribution/product/src/main/conf/axis2.xml
index 23df14ed9b..5d26edeaa4 100644
--- a/modules/distribution/product/src/main/conf/axis2.xml
+++ b/modules/distribution/product/src/main/conf/axis2.xml
@@ -166,10 +166,10 @@
class="org.apache.axis2.format.PlainTextFormatter"/>
-
-
+
+
-
-
+
+
-
+
diff --git a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_auth_failure_handler_.xml b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_auth_failure_handler_.xml
index 5a5213d83c..a2348de693 100644
--- a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_auth_failure_handler_.xml
+++ b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_auth_failure_handler_.xml
@@ -1,4 +1,5 @@
+
diff --git a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_cors_request_handler_.xml b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_cors_request_handler_.xml
index 503bc372ba..2f4ceb0763 100644
--- a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_cors_request_handler_.xml
+++ b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_cors_request_handler_.xml
@@ -1,3 +1,20 @@
+
diff --git a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_throttle_out_handler_.xml b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_throttle_out_handler_.xml
index 40e8124047..9b86af8852 100644
--- a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_throttle_out_handler_.xml
+++ b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/_throttle_out_handler_.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/main.xml b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/main.xml
index 9063e8adbe..3d485e2126 100644
--- a/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/main.xml
+++ b/modules/distribution/product/src/main/conf/synapse-configs/default/sequences/main.xml
@@ -86,6 +86,7 @@
+
diff --git a/modules/distribution/product/src/main/statistics/API_Manager_Analytics/analytics/am_stats_analyzer b/modules/distribution/product/src/main/statistics/API_Manager_Analytics/analytics/am_stats_analyzer
index 81b8054367..b1913d5a55 100644
--- a/modules/distribution/product/src/main/statistics/API_Manager_Analytics/analytics/am_stats_analyzer
+++ b/modules/distribution/product/src/main/statistics/API_Manager_Analytics/analytics/am_stats_analyzer
@@ -94,4 +94,35 @@ CREATE EXTERNAL TABLE IF NOT EXISTS APIDestinationDataSummaryData (api STRING, v
insert overwrite table APIDestinationDataSummaryData select api,version,apiPublisher, context,destination, sum(request) as total_request_count,hostName, year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day,concat(substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,16),':00') as time from APIDestinationData where context is not NULL group by api,version,apiPublisher,context,destination,hostName,year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),hour(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),minute(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,16);
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIRequestDataMinimal (key STRING,
+ api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,requestTime BIGINT,request INT) STORED BY
+ 'org.apache.hadoop.hive.cassandra.CassandraStorageHandler' WITH SERDEPROPERTIES ('wso2.carbon.datasource.name'='WSO2BAM_CASSANDRA_DATASOURCE',
+ "cassandra.cf.name" = "org_wso2_apimgt_statistics_request",
+ "cassandra.columns.mapping" = ":key,payload_api,payload_api_version,payload_context,payload_apiPublisher,payload_applicationName,payload_tenantDomain,payload_requestTime,payload_request" );
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIRequestSummaryDataMinimal (api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,year SMALLINT,month SMALLINT,day SMALLINT, week INT, time STRING,success_request_count INT) STORED BY
+ 'org.wso2.carbon.hadoop.hive.jdbc.storage.JDBCStorageHandler' TBLPROPERTIES ( 'wso2.carbon.datasource.name'='WSO2AM_STATS_DB',
+ 'hive.jdbc.update.on.duplicate' = 'true',
+ 'hive.jdbc.primary.key.fields'='api,api_version,context,apiPublisher,applicationName,tenantDomain,time',
+ 'hive.jdbc.table.create.query' = 'CREATE TABLE API_THROTTLED_OUT_SUMMARY ( api VARCHAR(100), api_version VARCHAR(100),context VARCHAR(100),apiPublisher VARCHAR(100), applicationName VARCHAR(100), tenantDomain VARCHAR(100), year SMALLINT, month SMALLINT, day SMALLINT, week INT, time VARCHAR(30), success_request_count INT , throttleout_count INT, PRIMARY KEY(api,api_version,context,apiPublisher,applicationName,tenantDomain,time))' );
+insert overwrite table APIRequestSummaryDataMinimal select api,api_version,context,apiPublisher,applicationName,tenantDomain, year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day,cast(requestTime/(1000 * 60 * 60 *24 * 7) as INT) as week,concat(substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13),':00:00') as time,sum(request) as success_request_count from APIRequestDataMinimal where context is not NULL group by api,api_version,context,apiPublisher,applicationName,tenantDomain,year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),cast(requestTime/(1000 * 60 * 60 *24 * 7) as INT),substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13);
+
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIThrottleData (key STRING,
+ api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,throttledTime BIGINT) STORED BY
+ 'org.apache.hadoop.hive.cassandra.CassandraStorageHandler' WITH SERDEPROPERTIES ('wso2.carbon.datasource.name'='WSO2BAM_CASSANDRA_DATASOURCE',
+ "cassandra.cf.name" = "org_wso2_apimgt_statistics_throttle",
+ "cassandra.columns.mapping" = ":key,payload_api,payload_api_version,payload_context,payload_apiPublisher,payload_applicationName,payload_tenantDomain,payload_throttledTime" );
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIThrottleSummaryData (api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,year SMALLINT,month SMALLINT,day SMALLINT,week INT, time STRING,throttleout_count INT) STORED BY
+ 'org.wso2.carbon.hadoop.hive.jdbc.storage.JDBCStorageHandler' TBLPROPERTIES ( 'wso2.carbon.datasource.name'='WSO2AM_STATS_DB',
+ 'hive.jdbc.update.on.duplicate' = 'true',
+ 'hive.jdbc.primary.key.fields'='api,api_version,context,apiPublisher,applicationName,tenantDomain,time',
+ 'hive.jdbc.table.create.query' = 'CREATE TABLE API_THROTTLED_OUT_SUMMARY ( api VARCHAR(100), api_version VARCHAR(100),context VARCHAR(100),apiPublisher VARCHAR(100), applicationName VARCHAR(100), tenantDomain VARCHAR(100), year SMALLINT, month SMALLINT, day SMALLINT,week INT, time VARCHAR(30), success_request_count INT , throttleout_count INT, PRIMARY KEY(api,api_version,context,apiPublisher,applicationName,tenantDomain,time))' );
+
+insert overwrite table APIThrottleSummaryData select api,api_version,context,apiPublisher,applicationName,tenantDomain, year(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day, cast(throttledTime/(1000 * 60 * 60 *24 * 7) as INT) as week, concat(substring(from_unixtime(cast(throttledTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13),':00:00') as time,count(apiPublisher) as throttleout_count from APIThrottleData where context is not NULL group by api,api_version,context,apiPublisher,applicationName,tenantDomain,year(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),cast(throttledTime/(1000 * 60 * 60 *24 * 7) as INT),substring(from_unixtime(cast(throttledTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13);
diff --git a/modules/distribution/product/src/main/statistics/API_Manager_Analytics_Oracle/analytics/am_stats_analyzer b/modules/distribution/product/src/main/statistics/API_Manager_Analytics_Oracle/analytics/am_stats_analyzer
index 9c176b27b6..5984108237 100644
--- a/modules/distribution/product/src/main/statistics/API_Manager_Analytics_Oracle/analytics/am_stats_analyzer
+++ b/modules/distribution/product/src/main/statistics/API_Manager_Analytics_Oracle/analytics/am_stats_analyzer
@@ -94,4 +94,34 @@ CREATE EXTERNAL TABLE IF NOT EXISTS APIDestinationDataSummaryData (api STRING, v
insert overwrite table APIDestinationDataSummaryData select api,version,apiPublisher, context,destination, sum(request) as total_request_count,hostName, year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day,concat(substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,16),':00') as time from APIDestinationData where context is not NULL group by api,version,apiPublisher,context,destination,hostName,year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),hour(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),minute(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,16);
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIRequestDataMinimal (key STRING,
+ api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,requestTime BIGINT,request INT) STORED BY
+ 'org.apache.hadoop.hive.cassandra.CassandraStorageHandler' WITH SERDEPROPERTIES ('wso2.carbon.datasource.name'='WSO2BAM_CASSANDRA_DATASOURCE',
+ "cassandra.cf.name" = "org_wso2_apimgt_statistics_request",
+ "cassandra.columns.mapping" = ":key,payload_api,payload_api_version,payload_context,payload_apiPublisher,payload_applicationName,payload_tenantDomain,payload_requestTime,payload_request" );
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIRequestSummaryDataMinimal (api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,year SMALLINT,month SMALLINT,day SMALLINT, week INT, time STRING,success_request_count INT) STORED BY
+ 'org.wso2.carbon.hadoop.hive.jdbc.storage.JDBCStorageHandler' TBLPROPERTIES ( 'wso2.carbon.datasource.name'='WSO2AM_STATS_DB',
+ 'hive.jdbc.update.on.duplicate' = 'true',
+ 'hive.jdbc.primary.key.fields'='api,api_version,context,apiPublisher,applicationName,tenantDomain,time',
+ 'hive.jdbc.table.create.query' = 'CREATE TABLE API_THROTTLED_OUT_SUMMARY ( api VARCHAR2(100), api_version VARCHAR2(100),context VARCHAR2(100),apiPublisher VARCHAR2(100), applicationName VARCHAR2(100), tenantDomain VARCHAR2(100), year SMALLINT, month SMALLINT, day SMALLINT, week INT, time VARCHAR2(30), success_request_count INT , throttleout_count INT, PRIMARY KEY(api,api_version,context,apiPublisher,applicationName,tenantDomain,time))' );
+insert overwrite table APIRequestSummaryDataMinimal select api,api_version,context,apiPublisher,applicationName,tenantDomain, year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day,cast(requestTime/(1000 * 60 * 60 *24 * 7) as INT) as week,concat(substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13),':00:00') as time,sum(request) as success_request_count from APIRequestDataMinimal where context is not NULL group by api,api_version,context,apiPublisher,applicationName,tenantDomain,year(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(requestTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),cast(requestTime/(1000 * 60 * 60 *24 * 7) as INT),substring(from_unixtime(cast(requestTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13);
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIThrottleData (key STRING,
+ api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,throttledTime BIGINT) STORED BY
+ 'org.apache.hadoop.hive.cassandra.CassandraStorageHandler' WITH SERDEPROPERTIES ('wso2.carbon.datasource.name'='WSO2BAM_CASSANDRA_DATASOURCE',
+ "cassandra.cf.name" = "org_wso2_apimgt_statistics_throttle",
+ "cassandra.columns.mapping" = ":key,payload_api,payload_api_version,payload_context,payload_apiPublisher,payload_applicationName,payload_tenantDomain,payload_throttledTime" );
+
+
+CREATE EXTERNAL TABLE IF NOT EXISTS APIThrottleSummaryData (api STRING,api_version STRING, context STRING, apiPublisher STRING,applicationName STRING,tenantDomain STRING,year SMALLINT,month SMALLINT,day SMALLINT,week INT, time STRING,throttleout_count INT) STORED BY
+ 'org.wso2.carbon.hadoop.hive.jdbc.storage.JDBCStorageHandler' TBLPROPERTIES ( 'wso2.carbon.datasource.name'='WSO2AM_STATS_DB',
+ 'hive.jdbc.update.on.duplicate' = 'true',
+ 'hive.jdbc.primary.key.fields'='api,api_version,context,apiPublisher,applicationName,tenantDomain,time',
+ 'hive.jdbc.table.create.query' = 'CREATE TABLE API_THROTTLED_OUT_SUMMARY ( api VARCHAR2(100), api_version VARCHAR2(100),context VARCHAR2(100),apiPublisher VARCHAR2(100), applicationName VARCHAR2(100), tenantDomain VARCHAR2(100), year SMALLINT, month SMALLINT, day SMALLINT,week INT, time VARCHAR2(30), success_request_count INT , throttleout_count INT, PRIMARY KEY(api,api_version,context,apiPublisher,applicationName,tenantDomain,time))' );
+
+insert overwrite table APIThrottleSummaryData select api,api_version,context,apiPublisher,applicationName,tenantDomain, year(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as year, month(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as month,day(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )) as day, cast(throttledTime/(1000 * 60 * 60 *24 * 7) as INT) as week, concat(substring(from_unixtime(cast(throttledTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13),':00:00') as time,count(apiPublisher) as throttleout_count from APIThrottleData where context is not NULL group by api,api_version,context,apiPublisher,applicationName,tenantDomain,year(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )), month(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),day(from_unixtime(cast(throttledTime/1000 as BIGINT),'yyyy-MM-dd HH:mm:ss.SSS' )),cast(throttledTime/(1000 * 60 * 60 *24 * 7) as INT),substring(from_unixtime(cast(throttledTime/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss'),0,13);
diff --git a/modules/distribution/product/src/main/statistics/README.txt b/modules/distribution/product/src/main/statistics/README.txt
index 0522418e86..61b74a6ab7 100644
--- a/modules/distribution/product/src/main/statistics/README.txt
+++ b/modules/distribution/product/src/main/statistics/README.txt
@@ -137,3 +137,7 @@ drop table APIRequestSummaryData;
drop table APIVersionUsageSummaryData;
drop table APIResponseData;
drop table APIResponseSummaryData;
+drop table APIRequestDataMinimal;
+drop table APIRequestSummaryDataMinimal;
+drop table APIThrottleData;
+drop table APIThrottleSummaryData;
diff --git a/modules/distribution/resources/api_templates/velocity_template.xml b/modules/distribution/resources/api_templates/velocity_template.xml
index 13998d2297..4302e0730a 100644
--- a/modules/distribution/resources/api_templates/velocity_template.xml
+++ b/modules/distribution/resources/api_templates/velocity_template.xml
@@ -183,6 +183,14 @@
#end
#end
+
+#macro ( handle_query_params $type $endpoint_config )
+#set($endpoints = $endpoint_config.get("${type}_endpoints"))
+#if ( $endpoints.get("url").contains("?") )
+
+#end
+#end
+
######################## End of Macros ######################################
@@ -245,8 +253,10 @@
#end
#if(($environmentType == 'sandbox') || ($environmentType =='hybrid' && ! $endpoint_config.get("production_endpoints") ))
+ #handle_query_params( "sandbox" $endpoint_config )
#draw_endpoint( "sandbox" $endpoint_config )
#else
+ #handle_query_params( "production" $endpoint_config )
#draw_endpoint( "production" $endpoint_config )
#end
#if($apiStatus != 'PROTOTYPED')
@@ -272,6 +282,8 @@
#else
#if($endpoint_config.get("production_endpoints") && $endpoint_config.get("sandbox_endpoints"))
+
+ #handle_query_params( "sandbox" $endpoint_config )
#draw_endpoint( "sandbox" $endpoint_config )
#elseif($endpoint_config.get("production_endpoints"))
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/pom.xml b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/pom.xml
new file mode 100644
index 0000000000..df261f8a32
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/pom.xml
@@ -0,0 +1,160 @@
+
+
+ 4.0.0
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.migrate.client
+ 1.7.0
+ bundle
+
+
+
+ wso2-nexus
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/groups/wso2-public/
+
+ true
+ daily
+ ignore
+
+
+
+ wso2.releases
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/repositories/releases/
+
+ true
+ daily
+ ignore
+
+
+
+ wso2.snapshots
+ WSO2 Snapshot Repository
+ http://maven.wso2.org/nexus/content/repositories/snapshots/
+
+ true
+ daily
+
+
+ false
+
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+ ${org.apache.felix.src.plugin.version}
+
+
+ generate-scr-scrdescriptor
+
+ scr
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+
+ 1.6
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+ ${org.apache.felix.budnle.plugin.version}
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.apimgt.migration.client.internal
+
+
+ org.apache.commons.logging.*; version=${org.wso2.carbon.logging.import.version},
+ org.wso2.carbon.registry.core.* version=${org.wso2.carbon.registry.core.import.version},
+ org.wso2.carbon.apimgt.impl,
+ *;resolution:=optional
+
+ *
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.5.3
+
+
+ dist
+ package
+
+ attached
+
+
+ false
+ src/assembly/dist.xml
+ wso2-api-migration-client-${project.version}
+
+
+
+
+
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core.services
+ ${org.wso2.carbon.core.services.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+ ${org.wso2.carbon.logging.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+ ${org.wso2.carbon.registry.core.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+ ${org.wso2.carbon.utils.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.impl
+ 1.2.2
+
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.api
+ 1.2.2
+
+
+
+
+ UTF-8
+ 1.7.2
+ 2.5.3
+ 4.2.0
+ 4.2.0
+ 1.0.4
+ 4.2.0
+ 4.2.0
+ 1.0.1
+
+
+
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/assembly/dist.xml b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/assembly/dist.xml
new file mode 100644
index 0000000000..e6caed26d2
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/assembly/dist.xml
@@ -0,0 +1,27 @@
+
+ dist
+
+ zip
+
+ false
+
+
+ ${project.basedir}
+
+
+ README*
+
+
+
+ ${project.basedir}/src/main/resources
+
+
+
+ ${project.build.directory}
+
+
+ *.jar
+
+
+
+
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java
new file mode 100644
index 0000000000..6250855b6e
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2015, 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.migration;
+
+/**
+ * A custom exception handler class to handle all the migration exceptions
+ */
+public class APIMigrationException extends Exception {
+
+ public APIMigrationException(String msg) {
+ super(msg);
+ }
+
+ public APIMigrationException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+ public APIMigrationException(Throwable throwable) {
+ super(throwable);
+ }
+}
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom16to17.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom16to17.java
new file mode 100644
index 0000000000..9308b838c7
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom16to17.java
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.wso2.carbon.apimgt.api.APIManagementException;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.internal.ServiceHolder;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
+import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
+import org.wso2.carbon.governance.api.util.GovernanceUtils;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.core.Registry;
+import org.wso2.carbon.registry.core.session.UserRegistry;
+import org.wso2.carbon.user.api.Tenant;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.tenant.TenantManager;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathExpressionException;
+import java.io.*;
+import java.sql.*;
+import java.util.*;
+
+
+/**
+ * This class contains all the methods which is used to migrate APIs from APIManager 1.6.0 to APIManager 1.7.0.
+ * The migration performs in database, registry and file system
+ */
+
+@SuppressWarnings("unchecked")
+public class MigrateFrom16to17 {
+
+ private static final Log log = LogFactory.getLog(MigrateFrom16to17.class);
+ private List tenantsArray;
+
+ public MigrateFrom16to17(String tenantArguments) throws UserStoreException {
+ TenantManager tenantManager = ServiceHolder.getRealmService().getTenantManager();
+
+ if (tenantArguments != null) { // Tenant arguments have been provided so need to load specific ones
+ tenantArguments = tenantArguments.replaceAll("\\s",""); // Remove spaces and tabs
+
+ tenantsArray = new ArrayList();
+
+ if (tenantArguments.contains(",")) { // Multiple arguments specified
+ String[] parts = tenantArguments.split(",");
+
+ for (int i = 0; i < parts.length; ++i) {
+ if (parts[i].length() > 0) {
+ populateTenants(tenantManager, tenantsArray, parts[i]);
+ }
+ }
+ }
+ else { // Only single argument provided
+ populateTenants(tenantManager, tenantsArray, tenantArguments);
+ }
+ } else { // Load all tenants
+ tenantsArray = new ArrayList(Arrays.asList(tenantManager.getAllTenants()));
+ Tenant superTenant = new Tenant();
+ superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
+ tenantsArray.add(superTenant);
+ }
+ }
+
+ private void populateTenants(TenantManager tenantManager, List tenantList, String argument) throws UserStoreException {
+ log.debug("Argument provided : " + argument);
+
+ if (argument.contains("@")) { // Username provided as argument
+ int tenantID = tenantManager.getTenantId(argument);
+
+ if (tenantID != -1) {
+ tenantList.add(tenantManager.getTenant(tenantID));
+ }
+ else {
+ log.error("Tenant does not exist for username " + argument);
+ }
+ }
+ else { // Domain name provided as argument
+ Tenant[] tenants = tenantManager.getAllTenantsForTenantDomainStr(argument);
+
+ if (tenants.length > 0) {
+ tenantList.addAll(Arrays.asList(tenants));
+ }
+ else {
+ log.error("Tenant does not exist for domain " + argument);
+ }
+ }
+ }
+
+
+ /**
+ * This method is used to migrate all registry resources
+ * This migrates swagger resources and rxts
+ *
+ * @throws APIMigrationException
+ */
+ public void registryResourceMigration() throws APIMigrationException {
+ swaggerMigration();
+ docResourceMigration();
+ rxtMigration();
+ }
+
+
+ /**
+ * This method is used to migrate rxt
+ * This adds three new attributes to the api rxt
+ *
+ * @throws APIMigrationException
+ */
+ void rxtMigration() throws APIMigrationException {
+ log.info("Rxt migration for API Manager 1.9.0 started.");
+ boolean isTenantFlowStarted = false;
+ for (Tenant tenant : tenantsArray) {
+ log.debug("Start rxtMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ isTenantFlowStarted = true;
+
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain(), true);
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId(), true);
+
+ Registry registry = getRegistry(tenant);
+ if (registry != null) {
+ GenericArtifactManager artifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY);
+ GenericArtifact[] artifacts = getGenericArtifacts(registry, artifactManager);
+
+ if (artifacts != null && artifactManager != null) {
+ for (GenericArtifact artifact : artifacts) {
+ RegistryMigration.rxtMigration(artifactManager, artifacts);
+ }
+ }
+ }
+ else {
+ log.debug("No api artifacts found in registry for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+ }
+
+ catch (APIManagementException e) {
+ ResourceUtil.handleException("Error occurred while reading API from the artifact ", e);
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+ log.debug("End rxtMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ log.info("Rxt resource migration done for all the tenants");
+ }
+
+
+ /**
+ * Doc resource migration
+ *
+ *
+ */
+ void docResourceMigration() {
+ log.info("Doc migration for API Manager 1.9.0 started.");
+ boolean isTenantFlowStarted = false;
+
+ for (Tenant tenant : tenantsArray) {
+ if (log.isDebugEnabled()) {
+ log.debug("Start docResourceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ isTenantFlowStarted = true;
+
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain());
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId());
+
+ Registry registry = getRegistry(tenant);
+
+ if (registry != null) {
+ GenericArtifactManager artifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY);
+ GenericArtifact[] artifacts = getGenericArtifacts(registry, artifactManager);
+
+ if (artifacts != null) {
+ RegistryMigration.updateDocResourceAssociation(artifacts, registry, tenant);
+ }
+ }
+ } catch (APIManagementException e) {
+ log.error("Error when getting GenericArtifactManager for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+
+ log.debug("End docResourceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ log.info("Doc resource migration done for all the tenants.");
+ }
+
+
+ /**
+ * This method is used to migrate swagger v1.2 resources to swagger v2.0 resource
+ * This reads the swagger v1.2 doc from the registry and creates swagger v2.0 doc
+ *
+ * @throws APIMigrationException
+ */
+ void swaggerMigration() {
+ log.info("Swagger migration for API Manager 1.9.0 started.");
+ boolean isTenantFlowStarted = false;
+
+ for (Tenant tenant : tenantsArray) {
+ if (log.isDebugEnabled()) {
+ log.debug("Start swaggerMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ isTenantFlowStarted = true;
+
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain());
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId());
+
+ Registry registry = getRegistry(tenant);
+
+ if (registry != null) {
+ GenericArtifactManager artifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY);
+ GenericArtifact[] artifacts = getGenericArtifacts(registry, artifactManager);
+
+ if (artifacts != null) {
+ RegistryMigration.swagger12Migration(artifacts, registry, tenant);
+ }
+ }
+ } catch (APIManagementException e) {
+ log.error("Error when getting GenericArtifactManager for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+
+ log.debug("End swaggerMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ log.info("Swagger resource migration done for all the tenants.");
+ }
+
+ private Registry getRegistry(Tenant tenant) {
+ log.debug("Calling getRegistry");
+ Registry registry = null;
+
+ try {
+ String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getRealmConfiguration().getAdminUserName();
+ log.debug("Tenant admin username : " + adminName);
+ registry = ServiceHolder.getRegistryService().getGovernanceUserRegistry(adminName, tenant.getId());
+ ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenant.getId());
+ } catch (UserStoreException e) {
+ log.error("Error occurred while reading tenant information of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (RegistryException e) {
+ log.error("Error occurred while accessing the registry of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+
+ return registry;
+ }
+
+
+ private GenericArtifact[] getGenericArtifacts(Registry registry, GenericArtifactManager manager) {
+ log.debug("Calling getGenericArtifacts");
+ GenericArtifact[] artifacts = null;
+
+ try {
+ if (GovernanceUtils.findGovernanceArtifactConfiguration(Constants.API, registry) != null) {
+ GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
+ artifacts = manager.getAllGenericArtifacts();
+
+ log.debug("Total number of api artifacts : " + artifacts.length);
+ }
+ else {
+ log.debug("API artifacts do not exist in registry");
+ }
+
+ } catch (RegistryException e) {
+ log.error("Error occurred when getting GenericArtifacts from registry", e);
+ }
+
+ return artifacts;
+ }
+
+
+ /**
+ * This method is used to migrate all the file system components
+ * such as sequences and synapse files
+ *
+ * @throws APIMigrationException
+ */
+ public void fileSystemMigration() throws APIMigrationException {
+ synapseAPIMigration();
+ }
+
+
+ /**
+ * This method is used to migrate synapse files
+ * This changes the synapse api and add the new handlers
+ *
+ * @throws APIMigrationException
+ */
+
+ void synapseAPIMigration() {
+ String repository = CarbonUtils.getCarbonRepository();
+ String tenantRepository = CarbonUtils.getCarbonTenantsDirPath();
+ for (Tenant tenant : tenantsArray) {
+ log.debug("Start synapseAPIMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ String apiFilePath;
+ if (tenant.getId() != MultitenantConstants.SUPER_TENANT_ID) {
+ apiFilePath = tenantRepository + "/" + tenant.getId() +
+ "/synapse-configs/default/api";
+ } else {
+ apiFilePath = repository + "synapse-configs/default/api";
+ }
+ File APIFiles = new File(apiFilePath);
+ File[] synapseFiles = APIFiles.listFiles();
+
+ if (synapseFiles == null) {
+ log.debug("No api folder " + apiFilePath + " exists for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ continue;
+ }
+
+ for (File synapseFile : synapseFiles) {
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ docFactory.setNamespaceAware(true);
+
+ try {
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(synapseFile);
+
+ doc.getDocumentElement().normalize();
+
+ Element rootElement = doc.getDocumentElement();
+
+ if (Constants.SYNAPSE_API_ROOT_ELEMENT.equals(rootElement.getNodeName()) &&
+ rootElement.hasAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VERSION)) {
+ SynapseMigration.modifyGoogleAnalyticsTrackingHandler(synapseFile, doc);
+ }
+
+
+ } catch (ParserConfigurationException e) {
+ log.error("Parsing exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (SAXException e) {
+ log.error("SAX exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (IOException e) {
+ log.error("IO exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (XPathExpressionException e) {
+ log.error("XPathExpression exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (TransformerException e) {
+ log.error("Transformer exception encountered for " + synapseFile.getAbsolutePath(), e);
+ }
+ }
+
+ log.debug("End synapseAPIMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+ }
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
new file mode 100644
index 0000000000..a8949f1140
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.wso2.carbon.utils.dbcreator.DatabaseCreator;
+
+import javax.sql.DataSource;
+import java.io.*;
+import java.sql.*;
+import java.util.StringTokenizer;
+
+public class MigrationDBCreator extends DatabaseCreator {
+
+ private static final Log log = LogFactory.getLog(MigrationDBCreator.class);
+ private DataSource dataSource;
+ private String delimiter = ";";
+ private Connection connection = null;
+ Statement statement;
+
+ public MigrationDBCreator(DataSource dataSource) {
+ super(dataSource);
+ this.dataSource = dataSource;
+ }
+
+ @Override
+ protected String getDbScriptLocation(String databaseType) {
+ String scriptName = databaseType + ".sql";
+ String resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.8.0_to_1.9.0/";
+ if (log.isDebugEnabled()) {
+ log.debug("Loading database script :" + scriptName);
+ }
+ return resourcePath + scriptName;
+ }
+
+ @Override
+ public void createRegistryDatabase() throws SQLException, APIMigrationException {
+ try {
+ connection = dataSource.getConnection();
+ connection.setAutoCommit(false);
+ statement = connection.createStatement();
+ executeSQLScript();
+ connection.commit();
+ if (log.isTraceEnabled()) {
+ log.trace("Registry tables are created successfully.");
+ }
+ } catch (SQLException e) {
+ ResourceUtil.handleException("Error occurred while migrating the database", e);
+ } catch (Exception e) {
+ /* executeSQLScript throws generic Exception because DatabaseCreator.getDatabaseType superclass throws */
+ ResourceUtil.handleException("Error occurred while executing sql script", e);
+ } finally {
+ if (connection != null) {
+ connection.close();
+ }
+
+ }
+ }
+
+
+ //org.wso2.carbon.utils.dbcreator.DatabaseCreator.getDatabaseType throws generic Exception
+ private void executeSQLScript() throws Exception {
+ String databaseType = DatabaseCreator.getDatabaseType(this.connection);
+ boolean keepFormat = false;
+ if (Constants.DB_TYPE_ORACLE.equals(databaseType)) {
+ delimiter = "/";
+ } else if (Constants.DB_TYPE_DB2.equals(databaseType)) {
+ delimiter = "/";
+ } else if (Constants.DB_TYPE_OPENEDGE.equals(databaseType)) {
+ delimiter = "/";
+ keepFormat = true;
+ }
+
+ String dbscriptName = getDbScriptLocation(databaseType);
+
+ StringBuffer sql = new StringBuffer();
+ BufferedReader reader = null;
+
+ try {
+ InputStream is = new FileInputStream(dbscriptName);
+ reader = new BufferedReader(new InputStreamReader(is, "UTF8"));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (!keepFormat) {
+ if (line.startsWith("//")) {
+ continue;
+ }
+ if (line.startsWith("--")) {
+ continue;
+ }
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if ("REM".equalsIgnoreCase(token)) {
+ continue;
+ }
+ }
+ }
+ sql.append(keepFormat ? "\n" : " ").append(line);
+
+ // SQL defines "--" as a comment to EOL
+ // and in Oracle it may contain a hint
+ // so we cannot just remove it, instead we must end it
+ if (!keepFormat && line.indexOf("--") >= 0) {
+ sql.append("\n");
+ }
+ if ((checkStringBufferEndsWith(sql, delimiter))) {
+ executeSQL(sql.substring(0, sql.length() - delimiter.length()));
+ sql.replace(0, sql.length(), "");
+ }
+ }
+ // Catch any statements not followed by ;
+ if (sql.length() > 0) {
+ executeSQL(sql.toString());
+ }
+ } catch (IOException e) {
+ log.error("Error occurred while executing SQL script for creating registry database", e);
+ throw new APIMigrationException("Error occurred while executing SQL script for creating registry database", e);
+
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+
+ private void executeSQL(String sql) throws APIMigrationException {
+ // Check and ignore empty statements
+ if ("".equals(sql.trim())) {
+ return;
+ }
+
+ ResultSet resultSet = null;
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("SQL : " + sql);
+ }
+
+ boolean returnedValue;
+ int updateCount;
+ int updateCountTotal = 0;
+ returnedValue = statement.execute(sql);
+ updateCount = statement.getUpdateCount();
+ resultSet = statement.getResultSet();
+ do {
+ if (!returnedValue && updateCount != -1) {
+ updateCountTotal += updateCount;
+ }
+ returnedValue = statement.getMoreResults();
+ if (returnedValue) {
+ updateCount = statement.getUpdateCount();
+ resultSet = statement.getResultSet();
+ }
+ } while (returnedValue);
+
+ if (log.isDebugEnabled()) {
+ log.debug(sql + " : " + updateCountTotal + " rows affected");
+ }
+ SQLWarning warning = connection.getWarnings();
+ while (warning != null) {
+ log.debug(warning + " sql warning");
+ warning = warning.getNextWarning();
+ }
+ connection.clearWarnings();
+ } catch (SQLException e) {
+ if (e.getSQLState().equals("X0Y32") || e.getSQLState().equals("42710")) {
+ // eliminating the table already exception for the derby and DB2 database types
+ if (log.isDebugEnabled()) {
+ log.info("Table Already Exists. Hence, skipping table creation");
+ }
+ } else {
+ throw new APIMigrationException("Error occurred while executing : " + sql, e);
+ }
+ } finally {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ log.error("Error occurred while closing result set.", e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java
new file mode 100644
index 0000000000..ac787a46c3
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java
@@ -0,0 +1,554 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.wso2.carbon.apimgt.api.APIManagementException;
+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.URITemplate;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.internal.ServiceHolder;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.governance.api.exception.GovernanceException;
+import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
+import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.core.*;
+import org.wso2.carbon.user.api.Tenant;
+import org.wso2.carbon.user.api.UserStoreException;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/**
+ * Created by uvindra on 8/8/15.
+ */
+public class RegistryMigration {
+ private static final Log log = LogFactory.getLog(RegistryMigration.class);
+
+ public static void updateDocResourceAssociation(GenericArtifact[] artifacts, Registry registry, Tenant tenant) {
+ log.debug("Calling updateDocResourceAssociation");
+ for (GenericArtifact artifact : artifacts) {
+ API api = getAPI(artifact);
+
+ if (api != null) {
+ APIIdentifier apiIdentifier = api.getId();
+ String apiName = apiIdentifier.getApiName();
+ String apiVersion = apiIdentifier.getVersion();
+ String apiProviderName = apiIdentifier.getProviderName();
+ APIIdentifier apiIdentfier = api.getId();
+
+ String apiResourcePath = APIUtil.getAPIPath(apiIdentfier);
+ try{
+ Association[] docAssociations = registry.getAssociations(apiResourcePath, "document");
+ for (Association association : docAssociations) {
+ String docPath = association.getDestinationPath();
+
+ Resource docResource = registry.get(docPath);
+ GenericArtifactManager docArtifactManager = new GenericArtifactManager(registry,
+ APIConstants.DOCUMENTATION_KEY);
+ GenericArtifact docArtifact = docArtifactManager.getGenericArtifact(
+ docResource.getUUID());
+ String docFilePath = docArtifact.getAttribute(APIConstants.DOC_FILE_PATH);
+ Documentation doc = APIUtil.getDocumentation(docArtifact);
+ if (Documentation.DocumentSourceType.FILE.equals(doc.getSourceType())) {
+ if(docFilePath != null && !docFilePath.equals("")){
+ //The docFilePatch comes as /t/tenanatdoman/registry/resource/_system/governance/apimgt/applicationdata..
+ //We need to remove the /t/tenanatdoman/registry/resource/_system/governance section to set permissions.
+ int startIndex = docFilePath.indexOf("governance") + "governance".length();
+ String filePath = docFilePath.substring(startIndex, docFilePath.length());
+ if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".") == -1) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("text/plain");
+ registry.put(filePath, resource);
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".wsdl") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/api-wsdl");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".pdf") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/pdf");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".xl") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/vnd.ms-excel");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".ppt") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/vnd.ms-powerpoint");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".xml") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/xml");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".js") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/javascript");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".css") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("text/css");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".csv") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("text/csv");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".html") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("text/html");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".json") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/json");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".png") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("image/png");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".ttf") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/x-font-ttf");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".eot") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/vnd.ms-fontobject");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".woff") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/font-woff");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".otf") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/x-font-otf");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".zip") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/zip");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".xhtml") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("application/xhtml+xml");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".txt") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("text/plain");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".png") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("image/png");
+ registry.put(filePath, resource);
+ }
+ } else if (filePath.split(RegistryConstants.PATH_SEPARATOR + "files" + RegistryConstants.PATH_SEPARATOR)[1].indexOf(".jpeg") > -1) {
+ String resourcePath = "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + filePath;
+ if (registry.resourceExists(resourcePath)) {
+ Resource resource = registry.get(filePath);
+ resource.setMediaType("image/jpeg");
+ registry.put(filePath, resource);
+ }
+ }
+
+ registry.copy(filePath, filePath);
+ registry.addAssociation(docArtifact.getPath(), filePath,
+ APIConstants.DOCUMENTATION_FILE_ASSOCIATION);
+ }
+ }
+ }
+ } catch (RegistryException e) {
+ log.error("Registry error encountered for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (APIManagementException e) {
+ log.error("Error occurred while creating swagger v2.0 document for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+ }
+ }
+ }
+
+ public static void rxtMigration(GenericArtifactManager manager, GenericArtifact[] artifacts) {
+ for (GenericArtifact artifact : artifacts) {
+ try {
+ artifact.setAttribute(APIConstants.PROTOTYPE_OVERVIEW_IMPLEMENTATION, APIConstants.IMPLEMENTATION_TYPE_ENDPOINT);
+
+ manager.updateGenericArtifact(artifact);
+
+ } catch (RegistryException e) {
+ log.error("Registry error encountered when updating rxt", e);
+ }
+ }
+
+ }
+
+ public static void swagger12Migration(GenericArtifact[] artifacts, Registry registry, Tenant tenant) {
+ for (GenericArtifact artifact : artifacts) {
+ API api = getAPI(artifact);
+
+ if (api != null) {
+ APIIdentifier apiIdentifier = api.getId();
+ try {
+ createSwagger12Resources(artifact, registry, api, tenant);
+
+ updateSwagger12ResourcesUsingSwagger11Doc(apiIdentifier, registry);
+ } catch (UserStoreException e) {
+ log.error("UserStoreException thrown when migrating swagger for api "+ api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (ParseException e) {
+ log.error("ParseException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (APIManagementException e) {
+ log.error("APIManagementException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (RegistryException e) {
+ log.error("RegistryException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (UnsupportedEncodingException e) {
+ log.error("UnsupportedEncodingException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (APIMigrationException e) {
+ log.error("APIMigrationException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * create swagger 1.2 resources
+ * @param artifact
+ * @param registry
+ * @param api
+ * @throws APIManagementException
+ * @throws RegistryException
+ * @throws UserStoreException
+ */
+ public static void createSwagger12Resources(GenericArtifact artifact, Registry registry,
+ API api, Tenant tenant) throws UserStoreException, APIManagementException, ParseException {
+
+ JSONParser parser = new JSONParser();
+ String pathJsonTemplate = "{\n \"path\": \"\",\n \"operations\": []\n}";
+ String operationJsonTemplate = "{\n \"method\": \"\",\n \"parameters\": []\n}";
+
+ // for apidoc
+ String apiJsonTemplate = "{\n \"apiVersion\": \"\",\n \"swaggerVersion\": \"1.2\",\n \"apis\": [],\n \"info\": {\n \"title\": \"\",\n \"description\": \"\",\n \"termsOfServiceUrl\": \"\",\n \"contact\": \"\",\n \"license\": \"\",\n \"licenseUrl\": \"\"\n },\n \"authorizations\": {\n \"oauth2\": {\n \"type\": \"oauth2\",\n \"scopes\": []\n }\n }\n}";
+
+ // for each resource
+ // String apiResourceJsontemplate =
+ // "{\n \"apiVersion\": \"\",\n \"swaggerVersion\": \"1.2\",\n \"resourcePath\":\"\",\n \"apis\": [],\n \"info\": {\n \"title\": \"\",\n \"description\": \"\",\n \"termsOfServiceUrl\": \"\",\n \"contact\": \"\",\n \"license\": \"\",\n \"licenseUrl\": \"\"\n },\n \"authorizations\": {\n \"oauth2\": {\n \"type\": \"oauth2\",\n \"scopes\": []\n }\n }\n}";
+ String apiResourceJsontemplate = "{\n \"apiVersion\": \"\",\n \"swaggerVersion\": \"1.2\",\n \"resourcePath\":\"\",\n \"apis\": [] \n}";
+
+ //Auth Types
+ HashMap auth_types = new HashMap();
+ auth_types.put("None","None");
+ auth_types.put("Application_User","Application User");
+ auth_types.put("Application","Application");
+ auth_types.put("Any","Application & Application User");
+
+ JSONObject mainAPIJson;
+ try {
+ String apiVersion = artifact
+ .getAttribute(APIConstants.API_OVERVIEW_VERSION);
+
+ Set uriTemplates = api.getUriTemplates();
+ Map> resourceNamepaths = new HashMap>();
+ Map> resourcePathJSONs = new HashMap>();
+
+ for (URITemplate template : uriTemplates) {
+
+ String path = template.getUriTemplate();
+
+ if (path == null) {
+ log.error("URI Template does not exist for api "+ api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ continue;
+ }
+
+ if (path.equals("/")) {
+ path = "/*";
+ }
+ List resourcePaths;
+ int resourceNameEndIndex = path.indexOf("/", 1);
+ String resourceName = "/default";
+ if(resourceNameEndIndex != -1) {
+ resourceName = path.substring(1, resourceNameEndIndex);
+ }
+
+ if(!resourceName.startsWith("/")) {
+ resourceName = "/" + resourceName;
+ }
+
+ if(resourceNamepaths.get(resourceName) != null) {
+ resourcePaths = resourceNamepaths.get(resourceName);
+ if (!resourcePaths.contains(path)) {
+ resourcePaths.add(path);
+ }
+ //verbs comes as a [POST, GET] type of a string
+ String[] httpVerbs = template.getMethodsAsString().split(" ");
+ String[] authtypes = template.getAuthTypeAsString().split(" ");
+ String[] tries = template.getThrottlingTiersAsString().split(" ");
+
+ for(int j = 0; j < httpVerbs.length ; j ++) {
+ final JSONObject operationJson = (JSONObject) parser.parse(operationJsonTemplate);
+ operationJson.put("method", httpVerbs[j]);
+ operationJson.put("auth_type", auth_types.get(authtypes[j]));
+ operationJson.put("throttling_tier", tries[j]);
+
+ if(resourcePathJSONs.get(path) != null) {
+ resourcePathJSONs.get(path).add(operationJson);
+
+ } else {
+ resourcePathJSONs.put(path, new ArrayList() {{
+ add(operationJson);
+ }});
+ }
+ }
+ resourceNamepaths.put(resourceName, resourcePaths);
+ } else {
+ resourcePaths = new ArrayList();
+ resourcePaths.add(path);
+
+ //verbs comes as a [POST, GET] type of a string
+ String[] httpVerbs = template.getMethodsAsString().split(" ");
+ String[] authtypes = template.getAuthTypeAsString().split(" ");
+ String[] tries = template.getThrottlingTiersAsString().split(" ");
+
+ for(int j = 0; j < httpVerbs.length ; j ++) {
+ final JSONObject operationJson = (JSONObject) parser.parse(operationJsonTemplate);
+ operationJson.put("method", httpVerbs[j]);
+ operationJson.put("auth_type", auth_types.get(authtypes[j]));
+ operationJson.put("throttling_tier", tries[j]);
+
+ if(resourcePathJSONs.get(path) != null) {
+ resourcePathJSONs.get(path).add(operationJson);
+
+ } else {
+ resourcePathJSONs.put(path, new ArrayList() {{
+ add(operationJson);
+ }});
+ }
+ }
+
+ resourceNamepaths.put(resourceName, resourcePaths);
+ }
+ }
+
+ //list to store the api array objects
+ List apiArray = new ArrayList();
+
+ for (Map.Entry> entry : resourcePathJSONs
+ .entrySet()) {
+ String resourcePath = entry.getKey();
+ JSONObject pathJson = (JSONObject) parser
+ .parse(pathJsonTemplate);
+ pathJson.put("path", resourcePath);
+ List methodJsons = entry.getValue();
+ for (JSONObject methodJson : methodJsons) {
+ JSONArray operations = (JSONArray) pathJson
+ .get("operations");
+ operations.add(methodJson);
+ }
+
+ apiArray.add(pathJson);
+ }
+
+ /**
+ * create only one resource doc for all the resources. name it as 'resources'
+ */
+ // create resources in the registry
+ APIIdentifier apiIdentfier = api.getId();
+ String apiDefinitionFilePath = APIUtil.getSwagger12DefinitionFilePath(apiIdentfier.getApiName(),
+ apiIdentfier.getVersion(),apiIdentfier.getProviderName());
+
+ String resourceName = Constants.API_DOC_12_ALL_RESOURCES_DOC;
+ JSONObject resourcesObj = (JSONObject) parser.parse(apiResourceJsontemplate);
+ resourcesObj.put("apiVersion", apiVersion);
+ resourcesObj.put("resourcePath", "/" + resourceName);
+ JSONArray apis = (JSONArray) resourcesObj.get("apis");
+ //add all the apis to single one
+ for(JSONObject arraObj : apiArray){
+ apis.add(arraObj);
+ }
+ String registryRes = apiDefinitionFilePath
+ + RegistryConstants.PATH_SEPARATOR + resourceName;
+ createResource(registry, resourcesObj.toJSONString(), registryRes, api,tenant);
+
+ // create api-doc file in the 1.2 resource location
+
+ mainAPIJson = (JSONObject) parser.parse(apiJsonTemplate);
+ mainAPIJson.put("apiVersion", apiVersion);
+ ((JSONObject)mainAPIJson.get("info")).put("description", "Available resources");
+ ((JSONObject)mainAPIJson.get("info")).put("title", artifact.getAttribute(APIConstants.API_OVERVIEW_NAME));
+
+ JSONArray apis1 = (JSONArray) mainAPIJson.get("apis");
+ JSONObject pathjob = new JSONObject();
+ pathjob.put("path", "/" + resourceName);
+ pathjob.put("description", "All resources for the api");
+ apis1.add(pathjob);
+
+
+ createResource(registry, mainAPIJson.toJSONString(),
+ apiDefinitionFilePath
+ + APIConstants.API_DOC_1_2_RESOURCE_NAME, api, tenant);
+
+ } catch (GovernanceException e) {
+ String msg = "Failed to get API fro artifact ";
+ throw new APIManagementException(msg, e);
+ } catch (ParseException e) {
+ throw new APIManagementException(
+ "Error while generating swagger 1.2 resource for api ", e);
+ }
+
+ }
+
+ /**
+ * save create resource at the given location and set permission
+ * @param re
+ * @param content
+ * @param resourcePath
+ * @param api
+ * @throws UserStoreException
+ * @throws RegistryException
+ * @throws APIManagementException
+ */
+ private static void createResource(Registry re, String content, String resourcePath, API api, Tenant tenant) throws UserStoreException{
+ try {
+ Resource docContent = re.newResource();
+ docContent.setContent(content);
+ docContent.setMediaType("text/plain");
+ re.put(resourcePath, docContent);
+
+ ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getAuthorizationManager().authorizeRole(APIConstants.ANONYMOUS_ROLE,
+ "_system/governance" + resourcePath,
+ ActionConstants.GET);
+ } catch (RegistryException e) {
+ String msg = "Failed to add the API Definition content of : "
+ + APIConstants.API_DEFINITION_DOC_NAME + " of API :" + api.getId().getApiName();
+ log.error(msg);
+ }
+ }
+
+ /**
+ * Update the swagger 1.2 resources using swagger 1.1 doc
+ * @param apiIdentfier
+ * @param registry
+ * @throws APIManagementException
+ * @throws RegistryException
+ */
+ private static void updateSwagger12ResourcesUsingSwagger11Doc(APIIdentifier apiIdentfier, Registry registry)
+ throws APIManagementException, RegistryException, UnsupportedEncodingException, APIMigrationException {
+
+ String apiDef11Path =
+ ResourceUtil.getSwagger11ResourceLocation(apiIdentfier.getApiName(),
+ apiIdentfier.getVersion());
+
+ if (!registry.resourceExists(apiDef11Path)) {
+ throw new APIMigrationException("Swagger 1.1 document at " + apiDef11Path + " does not exist");
+ }
+
+ Resource apiDef11 = registry.get(apiDef11Path);
+
+ String apiDef11Json = new String((byte[]) apiDef11.getContent(), "UTF8");
+
+ String swagger12location =
+ ResourceUtil.getSwagger12ResourceLocation(apiIdentfier.getApiName(),
+ apiIdentfier.getVersion(),
+ apiIdentfier.getProviderName());
+
+ if (!registry.resourceExists(swagger12location)) {
+ throw new APIMigrationException("Swagger 1.2 document at " + swagger12location + " does not exist");
+ }
+
+ Resource swagger12Res = registry.get(swagger12location);
+ String[] resourcePaths = (String[]) swagger12Res.getContent();
+
+ try {
+ ResourceUtil.updateAPISwaggerDocs(apiDef11Json, resourcePaths, registry);
+ } catch (ParseException e) {
+ throw new APIManagementException("Unable to parse registry resource", e);
+ }
+
+ }
+
+
+ private static API getAPI(GenericArtifact artifact) {
+ log.debug("Calling getAPI");
+ API api = null;
+
+ try {
+ api = APIUtil.getAPI(artifact);
+ } catch (APIManagementException e) {
+ log.error("Error when getting api artifact " + artifact.getId() + " from registry", e);
+ }
+
+ return api;
+ }
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/SynapseMigration.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/SynapseMigration.java
new file mode 100644
index 0000000000..eb19ec6368
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/SynapseMigration.java
@@ -0,0 +1,87 @@
+package org.wso2.carbon.apimgt.migration.client;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.File;
+import java.io.IOException;
+
+public class SynapseMigration {
+ private static final Log log = LogFactory.getLog(SynapseMigration.class);
+
+ /**
+ * method to add property element to the existing google analytics tracking
+ * handler
+ *
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ * @throws XPathExpressionException
+ * @throws TransformerException
+ */
+ public static void modifyGoogleAnalyticsTrackingHandler(File api, Document xmlDocument)
+ throws
+ TransformerException, XPathExpressionException {
+ // current handler element
+ String expression = "//handler[@class='org.wso2.carbon.apimgt.usage.publisher."
+ + "APIMgtGoogleAnalyticsTrackingHandler']";
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
+ xmlDocument, XPathConstants.NODESET);
+ Element oldHandlerElem = (Element) nodeList.item(0);
+
+ /*
+ * Replace
+ *
+ * with
+ *
+ *
+ *
+ */
+
+ if (oldHandlerElem != null) {
+ // new handler to replace the old one
+ Element newHandlerElem = xmlDocument.createElement("handler");
+ newHandlerElem.setAttribute("class",
+ "org.wso2.carbon.apimgt.usage.publisher."
+ + "APIMgtGoogleAnalyticsTrackingHandler");
+ // child element for the handler
+ Element propertyElem = xmlDocument.createElement("property");
+ propertyElem.setAttribute("name", "configKey");
+ propertyElem.setAttribute("value",
+ "gov:/apimgt/statistics/ga-config.xml");
+
+ newHandlerElem.appendChild(propertyElem);
+
+ Element root = xmlDocument.getDocumentElement();
+ NodeList handlersNodelist = root.getElementsByTagName("handlers");
+ Element handlers = (Element) handlersNodelist.item(0);
+ // replace old handler with the new one
+ handlers.replaceChild(newHandlerElem, oldHandlerElem);
+
+ // write the content into xml file
+ TransformerFactory transformerFactory = TransformerFactory
+ .newInstance();
+ Transformer transformer = transformerFactory.newTransformer();
+ DOMSource source = new DOMSource(xmlDocument);
+ StreamResult result = new StreamResult(api);
+ transformer.transform(source, result);
+ log.debug("Updated api: " + api.getName());
+ }
+
+ }
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
new file mode 100644
index 0000000000..52d4e94e9c
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
@@ -0,0 +1,263 @@
+/*
+* Copyright (c) 2015, 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.migration.client.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.service.component.ComponentContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
+import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.MigrateFrom16to17;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+
+/**
+ * @scr.component name="org.wso2.carbon.apimgt.migration.client" immediate="true"
+ * @scr.reference name="realm.service"
+ * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
+ * policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
+ * @scr.reference name="registry.service"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService" cardinality="1..1"
+ * policy="dynamic" bind="setRegistryService" unbind="unsetRegistryService"
+ * @scr.reference name="registry.core.dscomponent"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService" cardinality="1..1"
+ * policy="dynamic" bind="setRegistryService" unbind="unsetRegistryService"
+ * @scr.reference name="tenant.registryloader" interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader" cardinality="1..1"
+ * policy="dynamic" bind="setTenantRegistryLoader" unbind="unsetTenantRegistryLoader"
+ * @scr.reference name="apim.configuration" interface="org.wso2.carbon.apimgt.impl.APIManagerConfigurationService" cardinality="1..1"
+ * policy="dynamic" bind="setApiManagerConfig" unbind="unsetApiManagerConfig"
+ */
+
+@SuppressWarnings("unused")
+public class APIMMigrationServiceComponent {
+
+ private static final Log log = LogFactory.getLog(APIMMigrationServiceComponent.class);
+
+ /**
+ * Method to activate bundle.
+ *
+ * @param context OSGi component context.
+ */
+ protected void activate(ComponentContext context) {
+ boolean isCorrectProductVersion = false;
+ try {
+ APIMgtDBUtil.initialize();
+ } catch (Exception e) {
+ //APIMgtDBUtil.initialize() throws generic exception
+ log.error("Error occurred while initializing DB Util ", e);
+ }
+
+ // Product and version validation
+ File carbonXmlConfig = new File(CarbonUtils.getServerXml());
+
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+
+ try {
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(carbonXmlConfig);
+
+ doc.getDocumentElement().normalize();
+
+ NodeList nameNodes = doc.getElementsByTagName("Name");
+
+ if (nameNodes.getLength() > 0) {
+ Element name = (Element) nameNodes.item(0);
+ if (Constants.APIM_PRODUCT_NAME.equals(name.getTextContent())) {
+ NodeList versionNodes = doc.getElementsByTagName("Version");
+
+ if (versionNodes.getLength() > 0) {
+ Element version = (Element) versionNodes.item(0);
+ if (Constants.VERSION_1_7.equals(version.getTextContent())) {
+ isCorrectProductVersion = true;
+ }
+ }
+ }
+ }
+ } catch (ParserConfigurationException e) {
+ log.error("ParserConfigurationException when processing carbon.xml", e);
+ } catch (SAXException e) {
+ log.error("SAXException when processing carbon.xml", e);
+ } catch (IOException e) {
+ log.error("IOException when processing carbon.xml", e);
+ }
+
+ String tenants = System.getProperty(Constants.ARG_MIGRATE_TENANTS);
+ boolean migrateAll = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_ALL));
+ boolean isRegistryMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_REG));
+ boolean isFileSystemMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_FILE_SYSTEM));
+
+ try {
+ if (isCorrectProductVersion) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " to WSO2 API Manager " + Constants.VERSION_1_7);
+
+ // Create a thread and wait till the APIManager DBUtils is initialized
+
+ MigrateFrom16to17 migrateFrom16to17 = new MigrateFrom16to17(tenants);
+
+ boolean isArgumentValid = false;
+
+ //Default operation will migrate all three types of resources
+ if (migrateAll) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " resources to WSO2 API Manager " + Constants.VERSION_1_7);
+ migrateFrom16to17.registryResourceMigration();
+ migrateFrom16to17.fileSystemMigration();
+ isArgumentValid = true;
+ } else {
+ //Only performs registry migration
+ if (isRegistryMigration) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " registry resources to WSO2 API Manager " + Constants.VERSION_1_7);
+ migrateFrom16to17.registryResourceMigration();
+ isArgumentValid = true;
+ }
+ //Only performs file system migration
+ if (isFileSystemMigration) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " file system resources to WSO2 API Manager " + Constants.VERSION_1_7);
+ migrateFrom16to17.fileSystemMigration();
+ isArgumentValid = true;
+ }
+ }
+
+ if (isArgumentValid) {
+ log.info("API Manager " + Constants.PREVIOUS_VERSION + " to " + Constants.VERSION_1_7 + " migration successfully completed");
+ }
+ } else {
+ log.error("Migration client installed in incompatible product version. This migration client is only compatible with " +
+ Constants.APIM_PRODUCT_NAME + " " + Constants.VERSION_1_7 + ". Please verify the product/version in use.");
+ }
+ } catch (APIMigrationException e) {
+ log.error("API Management exception occurred while migrating", e);
+ } catch (UserStoreException e) {
+ log.error("User store exception occurred while migrating", e);
+ } catch (Exception e) {
+ log.error("Generic exception occurred while migrating", e);
+ } catch (Throwable t) {
+ log.error("Throwable error", t);
+ }
+ log.info("WSO2 API Manager migration component successfully activated.");
+ }
+
+ /**
+ * Method to deactivate bundle.
+ *
+ * @param context OSGi component context.
+ */
+ protected void deactivate(ComponentContext context) {
+ log.info("WSO2 API Manager migration bundle is deactivated");
+ }
+
+ /**
+ * Method to set registry service.
+ *
+ * @param registryService service to get tenant data.
+ */
+ protected void setRegistryService(RegistryService registryService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting RegistryService for WSO2 API Manager migration");
+ }
+ ServiceHolder.setRegistryService(registryService);
+ }
+
+ /**
+ * Method to unset registry service.
+ *
+ * @param registryService service to get registry data.
+ */
+ protected void unsetRegistryService(RegistryService registryService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unset Registry service");
+ }
+ ServiceHolder.setRegistryService(null);
+ }
+
+ /**
+ * Method to set realm service.
+ *
+ * @param realmService service to get tenant data.
+ */
+ protected void setRealmService(RealmService realmService) {
+ log.debug("Setting RealmService for WSO2 API Manager migration");
+ ServiceHolder.setRealmService(realmService);
+ }
+
+ /**
+ * Method to unset realm service.
+ *
+ * @param realmService service to get tenant data.
+ */
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unset Realm service");
+ }
+ ServiceHolder.setRealmService(null);
+ }
+
+ /**
+ * Method to set tenant registry loader
+ *
+ * @param tenantRegLoader tenant registry loader
+ */
+ protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegLoader) {
+ log.debug("Setting TenantRegistryLoader for WSO2 API Manager migration");
+ ServiceHolder.setTenantRegLoader(tenantRegLoader);
+ }
+
+ /**
+ * Method to unset tenant registry loader
+ *
+ * @param tenantRegLoader tenant registry loader
+ */
+ protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegLoader) {
+ log.debug("Unset Tenant Registry Loader");
+ ServiceHolder.setTenantRegLoader(null);
+ }
+
+ /**
+ * Method to set API Manager configuration
+ *
+ * @param apiManagerConfig api manager configuration
+ */
+ protected void setApiManagerConfig(APIManagerConfigurationService apiManagerConfig) {
+ log.info("Setting APIManager configuration");
+ }
+
+ /**
+ * Method to unset API manager configuration
+ *
+ * @param apiManagerConfig api manager configuration
+ */
+ protected void unsetApiManagerConfig(APIManagerConfigurationService apiManagerConfig) {
+ log.info("Un-setting APIManager configuration");
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java
new file mode 100644
index 0000000000..b03635c444
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2015, 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.migration.client.internal;
+
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.user.core.service.RealmService;
+
+@SuppressWarnings("unused")
+public class ServiceHolder {
+ //Registry Service which is used to get registry data.
+ private static RegistryService registryService;
+
+ //Realm Service which is used to get tenant data.
+ private static RealmService realmService;
+
+ //Tenant registry loader which is used to load tenant registry
+ private static TenantRegistryLoader tenantRegLoader;
+
+ /**
+ * Method to get RegistryService.
+ *
+ * @return registryService.
+ */
+ public static RegistryService getRegistryService() {
+ return registryService;
+ }
+
+ /**
+ * Method to set registry RegistryService.
+ *
+ * @param service registryService.
+ */
+ public static void setRegistryService(RegistryService service) {
+ registryService = service;
+ }
+
+ /**
+ * This method used to get RealmService.
+ *
+ * @return RealmService.
+ */
+ public static RealmService getRealmService() {
+ return realmService;
+ }
+
+ /**
+ * Method to set registry RealmService.
+ *
+ * @param service RealmService.
+ */
+ public static void setRealmService(RealmService service) {
+ realmService = service;
+ }
+
+ /**
+ * This method used to get TenantRegistryLoader
+ *
+ * @return tenantRegLoader Tenant registry loader for load tenant registry
+ */
+ public static TenantRegistryLoader getTenantRegLoader() {
+ return tenantRegLoader;
+ }
+
+ /**
+ * This method used to set TenantRegistryLoader
+ *
+ * @param service Tenant registry loader for load tenant registry
+ */
+ public static void setTenantRegLoader(TenantRegistryLoader service) {
+ tenantRegLoader = service;
+ }
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
new file mode 100644
index 0000000000..e8a95c495e
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2015, 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.migration.util;
+
+public class Constants {
+ public static final String APIM_PRODUCT_NAME = "WSO2 API Manager";
+ public static final String PREVIOUS_VERSION = "1.6.0";
+ public static final String VERSION_1_7 = "1.7.0";
+ public static final String LINE_BREAK = "\\n";
+ public static final String CONSTRAINT = "constraint";
+ public static final String API = "api";
+ public static final String MIGRATION_SCRIPTS_FOLDER = "migration-scripts";
+
+ // Migration client argument property names
+ public static final String ARG_MIGRATE_TO_VERSION = "migrateToVersion";
+ public static final String ARG_MIGRATE_TENANTS = "tenants";
+ public static final String ARG_MIGRATE_ALL = "migrate";
+ public static final String ARG_MIGRATE_REG = "migrateReg";
+ public static final String ARG_MIGRATE_FILE_SYSTEM = "migrateFS";
+
+ // Synapse configuration related
+ public static final String SYNAPSE_API_ROOT_ELEMENT = "api";
+ public static final String SYNAPSE_API_ATTRIBUTE_VERSION = "version";
+
+ /*
+ * Variables in api_doc.json version 1.1
+ */
+
+ public static final String API_DOC_11_BASE_PATH = "basePath";
+ public static final String API_DOC_11_RESOURCE_PATH = "resourcePath";
+ public static final String API_DOC_11_API_VERSION = "apiVersion";
+ public static final String API_DOC_11_APIS = "apis";
+ public static final String API_DOC_11_PATH = "path";
+ public static final String API_DOC_11_OPERATIONS = "operations";
+ public static final String API_DOC_11_METHOD = "httpMethod";
+ public static final String API_DOC_11_PARAMETERS = "parameters";
+
+ /*
+ * Variables in api_doc.json version 1.2
+ */
+
+ public static final String API_DOC_12_BASE_PATH = "basePath";
+ public static final String API_DOC_12_APIS = "apis";
+ public static final String API_DOC_12_PATH = "path";
+ public static final String API_DOC_12_OPERATIONS = "operations";
+ public static final String API_DOC_12_METHOD = "method";
+ public static final String API_DOC_12_PARAMETERS = "parameters";
+ public static final String API_DOC_12_NICKNAME = "nickname";
+ //this resource contains all the resources. This is introduced to swagger 1.2 location to hold
+ //all the resource during the migration of 1.6. AM 1.6 does not have resources seperated by name
+ //so all resources are in one doc
+ public static final String API_DOC_12_ALL_RESOURCES_DOC = "resources";
+
+ /**
+ * default parameter array
+ */
+ public static final String DEFAULT_PARAM_ARRAY = "[ " + " { "
+ + " \"dataType\": \"String\", "
+ + " \"description\": \"Access Token\", "
+ + " \"name\": \"Authorization\", "
+ + " \"allowMultiple\": false, "
+ + " \"required\": true, "
+ + " \"paramType\": \"header\" " + " }, "
+ + " { "
+ + " \"description\": \"Request Body\", "
+ + " \"name\": \"body\", "
+ + " \"allowMultiple\": false, "
+ + " \"type\": \"string\", "
+ + " \"required\": true, "
+ + " \"paramType\": \"body\" " + " } "
+ + "]";
+
+ public static final String DEFAULT_PARAM_FOR_URL_TEMPLATE = " { "
+ + "\"name\": \"\", "
+ + "\"allowMultiple\": false, "
+ + "\"required\": true, "
+ + "\"type\": \"string\", "
+ + "\"paramType\": \"path\" "
+ + "}";
+
+
+ //database types
+ public static final String DB_TYPE_ORACLE = "oracle";
+ public static final String DB_TYPE_DB2 = "db2";
+ public static final String DB_TYPE_MYSQL= "mysql";
+ public static final String DB_TYPE_MSSQL = "mssql";
+ public static final String DB_TYPE_POSTGRE = "postgre";
+ public static final String DB_TYPE_OPENEDGE = "openedge";
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
new file mode 100644
index 0000000000..8b6ced8fba
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
@@ -0,0 +1,617 @@
+/*
+* Copyright (c) 2015, 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.migration.util;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.MigrationDBCreator;
+import org.wso2.carbon.registry.core.Registry;
+import org.wso2.carbon.registry.core.RegistryConstants;
+import org.wso2.carbon.registry.core.Resource;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.utils.CarbonUtils;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ResourceUtil {
+
+ private static final Log log = LogFactory.getLog(ResourceUtil.class);
+
+ /**
+ * location for the swagger 1.1 resources
+ *
+ * @param apiName api name
+ * @param apiVersion api version
+ * @return swagger v1.1 location
+ */
+ public static String getSwagger11ResourceLocation(String apiName, String apiVersion) {
+ return APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR +
+ apiName +"-" + apiVersion + RegistryConstants.PATH_SEPARATOR + APIConstants.API_DOC_RESOURCE_NAME;
+ }
+
+
+ /**
+ * location for the swagger 1.2 resources
+ *
+ * @param apiName api name
+ * @param apiVersion api version
+ * @param apiProvider api provider
+ * @return swagger v1.2 location
+ */
+ public static String getSwagger12ResourceLocation(String apiName, String apiVersion, String apiProvider) {
+ return APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR + apiName + "-" + apiVersion + "-"
+ + apiProvider + RegistryConstants.PATH_SEPARATOR + APIConstants.API_DOC_1_2_LOCATION;
+ }
+
+
+ /**
+ * This method picks the query according to the users database
+ *
+ * @return exact query to execute
+ * @throws SQLException
+ * @throws APIMigrationException
+ * @throws IOException
+ */
+ public static String pickQueryFromResources(String queryType) throws SQLException, APIMigrationException,
+ IOException {
+
+ String queryTobeExecuted;
+ try {
+ String databaseType = MigrationDBCreator.getDatabaseType(APIMgtDBUtil.getConnection());
+
+ //pick from 18to19Migration/sql-scripts
+ String resourcePath = CarbonUtils.getCarbonHome() + File.separator + Constants.MIGRATION_SCRIPTS_FOLDER + File.separator;
+
+ if (Constants.CONSTRAINT.equals(queryType)) {
+ //queryTobeExecuted = resourcePath + "drop-fk.sql";
+ queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + "drop-fk.sql")), "UTF-8");
+ } else {
+ queryTobeExecuted = resourcePath + databaseType + ".sql";
+ //queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + databaseType + ".sql")), "UTF-8");
+ }
+
+ } catch (IOException e) {
+ throw new APIMigrationException("Error occurred while accessing the sql from resources. " + e);
+ } catch (Exception e) {
+ //getDatabaseType inherited from DBCreator, which throws generic exception
+ throw new APIMigrationException("Error occurred while searching for database type " + e);
+ }
+
+ return queryTobeExecuted;
+ }
+
+ /**
+ * To handle exceptions
+ *
+ * @param msg error message
+ * @throws APIMigrationException
+ */
+ public static void handleException(String msg, Throwable e) throws APIMigrationException {
+ log.error(msg, e);
+ throw new APIMigrationException(msg, e);
+ }
+
+
+
+
+ /**
+ * Get all the parameters related to each resource. The parameter array is
+ * an array which is part of the operations object inside each resource.
+ *
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of parameter array related to all the http methods for each
+ * resource. the key for
+ * the map is resourcepath_httpmethod
+ */
+ public static Map getAllParametersForResources(JSONObject resource) {
+ Map parameters = new HashMap();
+
+ String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
+ String resourcePathPrefix = resourcePath + "/" + apiVersion;
+
+ String key;
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+ for (int i = 0; i < apis.size(); i++) {
+
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);
+
+ if (resourcePathPrefix.length() > path.length()) {
+ log.error("Cannot obtain key prefix because swagger resourcePathPrefix : " + resourcePathPrefix + " is incompatible with path : " + path);
+ continue;
+ }
+
+ // get the key by removing the "apiVersion" and "resourcePath"
+ // from the "path" variable
+ // and concat the http method
+ String keyPrefix = path.substring(resourcePathPrefix.length());
+ if (keyPrefix.isEmpty()) {
+ keyPrefix = "/*";
+ }
+
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
+ JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);
+
+ key = keyPrefix + "_" + httpMethod.toLowerCase();
+
+ parameters.put(key, parameterArray);
+ }
+ }
+
+ return parameters;
+
+ }
+
+ /**
+ * Get all the operation object related to each resource. Method is inside the operation object
+ * this object contains the nickname, description related to that resource method
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of operations array related to all the http methods for each
+ * resource. the key for
+ * the map is resourcepath_httpmethod
+ */
+ private static Map getAllOperationsForResources(JSONObject resource) {
+ Map parameters = new HashMap();
+
+ String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
+ String resourcePathPrefix = resourcePath + "/" + apiVersion;
+
+ String key;
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+ for (int i = 0; i < apis.size(); i++) {
+
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);
+
+ if (resourcePathPrefix.length() > path.length()) {
+ log.error("Cannot obtain key prefix because swagger resourcePathPrefix : " + resourcePathPrefix + " is incompatible with path : " + path);
+ continue;
+ }
+
+ // get the key by removing the "apiVersion" and "resourcePath"
+ // from the "path" variable
+ // and concat the http method
+ String keyPrefix = path.substring(resourcePathPrefix.length());
+ if (keyPrefix.isEmpty()) {
+ keyPrefix = "/*";
+ }
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
+ JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);
+
+ key = keyPrefix + "_" + httpMethod.toLowerCase();
+
+ parameters.put(key, operation);
+ }
+ }
+
+ return parameters;
+ }
+ /**
+ * Get all the apis as a map. key for map is the full resource path for that api. key is created
+ * using 'basepath + apis[i].path' values in the api-doc.json file (swagger 1.1 doc)
+ *
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of apis in the swagger 1.1 doc. key is the full resource path for that resource
+ */
+ public static Map getAllAPIsByResourcePath(JSONObject resource) {
+ Map parameters = new HashMap();
+
+ String basePath = (String) resource.get(Constants.API_DOC_11_BASE_PATH);
+ String key = null;
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+ for (int i = 0; i < apis.size(); i++) {
+
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+ key = basePath + path;
+ parameters.put(key, apiInfo);
+ }
+
+ return parameters;
+
+ }
+
+ private static JSONArray getDefaultParameters() {
+ JSONParser parser = new JSONParser();
+ JSONArray defaultParam = null;
+ try {
+ defaultParam = (JSONArray) parser.parse(Constants.DEFAULT_PARAM_ARRAY);
+ } catch (ParseException e) {
+ log.error("ParseException when getting swagger default Parameters", e);
+ }
+ return defaultParam;
+
+ }
+
+ /**
+ * Modify the resource in registry location '1.2' to be compatible with the
+ * AM 1.8. add the
+ * parameters to operations element, add 'nickname' variable and the
+ * 'basePath' variable
+ *
+ * @param resource
+ * resource inside the 1.2 location
+ * @param allParameters
+ * map containing all the parameters extracted from api-doc
+ * containing
+ * resources for swagger 1.1
+ * @param allOperations
+ * @param basePath
+ * base path for the resource
+ * @return modified resource for the api
+ */
+ public static String getUpdatedSwagger12Resource(JSONObject resource,
+ Map allParameters,
+ Map allOperations, String basePath) {
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_12_APIS);
+ for (int i = 0; i < apis.size(); i++) {
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_12_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_12_OPERATIONS);
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String method = (String) operation.get(Constants.API_DOC_12_METHOD);
+
+ // nickname is method name + "_" + path without starting "/"
+ // symbol
+ String nickname = method.toLowerCase() + "_" + path.substring(1);
+ // add nickname variable
+ operation.put(Constants.API_DOC_12_NICKNAME, nickname);
+ String key = path + "_" + method.toLowerCase();
+
+ JSONArray parameters;
+ if (allParameters.containsKey(key)) {
+ parameters = allParameters.get(key);
+
+ //setting the 'type' to 'string' if this variable is missing
+ for(int m = 0; m < parameters.size(); m++ ){
+ JSONObject para = (JSONObject)parameters.get(m);
+ if(!para.containsKey("type")){
+ para.put("type", "string");
+ }
+ }
+
+ } else {
+ parameters = getDefaultParameters();
+
+ }
+ //if there are parameters already in this
+ JSONArray existingParams = (JSONArray) operation.get(Constants.API_DOC_12_PARAMETERS);
+ if(existingParams.isEmpty()) {
+ JSONParser parser = new JSONParser();
+ if(path.contains("{")) {
+ List urlParams = ResourceUtil.getURLTempateParams(path);
+ for(String p: urlParams){
+ try {
+ JSONObject paramObj = (JSONObject) parser.parse(Constants.DEFAULT_PARAM_FOR_URL_TEMPLATE);
+ paramObj.put("name", p);
+ parameters.add(paramObj);
+ } catch (ParseException e) {
+ log.error("ParseException when getting swagger default Parameters from URI template", e);
+ }
+ }
+ }
+ // add parameters array
+ operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
+ } else {
+ for(int k = 0; k < existingParams.size(); k ++ ) {
+ parameters.add(existingParams.get(k));
+ }
+ operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
+ }
+
+ //updating the resource description and nickname using values in the swagger 1.1 doc
+ if(allOperations.containsKey(key)){
+
+ //update info related to object
+ JSONObject operationObj11 = allOperations.get(key);
+ //add summery
+ if(operationObj11.containsKey("summary")) {
+ operation.put("summary", (String) operationObj11.get("summery"));
+ }
+
+ }
+ }
+ }
+
+ // add basePath variable
+ resource.put(Constants.API_DOC_12_BASE_PATH, basePath);
+
+ return resource.toJSONString();
+ }
+
+
+ /**
+ * update all the the swagger document in the registry related to an api
+ * @param apiDocJson
+ * @param docResourcePaths
+ * @param registry
+ * @throws ParseException
+ * @throws RegistryException
+ */
+ public static void updateAPISwaggerDocs(String apiDocJson, String[] docResourcePaths,
+ Registry registry) throws ParseException, RegistryException, UnsupportedEncodingException, APIMigrationException {
+
+ JSONParser parser = new JSONParser();
+ JSONObject apiDoc11 = (JSONObject) parser.parse(apiDocJson);
+
+ Map allParameters = ResourceUtil.getAllParametersForResources(apiDoc11);
+
+ Map allOperations = ResourceUtil.getAllOperationsForResources(apiDoc11);
+
+ Map apisByPath = ResourceUtil.getAllAPIsByResourcePath(apiDoc11);
+
+ //this collection holds description given for each resource against the resource name.
+ //descriptions added resources in an api in AM 1.7 are stored in api-doc 1.1. this desciption
+ //is showed in am 1.7 api console in the store applicatoin. AM 1.8 uses descriptions in
+ // api-doc in 1.2 resource folder. following map collects this value from api-doc 1.1 and
+ // store it to add to api-doc 1.2
+ Map descriptionsForResource = new HashMap();
+
+
+
+ String basePath = (String) apiDoc11.get(Constants.API_DOC_11_BASE_PATH);
+ String resourcePath = (String) apiDoc11.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) apiDoc11.get(Constants.API_DOC_11_API_VERSION);
+
+ if (basePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_BASE_PATH);
+ }
+
+ if (resourcePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_RESOURCE_PATH);
+ }
+
+ if (apiVersion == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_API_VERSION);
+ }
+
+ resourcePath = resourcePath.endsWith("/") ? resourcePath : resourcePath + "/";
+ String basePathForResource = basePath + resourcePath + apiVersion;
+
+ String apidoc12path = "";
+
+ //update each resource in the 1.2 folder except the api-doc resource
+ for (String docResourcePath : docResourcePaths) {
+ String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));
+
+ if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
+ //store api-doc in 1.2 folder for future use
+ apidoc12path = docResourcePath;
+ continue;
+ }
+
+ if (!registry.resourceExists(docResourcePath)) {
+ log.error("Doc resource path at : " + docResourcePath + " does not exist");
+ continue;
+ }
+
+ Resource resource = registry.get(docResourcePath);
+ JSONObject apiDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent(), "UTF8"));
+
+
+ String description = "";
+ //generate the key to query the descriptionsForResource map
+ JSONArray apisInResource = (JSONArray) apiDoc.get(Constants.API_DOC_12_APIS);
+
+ if (apisInResource == null) {
+ log.error("Could not find " + Constants.API_DOC_12_APIS + " in document resource path");
+ continue;
+ }
+
+ JSONObject apiTemp = (JSONObject) apisInResource.get(0);
+ String path = (String) apiTemp.get(Constants.API_DOC_12_PATH);
+
+ if (path == null) {
+ log.error("Could not find " + Constants.API_DOC_12_PATH + " in document resource path");
+ continue;
+ }
+
+ String key = "";
+ if (path.equals("/*")) {
+ key = basePathForResource;
+ } else {
+ key = basePathForResource + path;
+ }
+
+
+ //get the description for that resource. query the api list generated using api-doc 1.1
+ if(apisByPath.containsKey(key)) {
+ JSONObject apiInfo = (JSONObject) apisByPath.get(key);
+ description = (String) apiInfo.get("description");
+ descriptionsForResource.put(resourceName, description);
+ }
+
+ String updatedJson =
+ ResourceUtil.getUpdatedSwagger12Resource(apiDoc, allParameters, allOperations,
+ basePathForResource);
+ log.info("\t update " + resourceName.substring(1));
+ Resource res = registry.get(docResourcePath);
+ res.setContent(updatedJson);
+ //update the registry
+ registry.put(docResourcePath, res);
+
+ }
+
+ //update the api-doc. add the descriptions to each api resource
+ ResourceUtil.updateSwagger12APIdoc(apidoc12path, descriptionsForResource, registry, parser);
+
+ }
+
+
+
+ /**
+ * update the swagger 1.2 api-doc. This method updates the descriptions
+ * @param apidoc12path
+ * @param descriptionsForResource
+ * @param registry
+ * @param parser
+ * @throws RegistryException
+ * @throws ParseException
+ */
+ private static void updateSwagger12APIdoc(String apidoc12path,
+ Map descriptionsForResource,
+ Registry registry, JSONParser parser)
+ throws RegistryException,
+ ParseException, UnsupportedEncodingException, APIMigrationException {
+ if (!registry.resourceExists(apidoc12path)) {
+ throw new APIMigrationException("Swagger 1.2 doc does not exist");
+ }
+ Resource res = registry.get(apidoc12path);
+ JSONObject api12Doc = (JSONObject) parser.parse(new String((byte[]) res.getContent(), "UTF8"));
+ JSONArray apis = (JSONArray) api12Doc.get(Constants.API_DOC_12_APIS);
+ for (int j = 0; j < apis.size(); j++) {
+ JSONObject api = (JSONObject) apis.get(j);
+
+ // get the resource name for each api in api-doc 1.2
+ String resPathName = (String) api.get(Constants.API_DOC_12_PATH);
+ if (descriptionsForResource.containsKey(resPathName)) {
+ // if the descrption is available for that resource update it
+ api.put("description", descriptionsForResource.get(resPathName));
+ }
+ }
+ log.info("\t update api-doc");
+ res.setContent(api12Doc.toJSONString());
+ // update the registry
+ registry.put(apidoc12path, res);
+ }
+
+ /**
+ * remove header and body parameters
+ * @param docResourcePaths
+ * @param registry
+ * @throws RegistryException
+ * @throws ParseException
+ */
+ public static void updateSwagger12ResourcesForAM18(String[] docResourcePaths,
+ Registry registry) throws RegistryException, ParseException, UnsupportedEncodingException {
+ JSONParser parser = new JSONParser();
+ for (String docResourcePath : docResourcePaths) {
+
+ String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));
+
+ //modify this if api-doc resource needed to be changed
+ if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
+ continue;
+ }
+
+ Resource resource = registry.get(docResourcePath);
+ JSONObject resourceDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent(), "UTF8"));
+ JSONArray apis = (JSONArray) resourceDoc.get(Constants.API_DOC_12_APIS);
+ for (int j = 0; j < apis.size(); j++) {
+ JSONObject api = (JSONObject) apis.get(j);
+ JSONArray operations = (JSONArray) api.get("operations");
+
+ for (int k = 0; k < operations.size(); k++) {
+ JSONObject operation = (JSONObject) operations.get(k);
+ JSONArray parameters = (JSONArray) operation.get("parameters");
+ String method = (String) operation.get("method");
+ JSONArray parametersNew = new JSONArray();
+ //remove header and body parameters
+ for (int l = 0; l < parameters.size(); l++) {
+ JSONObject parameter = (JSONObject) parameters.get(l);
+
+ if(parameter.get("paramType").equals("header")){
+ continue;
+ }
+ if(parameter.get("paramType").equals("body")) {
+
+ //only remove body of a GET and DELETE
+ if("GET".equalsIgnoreCase(method) ||
+ "DELETE".equalsIgnoreCase(method)) {
+ continue;
+ }
+ }
+ parametersNew.add(parameter);
+ }
+ operation.put("parameters", parametersNew);
+ }
+
+
+ }
+
+ resource.setContent(resourceDoc.toJSONString());
+ //update the registry
+ registry.put(docResourcePath, resource);
+ }
+
+ }
+
+ /**
+ * extract the parameters from the url tempate.
+ * @param url
+ * @return
+ */
+ public static List getURLTempateParams(String url) {
+ boolean endVal = false;
+
+ List params = new ArrayList();
+ if(url.contains("{")){
+
+ int start = 0;
+ int end = 0;
+ for(int i = 0; i < url.length(); i++) {
+ if(url.charAt(i) == '{')
+ start = i;
+ else if(url.charAt(i) == '}') {
+ end = i;
+ endVal = true;
+ }
+
+ if(endVal){
+ params.add(url.substring(start + 1, end));
+ endVal = false;
+ }
+ }
+
+ }
+ return params;
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql
new file mode 100644
index 0000000000..a1e634e99d
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql
@@ -0,0 +1,371 @@
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP LOGIN_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP ERROR_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP CONSENT_PAGE_URL;
+
+ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN ALTER TOKEN_SCOPE VARCHAR (2048);
+
+ALTER TABLE AM_API_URL_MAPPING ADD MEDIATION_SCRIPT BLOB DEFAULT NULL;
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE (
+ SCOPE_ID INTEGER NOT NULL AUTO_INCREMENT,
+ SCOPE_KEY VARCHAR(100) NOT NULL,
+ NAME VARCHAR(255) NULL,
+ DESCRIPTION VARCHAR(512) NULL,
+ TENANT_ID INTEGER NOT NULL DEFAULT 0,
+ ROLES VARCHAR (500) NULL,
+ PRIMARY KEY (SCOPE_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR(255) NOT NULL,
+ SCOPE_ID INTEGER (11) NOT NULL,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_SCIM_GROUP (
+ ID INTEGER GENERATED ALWAYS AS IDENTITY,
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR(255) NOT NULL,
+ ATTR_NAME VARCHAR(1024) NOT NULL,
+ ATTR_VALUE VARCHAR(1024),
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_SCIM_PROVIDER (
+ CONSUMER_ID VARCHAR(255) NOT NULL,
+ PROVIDER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_PASSWORD VARCHAR(255) NOT NULL,
+ USER_URL VARCHAR(1024) NOT NULL,
+ GROUP_URL VARCHAR(1024),
+ BULK_URL VARCHAR(1024),
+ PRIMARY KEY (CONSUMER_ID,PROVIDER_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME TIMESTAMP,
+ PRIMARY KEY (USER_NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN TIMESTAMP NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ PRIMARY KEY (HANDLE)
+);
+
+CREATE TABLE IDN_STS_STORE (
+ ID INTEGER AUTO_INCREMENT,
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT BLOB NOT NULL,
+ CREATE_DATE TIMESTAMP NOT NULL,
+ EXPIRE_DATE TIMESTAMP NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
+);
+
+CREATE TABLE IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_THRIFT_SESSION (
+ SESSION_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME VARCHAR(255) NOT NULL,
+ LAST_MODIFIED_TIME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (SESSION_ID)
+);
+
+-- End of IDN Tables --
+
+
+-- Start of IDN-APPLICATION-MGT Tables--
+
+CREATE TABLE IF NOT EXISTS SP_APP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE(APP_NAME, TENANT_ID);
+
+CREATE TABLE IF NOT EXISTS SP_INBOUND_AUTH (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255) NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_AUTH_STEP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID));
+
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_ROLE_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_PROVISIONING_CONNECTOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ BLOCKING CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '1',
+ IS_PRIMARY CHAR(1) NOT NULL DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE MEDIUMBLOB,
+ CERTIFICATE BLOB,
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR (1) NOT NULL DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR (1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) NOT NULL DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) NOT NULL DEFAULT '0',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME));
+
+INSERT INTO IDP (TENANT_ID, NAME, HOME_REALM_ID) VALUES (-1234, 'LOCAL', 'localhost');
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+INSERT INTO IDP_AUTHENTICATOR (TENANT_ID, IDP_ID, NAME) VALUES (-1234, 1, 'samlsso');
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_CONFIG (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE BLOB,
+ PROPERTY_TYPE CHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_ENTITY (
+ ID INTEGER AUTO_INCREMENT,
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_LOCAL_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+-- End of IDN-APPLICATION-MGT Tables--
+
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING DROP PRIMARY KEY;
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ALTER CONSUMER_KEY SET NULL;
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD PRIMARY KEY(APPLICATION_ID,KEY_TYPE);
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD STATE VARCHAR(30) DEFAULT 'COMPLETED';
+
+CREATE TABLE IF NOT EXISTS AM_APPLICATION_REGISTRATION (
+ REG_ID INT AUTO_INCREMENT,
+ SUBSCRIBER_ID INT,
+ WF_REF VARCHAR(255) NOT NULL,
+ APP_ID INT,
+ TOKEN_TYPE VARCHAR(30),
+ ALLOWED_DOMAINS VARCHAR(256),
+ VALIDITY_PERIOD BIGINT,
+ UNIQUE (SUBSCRIBER_ID,APP_ID,TOKEN_TYPE),
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON UPDATE CASCADE ON DELETE RESTRICT,
+ FOREIGN KEY(APP_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY (REG_ID)
+);
+
+CREATE TABLE IF NOT EXISTS AM_API_SCOPES (
+ API_ID INTEGER NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS AM_API_DEFAULT_VERSION (
+ DEFAULT_VERSION_ID INT AUTO_INCREMENT,
+ API_NAME VARCHAR(256) NOT NULL ,
+ API_PROVIDER VARCHAR(256) NOT NULL ,
+ DEFAULT_API_VERSION VARCHAR(30) ,
+ PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
+ PRIMARY KEY (DEFAULT_VERSION_ID)
+);
+
+
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql
new file mode 100644
index 0000000000..121860f8d8
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql
@@ -0,0 +1,416 @@
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN LOGIN_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN ERROR_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN CONSENT_PAGE_URL;
+
+ALTER TABLE AM_API_URL_MAPPING ADD MEDIATION_SCRIPT VARBINARY(MAX) DEFAULT NULL;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_OAUTH2_SCOPE]') AND TYPE IN (N'U'))
+CREATE TABLE IDN_OAUTH2_SCOPE (
+ SCOPE_ID INTEGER IDENTITY(1,1),
+ SCOPE_KEY VARCHAR(100) NOT NULL,
+ NAME VARCHAR(255) NULL,
+ DESCRIPTION VARCHAR(512) NULL,
+ TENANT_ID INTEGER NOT NULL DEFAULT 0,
+ ROLES VARCHAR (500) NULL,
+ PRIMARY KEY (SCOPE_ID)
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_OAUTH2_RESOURCE_SCOPE]') AND TYPE IN (N'U'))
+CREATE TABLE IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR(255) NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE TABLE IDN_SCIM_GROUP (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR(255) NOT NULL,
+ ATTR_NAME VARCHAR(1024) NOT NULL,
+ ATTR_VALUE VARCHAR(1024),
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IDN_SCIM_PROVIDER (
+ CONSUMER_ID VARCHAR(255) NOT NULL,
+ PROVIDER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_PASSWORD VARCHAR(255) NOT NULL,
+ USER_URL VARCHAR(1024) NOT NULL,
+ GROUP_URL VARCHAR(1024),
+ BULK_URL VARCHAR(1024),
+ PRIMARY KEY (CONSUMER_ID,PROVIDER_ID)
+);
+
+CREATE TABLE IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME DATETIME,
+ PRIMARY KEY (USER_NAME, TENANT_ID)
+);
+
+CREATE TABLE IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN DATETIME NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ PRIMARY KEY (HANDLE)
+);
+
+CREATE TABLE IDN_STS_STORE (
+ ID INTEGER IDENTITY(1,1),
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT VARBINARY(MAX) NOT NULL,
+ CREATE_DATE DATETIME NOT NULL,
+ EXPIRE_DATE DATETIME NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
+);
+
+CREATE TABLE IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA)
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_THRIFT_SESSION]') AND TYPE IN (N'U'))
+CREATE TABLE IDN_THRIFT_SESSION (
+ SESSION_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME VARCHAR(255) NOT NULL,
+ LAST_MODIFIED_TIME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (SESSION_ID)
+);
+
+-- End of IDN Tables --
+
+
+-- Start of IDN-APPLICATION-MGT Tables--
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_APP]') AND TYPE IN (N'U'))
+CREATE TABLE SP_APP (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE(APP_NAME, TENANT_ID);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_INBOUND_AUTH]') AND TYPE IN (N'U'))
+CREATE TABLE SP_INBOUND_AUTH (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255) NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_AUTH_STEP]') AND TYPE IN (N'U'))
+CREATE TABLE SP_AUTH_STEP (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_FEDERATED_IDP]') AND TYPE IN (N'U'))
+CREATE TABLE SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID)
+);
+
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_CLAIM_MAPPING]') AND TYPE IN (N'U'))
+CREATE TABLE SP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_ROLE_MAPPING]') AND TYPE IN (N'U'))
+CREATE TABLE SP_ROLE_MAPPING (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_REQ_PATH_AUTHENTICATOR]') AND TYPE IN (N'U'))
+CREATE TABLE SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[SP_PROVISIONING_CONNECTOR]') AND TYPE IN (N'U'))
+CREATE TABLE SP_PROVISIONING_CONNECTOR (
+ ID INTEGER NOT NULL IDENTITY(1,1),
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ BLOCKING CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID)
+);
+
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP]') AND TYPE IN (N'U'))
+CREATE TABLE IDP (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '1',
+ IS_PRIMARY CHAR(1) NOT NULL DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE VARBINARY(MAX),
+ CERTIFICATE VARBINARY(MAX),
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR (1) NOT NULL DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR (1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) NOT NULL DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) NOT NULL DEFAULT '0',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME)
+);
+
+INSERT INTO IDP (TENANT_ID, NAME, HOME_REALM_ID) VALUES (-1234, 'LOCAL', 'localhost');
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_ROLE]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_ROLE (
+ ID INTEGER IDENTITY(1,1),
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_ROLE_MAPPING]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_ROLE_MAPPING (
+ ID INTEGER IDENTITY(1,1),
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_CLAIM]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_CLAIM (
+ ID INTEGER IDENTITY(1,1),
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_CLAIM_MAPPING]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_CLAIM_MAPPING (
+ ID INTEGER IDENTITY(1,1),
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_AUTHENTICATOR]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_AUTHENTICATOR (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+
+INSERT INTO IDP_AUTHENTICATOR (TENANT_ID, IDP_ID, NAME) VALUES (-1234, 1, 'samlsso');
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_AUTHENTICATOR_PROPERTY]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_PROVISIONING_CONFIG]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_PROVISIONING_CONFIG (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_PROV_CONFIG_PROPERTY]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE VARBINARY(MAX),
+ PROPERTY_TYPE CHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_PROVISIONING_ENTITY]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_PROVISIONING_ENTITY (
+ ID INTEGER IDENTITY(1,1),
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDP_LOCAL_CLAIM]') AND TYPE IN (N'U'))
+CREATE TABLE IDP_LOCAL_CLAIM (
+ ID INTEGER IDENTITY(1,1),
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+-- End of IDN-APPLICATION-MGT Tables--
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD STATE VARCHAR(30) DEFAULT 'COMPLETED';
+
+DECLARE @SQL VARCHAR(4000);
+SET @SQL = 'ALTER TABLE |TABLE_NAME| DROP CONSTRAINT |CONSTRAINT_NAME|';
+
+SET @SQL = REPLACE(@SQL, '|CONSTRAINT_NAME|',( SELECT name FROM sysobjects WHERE xtype = 'PK' AND parent_obj = OBJECT_ID('AM_APPLICATION_KEY_MAPPING')));
+SET @SQL = REPLACE(@SQL,'|TABLE_NAME|','AM_APPLICATION_KEY_MAPPING');
+EXEC (@SQL);
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD PRIMARY KEY(APPLICATION_ID,KEY_TYPE);
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ALTER COLUMN CONSUMER_KEY VARCHAR(512) NULL;
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[AM_APPLICATION_REGISTRATION]') AND TYPE IN (N'U'))
+CREATE TABLE AM_APPLICATION_REGISTRATION (
+ REG_ID INTEGER IDENTITY(1,1),
+ SUBSCRIBER_ID INTEGER,
+ WF_REF VARCHAR(255) NOT NULL,
+ APP_ID INTEGER,
+ TOKEN_TYPE VARCHAR(30),
+ ALLOWED_DOMAINS VARCHAR(256),
+ VALIDITY_PERIOD BIGINT,
+ UNIQUE (SUBSCRIBER_ID,APP_ID,TOKEN_TYPE),
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON DELETE NO ACTION,
+ FOREIGN KEY(APP_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON UPDATE CASCADE ON DELETE NO ACTION,
+ PRIMARY KEY (REG_ID)
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[AM_API_SCOPES]') AND TYPE IN (N'U'))
+CREATE TABLE AM_API_SCOPES (
+ API_ID INTEGER NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[AM_API_DEFAULT_VERSION]') AND TYPE IN (N'U'))
+CREATE TABLE AM_API_DEFAULT_VERSION (
+ DEFAULT_VERSION_ID INT IDENTITY(1,1),
+ API_NAME VARCHAR(256) NOT NULL ,
+ API_PROVIDER VARCHAR(256) NOT NULL ,
+ DEFAULT_API_VERSION VARCHAR(30) ,
+ PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
+ PRIMARY KEY (DEFAULT_VERSION_ID)
+);
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql
new file mode 100644
index 0000000000..2766074ba7
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql
@@ -0,0 +1,383 @@
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP LOGIN_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP ERROR_PAGE_URL;
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP CONSENT_PAGE_URL;
+
+ALTER TABLE AM_API_URL_MAPPING ADD MEDIATION_SCRIPT BLOB DEFAULT NULL;
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE (
+ SCOPE_ID INT(11) NOT NULL AUTO_INCREMENT,
+ SCOPE_KEY VARCHAR(100) NOT NULL,
+ NAME VARCHAR(255) NULL,
+ DESCRIPTION VARCHAR(512) NULL,
+ TENANT_ID INT(11) NOT NULL DEFAULT 0,
+ ROLES VARCHAR (500) NULL,
+ PRIMARY KEY (SCOPE_ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR(255) NOT NULL,
+ SCOPE_ID INTEGER (11) NOT NULL,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_SCIM_GROUP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR(255) NOT NULL,
+ ATTR_NAME VARCHAR(1024) NOT NULL,
+ ATTR_VALUE VARCHAR(1024),
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_SCIM_PROVIDER (
+ CONSUMER_ID VARCHAR(255) NOT NULL,
+ PROVIDER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_PASSWORD VARCHAR(255) NOT NULL,
+ USER_URL VARCHAR(1024) NOT NULL,
+ GROUP_URL VARCHAR(1024),
+ BULK_URL VARCHAR(1024),
+ PRIMARY KEY (CONSUMER_ID,PROVIDER_ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME TIMESTAMP,
+ PRIMARY KEY (USER_NAME, TENANT_ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN TIMESTAMP NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ PRIMARY KEY (HANDLE)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_STS_STORE (
+ ID INTEGER AUTO_INCREMENT,
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT BLOB(1024) NOT NULL,
+ CREATE_DATE TIMESTAMP NOT NULL,
+ EXPIRE_DATE TIMESTAMP NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDN_THRIFT_SESSION (
+ SESSION_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME VARCHAR(255) NOT NULL,
+ LAST_MODIFIED_TIME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (SESSION_ID)
+)ENGINE INNODB;
+
+-- End of IDN Tables --
+
+
+-- Start of IDN-APPLICATION-MGT Tables--
+
+CREATE TABLE IF NOT EXISTS SP_APP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE(APP_NAME, TENANT_ID);
+
+CREATE TABLE IF NOT EXISTS SP_INBOUND_AUTH (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255) NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_AUTH_STEP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_ROLE_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_PROVISIONING_CONNECTOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ BLOCKING CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE INNODB;
+
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '1',
+ IS_PRIMARY CHAR(1) NOT NULL DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE MEDIUMBLOB,
+ CERTIFICATE BLOB,
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR (1) NOT NULL DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR (1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) NOT NULL DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) NOT NULL DEFAULT '0',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME)
+)ENGINE INNODB;
+
+INSERT INTO IDP (TENANT_ID, NAME, HOME_REALM_ID) VALUES (-1234, 'LOCAL', 'localhost');
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+INSERT INTO IDP_AUTHENTICATOR (TENANT_ID, IDP_ID, NAME) VALUES (-1234, 1, 'samlsso');
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_CONFIG (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE BLOB,
+ PROPERTY_TYPE CHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_ENTITY (
+ ID INTEGER AUTO_INCREMENT,
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS IDP_LOCAL_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE INNODB;
+-- End of IDN-APPLICATION-MGT Tables--
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD STATE VARCHAR(30) DEFAULT 'COMPLETED';
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING DROP PRIMARY KEY, ADD PRIMARY KEY(APPLICATION_ID,KEY_TYPE);
+
+CREATE TABLE IF NOT EXISTS AM_APPLICATION_REGISTRATION (
+ REG_ID INT AUTO_INCREMENT,
+ SUBSCRIBER_ID INT,
+ WF_REF VARCHAR(255) NOT NULL,
+ APP_ID INT,
+ TOKEN_TYPE VARCHAR(30),
+ ALLOWED_DOMAINS VARCHAR(256),
+ VALIDITY_PERIOD BIGINT,
+ UNIQUE (SUBSCRIBER_ID,APP_ID,TOKEN_TYPE),
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON UPDATE CASCADE ON DELETE RESTRICT,
+ FOREIGN KEY(APP_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY (REG_ID)
+)ENGINE INNODB;
+
+CREATE TABLE IF NOT EXISTS AM_API_SCOPES (
+ API_ID INTEGER NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE ON UPDATE CASCADE
+)ENGINE = INNODB;
+
+CREATE TABLE IF NOT EXISTS AM_API_DEFAULT_VERSION (
+ DEFAULT_VERSION_ID INT AUTO_INCREMENT,
+ API_NAME VARCHAR(256) NOT NULL ,
+ API_PROVIDER VARCHAR(256) NOT NULL ,
+ DEFAULT_API_VERSION VARCHAR(30) ,
+ PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
+ PRIMARY KEY (DEFAULT_VERSION_ID)
+);
diff --git a/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql
new file mode 100644
index 0000000000..0809fe4bc2
--- /dev/null
+++ b/modules/distribution/resources/migration-1.6.0_to_1.7.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql
@@ -0,0 +1,697 @@
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN LOGIN_PAGE_URL
+/
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN ERROR_PAGE_URL
+/
+ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN CONSENT_PAGE_URL
+/
+/*
+DROP INDEX IDX_AT_CK_AU
+/
+DROP SEQUENCE IDP_SEQUENCE
+/
+DROP SEQUENCE IDP_ROLE_MAPPINGS_SEQUENCE
+/
+DROP SEQUENCE IDP_ROLES_SEQUENCE
+/
+ALTER TABLE UM_TENANT_IDP_ROLE_MAPPINGS DROP PRIMARY KEY CASCADE
+/
+ALTER TABLE UM_TENANT_IDP_ROLES DROP PRIMARY KEY CASCADE
+/
+ALTER TABLE IDP_BASE_TABLE DROP PRIMARY KEY CASCADE
+/
+ALTER TABLE UM_TENANT_IDP DROP PRIMARY KEY CASCADE
+/
+DROP TABLE UM_TENANT_IDP_ROLE_MAPPINGS CASCADE CONSTRAINTS
+/
+DROP TABLE UM_TENANT_IDP_ROLES CASCADE CONSTRAINTS
+/
+DROP TABLE UM_TENANT_IDP CASCADE CONSTRAINTS
+/
+DROP TABLE IDP_BASE_TABLE CASCADE CONSTRAINTS
+/
+*/
+ALTER TABLE AM_API_URL_MAPPING ADD (MEDIATION_SCRIPT BLOB DEFAULT NULL)
+/
+CREATE TABLE IDN_OAUTH2_SCOPE (
+ SCOPE_ID INTEGER,
+ SCOPE_KEY VARCHAR2 (100) NOT NULL,
+ NAME VARCHAR2 (255) NULL,
+ DESCRIPTION VARCHAR2 (512) NULL,
+ TENANT_ID INTEGER DEFAULT 0 NOT NULL,
+ ROLES VARCHAR2 (500) NULL,
+ PRIMARY KEY (SCOPE_ID))
+/
+CREATE SEQUENCE IDN_OAUTH2_SCOPE_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDN_OAUTH2_SCOPE_TRIGGER
+ BEFORE INSERT
+ ON IDN_OAUTH2_SCOPE
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDN_OAUTH2_SCOPE_SEQUENCE.nextval INTO :NEW.SCOPE_ID FROM dual;
+ END;
+/
+CREATE TABLE IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR2 (255) NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE
+)
+/
+CREATE TABLE IDN_SCIM_GROUP (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR2(255) NOT NULL,
+ ATTR_NAME VARCHAR2(1024) NOT NULL,
+ ATTR_VALUE VARCHAR2(1024),
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE IDN_SCIM_GROUP_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDN_SCIM_GROUP_TRIGGER
+ BEFORE INSERT
+ ON IDN_SCIM_GROUP
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDN_SCIM_GROUP_SEQUENCE.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDN_SCIM_PROVIDER (
+ CONSUMER_ID VARCHAR(255) NOT NULL,
+ PROVIDER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_PASSWORD VARCHAR(255) NOT NULL,
+ USER_URL VARCHAR(1024) NOT NULL,
+ GROUP_URL VARCHAR(1024),
+ BULK_URL VARCHAR(1024),
+ PRIMARY KEY (CONSUMER_ID,PROVIDER_ID))
+/
+CREATE TABLE IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME TIMESTAMP,
+ PRIMARY KEY (USER_NAME, TENANT_ID))
+/
+CREATE TABLE IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN TIMESTAMP NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ PRIMARY KEY (HANDLE))
+/
+CREATE TABLE IDN_STS_STORE (
+ ID INTEGER,
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT BLOB NOT NULL,
+ CREATE_DATE TIMESTAMP NOT NULL,
+ EXPIRE_DATE TIMESTAMP NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE IDN_STS_STORE_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDN_STS_STORE_TRIGGER
+ BEFORE INSERT
+ ON IDN_STS_STORE
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDN_STS_STORE_SEQUENCE.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY))
+/
+CREATE TABLE IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA))
+/
+-- End of IDN Tables --
+
+
+-- Start of IDN-APPLICATION-MGT Tables--
+
+CREATE TABLE SP_APP (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_APP_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_APP_TRIG
+ BEFORE INSERT
+ ON SP_APP
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_APP_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE UNIQUE INDEX APPLICATION_NAME_CONSTRAINT ON SP_APP(APP_NAME, TENANT_ID)
+/
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE (APP_NAME, TENANT_ID) USING INDEX APPLICATION_NAME_CONSTRAINT
+/
+CREATE TABLE SP_INBOUND_AUTH (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255) NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_INBOUND_AUTH_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_INBOUND_AUTH_TRIG
+ BEFORE INSERT
+ ON SP_INBOUND_AUTH
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_INBOUND_AUTH_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_AUTH_STEP (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_AUTH_STEP_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_AUTH_STEP_TRIG
+ BEFORE INSERT
+ ON SP_AUTH_STEP
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_AUTH_STEP_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID))
+/
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_CLAIM_MAPPING (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_CLAIM_MAPPING_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_CLAIM_MAPPING_TRIG
+ BEFORE INSERT
+ ON SP_CLAIM_MAPPING
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_CLAIM_MAPPING_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_ROLE_MAPPING (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_ROLE_MAPPING_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_ROLE_MAPPING_TRIG
+ BEFORE INSERT
+ ON SP_ROLE_MAPPING
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_ROLE_MAPPING_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_REQ_PATH_AUTH_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_REQ_PATH_AUTH_TRIG
+ BEFORE INSERT
+ ON SP_REQ_PATH_AUTHENTICATOR
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_REQ_PATH_AUTH_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE SP_PROVISIONING_CONNECTOR (
+ ID INTEGER,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) DEFAULT '0',
+ BLOCKING CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID))
+/
+CREATE SEQUENCE SP_PROV_CONNECTOR_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER SP_PROV_CONNECTOR_TRIG
+ BEFORE INSERT
+ ON SP_PROVISIONING_CONNECTOR
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT SP_PROV_CONNECTOR_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+/
+CREATE TABLE IDP (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) DEFAULT '1',
+ IS_PRIMARY CHAR(1) DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE BLOB,
+ CERTIFICATE BLOB,
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR (1) DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR (1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ DISPLAY_NAME VARCHAR(254),
+ UNIQUE (TENANT_ID, NAME))
+/
+CREATE SEQUENCE IDP_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_TRIG
+ BEFORE INSERT
+ ON IDP
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+INSERT INTO IDP (TENANT_ID, NAME, HOME_REALM_ID) VALUES (-1234, 'LOCAL', 'localhost')
+/
+CREATE TABLE IDP_ROLE (
+ ID INTEGER,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_ROLE_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_ROLE_TRIG
+ BEFORE INSERT
+ ON IDP_ROLE
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_ROLE_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_ROLE_MAPPING (
+ ID INTEGER,
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_ROLE_MAPPING_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_ROLE_MAPPING_TRIG
+ BEFORE INSERT
+ ON IDP_ROLE_MAPPING
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_ROLE_MAPPING_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_CLAIM (
+ ID INTEGER,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE)
+/
+CREATE TABLE IDP_CLAIM_MAPPING (
+ ID INTEGER,
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_CLAIM_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_CLAIM_TRIG
+ BEFORE INSERT
+ ON IDP_CLAIM
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_CLAIM_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE SEQUENCE IDP_CLAIM_MAPPING_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_CLAIM_MAPPING_TRIG
+ BEFORE INSERT
+ ON IDP_CLAIM_MAPPING
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_CLAIM_MAPPING_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_AUTHENTICATOR (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_AUTHENTICATOR_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_AUTHENTICATOR_TRIG
+ BEFORE INSERT
+ ON IDP_AUTHENTICATOR
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_AUTHENTICATOR_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+INSERT INTO IDP_AUTHENTICATOR (TENANT_ID, IDP_ID, NAME) VALUES (-1234, 1, 'saml2sso')
+/
+CREATE TABLE IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_AUTHENTICATOR_PROP_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_AUTHENTICATOR_PROP_TRIG
+ BEFORE INSERT
+ ON IDP_AUTHENTICATOR_PROPERTY
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_AUTHENTICATOR_PROP_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_PROVISIONING_CONFIG (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_PROVISIONING_CONFIG_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_PROVISIONING_CONFIG_TRIG
+ BEFORE INSERT
+ ON IDP_PROVISIONING_CONFIG
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_PROVISIONING_CONFIG_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE BLOB,
+ PROPERTY_TYPE CHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_PROV_CONFIG_PROP_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_PROV_CONFIG_PROP_TRIG
+ BEFORE INSERT
+ ON IDP_PROV_CONFIG_PROPERTY
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_PROV_CONFIG_PROP_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_PROVISIONING_ENTITY (
+ ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_PROV_ENTITY_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_PROV_ENTITY_TRIG
+ BEFORE INSERT
+ ON IDP_PROVISIONING_ENTITY
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_PROV_ENTITY_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+CREATE TABLE IDP_LOCAL_CLAIM (
+ ID INTEGER,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE)
+/
+CREATE SEQUENCE IDP_LOCAL_CLAIM_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER IDP_LOCAL_CLAIM_TRIG
+ BEFORE INSERT
+ ON IDP_LOCAL_CLAIM
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT IDP_LOCAL_CLAIM_SEQ.nextval INTO :NEW.ID FROM dual;
+ END;
+/
+
+-- End of IDN-APPLICATION-MGT Tables--
+
+ALTER TABLE AM_APPLICATION_KEY_MAPPING DROP PRIMARY KEY CASCADE
+/
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD (STATE VARCHAR2(30 BYTE) DEFAULT 'COMPLETED' NOT NULL)
+/
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD PRIMARY KEY (APPLICATION_ID, KEY_TYPE)
+/
+CREATE TABLE AM_APPLICATION_REGISTRATION (
+ REG_ID INTEGER ,
+ SUBSCRIBER_ID INTEGER,
+ WF_REF VARCHAR2(255) NOT NULL,
+ APP_ID INTEGER,
+ TOKEN_TYPE VARCHAR2(30),
+ ALLOWED_DOMAINS VARCHAR2(256),
+ VALIDITY_PERIOD NUMBER(19),
+ UNIQUE (SUBSCRIBER_ID,APP_ID,TOKEN_TYPE),
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID),
+ FOREIGN KEY(APP_ID) REFERENCES AM_APPLICATION(APPLICATION_ID),
+ PRIMARY KEY (REG_ID)
+)
+/
+CREATE SEQUENCE AM_APP_REGISTRATION_SEQUENCE START WITH 1 INCREMENT BY 1
+/
+CREATE OR REPLACE TRIGGER AM_APP_REGISTRATION_TRIGGER
+ BEFORE INSERT
+ ON AM_APPLICATION_REGISTRATION
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+BEGIN
+ SELECT AM_APP_REGISTRATION_SEQUENCE.nextval INTO :NEW.REG_ID FROM dual;
+ END;
+/
+CREATE TABLE AM_API_SCOPES (
+ API_ID INTEGER NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE
+)
+/
+CREATE TABLE AM_API_DEFAULT_VERSION (
+ DEFAULT_VERSION_ID NUMBER,
+ API_NAME VARCHAR(256) NOT NULL ,
+ API_PROVIDER VARCHAR(256) NOT NULL ,
+ DEFAULT_API_VERSION VARCHAR(30) ,
+ PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
+ PRIMARY KEY (DEFAULT_VERSION_ID)
+)
+/
+CREATE SEQUENCE AM_API_DEFAULT_VERSION_SEQ START WITH 1 INCREMENT BY 1 NOCACHE
+/
+CREATE OR REPLACE TRIGGER AM_API_DEFAULT_VERSION_TRG
+ BEFORE INSERT
+ ON AM_API_DEFAULT_VERSION
+ REFERENCING NEW AS NEW
+ FOR EACH ROW
+ BEGIN
+ SELECT AM_API_DEFAULT_VERSION_SEQ.nextval INTO :NEW.DEFAULT_VERSION_ID FROM dual;
+ END;
+/
+CREATE OR REPLACE FUNCTION DROP_ALL_SCHEMA_OBJECTS RETURN NUMBER AS
+PRAGMA AUTONOMOUS_TRANSACTION;
+cursor c_get_objects is
+ select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name
+ from user_objects
+ where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW')
+ order by object_type;
+cursor c_get_objects_type is
+ select object_type, '"'||object_name||'"' obj_name
+ from user_objects
+ where object_type in ('TYPE');
+BEGIN
+ begin
+ for object_rec in c_get_objects loop
+ execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
+ end loop;
+ for object_rec in c_get_objects_type loop
+ begin
+ execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
+ end;
+ end loop;
+ end;
+ RETURN 0;
+END DROP_ALL_SCHEMA_OBJECTS;
+/
+ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN MODIFY(TOKEN_SCOPE VARCHAR2(2048 BYTE))
+/
+DECLARE
+statement VARCHAR2(2000);
+constr_name VARCHAR2(30);
+BEGIN
+ SELECT CONSTRAINT_NAME INTO constr_name FROM USER_CONS_COLUMNS WHERE table_name = 'IDN_OAUTH1A_ACCESS_TOKEN' AND column_name = 'CONSUMER_KEY';
+ statement := 'ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN DROP CONSTRAINT '|| constr_name;
+ EXECUTE IMMEDIATE(statement);
+END;
+/
+ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN ADD FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS (CONSUMER_KEY) ON DELETE CASCADE
+/
+DECLARE
+statement VARCHAR2(2000);
+constr_name VARCHAR2(30);
+BEGIN
+ SELECT CONSTRAINT_NAME INTO constr_name FROM USER_CONS_COLUMNS WHERE table_name = 'IDN_OAUTH1A_REQUEST_TOKEN' AND column_name = 'CONSUMER_KEY';
+ statement := 'ALTER TABLE IDN_OAUTH1A_REQUEST_TOKEN DROP CONSTRAINT '|| constr_name;
+ EXECUTE IMMEDIATE(statement);
+END;
+/
+ALTER TABLE IDN_OAUTH1A_REQUEST_TOKEN ADD FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS (CONSUMER_KEY) ON DELETE CASCADE
+/
+DECLARE
+statement VARCHAR2(2000);
+constr_name VARCHAR2(30);
+BEGIN
+ SELECT CONSTRAINT_NAME INTO constr_name FROM USER_CONS_COLUMNS WHERE table_name = 'IDN_OAUTH2_AUTHORIZATION_CODE' AND column_name = 'CONSUMER_KEY';
+ statement := 'ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE DROP CONSTRAINT '|| constr_name;
+ EXECUTE IMMEDIATE(statement);
+END;
+/
+ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE ADD FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS (CONSUMER_KEY) ON DELETE CASCADE
+/
+
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/pom.xml b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/pom.xml
new file mode 100644
index 0000000000..dd9c729238
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/pom.xml
@@ -0,0 +1,164 @@
+
+
+ 4.0.0
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.migrate.client
+ 1.8.0
+ bundle
+
+
+
+ wso2-nexus
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/groups/wso2-public/
+
+ true
+ daily
+ ignore
+
+
+
+ wso2.releases
+ WSO2 internal Repository
+ http://maven.wso2.org/nexus/content/repositories/releases/
+
+ true
+ daily
+ ignore
+
+
+
+ wso2.snapshots
+ WSO2 Snapshot Repository
+ http://maven.wso2.org/nexus/content/repositories/snapshots/
+
+ true
+ daily
+
+
+ false
+
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+ ${org.apache.felix.src.plugin.version}
+
+
+ generate-scr-scrdescriptor
+
+ scr
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+
+ 1.6
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+ ${org.apache.felix.budnle.plugin.version}
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.apimgt.migration.client.internal
+
+
+ org.apache.commons.logging.*; version=${org.wso2.carbon.logging.import.version},
+ org.wso2.carbon.registry.core.* version=${org.wso2.carbon.registry.core.import.version},
+ org.wso2.carbon.apimgt.impl,
+ *;resolution:=optional
+
+ *
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.5.3
+
+
+ dist
+ package
+
+ attached
+
+
+ false
+ src/assembly/dist.xml
+ wso2-api-migration-client-${project.version}
+
+
+
+
+
+
+
+
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core.services
+ ${org.wso2.carbon.core.services.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+ ${org.wso2.carbon.logging.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+ ${org.wso2.carbon.registry.core.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+ ${org.wso2.carbon.utils.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.impl
+ 1.2.3
+
+
+ org.wso2.carbon
+ org.wso2.carbon.apimgt.api
+ 1.2.3
+
+
+
+
+ UTF-8
+ 1.7.2
+ 2.5.3
+ 4.2.0
+ 4.2.0
+ 1.0.4
+ 4.2.0
+ 4.2.0
+ 1.0.1
+
+
+
+
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/assembly/dist.xml b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/assembly/dist.xml
new file mode 100644
index 0000000000..e6caed26d2
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/assembly/dist.xml
@@ -0,0 +1,27 @@
+
+ dist
+
+ zip
+
+ false
+
+
+ ${project.basedir}
+
+
+ README*
+
+
+
+ ${project.basedir}/src/main/resources
+
+
+
+ ${project.build.directory}
+
+
+ *.jar
+
+
+
+
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java
new file mode 100644
index 0000000000..6250855b6e
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/APIMigrationException.java
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2015, 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.migration;
+
+/**
+ * A custom exception handler class to handle all the migration exceptions
+ */
+public class APIMigrationException extends Exception {
+
+ public APIMigrationException(String msg) {
+ super(msg);
+ }
+
+ public APIMigrationException(String msg, Throwable e) {
+ super(msg, e);
+ }
+
+ public APIMigrationException(Throwable throwable) {
+ super(throwable);
+ }
+}
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom17to18.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom17to18.java
new file mode 100644
index 0000000000..bcbf424df8
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom17to18.java
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.api.APIManagementException;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.internal.ServiceHolder;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
+import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
+import org.wso2.carbon.governance.api.util.GovernanceUtils;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.core.Registry;
+import org.wso2.carbon.registry.core.session.UserRegistry;
+import org.wso2.carbon.user.api.Tenant;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.tenant.TenantManager;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * This class contains all the methods which is used to migrate APIs from APIManager 1.8.0 to APIManager 1.9.0.
+ * The migration performs in database, registry and file system
+ */
+
+@SuppressWarnings("unchecked")
+public class MigrateFrom17to18 {
+
+ private static final Log log = LogFactory.getLog(MigrateFrom17to18.class);
+ private List tenantsArray;
+
+ public MigrateFrom17to18(String tenantArguments) throws UserStoreException {
+ TenantManager tenantManager = ServiceHolder.getRealmService().getTenantManager();
+
+ if (tenantArguments != null) { // Tenant arguments have been provided so need to load specific ones
+ tenantArguments = tenantArguments.replaceAll("\\s", ""); // Remove spaces and tabs
+
+ tenantsArray = new ArrayList();
+
+ if (tenantArguments.contains(",")) { // Multiple arguments specified
+ String[] parts = tenantArguments.split(",");
+
+ for (int i = 0; i < parts.length; ++i) {
+ if (parts[i].length() > 0) {
+ populateTenants(tenantManager, tenantsArray, parts[i]);
+ }
+ }
+ } else { // Only single argument provided
+ populateTenants(tenantManager, tenantsArray, tenantArguments);
+ }
+ } else { // Load all tenants
+ tenantsArray = new ArrayList(Arrays.asList(tenantManager.getAllTenants()));
+ Tenant superTenant = new Tenant();
+ superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
+ tenantsArray.add(superTenant);
+ }
+ }
+
+ private void populateTenants(TenantManager tenantManager, List tenantList, String argument) throws UserStoreException {
+ log.debug("Argument provided : " + argument);
+
+ if (argument.contains("@")) { // Username provided as argument
+ int tenantID = tenantManager.getTenantId(argument);
+
+ if (tenantID != -1) {
+ tenantList.add(tenantManager.getTenant(tenantID));
+ } else {
+ log.error("Tenant does not exist for username " + argument);
+ }
+ } else { // Domain name provided as argument
+ Tenant[] tenants = tenantManager.getAllTenantsForTenantDomainStr(argument);
+
+ if (tenants.length > 0) {
+ tenantList.addAll(Arrays.asList(tenants));
+ } else {
+ log.error("Tenant does not exist for domain " + argument);
+ }
+ }
+ }
+
+
+ /**
+ * This method is used to migrate all registry resources
+ * This migrates swagger resources and rxts
+ *
+ * @throws APIMigrationException
+ */
+ public void registryResourceMigration() throws APIMigrationException {
+ swaggerMigration();
+ }
+
+
+ /**
+ * This method is used to migrate swagger v1.2 resources to swagger v2.0 resource
+ * This reads the swagger v1.2 doc from the registry and creates swagger v2.0 doc
+ *
+ * @throws APIMigrationException
+ */
+ void swaggerMigration() {
+ log.info("Swagger migration for API Manager 1.9.0 started.");
+ boolean isTenantFlowStarted = false;
+
+ for (Tenant tenant : tenantsArray) {
+ if (log.isDebugEnabled()) {
+ log.debug("Start swaggerMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ isTenantFlowStarted = true;
+
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain());
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId());
+
+ Registry registry = getRegistry(tenant);
+
+ if (registry != null) {
+ GenericArtifactManager artifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY);
+ GenericArtifact[] artifacts = getGenericArtifacts(registry, artifactManager);
+
+ if (artifacts != null) {
+ RegistryMigration.swagger12Migration(artifacts, registry, tenant);
+ }
+ }
+ } catch (APIManagementException e) {
+ log.error("Error when getting GenericArtifactManager for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+
+ log.debug("End swaggerMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ log.info("Swagger resource migration done for all the tenants.");
+ }
+
+ private Registry getRegistry(Tenant tenant) {
+ log.debug("Calling getRegistry");
+ Registry registry = null;
+
+ try {
+ String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getRealmConfiguration().getAdminUserName();
+ log.debug("Tenant admin username : " + adminName);
+ registry = ServiceHolder.getRegistryService().getGovernanceUserRegistry(adminName, tenant.getId());
+ ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenant.getId());
+ } catch (UserStoreException e) {
+ log.error("Error occurred while reading tenant information of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (RegistryException e) {
+ log.error("Error occurred while accessing the registry of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+
+ return registry;
+ }
+
+
+ private GenericArtifact[] getGenericArtifacts(Registry registry, GenericArtifactManager manager) {
+ log.debug("Calling getGenericArtifacts");
+ GenericArtifact[] artifacts = null;
+
+ try {
+ if (GovernanceUtils.findGovernanceArtifactConfiguration(Constants.API, registry) != null) {
+ GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
+ artifacts = manager.getAllGenericArtifacts();
+
+ log.debug("Total number of api artifacts : " + artifacts.length);
+ } else {
+ log.debug("API artifacts do not exist in registry");
+ }
+
+ } catch (RegistryException e) {
+ log.error("Error occurred when getting GenericArtifacts from registry", e);
+ }
+
+ return artifacts;
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
new file mode 100644
index 0000000000..a8949f1140
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
@@ -0,0 +1,206 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.wso2.carbon.utils.dbcreator.DatabaseCreator;
+
+import javax.sql.DataSource;
+import java.io.*;
+import java.sql.*;
+import java.util.StringTokenizer;
+
+public class MigrationDBCreator extends DatabaseCreator {
+
+ private static final Log log = LogFactory.getLog(MigrationDBCreator.class);
+ private DataSource dataSource;
+ private String delimiter = ";";
+ private Connection connection = null;
+ Statement statement;
+
+ public MigrationDBCreator(DataSource dataSource) {
+ super(dataSource);
+ this.dataSource = dataSource;
+ }
+
+ @Override
+ protected String getDbScriptLocation(String databaseType) {
+ String scriptName = databaseType + ".sql";
+ String resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.8.0_to_1.9.0/";
+ if (log.isDebugEnabled()) {
+ log.debug("Loading database script :" + scriptName);
+ }
+ return resourcePath + scriptName;
+ }
+
+ @Override
+ public void createRegistryDatabase() throws SQLException, APIMigrationException {
+ try {
+ connection = dataSource.getConnection();
+ connection.setAutoCommit(false);
+ statement = connection.createStatement();
+ executeSQLScript();
+ connection.commit();
+ if (log.isTraceEnabled()) {
+ log.trace("Registry tables are created successfully.");
+ }
+ } catch (SQLException e) {
+ ResourceUtil.handleException("Error occurred while migrating the database", e);
+ } catch (Exception e) {
+ /* executeSQLScript throws generic Exception because DatabaseCreator.getDatabaseType superclass throws */
+ ResourceUtil.handleException("Error occurred while executing sql script", e);
+ } finally {
+ if (connection != null) {
+ connection.close();
+ }
+
+ }
+ }
+
+
+ //org.wso2.carbon.utils.dbcreator.DatabaseCreator.getDatabaseType throws generic Exception
+ private void executeSQLScript() throws Exception {
+ String databaseType = DatabaseCreator.getDatabaseType(this.connection);
+ boolean keepFormat = false;
+ if (Constants.DB_TYPE_ORACLE.equals(databaseType)) {
+ delimiter = "/";
+ } else if (Constants.DB_TYPE_DB2.equals(databaseType)) {
+ delimiter = "/";
+ } else if (Constants.DB_TYPE_OPENEDGE.equals(databaseType)) {
+ delimiter = "/";
+ keepFormat = true;
+ }
+
+ String dbscriptName = getDbScriptLocation(databaseType);
+
+ StringBuffer sql = new StringBuffer();
+ BufferedReader reader = null;
+
+ try {
+ InputStream is = new FileInputStream(dbscriptName);
+ reader = new BufferedReader(new InputStreamReader(is, "UTF8"));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (!keepFormat) {
+ if (line.startsWith("//")) {
+ continue;
+ }
+ if (line.startsWith("--")) {
+ continue;
+ }
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if ("REM".equalsIgnoreCase(token)) {
+ continue;
+ }
+ }
+ }
+ sql.append(keepFormat ? "\n" : " ").append(line);
+
+ // SQL defines "--" as a comment to EOL
+ // and in Oracle it may contain a hint
+ // so we cannot just remove it, instead we must end it
+ if (!keepFormat && line.indexOf("--") >= 0) {
+ sql.append("\n");
+ }
+ if ((checkStringBufferEndsWith(sql, delimiter))) {
+ executeSQL(sql.substring(0, sql.length() - delimiter.length()));
+ sql.replace(0, sql.length(), "");
+ }
+ }
+ // Catch any statements not followed by ;
+ if (sql.length() > 0) {
+ executeSQL(sql.toString());
+ }
+ } catch (IOException e) {
+ log.error("Error occurred while executing SQL script for creating registry database", e);
+ throw new APIMigrationException("Error occurred while executing SQL script for creating registry database", e);
+
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+
+ private void executeSQL(String sql) throws APIMigrationException {
+ // Check and ignore empty statements
+ if ("".equals(sql.trim())) {
+ return;
+ }
+
+ ResultSet resultSet = null;
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("SQL : " + sql);
+ }
+
+ boolean returnedValue;
+ int updateCount;
+ int updateCountTotal = 0;
+ returnedValue = statement.execute(sql);
+ updateCount = statement.getUpdateCount();
+ resultSet = statement.getResultSet();
+ do {
+ if (!returnedValue && updateCount != -1) {
+ updateCountTotal += updateCount;
+ }
+ returnedValue = statement.getMoreResults();
+ if (returnedValue) {
+ updateCount = statement.getUpdateCount();
+ resultSet = statement.getResultSet();
+ }
+ } while (returnedValue);
+
+ if (log.isDebugEnabled()) {
+ log.debug(sql + " : " + updateCountTotal + " rows affected");
+ }
+ SQLWarning warning = connection.getWarnings();
+ while (warning != null) {
+ log.debug(warning + " sql warning");
+ warning = warning.getNextWarning();
+ }
+ connection.clearWarnings();
+ } catch (SQLException e) {
+ if (e.getSQLState().equals("X0Y32") || e.getSQLState().equals("42710")) {
+ // eliminating the table already exception for the derby and DB2 database types
+ if (log.isDebugEnabled()) {
+ log.info("Table Already Exists. Hence, skipping table creation");
+ }
+ } else {
+ throw new APIMigrationException("Error occurred while executing : " + sql, e);
+ }
+ } finally {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ log.error("Error occurred while closing result set.", e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java
new file mode 100644
index 0000000000..cb07af233b
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/RegistryMigration.java
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2015, 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.migration.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.wso2.carbon.apimgt.api.APIManagementException;
+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.URITemplate;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.internal.ServiceHolder;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.governance.api.exception.GovernanceException;
+import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
+import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.core.*;
+import org.wso2.carbon.user.api.Tenant;
+import org.wso2.carbon.user.api.UserStoreException;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+public class RegistryMigration {
+ private static final Log log = LogFactory.getLog(RegistryMigration.class);
+
+
+ public static void swagger12Migration(GenericArtifact[] artifacts, Registry registry, Tenant tenant) {
+ for (GenericArtifact artifact : artifacts) {
+ API api = getAPI(artifact);
+
+ if (api != null) {
+ APIIdentifier apiIdentifier = api.getId();
+ try {
+ String apiDef11Path = APIUtil.getAPIDefinitionFilePath(apiIdentifier.getApiName(),
+ apiIdentifier.getVersion(),
+ apiIdentifier.getProviderName());
+
+ if (!registry.resourceExists(apiDef11Path)) {
+ log.error("Swagger 1.1 document does not exist for api " +
+ apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + "-" + apiIdentifier.getProviderName() +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ continue;
+ }
+
+ Resource apiDef11 = registry.get(apiDef11Path);
+
+ String apiDef11Json = new String((byte[]) apiDef11.getContent(), "UTF8");
+
+ String swagger12location = ResourceUtil.getSwagger12ResourceLocation(apiIdentifier.getApiName(),
+ apiIdentifier.getVersion(),
+ apiIdentifier.getProviderName());
+
+ if(!registry.resourceExists(swagger12location)) {
+ log.error("Swagger 1.2 document does not exist for api " +
+ apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + "-" + apiIdentifier.getProviderName() +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ } else {
+ String allResourceFile = swagger12location + RegistryConstants.PATH_SEPARATOR
+ + Constants.API_DOC_12_ALL_RESOURCES_DOC;
+ if(registry.resourceExists(allResourceFile)) {
+ //no need to update the swagger doc 1.2 with 1.1 doc because it has already happened
+ //remove parameters to suit AM 1.8
+ log.debug("Remove unwanted parameters from swagger 1.2 doc for api : " + apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + "-" + apiIdentifier.getProviderName() +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ ResourceUtil.updateSwagger12ResourcesForAM18(new String[]{allResourceFile}, registry);
+ } else {
+ Resource swagger12Res = registry.get(swagger12location);
+ String[] resourcePaths = (String[]) swagger12Res.getContent();
+
+ log.debug("Updating swagger 1.2 resource using 1.1 for api : " + apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + "-" + apiIdentifier.getProviderName() +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ ResourceUtil.updateAPISwaggerDocs(apiDef11Json, resourcePaths, registry);
+ //remove paramaters to suit AM 1.8
+ ResourceUtil.updateSwagger12ResourcesForAM18(resourcePaths, registry);
+ log.debug("Remove unwanted parameters from swagger 1.2 doc for api : " + apiIdentifier.getApiName() + "-" + apiIdentifier.getVersion() + "-" + apiIdentifier.getProviderName() +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+ }
+ } catch (ParseException e) {
+ log.error("ParseException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (RegistryException e) {
+ log.error("RegistryException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (UnsupportedEncodingException e) {
+ log.error("UnsupportedEncodingException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (APIMigrationException e) {
+ log.error("APIMigrationException thrown when migrating swagger for api " + api.getId().getApiName() + "-" + api.getId().getVersion() + "-" + api.getId().getProviderName() + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+ }
+ }
+ }
+
+
+ private static API getAPI(GenericArtifact artifact) {
+ log.debug("Calling getAPI");
+ API api = null;
+
+ try {
+ api = APIUtil.getAPI(artifact);
+ } catch (APIManagementException e) {
+ log.error("Error when getting api artifact " + artifact.getId() + " from registry", e);
+ }
+
+ return api;
+ }
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
new file mode 100644
index 0000000000..9dbca05f61
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
@@ -0,0 +1,247 @@
+/*
+* Copyright (c) 2015, 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.migration.client.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.service.component.ComponentContext;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
+import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.MigrateFrom17to18;
+import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.utils.CarbonUtils;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+
+/**
+ * @scr.component name="org.wso2.carbon.apimgt.migration.client" immediate="true"
+ * @scr.reference name="realm.service"
+ * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
+ * policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
+ * @scr.reference name="registry.service"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService" cardinality="1..1"
+ * policy="dynamic" bind="setRegistryService" unbind="unsetRegistryService"
+ * @scr.reference name="registry.core.dscomponent"
+ * interface="org.wso2.carbon.registry.core.service.RegistryService" cardinality="1..1"
+ * policy="dynamic" bind="setRegistryService" unbind="unsetRegistryService"
+ * @scr.reference name="tenant.registryloader" interface="org.wso2.carbon.registry.core.service.TenantRegistryLoader" cardinality="1..1"
+ * policy="dynamic" bind="setTenantRegistryLoader" unbind="unsetTenantRegistryLoader"
+ * @scr.reference name="apim.configuration" interface="org.wso2.carbon.apimgt.impl.APIManagerConfigurationService" cardinality="1..1"
+ * policy="dynamic" bind="setApiManagerConfig" unbind="unsetApiManagerConfig"
+ */
+
+@SuppressWarnings("unused")
+public class APIMMigrationServiceComponent {
+
+ private static final Log log = LogFactory.getLog(APIMMigrationServiceComponent.class);
+
+ /**
+ * Method to activate bundle.
+ *
+ * @param context OSGi component context.
+ */
+ protected void activate(ComponentContext context) {
+ boolean isCorrectProductVersion = false;
+ try {
+ APIMgtDBUtil.initialize();
+ } catch (Exception e) {
+ //APIMgtDBUtil.initialize() throws generic exception
+ log.error("Error occurred while initializing DB Util ", e);
+ }
+
+ // Product and version validation
+ File carbonXmlConfig = new File(CarbonUtils.getServerXml());
+
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+
+ try {
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(carbonXmlConfig);
+
+ doc.getDocumentElement().normalize();
+
+ NodeList nameNodes = doc.getElementsByTagName("Name");
+
+ if (nameNodes.getLength() > 0) {
+ Element name = (Element) nameNodes.item(0);
+ if (Constants.APIM_PRODUCT_NAME.equals(name.getTextContent())) {
+ NodeList versionNodes = doc.getElementsByTagName("Version");
+
+ if (versionNodes.getLength() > 0) {
+ Element version = (Element) versionNodes.item(0);
+ if (Constants.VERSION_1_8.equals(version.getTextContent())) {
+ isCorrectProductVersion = true;
+ }
+ }
+ }
+ }
+ } catch (ParserConfigurationException e) {
+ log.error("ParserConfigurationException when processing carbon.xml", e);
+ } catch (SAXException e) {
+ log.error("SAXException when processing carbon.xml", e);
+ } catch (IOException e) {
+ log.error("IOException when processing carbon.xml", e);
+ }
+
+ String tenants = System.getProperty(Constants.ARG_MIGRATE_TENANTS);
+ boolean migrateAll = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_ALL));
+
+ try {
+ if (isCorrectProductVersion) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " to WSO2 API Manager " + Constants.VERSION_1_8);
+
+ // Create a thread and wait till the APIManager DBUtils is initialized
+
+ MigrateFrom17to18 migrateFrom17to18 = new MigrateFrom17to18(tenants);
+
+ boolean isArgumentValid = false;
+
+ //Default operation will migrate all three types of resources
+ if (migrateAll) {
+ log.info("Migrating WSO2 API Manager " + Constants.PREVIOUS_VERSION + " resources to WSO2 API Manager " + Constants.VERSION_1_8);
+ migrateFrom17to18.registryResourceMigration();
+ isArgumentValid = true;
+ }
+
+ if (isArgumentValid) {
+ log.info("API Manager " + Constants.PREVIOUS_VERSION + " to " + Constants.VERSION_1_8 + " migration successfully completed");
+ }
+ } else {
+ log.error("Migration client installed in incompatible product version. This migration client is only compatible with " +
+ Constants.APIM_PRODUCT_NAME + " " + Constants.VERSION_1_8 + ". Please verify the product/version in use.");
+ }
+ } catch (APIMigrationException e) {
+ log.error("API Management exception occurred while migrating", e);
+ } catch (UserStoreException e) {
+ log.error("User store exception occurred while migrating", e);
+ } catch (Exception e) {
+ log.error("Generic exception occurred while migrating", e);
+ } catch (Throwable t) {
+ log.error("Throwable error", t);
+ }
+ log.info("WSO2 API Manager migration component successfully activated.");
+ }
+
+ /**
+ * Method to deactivate bundle.
+ *
+ * @param context OSGi component context.
+ */
+ protected void deactivate(ComponentContext context) {
+ log.info("WSO2 API Manager migration bundle is deactivated");
+ }
+
+ /**
+ * Method to set registry service.
+ *
+ * @param registryService service to get tenant data.
+ */
+ protected void setRegistryService(RegistryService registryService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting RegistryService for WSO2 API Manager migration");
+ }
+ ServiceHolder.setRegistryService(registryService);
+ }
+
+ /**
+ * Method to unset registry service.
+ *
+ * @param registryService service to get registry data.
+ */
+ protected void unsetRegistryService(RegistryService registryService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unset Registry service");
+ }
+ ServiceHolder.setRegistryService(null);
+ }
+
+ /**
+ * Method to set realm service.
+ *
+ * @param realmService service to get tenant data.
+ */
+ protected void setRealmService(RealmService realmService) {
+ log.debug("Setting RealmService for WSO2 API Manager migration");
+ ServiceHolder.setRealmService(realmService);
+ }
+
+ /**
+ * Method to unset realm service.
+ *
+ * @param realmService service to get tenant data.
+ */
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unset Realm service");
+ }
+ ServiceHolder.setRealmService(null);
+ }
+
+ /**
+ * Method to set tenant registry loader
+ *
+ * @param tenantRegLoader tenant registry loader
+ */
+ protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegLoader) {
+ log.debug("Setting TenantRegistryLoader for WSO2 API Manager migration");
+ ServiceHolder.setTenantRegLoader(tenantRegLoader);
+ }
+
+ /**
+ * Method to unset tenant registry loader
+ *
+ * @param tenantRegLoader tenant registry loader
+ */
+ protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegLoader) {
+ log.debug("Unset Tenant Registry Loader");
+ ServiceHolder.setTenantRegLoader(null);
+ }
+
+ /**
+ * Method to set API Manager configuration
+ *
+ * @param apiManagerConfig api manager configuration
+ */
+ protected void setApiManagerConfig(APIManagerConfigurationService apiManagerConfig) {
+ log.info("Setting APIManager configuration");
+ }
+
+ /**
+ * Method to unset API manager configuration
+ *
+ * @param apiManagerConfig api manager configuration
+ */
+ protected void unsetApiManagerConfig(APIManagerConfigurationService apiManagerConfig) {
+ log.info("Un-setting APIManager configuration");
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java
new file mode 100644
index 0000000000..b03635c444
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/ServiceHolder.java
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2015, 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.migration.client.internal;
+
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
+import org.wso2.carbon.user.core.service.RealmService;
+
+@SuppressWarnings("unused")
+public class ServiceHolder {
+ //Registry Service which is used to get registry data.
+ private static RegistryService registryService;
+
+ //Realm Service which is used to get tenant data.
+ private static RealmService realmService;
+
+ //Tenant registry loader which is used to load tenant registry
+ private static TenantRegistryLoader tenantRegLoader;
+
+ /**
+ * Method to get RegistryService.
+ *
+ * @return registryService.
+ */
+ public static RegistryService getRegistryService() {
+ return registryService;
+ }
+
+ /**
+ * Method to set registry RegistryService.
+ *
+ * @param service registryService.
+ */
+ public static void setRegistryService(RegistryService service) {
+ registryService = service;
+ }
+
+ /**
+ * This method used to get RealmService.
+ *
+ * @return RealmService.
+ */
+ public static RealmService getRealmService() {
+ return realmService;
+ }
+
+ /**
+ * Method to set registry RealmService.
+ *
+ * @param service RealmService.
+ */
+ public static void setRealmService(RealmService service) {
+ realmService = service;
+ }
+
+ /**
+ * This method used to get TenantRegistryLoader
+ *
+ * @return tenantRegLoader Tenant registry loader for load tenant registry
+ */
+ public static TenantRegistryLoader getTenantRegLoader() {
+ return tenantRegLoader;
+ }
+
+ /**
+ * This method used to set TenantRegistryLoader
+ *
+ * @param service Tenant registry loader for load tenant registry
+ */
+ public static void setTenantRegLoader(TenantRegistryLoader service) {
+ tenantRegLoader = service;
+ }
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
new file mode 100644
index 0000000000..3b37ba6dab
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2015, 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.migration.util;
+
+public class Constants {
+ public static final String APIM_PRODUCT_NAME = "WSO2 API Manager";
+ public static final String PREVIOUS_VERSION = "1.7.0";
+ public static final String VERSION_1_8 = "1.8.0";
+ public static final String LINE_BREAK = "\\n";
+ public static final String CONSTRAINT = "constraint";
+ public static final String API = "api";
+ public static final String MIGRATION_SCRIPTS_FOLDER = "migration-scripts";
+
+ // Migration client argument property names
+ public static final String ARG_MIGRATE_TO_VERSION = "migrateToVersion";
+ public static final String ARG_MIGRATE_TENANTS = "tenants";
+ public static final String ARG_MIGRATE_ALL = "migrate";
+
+ // Synapse configuration related
+ public static final String SYNAPSE_API_ROOT_ELEMENT = "api";
+ public static final String SYNAPSE_API_ATTRIBUTE_VERSION = "version";
+
+ /*
+ * Variables in api_doc.json version 1.1
+ */
+
+ public static final String API_DOC_11_BASE_PATH = "basePath";
+ public static final String API_DOC_11_RESOURCE_PATH = "resourcePath";
+ public static final String API_DOC_11_API_VERSION = "apiVersion";
+ public static final String API_DOC_11_APIS = "apis";
+ public static final String API_DOC_11_PATH = "path";
+ public static final String API_DOC_11_OPERATIONS = "operations";
+ public static final String API_DOC_11_METHOD = "httpMethod";
+ public static final String API_DOC_11_PARAMETERS = "parameters";
+
+ /*
+ * Variables in api_doc.json version 1.2
+ */
+
+ public static final String API_DOC_12_BASE_PATH = "basePath";
+ public static final String API_DOC_12_APIS = "apis";
+ public static final String API_DOC_12_PATH = "path";
+ public static final String API_DOC_12_OPERATIONS = "operations";
+ public static final String API_DOC_12_METHOD = "method";
+ public static final String API_DOC_12_PARAMETERS = "parameters";
+ public static final String API_DOC_12_NICKNAME = "nickname";
+ //this resource contains all the resources. This is introduced to swagger 1.2 location to hold
+ //all the resource during the migration of 1.6. AM 1.6 does not have resources seperated by name
+ //so all resources are in one doc
+ public static final String API_DOC_12_ALL_RESOURCES_DOC = "resources";
+
+ /**
+ * default parameter array
+ */
+ public static final String DEFAULT_PARAM_ARRAY = "[ " + " { "
+ + " \"dataType\": \"String\", "
+ + " \"description\": \"Access Token\", "
+ + " \"name\": \"Authorization\", "
+ + " \"allowMultiple\": false, "
+ + " \"required\": true, "
+ + " \"paramType\": \"header\" " + " }, "
+ + " { "
+ + " \"description\": \"Request Body\", "
+ + " \"name\": \"body\", "
+ + " \"allowMultiple\": false, "
+ + " \"type\": \"string\", "
+ + " \"required\": true, "
+ + " \"paramType\": \"body\" " + " } "
+ + "]";
+
+ public static final String DEFAULT_PARAM_FOR_URL_TEMPLATE = " { "
+ + "\"name\": \"\", "
+ + "\"allowMultiple\": false, "
+ + "\"required\": true, "
+ + "\"type\": \"string\", "
+ + "\"paramType\": \"path\" "
+ + "}";
+
+
+ //database types
+ public static final String DB_TYPE_ORACLE = "oracle";
+ public static final String DB_TYPE_DB2 = "db2";
+ public static final String DB_TYPE_MYSQL= "mysql";
+ public static final String DB_TYPE_MSSQL = "mssql";
+ public static final String DB_TYPE_POSTGRE = "postgre";
+ public static final String DB_TYPE_OPENEDGE = "openedge";
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
new file mode 100644
index 0000000000..d2fbee5974
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
@@ -0,0 +1,696 @@
+/*
+* Copyright (c) 2015, 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.migration.util;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.client.MigrationDBCreator;
+import org.wso2.carbon.registry.core.Registry;
+import org.wso2.carbon.registry.core.RegistryConstants;
+import org.wso2.carbon.registry.core.Resource;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.utils.CarbonUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ResourceUtil {
+
+ private static final Log log = LogFactory.getLog(ResourceUtil.class);
+
+ /**
+ * location for the swagger 1.2 resources
+ *
+ * @param apiName api name
+ * @param apiVersion api version
+ * @param apiProvider api provider
+ * @return swagger v1.2 location
+ */
+ public static String getSwagger12ResourceLocation(String apiName, String apiVersion, String apiProvider) {
+ return APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR + apiName + "-" + apiVersion + "-"
+ + apiProvider + RegistryConstants.PATH_SEPARATOR + APIConstants.API_DOC_1_2_LOCATION;
+ }
+
+
+ /**
+ * This method picks the query according to the users database
+ *
+ * @return exact query to execute
+ * @throws SQLException
+ * @throws APIMigrationException
+ * @throws IOException
+ */
+ public static String pickQueryFromResources(String queryType) throws SQLException, APIMigrationException,
+ IOException {
+
+ String queryTobeExecuted;
+ try {
+ String databaseType = MigrationDBCreator.getDatabaseType(APIMgtDBUtil.getConnection());
+
+ //pick from 18to19Migration/sql-scripts
+ String resourcePath = CarbonUtils.getCarbonHome() + File.separator + Constants.MIGRATION_SCRIPTS_FOLDER + File.separator;
+
+ if (Constants.CONSTRAINT.equals(queryType)) {
+ //queryTobeExecuted = resourcePath + "drop-fk.sql";
+ queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + "drop-fk.sql")), "UTF-8");
+ } else {
+ queryTobeExecuted = resourcePath + databaseType + ".sql";
+ //queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + databaseType + ".sql")), "UTF-8");
+ }
+
+ } catch (IOException e) {
+ throw new APIMigrationException("Error occurred while accessing the sql from resources. " + e);
+ } catch (Exception e) {
+ //getDatabaseType inherited from DBCreator, which throws generic exception
+ throw new APIMigrationException("Error occurred while searching for database type " + e);
+ }
+
+ return queryTobeExecuted;
+ }
+
+ /**
+ * To handle exceptions
+ *
+ * @param msg error message
+ * @throws APIMigrationException
+ */
+ public static void handleException(String msg, Throwable e) throws APIMigrationException {
+ log.error(msg, e);
+ throw new APIMigrationException(msg, e);
+ }
+
+
+
+
+ /**
+ * Get all the parameters related to each resource. The parameter array is
+ * an array which is part of the operations object inside each resource.
+ *
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of parameter array related to all the http methods for each
+ * resource. the key for
+ * the map is resourcepath_httpmethod
+ */
+ public static Map getAllParametersForResources(JSONObject resource) throws APIMigrationException {
+ Map parameters = new HashMap();
+
+ String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
+
+ if (resourcePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_RESOURCE_PATH);
+ }
+
+ if (apiVersion == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_API_VERSION);
+ }
+
+ String resourcePathPrefix = resourcePath + "/" + apiVersion;
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+
+ if (apis == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_APIS);
+ }
+
+ for (int i = 0; i < apis.size(); i++) {
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);
+
+ if (path == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_PATH);
+ }
+
+ if (operations == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_OPERATIONS);
+ }
+
+ if (resourcePathPrefix.length() > path.length()) {
+ throw new APIMigrationException("Cannot obtain key prefix from swagger 1.1 document because resourcePathPrefix : " +
+ resourcePathPrefix + " is incompatible with path : " + path);
+ }
+
+ // get the key by removing the "apiVersion" and "resourcePath"
+ // from the "path" variable
+ // and concat the http method
+ String keyPrefix = path.substring(resourcePathPrefix.length());
+ if (keyPrefix.isEmpty()) {
+ keyPrefix = "/*";
+ }
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
+ JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);
+
+ if (httpMethod == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_METHOD);
+ }
+
+ if (parameterArray == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_PARAMETERS);
+ }
+
+
+ String key = keyPrefix + "_" + httpMethod.toLowerCase();
+
+ parameters.put(key, parameterArray);
+ }
+ }
+
+ return parameters;
+ }
+
+ /**
+ * Get all the operation object related to each resource. Method is inside the operation object
+ * this object contains the nickname, description related to that resource method
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of operations array related to all the http methods for each
+ * resource. the key for
+ * the map is resourcepath_httpmethod
+ */
+ private static Map getAllOperationsForResources(JSONObject resource) throws APIMigrationException {
+ Map parameters = new HashMap();
+
+ String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
+
+ if (resourcePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_RESOURCE_PATH);
+ }
+
+ if (apiVersion == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_API_VERSION);
+ }
+
+ String resourcePathPrefix = resourcePath + "/" + apiVersion;
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+
+ if (apis == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_APIS);
+ }
+
+ for (int i = 0; i < apis.size(); i++) {
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);
+
+ if (path == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_PATH);
+ }
+
+ if (operations == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_OPERATIONS);
+ }
+
+ if (resourcePathPrefix.length() > path.length()) {
+ throw new APIMigrationException("Cannot obtain key prefix from swagger 1.1 document because resourcePathPrefix : " +
+ resourcePathPrefix + " is incompatible with path : " + path);
+ }
+
+ // get the key by removing the "apiVersion" and "resourcePath"
+ // from the "path" variable
+ // and concat the http method
+ String keyPrefix = path.substring(resourcePathPrefix.length());
+ if (keyPrefix.isEmpty()) {
+ keyPrefix = "/*";
+ }
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
+
+ if (httpMethod == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_METHOD);
+ }
+
+ String key = keyPrefix + "_" + httpMethod.toLowerCase();
+
+ parameters.put(key, operation);
+ }
+ }
+
+ return parameters;
+ }
+ /**
+ * Get all the apis as a map. key for map is the full resource path for that api. key is created
+ * using 'basepath + apis[i].path' values in the api-doc.json file (swagger 1.1 doc)
+ *
+ * @param resource
+ * api-doc which contains swagger 1.1 info
+ * @return map of apis in the swagger 1.1 doc. key is the full resource path for that resource
+ */
+ public static Map getAllAPIsByResourcePath(JSONObject resource) throws APIMigrationException {
+ Map parameters = new HashMap();
+
+ String basePath = (String) resource.get(Constants.API_DOC_11_BASE_PATH);
+
+ if (basePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_BASE_PATH);
+ }
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
+
+ if (apis == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_APIS);
+ }
+
+ for (int i = 0; i < apis.size(); i++) {
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
+
+ if (path == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_PATH);
+ }
+
+ String key = basePath + path;
+ parameters.put(key, apiInfo);
+ }
+
+ return parameters;
+
+ }
+
+ private static JSONArray getDefaultParameters() {
+ JSONParser parser = new JSONParser();
+ JSONArray defaultParam = null;
+ try {
+ defaultParam = (JSONArray) parser.parse(Constants.DEFAULT_PARAM_ARRAY);
+ } catch (ParseException e) {
+ log.error("ParseException when getting swagger default Parameters", e);
+ }
+ return defaultParam;
+
+ }
+
+ /**
+ * Modify the resource in registry location '1.2' to be compatible with the
+ * AM 1.8. add the
+ * parameters to operations element, add 'nickname' variable and the
+ * 'basePath' variable
+ *
+ * @param resource
+ * resource inside the 1.2 location
+ * @param allParameters
+ * map containing all the parameters extracted from api-doc
+ * containing
+ * resources for swagger 1.1
+ * @param allOperations
+ * @param basePath
+ * base path for the resource
+ * @return modified resource for the api
+ */
+ public static String getUpdatedSwagger12Resource(JSONObject resource,
+ Map allParameters,
+ Map allOperations, String basePath) throws APIMigrationException {
+
+ JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_12_APIS);
+
+ if (apis == null) {
+ throw new APIMigrationException("Swagger 1.2 document does not contain required field: " + Constants.API_DOC_12_APIS);
+ }
+
+ for (int i = 0; i < apis.size(); i++) {
+ JSONObject apiInfo = (JSONObject) apis.get(i);
+ String path = (String) apiInfo.get(Constants.API_DOC_12_PATH);
+ JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_12_OPERATIONS);
+
+ if (path == null) {
+ log.error("Swagger 1.2 document does not contain required field: " + Constants.API_DOC_12_PATH);
+ continue;
+ }
+
+ if (operations == null) {
+ log.error("Swagger 1.2 document does not contain required field: " + Constants.API_DOC_12_OPERATIONS);
+ continue;
+ }
+
+ for (int j = 0; j < operations.size(); j++) {
+ JSONObject operation = (JSONObject) operations.get(j);
+ String method = (String) operation.get(Constants.API_DOC_12_METHOD);
+
+ if (method == null) {
+ log.error("Swagger 1.2 document does not contain required field: " + Constants.API_DOC_12_METHOD);
+ continue;
+ }
+
+ // nickname is method name + "_" + path without starting "/"
+ // symbol
+ String nickname = method.toLowerCase() + "_" + path.substring(1);
+ // add nickname variable
+ operation.put(Constants.API_DOC_12_NICKNAME, nickname);
+ String key = path + "_" + method.toLowerCase();
+
+ JSONArray parameters;
+ if (allParameters.containsKey(key)) {
+ parameters = allParameters.get(key);
+
+ //setting the 'type' to 'string' if this variable is missing
+ for(int m = 0; m < parameters.size(); m++ ){
+ JSONObject para = (JSONObject)parameters.get(m);
+ if(!para.containsKey("type")){
+ para.put("type", "string");
+ }
+ }
+
+ } else {
+ parameters = getDefaultParameters();
+
+ }
+ //if there are parameters already in this
+ JSONArray existingParams = (JSONArray) operation.get(Constants.API_DOC_12_PARAMETERS);
+
+ if (existingParams != null) {
+ if (existingParams.isEmpty()) {
+ JSONParser parser = new JSONParser();
+ if (path.contains("{")) {
+ List urlParams = ResourceUtil.getURLTempateParams(path);
+ for (String p : urlParams) {
+ try {
+ JSONObject paramObj = (JSONObject) parser.parse(Constants.DEFAULT_PARAM_FOR_URL_TEMPLATE);
+ paramObj.put("name", p);
+ parameters.add(paramObj);
+ } catch (ParseException e) {
+ log.error("ParseException when getting swagger default Parameters from URI template", e);
+ }
+ }
+ }
+ // add parameters array
+ operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
+ } else {
+ for (int k = 0; k < existingParams.size(); k++) {
+ parameters.add(existingParams.get(k));
+ }
+ operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
+ }
+ }
+
+ //updating the resource description and nickname using values in the swagger 1.1 doc
+ if(allOperations.containsKey(key)){
+
+ //update info related to object
+ JSONObject operationObj11 = allOperations.get(key);
+ //add summery
+ if(operationObj11.containsKey("summary")) {
+ operation.put("summary", (String) operationObj11.get("summery"));
+ }
+
+ }
+ }
+ }
+
+ // add basePath variable
+ resource.put(Constants.API_DOC_12_BASE_PATH, basePath);
+
+ return resource.toJSONString();
+ }
+
+
+ /**
+ * update all the the swagger document in the registry related to an api
+ * @param apiDocJson
+ * @param docResourcePaths
+ * @param registry
+ * @throws ParseException
+ * @throws RegistryException
+ */
+ public static void updateAPISwaggerDocs(String apiDocJson, String[] docResourcePaths,
+ Registry registry) throws ParseException, RegistryException, UnsupportedEncodingException, APIMigrationException {
+
+ JSONParser parser = new JSONParser();
+ JSONObject apiDoc11 = (JSONObject) parser.parse(apiDocJson);
+
+ Map allParameters = ResourceUtil.getAllParametersForResources(apiDoc11);
+
+ Map allOperations = ResourceUtil.getAllOperationsForResources(apiDoc11);
+
+ Map apisByPath = ResourceUtil.getAllAPIsByResourcePath(apiDoc11);
+
+ //this collection holds description given for each resource against the resource name.
+ //descriptions added resources in an api in AM 1.7 are stored in api-doc 1.1. this desciption
+ //is showed in am 1.7 api console in the store applicatoin. AM 1.8 uses descriptions in
+ // api-doc in 1.2 resource folder. following map collects this value from api-doc 1.1 and
+ // store it to add to api-doc 1.2
+ Map descriptionsForResource = new HashMap();
+
+ String basePath = (String) apiDoc11.get(Constants.API_DOC_11_BASE_PATH);
+ String resourcePath = (String) apiDoc11.get(Constants.API_DOC_11_RESOURCE_PATH);
+ String apiVersion = (String) apiDoc11.get(Constants.API_DOC_11_API_VERSION);
+
+ if (basePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_BASE_PATH);
+ }
+
+ if (resourcePath == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_RESOURCE_PATH);
+ }
+
+ if (apiVersion == null) {
+ throw new APIMigrationException("Swagger 1.1 document does not contain required field: " + Constants.API_DOC_11_API_VERSION);
+ }
+
+ resourcePath = resourcePath.endsWith("/") ? resourcePath : resourcePath + "/";
+ String basePathForResource = basePath + resourcePath + apiVersion;
+
+ String apidoc12path = "";
+
+ //update each resource in the 1.2 folder except the api-doc resource
+ for (String docResourcePath : docResourcePaths) {
+ String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));
+
+ if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
+ //store api-doc in 1.2 folder for future use
+ apidoc12path = docResourcePath;
+ continue;
+ }
+
+ if (!registry.resourceExists(docResourcePath)) {
+ log.error("Doc resource path at : " + docResourcePath + " does not exist");
+ continue;
+ }
+
+ Resource resource = registry.get(docResourcePath);
+ JSONObject apiDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent(), "UTF8"));
+
+
+ String description = "";
+ //generate the key to query the descriptionsForResource map
+ JSONArray apisInResource = (JSONArray) apiDoc.get(Constants.API_DOC_12_APIS);
+
+ if (apisInResource == null) {
+ log.error("Could not find " + Constants.API_DOC_12_APIS + " in document resource path");
+ continue;
+ }
+
+ JSONObject apiTemp = (JSONObject) apisInResource.get(0);
+ String path = (String) apiTemp.get(Constants.API_DOC_12_PATH);
+
+ if (path == null) {
+ log.error("Could not find " + Constants.API_DOC_12_PATH + " in document resource path");
+ continue;
+ }
+
+ String key = "";
+ if (path.equals("/*")) {
+ key = basePathForResource;
+ } else {
+ key = basePathForResource + path;
+ }
+
+
+ //get the description for that resource. query the api list generated using api-doc 1.1
+ if(apisByPath.containsKey(key)) {
+ JSONObject apiInfo = (JSONObject) apisByPath.get(key);
+ description = (String) apiInfo.get("description");
+ descriptionsForResource.put(resourceName, description);
+ }
+
+ String updatedJson =
+ ResourceUtil.getUpdatedSwagger12Resource(apiDoc, allParameters, allOperations,
+ basePathForResource);
+ log.info("\t update " + resourceName.substring(1));
+ Resource res = registry.get(docResourcePath);
+ res.setContent(updatedJson);
+ //update the registry
+ registry.put(docResourcePath, res);
+
+ }
+
+ //update the api-doc. add the descriptions to each api resource
+ ResourceUtil.updateSwagger12APIdoc(apidoc12path, descriptionsForResource, registry, parser);
+
+ }
+
+
+
+ /**
+ * update the swagger 1.2 api-doc. This method updates the descriptions
+ * @param apidoc12path
+ * @param descriptionsForResource
+ * @param registry
+ * @param parser
+ * @throws RegistryException
+ * @throws ParseException
+ */
+ private static void updateSwagger12APIdoc(String apidoc12path,
+ Map descriptionsForResource,
+ Registry registry, JSONParser parser)
+ throws RegistryException,
+ ParseException, UnsupportedEncodingException, APIMigrationException {
+ if (!registry.resourceExists(apidoc12path)) {
+ throw new APIMigrationException("Swagger 1.2 doc does not exist");
+ }
+
+ Resource res = registry.get(apidoc12path);
+ JSONObject api12Doc = (JSONObject) parser.parse(new String((byte[]) res.getContent(), "UTF8"));
+ JSONArray apis = (JSONArray) api12Doc.get(Constants.API_DOC_12_APIS);
+ for (int j = 0; j < apis.size(); j++) {
+ JSONObject api = (JSONObject) apis.get(j);
+
+ // get the resource name for each api in api-doc 1.2
+ String resPathName = (String) api.get(Constants.API_DOC_12_PATH);
+ if (descriptionsForResource.containsKey(resPathName)) {
+ // if the descrption is available for that resource update it
+ api.put("description", descriptionsForResource.get(resPathName));
+ }
+ }
+ log.info("\t update api-doc");
+ res.setContent(api12Doc.toJSONString());
+ // update the registry
+ registry.put(apidoc12path, res);
+ }
+
+ /**
+ * remove header and body parameters
+ * @param docResourcePaths
+ * @param registry
+ * @throws RegistryException
+ * @throws ParseException
+ */
+ public static void updateSwagger12ResourcesForAM18(String[] docResourcePaths,
+ Registry registry) throws RegistryException, ParseException, UnsupportedEncodingException, APIMigrationException {
+ JSONParser parser = new JSONParser();
+ for (String docResourcePath : docResourcePaths) {
+
+ String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));
+
+ //modify this if api-doc resource needed to be changed
+ if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
+ continue;
+ }
+
+ if (!registry.resourceExists(docResourcePath)) {
+ throw new APIMigrationException("Doc resource does not exist in swagger 1.2");
+ }
+
+ Resource resource = registry.get(docResourcePath);
+ JSONObject resourceDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent(), "UTF8"));
+ JSONArray apis = (JSONArray) resourceDoc.get(Constants.API_DOC_12_APIS);
+
+ if (apis == null) {
+ throw new APIMigrationException("Swagger 1.2 doc does not contain required field : " + Constants.API_DOC_12_APIS);
+ }
+
+ for (int j = 0; j < apis.size(); j++) {
+ JSONObject api = (JSONObject) apis.get(j);
+ JSONArray operations = (JSONArray) api.get("operations");
+
+ for (int k = 0; k < operations.size(); k++) {
+ JSONObject operation = (JSONObject) operations.get(k);
+ JSONArray parameters = (JSONArray) operation.get("parameters");
+ String method = (String) operation.get("method");
+ JSONArray parametersNew = new JSONArray();
+ //remove header and body parameters
+ for (int l = 0; l < parameters.size(); l++) {
+ JSONObject parameter = (JSONObject) parameters.get(l);
+
+ if(parameter.get("paramType").equals("header")){
+ continue;
+ }
+ if(parameter.get("paramType").equals("body")) {
+
+ //only remove body of a GET and DELETE
+ if("GET".equalsIgnoreCase(method) ||
+ "DELETE".equalsIgnoreCase(method)) {
+ continue;
+ }
+ }
+ parametersNew.add(parameter);
+ }
+ operation.put("parameters", parametersNew);
+ }
+
+
+ }
+
+ resource.setContent(resourceDoc.toJSONString());
+ //update the registry
+ registry.put(docResourcePath, resource);
+ }
+
+ }
+
+ /**
+ * extract the parameters from the url tempate.
+ * @param url
+ * @return
+ */
+ public static List getURLTempateParams(String url) {
+ boolean endVal = false;
+
+ List params = new ArrayList();
+ if(url.contains("{")){
+
+ int start = 0;
+ int end = 0;
+ for(int i = 0; i < url.length(); i++) {
+ if(url.charAt(i) == '{')
+ start = i;
+ else if(url.charAt(i) == '}') {
+ end = i;
+ endVal = true;
+ }
+
+ if(endVal){
+ params.add(url.substring(start + 1, end));
+ endVal = false;
+ }
+ }
+
+ }
+ return params;
+ }
+
+}
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql
new file mode 100644
index 0000000000..5b59b9119c
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/h2.sql
@@ -0,0 +1 @@
+ALTER TABLE AM_SUBSCRIPTION ADD SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE';
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql
new file mode 100644
index 0000000000..5b59b9119c
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mssql.sql
@@ -0,0 +1 @@
+ALTER TABLE AM_SUBSCRIPTION ADD SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE';
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql
new file mode 100644
index 0000000000..45e75b01b0
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/mysql.sql
@@ -0,0 +1 @@
+ALTER TABLE AM_SUBSCRIPTION ADD COLUMN SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE';
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql
new file mode 100644
index 0000000000..5b59b9119c
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/oracle.sql
@@ -0,0 +1 @@
+ALTER TABLE AM_SUBSCRIPTION ADD SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE';
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/postgresql.sql b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/postgresql.sql
new file mode 100644
index 0000000000..45e75b01b0
--- /dev/null
+++ b/modules/distribution/resources/migration-1.7.0_to_1.8.0/wso2-api-migration-client/src/main/resources/migration-scripts/postgresql.sql
@@ -0,0 +1 @@
+ALTER TABLE AM_SUBSCRIPTION ADD COLUMN SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE';
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/pom.xml b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/pom.xml
index 0cd0a6ae27..52b0add516 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/pom.xml
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/pom.xml
@@ -6,7 +6,7 @@
org.wso2.carbon
org.wso2.carbon.apimgt.migrate.client
- 1.9.1-SNAPSHOT
+ 1.9.X
bundle
@@ -59,6 +59,15 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+
+ 1.6
+
+
org.apache.felix
maven-bundle-plugin
@@ -81,30 +90,29 @@
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.5.3
+
+
+ dist
+ package
+
+ attached
+
+
+ false
+ src/assembly/dist.xml
+ wso2-api-migration-client
+
+
+
+
-
- org.apache.ws.commons.axiom
- axiom-api
- ${org.apache.ws.commons.axiom.version}
-
-
- org.apache.ws.commons.axiom
- axiom-impl
- ${org.apache.ws.commons.axiom.version}
-
-
- org.apache.ws.commons.axiom.wso2
- axiom
- ${org.apache.ws.commons.axiom.wso2.version}
-
-
- org.bouncycastle.wso2
- bcprov-jdk15on
- ${org.bouncycastle.wso2.version}
-
org.wso2.carbon
org.wso2.carbon.core.services
@@ -120,41 +128,20 @@
org.wso2.carbon.registry.core
${org.wso2.carbon.registry.core.version}
-
- org.wso2.carbon
- org.wso2.carbon.registry.api
- ${org.wso2.carbon.registry.api.version}
- provided
-
org.wso2.carbon
org.wso2.carbon.utils
${org.wso2.carbon.utils.version}
- commons-scxml.wso2
- commons-scxml
- ${commons-scxml.wso2.version}
-
-
- commons-codec
- commons-codec
- ${commons-codec.version}
-
-
- commons-logging
- commons-logging
- ${commons-logging.version}
-
-
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.impl
- [1.2.1,1.2.4]
+ [1.2.0,1.3.0)
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.api
- [1.2.1,1.2.4]
+ [1.2.0,1.3.0)
@@ -162,23 +149,12 @@
UTF-8
1.7.2
2.5.3
- 1.2.14
- 1.2.11.wso2v5
- 1.49.0.wso2v2
4.2.0
4.2.0
1.0.4
4.2.0
- 4.2.0
4.2.0
1.0.1
- 1.8
- 1.10
- 1.1.3
- 0.9.0.wso2v1
- 0.0.0
- 2.4.0
- 2.4.0
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/assembly/dist.xml b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/assembly/dist.xml
new file mode 100644
index 0000000000..88ddad5f7e
--- /dev/null
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/assembly/dist.xml
@@ -0,0 +1,29 @@
+
+ dist
+
+ zip
+
+ false
+
+
+
+ migration-scripts/18-19-migration
+
+
+
+
+ ${project.basedir}/src/main/resources/18to19Migration/sql-scripts
+ migration-scripts/18-19-migration
+
+ *.sql
+
+
+
+ ${project.build.directory}
+
+
+ *.jar
+
+
+
+
\ No newline at end of file
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom18to19.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom18to19.java
index 49bdfb6d2c..0641315d4f 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom18to19.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrateFrom18to19.java
@@ -23,21 +23,27 @@
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.definitions.APIDefinitionFromSwagger20;
import org.wso2.carbon.apimgt.impl.utils.APIMgtDBUtil;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.apimgt.migration.APIMigrationException;
import org.wso2.carbon.apimgt.migration.client.internal.ServiceHolder;
import org.wso2.carbon.apimgt.migration.util.Constants;
import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
+import org.wso2.carbon.apimgt.migration.util.StatDBUtil;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
import org.wso2.carbon.governance.api.util.GovernanceUtils;
+import org.wso2.carbon.registry.api.RegistryException;
+import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.registry.core.ActionConstants;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.RegistryConstants;
@@ -46,29 +52,15 @@
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.tenant.TenantManager;
import org.wso2.carbon.utils.CarbonUtils;
-import org.wso2.carbon.registry.api.RegistryException;
-import org.wso2.carbon.registry.api.Resource;
+import org.xml.sax.SAXException;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.*;
import java.net.MalformedURLException;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
+import java.sql.*;
+import java.util.*;
/**
@@ -82,13 +74,88 @@ public class MigrateFrom18to19 implements MigrationClient {
private static final Log log = LogFactory.getLog(MigrateFrom18to19.class);
private List tenantsArray;
- public MigrateFrom18to19() throws UserStoreException {
+ public MigrateFrom18to19(String tenantArguments, String blackListTenantArguments) throws UserStoreException {
TenantManager tenantManager = ServiceHolder.getRealmService().getTenantManager();
- tenantsArray = new ArrayList(Arrays.asList(tenantManager.getAllTenants()));
- Tenant superTenant = new Tenant();
- superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
- superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
- tenantsArray.add(superTenant);
+
+ if (tenantArguments != null) { // Tenant arguments have been provided so need to load specific ones
+ tenantArguments = tenantArguments.replaceAll("\\s", ""); // Remove spaces and tabs
+
+ tenantsArray = new ArrayList();
+
+ buildTenantList(tenantManager, tenantsArray, tenantArguments);
+ } else if (blackListTenantArguments != null) {
+ blackListTenantArguments = blackListTenantArguments.replaceAll("\\s", ""); // Remove spaces and tabs
+
+ List blackListTenants = new ArrayList();
+ buildTenantList(tenantManager, blackListTenants, blackListTenantArguments);
+
+ List allTenants = new ArrayList(Arrays.asList(tenantManager.getAllTenants()));
+ Tenant superTenant = new Tenant();
+ superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
+ allTenants.add(superTenant);
+
+ tenantsArray = new ArrayList();
+
+ for (Tenant tenant : allTenants) {
+ boolean isBlackListed = false;
+ for (Tenant blackListTenant : blackListTenants) {
+ if (blackListTenant.getId() == tenant.getId()) {
+ isBlackListed = true;
+ break;
+ }
+ }
+
+ if (!isBlackListed) {
+ tenantsArray.add(tenant);
+ }
+ }
+
+ } else { // Load all tenants
+ tenantsArray = new ArrayList(Arrays.asList(tenantManager.getAllTenants()));
+ Tenant superTenant = new Tenant();
+ superTenant.setDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ superTenant.setId(MultitenantConstants.SUPER_TENANT_ID);
+ tenantsArray.add(superTenant);
+ }
+ }
+
+
+ private void buildTenantList(TenantManager tenantManager, List tenantList, String tenantArguments) throws UserStoreException {
+ if (tenantArguments.contains(",")) { // Multiple arguments specified
+ String[] parts = tenantArguments.split(",");
+
+ for (int i = 0; i < parts.length; ++i) {
+ if (parts[i].length() > 0) {
+ populateTenants(tenantManager, tenantList, parts[i]);
+ }
+ }
+ } else { // Only single argument provided
+ populateTenants(tenantManager, tenantList, tenantArguments);
+ }
+ }
+
+
+ private void populateTenants(TenantManager tenantManager, List tenantList, String argument) throws UserStoreException {
+ log.debug("Argument provided : " + argument);
+
+ if (argument.contains("@")) { // Username provided as argument
+ int tenantID = tenantManager.getTenantId(argument);
+
+ if (tenantID != -1) {
+ tenantList.add(tenantManager.getTenant(tenantID));
+ } else {
+ log.error("Tenant does not exist for username " + argument);
+ }
+ } else { // Domain name provided as argument
+ Tenant[] tenants = tenantManager.getAllTenantsForTenantDomainStr(argument);
+
+ if (tenants.length > 0) {
+ tenantList.addAll(Arrays.asList(tenants));
+ } else {
+ log.error("Tenant does not exist for domain " + argument);
+ }
+ }
}
/**
@@ -100,21 +167,21 @@ public MigrateFrom18to19() throws UserStoreException {
* @throws SQLException
*/
@Override
- public void databaseMigration(String migrateVersion) throws APIMigrationException, SQLException {
- log.info("Database migration for API Manager 1.8.0 started");
+ public void databaseMigration(String migrateVersion) throws SQLException {
+ log.info("Database migration for API Manager " + Constants.VERSION_1_9 + " started");
Connection connection = null;
PreparedStatement preparedStatement = null;
+ BufferedReader bufferedReader = null;
try {
connection = APIMgtDBUtil.getConnection();
String dbType = MigrationDBCreator.getDatabaseType(connection);
String dbScript = ResourceUtil.pickQueryFromResources(migrateVersion, dbType);
- BufferedReader bufferedReader;
InputStream is = new FileInputStream(dbScript);
- bufferedReader = new BufferedReader(new InputStreamReader(is));
+ bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF8"));
String sqlQuery;
while ((sqlQuery = bufferedReader.readLine()) != null) {
- if ("oracle".equals(dbType)) {
+ if (Constants.DB_TYPE_ORACLE.equals(dbType)) {
sqlQuery = sqlQuery.replace(";", "");
}
sqlQuery = sqlQuery.trim();
@@ -137,20 +204,25 @@ public void databaseMigration(String migrateVersion) throws APIMigrationExceptio
preparedStatement = connection.prepareStatement(sqlQuery.trim());
preparedStatement.execute();
connection.commit();
- preparedStatement.close();
}
}
//To drop the foreign key
dropFKConstraint(migrateVersion, dbType);
+ bufferedReader.close();
+
} catch (IOException e) {
- //ResourceUtil.handleException("Error occurred while finding the query. Please check the file path.", e);
+ //Errors logged to let user know the state of the db migration and continue other resource migrations
log.error("Error occurred while migrating databases", e);
} catch (Exception e) {
- //ResourceUtil.handleException("Error occurred while finding the query. Please check the file path.", e);
+ /* MigrationDBCreator extends from org.wso2.carbon.utils.dbcreator.DatabaseCreator and in the super class
+ method getDatabaseType throws generic Exception */
log.error("Error occurred while migrating databases", e);
} finally {
+ if (preparedStatement != null) {
+ preparedStatement.close();
+ }
if (connection != null) {
connection.close();
}
@@ -160,46 +232,63 @@ public void databaseMigration(String migrateVersion) throws APIMigrationExceptio
/**
* This method is used to remove the FK constraint which is unnamed
- * This finds the name of the constraint and build the query to delete the constaint and execute it
+ * This finds the name of the constraint and build the query to delete the constraint and execute it
*
* @param migrateVersion version to be migrated
* @param dbType database type of the user
* @throws SQLException
* @throws IOException
- * @throws APIMigrationException
*/
- public void dropFKConstraint(String migrateVersion, String dbType) throws SQLException, IOException, APIMigrationException {
- String constraintName = null;
- Connection connection;
- String queryToExecute = ResourceUtil.pickQueryFromResources(migrateVersion, Constants.CONSTRAINT).trim();
- String queryArray[] = queryToExecute.split(Constants.LINE_BREAK);
-
- connection = APIMgtDBUtil.getConnection();
- connection.setAutoCommit(false);
- Statement statement = connection.createStatement();
- if ("oracle".equals(dbType)) {
- queryArray[0] = queryArray[0].replace(Constants.DELIMITER, "");
- }
- ResultSet resultSet = statement.executeQuery(queryArray[0]);
- while (resultSet.next()) {
- constraintName = resultSet.getString("constraint_name");
- }
+ public void dropFKConstraint(String migrateVersion, String dbType) throws SQLException {
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+ ResultSet resultSet = null;
+ Statement statement = null;
+ try {
+ String queryToExecute = ResourceUtil.pickQueryFromResources(migrateVersion, Constants.CONSTRAINT).trim();
+ String queryArray[] = queryToExecute.split(Constants.LINE_BREAK);
- if (constraintName != null) {
- queryToExecute = queryArray[1].replace("", constraintName);
- if ("oracle".equals(dbType)) {
- queryToExecute = queryToExecute.replace(Constants.DELIMITER, "");
+ connection = APIMgtDBUtil.getConnection();
+ connection.setAutoCommit(false);
+ statement = connection.createStatement();
+ if (Constants.DB_TYPE_ORACLE.equals(dbType)) {
+ queryArray[0] = queryArray[0].replace(Constants.DELIMITER, "");
}
+ resultSet = statement.executeQuery(queryArray[0]);
+ String constraintName = null;
- if (queryToExecute.contains("\\n")) {
- queryToExecute = queryToExecute.replace("\\n", "");
+ while (resultSet.next()) {
+ constraintName = resultSet.getString("constraint_name");
}
- PreparedStatement preparedStatement = connection.prepareStatement(queryToExecute);
- preparedStatement.execute();
- connection.commit();
- preparedStatement.close();
+
+ if (constraintName != null) {
+ queryToExecute = queryArray[1].replace("", constraintName);
+ if (Constants.DB_TYPE_ORACLE.equals(dbType)) {
+ queryToExecute = queryToExecute.replace(Constants.DELIMITER, "");
+ }
+
+ if (queryToExecute.contains("\\n")) {
+ queryToExecute = queryToExecute.replace("\\n", "");
+ }
+ preparedStatement = connection.prepareStatement(queryToExecute);
+ preparedStatement.execute();
+ connection.commit();
+ }
+ } catch (APIMigrationException e) {
+ //Foreign key might be already deleted, log the error and let it continue
+ log.error("Error occurred while deleting foreign key", e);
+ } catch (IOException e) {
+ //If user does not add the file migration will continue and migrate the db without deleting
+ // the foreign key reference
+ log.error("Error occurred while finding the foreign key deletion query for execution", e);
+ } finally {
+ if (statement != null) {
+ statement.close();
+ }
+
+ APIMgtDBUtil.closeAllConnections(preparedStatement, connection, resultSet);
}
- connection.close();
+
}
/**
@@ -223,69 +312,71 @@ public void registryResourceMigration() throws APIMigrationException {
* @throws APIMigrationException
*/
void rxtMigration() throws APIMigrationException {
- log.info("Rxt migration for API Manager 1.9.0 started.");
+ log.info("Rxt migration for API Manager " + Constants.VERSION_1_9 + " started.");
boolean isTenantFlowStarted = false;
- try {
- for (Tenant tenant : tenantsArray) {
+ for (Tenant tenant : tenantsArray) {
+ log.debug("Start rxtMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ try {
PrivilegedCarbonContext.startTenantFlow();
isTenantFlowStarted = true;
- /*Use the super tenant instead of tenant because tenants do not have access to master-datasources.xml
- If you use tenant details instead of super tenant, you will get javax.naming.NameNotFoundException:
- Name [jdbc/AM_API] is not bound in this Context. Unable to find [jdbc]*/
-
- PrivilegedCarbonContext.getThreadLocalCarbonContext().
- setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
- PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain(), true);
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId(), true);
String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId())
.getRealmConfiguration().getAdminUserName();
+
+ log.debug("Tenant admin username : " + adminName);
ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenant.getId());
Registry registry = ServiceHolder.getRegistryService().getGovernanceUserRegistry(adminName, tenant
.getId());
GenericArtifactManager artifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY);
- //GenericArtifactManager manager = new GenericArtifactManager(registry, "api");
- GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
- GenericArtifact[] artifacts = artifactManager.getAllGenericArtifacts();
- for (GenericArtifact artifact : artifacts) {
- API api = APIUtil.getAPI(artifact, registry);
- APIIdentifier apiIdentifier = api.getId();
- String apiVersion = apiIdentifier.getVersion();
+ if (artifactManager != null) {
+ GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
+ GenericArtifact[] artifacts = artifactManager.getAllGenericArtifacts();
+ for (GenericArtifact artifact : artifacts) {
+ API api = APIUtil.getAPI(artifact, registry);
- if(!(api.getContext().endsWith(RegistryConstants.PATH_SEPARATOR + apiVersion))) {
- artifact.setAttribute("overview_context", api.getContext() +
- RegistryConstants.PATH_SEPARATOR + apiVersion);
- }
+ if (api == null) {
+ log.error("Cannot find corresponding api for registry artifact " + artifact.getAttribute("overview_name") + "-" + artifact.getAttribute("overview_version") + "-" + artifact.getAttribute("overview_provider") +
+ " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ") in AM_DB");
+ continue;
+ }
- artifact.addAttribute("overview_contextTemplate", api.getContext() +
- RegistryConstants.PATH_SEPARATOR + "{version}");
- artifact.addAttribute("overview_environments", "");
- artifact.addAttribute("overview_versionType", "");
+ APIIdentifier apiIdentifier = api.getId();
+ String apiVersion = apiIdentifier.getVersion();
- artifactManager.updateGenericArtifact(artifact);
- }
+ if (!(api.getContext().endsWith(RegistryConstants.PATH_SEPARATOR + apiVersion))) {
+ artifact.setAttribute("overview_context", api.getContext() +
+ RegistryConstants.PATH_SEPARATOR + apiVersion);
+ }
- }
- if(isTenantFlowStarted){
- PrivilegedCarbonContext.endTenantFlow();
- }
+ artifact.addAttribute("overview_contextTemplate", api.getContext() +
+ RegistryConstants.PATH_SEPARATOR + "{version}");
+ artifact.addAttribute("overview_environments", "");
+ artifact.addAttribute("overview_versionType", "");
- } catch (APIManagementException e) {
- ResourceUtil.handleException("Error occurred while reading API from the artifact ", e);
- } catch (RegistryException e) {
- ResourceUtil.handleException("Error occurred while accessing the registry", e);
- } catch (UserStoreException e) {
- ResourceUtil.handleException("Error occurred while reading tenant information", e);
- }
- finally {
- if(isTenantFlowStarted){
- PrivilegedCarbonContext.endTenantFlow();
+ artifactManager.updateGenericArtifact(artifact);
+ }
+ } else {
+ log.debug("No api artifacts found in registry for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+ } catch (APIManagementException e) {
+ ResourceUtil.handleException("Error occurred while reading API from the artifact ", e);
+ } catch (RegistryException e) {
+ ResourceUtil.handleException("Error occurred while accessing the registry", e);
+ } catch (UserStoreException e) {
+ ResourceUtil.handleException("Error occurred while reading tenant information", e);
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
}
+ log.debug("End rxtMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
}
- if (log.isDebugEnabled()) {
- log.debug("Rxt resource migration done for all the tenants");
- }
+
+ log.info("Rxt resource migration done for all the tenants");
}
@@ -306,10 +397,8 @@ void copyNewRxtFileToRegistry() throws APIMigrationException {
int tenantId = tenant.getId();
isTenantFlowStarted = true;
PrivilegedCarbonContext.startTenantFlow();
- PrivilegedCarbonContext.getThreadLocalCarbonContext()
- .setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
- PrivilegedCarbonContext.getThreadLocalCarbonContext()
- .setTenantId(MultitenantConstants.SUPER_TENANT_ID);
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain(), true);
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId(), true);
String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenantId)
.getRealmConfiguration().getAdminUserName();
@@ -357,93 +446,156 @@ void copyNewRxtFileToRegistry() throws APIMigrationException {
* @throws APIMigrationException
*/
void swaggerResourceMigration() throws APIMigrationException {
- log.info("Swagger migration for API Manager 1.9.0 started.");
+ log.info("Swagger migration for API Manager " + Constants.VERSION_1_9 + " started.");
boolean isTenantFlowStarted = false;
- try {
- for (Tenant tenant : tenantsArray) {
- if (log.isDebugEnabled()) {
- log.debug("Swagger migration for tenant " + tenant.getDomain() + "[" + tenant.getId() + "]" + " ");
- }
+ for (Tenant tenant : tenantsArray) {
+ if (log.isDebugEnabled()) {
+ log.debug("Start swaggerResourceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ try {
PrivilegedCarbonContext.startTenantFlow();
isTenantFlowStarted = true;
- //Use the super tenant instead of tenant because tenants do not have access to master-datasources.xml
- PrivilegedCarbonContext.getThreadLocalCarbonContext().
- setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
- PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
-
- String adminName = ServiceHolder.getRealmService().getTenantUserRealm(
- tenant.getId()).getRealmConfiguration().getAdminUserName();
- ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenant.getId());
- Registry registry = ServiceHolder.getRegistryService().
- getGovernanceUserRegistry(adminName, tenant.getId());
- GenericArtifactManager manager = new GenericArtifactManager(registry, "api");
- GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
- GenericArtifact[] artifacts = manager.getAllGenericArtifacts();
-
- for (GenericArtifact artifact : artifacts) {
- API api = APIUtil.getAPI(artifact, registry);
- APIIdentifier apiIdentifier = api.getId();
- String apiName = apiIdentifier.getApiName();
- String apiVersion = apiIdentifier.getVersion();
- String apiProviderName = apiIdentifier.getProviderName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenant.getDomain());
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant.getId());
- String swagger12location = ResourceUtil.getSwagger12ResourceLocation(apiName,
- apiVersion, apiProviderName);
+ Registry registry = getRegistry(tenant);
- if (!registry.resourceExists(swagger12location)) {
- log.error("Swagger Resource migration has not happen yet for " +
- apiName + "-" + apiVersion + "-"
- + apiProviderName);
+ if (registry != null) {
+ GenericArtifact[] artifacts = getGenericArtifacts(registry);
- } else {
- if (log.isDebugEnabled()) {
- log.debug("Creating swagger v2.0 resource for : " + apiName + "-" + apiVersion + "-"
- + apiProviderName);
- }
- //get swagger v2 doc
- String swagger2doc = getSwagger2docUsingSwagger12RegistryResources(registry, swagger12location);
-
- //create location in registry and add this
- String swagger2location = ResourceUtil.getSwagger2ResourceLocation(apiName, apiVersion,
- apiProviderName);
-
- Resource docContent = registry.newResource();
- docContent.setContent(swagger2doc);
- docContent.setMediaType("application/json");
- registry.put(swagger2location, docContent);
-
- //Currently set to ANONYMOUS_ROLE, need to set to visible roles
- ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getAuthorizationManager()
- .authorizeRole(APIConstants.ANONYMOUS_ROLE,
- "_system/governance" + swagger2location, ActionConstants.GET);
+ if (artifacts != null) {
+ updateSwaggerResources(artifacts, registry, tenant);
}
}
-
- PrivilegedCarbonContext.endTenantFlow();
+ } finally {
+ if (isTenantFlowStarted) {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
}
- } catch (MalformedURLException e) {
- ResourceUtil.handleException("Error occurred while creating swagger v2.0 document ", e);
- } catch (APIManagementException e) {
- ResourceUtil.handleException("Error occurred while reading API from the artifact ", e);
- } catch (RegistryException e) {
- ResourceUtil.handleException("Error occurred while accessing the registry", e);
- } catch (ParseException e) {
- ResourceUtil.handleException("Error occurred while getting swagger v2.0 document", e);
+
+ log.debug("End swaggerResourceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ }
+
+ log.info("Swagger resource migration done for all the tenants.");
+ }
+
+ private Registry getRegistry(Tenant tenant) {
+ log.debug("Calling getRegistry");
+ Registry registry = null;
+
+ try {
+ String adminName = ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getRealmConfiguration().getAdminUserName();
+ log.debug("Tenant admin username : " + adminName);
+ registry = ServiceHolder.getRegistryService().getGovernanceUserRegistry(adminName, tenant.getId());
+ ServiceHolder.getTenantRegLoader().loadTenantRegistry(tenant.getId());
} catch (UserStoreException e) {
- ResourceUtil.handleException("Error occurred while reading tenant information", e);
+ log.error("Error occurred while reading tenant information of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (RegistryException e) {
+ log.error("Error occurred while accessing the registry of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
}
- if(isTenantFlowStarted){
- PrivilegedCarbonContext.endTenantFlow();
+
+ return registry;
+ }
+
+
+ private GenericArtifact[] getGenericArtifacts(Registry registry) {
+ log.debug("Calling getGenericArtifacts");
+ GenericArtifact[] artifacts = null;
+
+ try {
+ if (GovernanceUtils.findGovernanceArtifactConfiguration(Constants.API, registry) != null) {
+ GenericArtifactManager manager = new GenericArtifactManager(registry, Constants.API);
+ GovernanceUtils.loadGovernanceArtifacts((UserRegistry) registry);
+ artifacts = manager.getAllGenericArtifacts();
+
+ log.debug("Total number of api artifacts : " + artifacts.length);
+ } else {
+ log.debug("API artifacts do not exist in registry");
+ }
+
+ } catch (RegistryException e) {
+ log.error("Error occurred when getting GenericArtifacts from registry", e);
}
- if (log.isDebugEnabled()) {
- log.debug("Swagger resource migration done for all the tenants");
+ return artifacts;
+ }
+
+ private API getAPI(GenericArtifact artifact) {
+ log.debug("Calling getAPI");
+ API api = null;
+
+ try {
+ api = APIUtil.getAPI(artifact);
+ } catch (APIManagementException e) {
+ log.error("Error when getting api artifact " + artifact.getId() + " from registry", e);
}
+ return api;
+ }
+
+ private void updateSwaggerResources(GenericArtifact[] artifacts, Registry registry, Tenant tenant) throws APIMigrationException {
+ log.debug("Calling updateSwaggerResources");
+ for (GenericArtifact artifact : artifacts) {
+ API api = getAPI(artifact);
+
+ if (api != null) {
+ APIIdentifier apiIdentifier = api.getId();
+ String apiName = apiIdentifier.getApiName();
+ String apiVersion = apiIdentifier.getVersion();
+ String apiProviderName = apiIdentifier.getProviderName();
+ try {
+ String swagger2location = ResourceUtil.getSwagger2ResourceLocation(apiName, apiVersion, apiProviderName);
+
+ // Create swagger 2.0 doc only if it does not exist
+ /*if (registry.resourceExists(swagger2location)) {
+ continue;
+ }*/
+
+ String swagger12location = ResourceUtil.getSwagger12ResourceLocation(apiName, apiVersion, apiProviderName);
+
+ String swagger2Document;
+
+ if (!registry.resourceExists(swagger12location)) {
+ log.debug("Creating swagger v2.0 resource from scratch for : " + apiName + "-" + apiVersion + "-" + apiProviderName);
+
+ APIDefinitionFromSwagger20 definitionFromSwagger20 = new APIDefinitionFromSwagger20();
+
+ swagger2Document = definitionFromSwagger20.generateAPIDefinition(api);
+ } else {
+ log.debug("Creating swagger v2.0 resource using v1.2 for : " + apiName + "-" + apiVersion + "-" + apiProviderName);
+ swagger2Document = getSwagger2docUsingSwagger12RegistryResources(registry, swagger12location, api);
+ }
+
+ Resource docContent = registry.newResource();
+ docContent.setContent(swagger2Document);
+ docContent.setMediaType("application/json");
+ registry.put(swagger2location, docContent);
+
+ ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getAuthorizationManager()
+ .authorizeRole(APIConstants.ANONYMOUS_ROLE,
+ "_system/governance" + swagger2location, ActionConstants.GET);
+ ServiceHolder.getRealmService().getTenantUserRealm(tenant.getId()).getAuthorizationManager()
+ .authorizeRole(APIConstants.EVERYONE_ROLE,
+ "_system/governance" + swagger2location, ActionConstants.GET);
+ } catch (RegistryException e) {
+ log.error("Registry error encountered for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (ParseException e) {
+ log.error("Error occurred while parsing swagger v1.2 document for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (UserStoreException e) {
+ log.error("Error occurred while setting permissions of swagger v2.0 document for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (MalformedURLException e) {
+ log.error("Error occurred while creating swagger v2.0 document for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ } catch (APIManagementException e) {
+ log.error("Error occurred while creating swagger v2.0 document for api " + apiName + "-" + apiVersion + "-" + apiProviderName + " of tenant " + tenant.getId() + "(" + tenant.getDomain() + ")", e);
+ }
+ }
+ }
}
+
/**
* This method generates swagger v2 doc using swagger 1.2 doc
*
@@ -455,46 +607,67 @@ void swaggerResourceMigration() throws APIMigrationException {
* @throws org.wso2.carbon.registry.core.exceptions.RegistryException
*/
- private String getSwagger2docUsingSwagger12RegistryResources(Registry registry, String swagger12location)
+ private String getSwagger2docUsingSwagger12RegistryResources(Registry registry, String swagger12location, API api)
throws MalformedURLException, ParseException, RegistryException {
-
+ log.debug("Calling getSwagger2docUsingSwagger12RegistryResources");
JSONParser parser = new JSONParser();
String swagger12BasePath = null;
Resource swaggerRes = registry.get(swagger12location + APIConstants.API_DOC_1_2_RESOURCE_NAME);
- JSONObject swagger12doc = (JSONObject) parser.parse(new String((byte[]) swaggerRes.getContent()));
- Map apiDefPaths = new HashMap();
- Resource swagger12Res = registry.get(swagger12location);
+ try {
+ JSONObject swagger12doc = (JSONObject) parser.parse(new String((byte[]) swaggerRes.getContent(), "UTF8"));
- //get all the resources inside the 1.2 resource location
- String[] apiDefinitions = (String[]) swagger12Res.getContent();
+ Map apiDefPaths = new HashMap();
+ Resource swagger12Res = registry.get(swagger12location);
- //get each resource in the 1.2 folder except the api-doc resource
- for (String apiDefinition : apiDefinitions) {
+ //get all the resources inside the 1.2 resource location
+ String[] apiDefinitions = (String[]) swagger12Res.getContent();
- String resourceName = apiDefinition.substring(apiDefinition.lastIndexOf("/"));
- //skip if api-doc file
- if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
- continue;
- }
+ //get each resource in the 1.2 folder except the api-doc resource
+ for (String apiDefinition : apiDefinitions) {
+
+ String resourceName = apiDefinition.substring(apiDefinition.lastIndexOf("/"));
+ //skip if api-doc file
+ if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
+ continue;
+ }
+
+ Resource resource = registry.get(apiDefinition);
+
+ String swaggerDocContent;
- Resource resource = registry.get(apiDefinition);
- JSONObject apiDef =
- (JSONObject) parser.parse(new String((byte[]) resource.getContent()));
- //get the base path. this is same for all api definitions.
- swagger12BasePath = (String) apiDef.get("basePath");
- JSONArray apiArray = (JSONArray) apiDef.get("apis");
- for (Object anApiArray : apiArray) {
- JSONObject api = (JSONObject) anApiArray;
- String path = (String) api.get("path");
- JSONArray operations = (JSONArray) api.get("operations");
- //set the operations object inside each api definition and set it in a map against its resource path
- apiDefPaths.put(path, operations);
+ if (resource.getContent() instanceof String[]) {
+ swaggerDocContent = Arrays.toString((String[]) resource.getContent());
+ } else {
+ swaggerDocContent = new String((byte[]) resource.getContent(), "UTF8");
+ }
+
+ log.debug("swaggerDocContent : " + swaggerDocContent);
+
+ JSONObject apiDef = (JSONObject) parser.parse(swaggerDocContent);
+ //get the base path. this is same for all api definitions.
+ swagger12BasePath = (String) apiDef.get("basePath");
+ if (apiDef.containsKey("apis")) {
+ JSONArray apiArray = (JSONArray) apiDef.get("apis");
+ for (Object anApiArray : apiArray) {
+ JSONObject apiObject = (JSONObject) anApiArray;
+ String path = (String) apiObject.get("path");
+ JSONArray operations = (JSONArray) apiObject.get("operations");
+ //set the operations object inside each api definition and set it in a map against its resource path
+ apiDefPaths.put(path, operations);
+ }
+ } else {
+ log.error("Cannot find resources in swagger v1.2 document");
+ }
}
+ JSONObject swagger2Doc = generateSwagger2Document(swagger12doc, apiDefPaths, swagger12BasePath, api);
+ return swagger2Doc.toJSONString();
+ } catch (UnsupportedEncodingException e) {
+ log.error("Error while reading swagger resource", e);
}
- JSONObject swagger2Doc = generateSwagger2Document(swagger12doc, apiDefPaths, swagger12BasePath);
- return swagger2Doc.toJSONString();
+
+ return null;
}
@@ -510,37 +683,52 @@ private String getSwagger2docUsingSwagger12RegistryResources(Registry registry,
*/
private static JSONObject generateSwagger2Document(JSONObject swagger12doc,
- Map apiDefPaths, String swagger12BasePath)
+ Map apiDefPaths, String swagger12BasePath, API api)
throws ParseException, MalformedURLException {
+ log.debug("Calling generateSwagger2Document");
+
//create swagger 2.0 doc
JSONObject swagger20doc = new JSONObject();
//set swagger version
- swagger20doc.put("swagger", "2.0");
+ swagger20doc.put(Constants.SWAGGER, Constants.SWAGGER_V2);
//set the info object
- JSONObject info = generateInfoObject(swagger12doc);
+ JSONObject info = generateInfoObject(swagger12doc, api);
//update info object
- swagger20doc.put("info", info);
+ swagger20doc.put(Constants.SWAGGER_INFO, info);
//set the paths object
JSONObject pathObj = generatePathsObj(apiDefPaths);
- swagger20doc.put("paths", pathObj);
-
- URL url = new URL(swagger12BasePath);
- swagger20doc.put("host", url.getHost());
- swagger20doc.put("basePath", url.getPath());
-
- JSONArray schemes = new JSONArray();
- schemes.add(url.getProtocol());
- swagger20doc.put("schemes", schemes);
+ //JSONObject pathObj = generatePathsObj(api);
+ swagger20doc.put(Constants.SWAGGER_PATHS, pathObj);
+
+ //Base path and host is not needed for swagger v2.0
+ /*if (swagger12BasePath != null) {
+ URL url = new URL(swagger12BasePath);
+ swagger20doc.put(Constants.SWAGGER_HOST, url.getHost());
+ swagger20doc.put(Constants.SWAGGER_BASE_PATH, url.getPath());
+
+ JSONArray schemes = new JSONArray();
+ schemes.add(url.getProtocol());
+ swagger20doc.put(Constants.SWAGGER_SCHEMES, schemes);
+ }
+ else {
+ log.debug("swagger12BasePath is null");
+ }*/
//securityDefinitions
- if (swagger12doc.containsKey("authorizations")) {
+ if (swagger12doc.containsKey(Constants.SWAGGER_AUTHORIZATIONS)) {
JSONObject securityDefinitions = generateSecurityDefinitionsObject(swagger12doc);
- swagger20doc.put("securityDefinitions", securityDefinitions);
+ swagger20doc.put(Constants.SWAGGER_X_WSO2_SECURITY, securityDefinitions);
}
+ //Add a sample definition
+ JSONObject sampleDefinitionObject = new JSONObject();
+ JSONObject sampleItemObject = new JSONObject();
+ sampleDefinitionObject.put(Constants.SWAGGER_SAMPLE_DEFINITION, sampleItemObject);
+ swagger20doc.put(Constants.SWAGGER_DEFINITIONS, sampleDefinitionObject);
+
return swagger20doc;
}
@@ -554,20 +742,23 @@ private static JSONObject generateSwagger2Document(JSONObject swagger12doc,
* @throws ParseException
*/
private static JSONObject generateSecurityDefinitionsObject(JSONObject swagger12doc) throws ParseException {
+ log.debug("Calling generateSecurityDefinitionsObject");
JSONParser parser = new JSONParser();
JSONObject securityDefinitionObject = new JSONObject();
JSONObject securitySchemeObject = (JSONObject) parser.parse(Constants.DEFAULT_SECURITY_SCHEME);
-
- JSONObject authorizations = (JSONObject) swagger12doc.get("authorizations");
- Set authTypes = authorizations.keySet();
-
- for (Object obj : authTypes) {
- JSONObject authObj = (JSONObject) authorizations.get(obj.toString());
- if (authObj.containsKey("scopes")) {
- //Put it to custom WSO2 scopes
- securitySchemeObject.put("x-wso2-scopes", authObj.get("scopes"));
+ if(swagger12doc.containsKey(Constants.SWAGGER_AUTHORIZATIONS)) {
+ JSONObject authorizations = (JSONObject) swagger12doc.get(Constants.SWAGGER_AUTHORIZATIONS);
+ Set authTypes = authorizations.keySet();
+ for (Object obj : authTypes) {
+ JSONObject authObj = (JSONObject) authorizations.get(obj.toString());
+ if (authObj.containsKey(Constants.SWAGGER_SCOPES)) {
+ //Put it to custom WSO2 scopes
+ if(authObj.containsKey(Constants.SWAGGER_SCOPES)) {
+ securitySchemeObject.put(Constants.SWAGGER_X_WSO2_SCOPES, authObj.get(Constants.SWAGGER_SCOPES));
+ }
+ }
+ securityDefinitionObject.put(Constants.SWAGGER_OBJECT_NAME_APIM, securitySchemeObject);
}
- securityDefinitionObject.put(obj.toString(), securitySchemeObject);
}
return securityDefinitionObject;
}
@@ -581,51 +772,60 @@ private static JSONObject generateSecurityDefinitionsObject(JSONObject swagger12
* @return swagger v2 infoObject
* @throws ParseException
*/
- private static JSONObject generateInfoObject(JSONObject swagger12doc) throws ParseException {
+ private static JSONObject generateInfoObject(JSONObject swagger12doc, API api) throws ParseException {
- JSONObject infoObj = (JSONObject) swagger12doc.get("info");
+ JSONObject infoObj;
JSONParser parser = new JSONParser();
JSONObject swagger2InfoObj = (JSONObject) parser.parse(Constants.DEFAULT_INFO);
+ String title = api.getId().getApiName();
+ String version = api.getId().getVersion();
- //set the required parameters first
- String title = (String) infoObj.get("title");
- String version = (String) swagger12doc.get("apiVersion");
-
- swagger2InfoObj.put("title", title);
- swagger2InfoObj.put("version", version);
- if (infoObj.containsKey("description")) {
- swagger2InfoObj.put("description", infoObj.get("description"));
- }
- if (infoObj.containsKey("termsOfServiceUrl")) {
- swagger2InfoObj.put("termsOfService", infoObj.get("termsOfServiceUrl"));
- }
+ /*Check whether info object is available in swagger 1.2 or not, if not skip reading it and get title and version
+ from API object */
+ if (swagger12doc.containsKey("info")) {
+ infoObj = (JSONObject) swagger12doc.get("info");
+ if (infoObj.containsKey("title")) {
+ title = (String) infoObj.get("title");
+ }
+ if (infoObj.containsKey("apiVersion")) {
+ version = (String) swagger12doc.get("apiVersion");
+ }
+ if (infoObj.containsKey(Constants.SWAGGER_DESCRIPTION)) {
+ swagger2InfoObj.put(Constants.SWAGGER_DESCRIPTION, infoObj.get("description"));
+ }
+ if (infoObj.containsKey(Constants.SWAGGER_TERMS_OF_SERVICE_URL)) {
+ swagger2InfoObj.put(Constants.SWAGGER_TERMS_OF_SERVICE, infoObj.get(Constants.SWAGGER_TERMS_OF_SERVICE_URL));
+ }
- //contact object
- if (infoObj.containsKey("contact")) {
- JSONObject contactsObj = new JSONObject();
- String contact = (String) infoObj.get("contact");
- if (contact.contains("http")) {
- contactsObj.put("url", contact);
- } else if (contact.contains("@")) {
- contactsObj.put("email", contact);
- } else {
- contactsObj.put("name", contact);
+ //contact object
+ if (infoObj.containsKey(Constants.SWAGGER_CONTACT)) {
+ JSONObject contactsObj = new JSONObject();
+ String contact = (String) infoObj.get(Constants.SWAGGER_CONTACT);
+ if (contact.contains("http")) {
+ contactsObj.put(Constants.SWAGGER_URL, contact);
+ } else if (contact.contains("@")) {
+ contactsObj.put(Constants.SWAGGER_EMAIL, contact);
+ } else {
+ contactsObj.put(Constants.SWAGGER_NAME, contact);
+ }
+ swagger2InfoObj.put(Constants.SWAGGER_CONTACT, contactsObj);
}
- swagger2InfoObj.put("contact", contactsObj);
- }
- //licence object
- JSONObject licenseObj = new JSONObject();
- if (infoObj.containsKey("license")) {
- licenseObj.put("name", infoObj.get("license"));
- }
- if (infoObj.containsKey("licenseUrl")) {
- licenseObj.put("url", infoObj.get("licenseUrl"));
- }
- if (!licenseObj.isEmpty()) {
- swagger2InfoObj.put("license", licenseObj);
+ //licence object
+ JSONObject licenseObj = new JSONObject();
+ if (infoObj.containsKey(Constants.SWAGGER_LICENCE)) {
+ licenseObj.put(Constants.SWAGGER_NAME, infoObj.get(Constants.SWAGGER_LICENCE));
+ }
+ if (infoObj.containsKey(Constants.SWAGGER_LICENCE_URL)) {
+ licenseObj.put(Constants.SWAGGER_URL, infoObj.get(Constants.SWAGGER_LICENCE_URL));
+ }
+ if (!licenseObj.isEmpty()) {
+ swagger2InfoObj.put(Constants.SWAGGER_LICENCE, licenseObj);
+ }
}
+ swagger2InfoObj.put(Constants.SWAGGER_TITLE, title);
+ swagger2InfoObj.put(Constants.SWAGGER_VER, version);
return swagger2InfoObj;
}
@@ -640,7 +840,13 @@ private static JSONObject generateInfoObject(JSONObject swagger12doc) throws Par
*/
private static JSONObject generatePathsObj(Map apiDefinitionPaths) throws ParseException {
JSONObject pathsObj = new JSONObject();
- JSONParser jsonParser = new JSONParser();
+
+ String defaultType = "string";
+ //add default response
+ JSONObject responseObject = new JSONObject();
+ JSONObject status200 = new JSONObject();
+ status200.put(Constants.SWAGGER_DESCRIPTION, "OK");
+ responseObject.put(Constants.SWAGGER_RESPONSE_200, status200);
for (Map.Entry entry : apiDefinitionPaths.entrySet()) {
String key = entry.getKey();
@@ -648,64 +854,81 @@ private static JSONObject generatePathsObj(Map apiDefinitionP
JSONObject pathItemObj = new JSONObject();
for (Object operation : operations) {
JSONObject operationObject = (JSONObject) operation;
- String method = (String) operationObject.get("method");
- JSONArray swagger2ParamObjects = (JSONArray) operationObject.get("parameters");
- JSONObject swagger2OperationsObj = new JSONObject();
- JSONArray newParameters = new JSONArray();
- for (Object swagger2ParamObj : swagger2ParamObjects) {
- JSONObject oldParam = (JSONObject) swagger2ParamObj;
- JSONObject paramObj = new JSONObject();
- paramObj.put("name", oldParam.get("name"));
- paramObj.put("in", oldParam.get("paramType"));
- paramObj.put("required", oldParam.get("required"));
- if (paramObj.containsKey("description")) {
- paramObj.put("description", oldParam.get("description"));
- } else {
- paramObj.put("description", "");
- }
- //Skip body parameter of GET and DELETE methods
- /*if (!("GET".equals(method)) && !("DELETE".equals(method))) {
- newParameters.add(paramObj);
- } else {
- if (!("body".equals(oldParam.get("paramType")))) {
+ if (operationObject.containsKey("method")) {
+ String method = (String) operationObject.get("method");
+ if (operationObject.containsKey("parameters")) {
+ JSONArray swagger2ParamObjects = (JSONArray) operationObject.get("parameters");
+ JSONObject swagger2OperationsObj = new JSONObject();
+ JSONArray newParameters = new JSONArray();
+ for (Object swagger2ParamObj : swagger2ParamObjects) {
+ JSONObject oldParam = (JSONObject) swagger2ParamObj;
+ JSONObject paramObj = new JSONObject();
+ paramObj.put(Constants.SWAGGER_NAME, oldParam.get(Constants.SWAGGER_NAME));
+
+ paramObj.put(Constants.SWAGGER_PARAM_TYPE_IN, oldParam.get("paramType"));
+ if (Constants.SWAGGER_PARAM_TYPE_BODY.equals(oldParam.get("paramType"))) {
+ JSONObject refObject = new JSONObject();
+ refObject.put(Constants.SWAGGER_REF, "#/definitions/sampleItem");
+ paramObj.put(Constants.SWAGGER_BODY_SCHEMA, refObject);
+ } else {
+ if (paramObj.containsKey(Constants.SWAGGER_REQUIRED_PARAM)) {
+ paramObj.put(Constants.SWAGGER_PARAM_TYPE, oldParam.get("type"));
+ } else {
+ paramObj.put(Constants.SWAGGER_PARAM_TYPE, defaultType);
+ }
+ }
+
+ if (paramObj.containsKey(Constants.SWAGGER_REQUIRED_PARAM)) {
+ paramObj.put(Constants.SWAGGER_REQUIRED_PARAM, oldParam.get(Constants.SWAGGER_REQUIRED_PARAM));
+ } else {
+ paramObj.put(Constants.SWAGGER_REQUIRED_PARAM, false);
+ }
+ if (paramObj.containsKey(Constants.SWAGGER_DESCRIPTION)) {
+ paramObj.put(Constants.SWAGGER_DESCRIPTION, oldParam.get(Constants.SWAGGER_DESCRIPTION));
+ } else {
+ paramObj.put(Constants.SWAGGER_DESCRIPTION, "");
+ }
newParameters.add(paramObj);
}
- }*/
- }
-
- //generate the Operation object
- // (https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operationObject)
- swagger2OperationsObj.put("operationId", operationObject.get("nickname"));
- //setting operation level params
- swagger2OperationsObj.put("parameters", newParameters);
- if (operationObject.containsKey("notes")) {
- swagger2OperationsObj.put("description", operationObject.get("notes"));
- }
- if (operationObject.containsKey("summary")) {
- swagger2OperationsObj.put("summary", operationObject.get("summary"));
- }
+ //generate the Operation object
+ // (https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operationObject)
+ swagger2OperationsObj.put(Constants.SWAGGER_OPERATION_ID, operationObject.get("nickname"));
+ //setting operation level params
+ swagger2OperationsObj.put(Constants.SWAGGER_PARAMETERS, newParameters);
- //set pathItem object for the resource
- //(https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#pathItemObject)
- pathItemObj.put(method.toLowerCase(), swagger2OperationsObj);
+ //Add auth_type and throttling_tier
+ if (operationObject.containsKey(Constants.SWAGGER_AUTH_TYPE)) {
+ swagger2OperationsObj.put(Constants.SWAGGER_X_AUTH_TYPE, operationObject.get(Constants.SWAGGER_AUTH_TYPE));
+ }
+ if (operationObject.containsKey(Constants.SWAGGER_THROTTLING_TIER)) {
+ swagger2OperationsObj.put(Constants.SWAGGER_X_THROTTLING_TIER, operationObject.get(Constants.SWAGGER_THROTTLING_TIER));
+ }
- //set the responseObject
- //(https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responsesObject)
- JSONObject responseObject = null;
- if (operationObject.containsKey("responseMessages")) {
- responseObject = new JSONObject();
- JSONArray responseMessages = (JSONArray) operationObject.get("responseMessages");
- for (Object responseMessage : responseMessages) {
- JSONObject errorObj = (JSONObject) responseMessage;
- responseObject.put(errorObj.get("code"), errorObj.get("message"));
+ if (operationObject.containsKey("notes")) {
+ swagger2OperationsObj.put(Constants.SWAGGER_DESCRIPTION, operationObject.get("notes"));
+ }
+ if (operationObject.containsKey(Constants.SWAGGER_SUMMARY)) {
+ swagger2OperationsObj.put(Constants.SWAGGER_SUMMARY, operationObject.get(Constants.SWAGGER_SUMMARY));
+ }
+ //set pathItem object for the resource
+ //(https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#pathItemObject)
+ pathItemObj.put(method.toLowerCase(), swagger2OperationsObj);
+ //set the responseObject
+ //(https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responsesObject)
+ if (operationObject.containsKey("responseMessages")) {
+ responseObject = new JSONObject();
+ JSONArray responseMessages = (JSONArray) operationObject.get("responseMessages");
+ for (Object responseMessage : responseMessages) {
+ JSONObject errorObj = (JSONObject) responseMessage;
+ responseObject.put(errorObj.get("code"), errorObj.get("message"));
+ }
+ }
+ swagger2OperationsObj.put(Constants.SWAGGER_RESPONSES, responseObject);
}
+ } else {
+ log.error("Needed parameter method does not exists in swagger v1.2 doc");
}
- if (responseObject == null) {
- //set a default response message since this is required field
- responseObject = (JSONObject) jsonParser.parse(Constants.DEFAULT_RESPONSE);
- }
- swagger2OperationsObj.put("responses", responseObject);
}
pathsObj.put(key, pathItemObj);
}
@@ -721,7 +944,7 @@ private static JSONObject generatePathsObj(Map apiDefinitionP
*/
@Override
public void cleanOldResources() throws APIMigrationException {
- log.info("Resource cleanup started for API Manager 1.9.0");
+ log.info("Resource cleanup started for API Manager " + Constants.VERSION_1_9);
try {
for (Tenant tenant : tenantsArray) {
PrivilegedCarbonContext.startTenantFlow();
@@ -770,6 +993,17 @@ public void cleanOldResources() throws APIMigrationException {
}
}
+ /**
+ * This method is used to migrate API stats database.
+ * Database schema changes and data modifications as required will be carried out.
+ *
+ * @throws APIMigrationException
+ */
+ @Override
+ public void statsMigration() throws APIMigrationException {
+ StatDBUtil.updateContext();
+ }
+
/**
* This method is used to migrate all the file system components
* such as sequences and synapse files
@@ -788,10 +1022,11 @@ public void fileSystemMigration() throws APIMigrationException {
*
* @throws APIMigrationException
*/
- void sequenceMigration() throws APIMigrationException {
+ void sequenceMigration() {
String repository = CarbonUtils.getCarbonRepository();
String TenantRepo = CarbonUtils.getCarbonTenantsDirPath();
for (Tenant tenant : tenantsArray) {
+ log.debug("Start sequenceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
String SequenceFilePath;
if (tenant.getId() != MultitenantConstants.SUPER_TENANT_ID) {
SequenceFilePath = TenantRepo + "/" + tenant.getId() +
@@ -799,6 +1034,13 @@ void sequenceMigration() throws APIMigrationException {
} else {
SequenceFilePath = repository + "synapse-configs/default/sequences/";
}
+
+ File sequenceFolder = new File(SequenceFilePath);
+ if (!sequenceFolder.exists()) {
+ log.debug("No sequence folder exists for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ continue;
+ }
+
try {
FileUtils.copyInputStreamToFile(MigrateFrom18to19.class.getResourceAsStream(
"/18to19Migration/sequence-scripts/_cors_request_handler_.xml"),
@@ -808,8 +1050,12 @@ void sequenceMigration() throws APIMigrationException {
ResourceUtil.copyNewSequenceToExistingSequences(SequenceFilePath, "_token_fault_");
ResourceUtil.copyNewSequenceToExistingSequences(SequenceFilePath, "fault");
} catch (IOException e) {
- ResourceUtil.handleException("Error occurred while reading file to copy.", e);
+ log.error("Error occurred while reading file to copy.", e);
+ } catch (APIMigrationException e) {
+ log.error("Copying sequences failed", e);
}
+
+ log.debug("End sequenceMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
}
}
@@ -821,32 +1067,56 @@ void sequenceMigration() throws APIMigrationException {
* @throws APIMigrationException
*/
- void synapseAPIMigration() throws APIMigrationException {
+ void synapseAPIMigration() {
String repository = CarbonUtils.getCarbonRepository();
String tenantRepository = CarbonUtils.getCarbonTenantsDirPath();
for (Tenant tenant : tenantsArray) {
-
- String SequenceFilePath;
+ log.debug("Start synapseAPIMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ String apiFilePath;
if (tenant.getId() != MultitenantConstants.SUPER_TENANT_ID) {
- SequenceFilePath = tenantRepository + "/" + tenant.getId() +
+ apiFilePath = tenantRepository + "/" + tenant.getId() +
"/synapse-configs/default/api";
} else {
- SequenceFilePath = repository + "synapse-configs/default/api";
+ apiFilePath = repository + "synapse-configs/default/api";
}
- File APIFiles = new File(SequenceFilePath);
+ File APIFiles = new File(apiFilePath);
File[] synapseFiles = APIFiles.listFiles();
+
+ if (synapseFiles == null) {
+ log.debug("No api folder " + apiFilePath + " exists for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
+ continue;
+ }
+
for (File synapseFile : synapseFiles) {
- if (tenant.getId() == MultitenantConstants.SUPER_TENANT_ID) {
- if (synapseFile.getName().matches("[\\w+][--][\\w+][__v]")) {
- ResourceUtil.updateSynapseAPI(synapseFile, "ENDPOINT");
- }
- } else {
- if (synapseFile.getName().matches("[\\w+][-AT-]" + tenant.getDomain() + "[--][\\w+][--v]]")) {
- ResourceUtil.updateSynapseAPI(synapseFile, "ENDPOINT");
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ docFactory.setNamespaceAware(true);
+
+ try {
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(synapseFile);
+
+ doc.getDocumentElement().normalize();
+
+ Element rootElement = doc.getDocumentElement();
+
+ if (Constants.SYNAPSE_API_ROOT_ELEMENT.equals(rootElement.getNodeName()) &&
+ rootElement.hasAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VERSION)) {
+ ResourceUtil.updateSynapseAPI(doc, synapseFile);
}
- }
+
+ } catch (ParserConfigurationException e) {
+ log.error("Parsing exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (SAXException e) {
+ log.error("SAX exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (IOException e) {
+ log.error("IO exception encountered for " + synapseFile.getAbsolutePath(), e);
+ } catch (APIMigrationException e) {
+ log.error("Updating synapse file failed for " + synapseFile.getAbsolutePath(), e);
+ }
}
+
+ log.debug("End synapseAPIMigration for tenant " + tenant.getId() + "(" + tenant.getDomain() + ")");
}
}
}
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationClient.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationClient.java
index 07d2ba13dc..868b36cde4 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationClient.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationClient.java
@@ -65,4 +65,12 @@ public interface MigrationClient {
*/
public void cleanOldResources() throws APIMigrationException;
+ /**
+ * This method is used to migrate API stats database.
+ * Database schema changes and data modifications as required will be carried out.
+ *
+ * @throws APIMigrationException
+ */
+ public void statsMigration() throws APIMigrationException;
+
}
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
index 0ef7593adf..af67c52770 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/MigrationDBCreator.java
@@ -19,13 +19,22 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.migration.APIMigrationException;
+import org.wso2.carbon.apimgt.migration.util.Constants;
import org.wso2.carbon.apimgt.migration.util.ResourceUtil;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.dbcreator.DatabaseCreator;
import javax.sql.DataSource;
-import java.io.*;
-import java.sql.*;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
import java.util.StringTokenizer;
public class MigrationDBCreator extends DatabaseCreator {
@@ -53,22 +62,6 @@ protected String getDbScriptLocation(String databaseType) {
@Override
public void createRegistryDatabase() throws SQLException, APIMigrationException {
- /*String databaseType;
- try {
- databaseType = DatabaseCreator.getDatabaseType(this.dataSource.getConnection());
-
- String scriptPath = getDbScriptLocation(databaseType);
- File scriptFile = new File(scriptPath);
- if (scriptFile.exists()) {
- super.createRegistryDatabase();
- } else {
- log.error("API Migration client cannot find the database script.");
- }
- } catch (Exception e) {
- ResourceUtil.handleException("Error occurred while accessing the database connection", e);
- }*/
-
-
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
@@ -81,6 +74,7 @@ public void createRegistryDatabase() throws SQLException, APIMigrationException
} catch (SQLException e) {
ResourceUtil.handleException("Error occurred while migrating the database", e);
} catch (Exception e) {
+ /* executeSQLScript throws generic Exception because DatabaseCreator.getDatabaseType superclass throws */
ResourceUtil.handleException("Error occurred while executing sql script", e);
} finally {
if (connection != null) {
@@ -91,14 +85,15 @@ public void createRegistryDatabase() throws SQLException, APIMigrationException
}
+ //org.wso2.carbon.utils.dbcreator.DatabaseCreator.getDatabaseType throws generic Exception
private void executeSQLScript() throws Exception {
String databaseType = DatabaseCreator.getDatabaseType(this.connection);
boolean keepFormat = false;
- if ("oracle".equals(databaseType)) {
+ if (Constants.DB_TYPE_ORACLE.equals(databaseType)) {
delimiter = "/";
- } else if ("db2".equals(databaseType)) {
+ } else if (Constants.DB_TYPE_DB2.equals(databaseType)) {
delimiter = "/";
- } else if ("openedge".equals(databaseType)) {
+ } else if (Constants.DB_TYPE_OPENEDGE.equals(databaseType)) {
delimiter = "/";
keepFormat = true;
}
@@ -110,7 +105,7 @@ private void executeSQLScript() throws Exception {
try {
InputStream is = new FileInputStream(dbscriptName);
- reader = new BufferedReader(new InputStreamReader(is));
+ reader = new BufferedReader(new InputStreamReader(is, "UTF8"));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
@@ -148,17 +143,17 @@ private void executeSQLScript() throws Exception {
}
} catch (IOException e) {
log.error("Error occurred while executing SQL script for creating registry database", e);
- throw new Exception("Error occurred while executing SQL script for creating registry database", e);
+ throw new APIMigrationException("Error occurred while executing SQL script for creating registry database", e);
} finally {
- if(reader != null){
+ if (reader != null) {
reader.close();
}
}
}
- private void executeSQL(String sql) throws Exception {
+ private void executeSQL(String sql) throws APIMigrationException {
// Check and ignore empty statements
if ("".equals(sql.trim())) {
return;
@@ -203,7 +198,7 @@ private void executeSQL(String sql) throws Exception {
log.info("Table Already Exists. Hence, skipping table creation");
}
} else {
- throw new Exception("Error occurred while executing : " + sql, e);
+ throw new APIMigrationException("Error occurred while executing : " + sql, e);
}
} finally {
if (resultSet != null) {
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
index fedf9f7c32..2b4a6a43c7 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/client/internal/APIMMigrationServiceComponent.java
@@ -25,14 +25,13 @@
import org.wso2.carbon.apimgt.migration.client.MigrateFrom18to19;
import org.wso2.carbon.apimgt.migration.client.MigrationClient;
import org.wso2.carbon.apimgt.migration.util.Constants;
+import org.wso2.carbon.apimgt.migration.util.StatDBUtil;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.service.RealmService;
import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
/**
@@ -63,70 +62,51 @@ public class APIMMigrationServiceComponent {
* @param context OSGi component context.
*/
protected void activate(ComponentContext context) {
- String migrateVersion = null;
- boolean cleanupNeeded = false;
- boolean isDBMigrationNeeded = false;
- boolean isRegistryMigrationNeeded = false;
- boolean isFileSystemMigrationNeeded = false;
-
try {
APIMgtDBUtil.initialize();
} catch (Exception e) {
- log.error("Error occurred while initializing DB Util " + e.getMessage());
+ //APIMgtDBUtil.initialize() throws generic exception
+ log.error("Error occurred while initializing DB Util ", e);
}
- Map argsMap = new HashMap();
- argsMap.put("migrateVersion", System.getProperty("migrate"));
- argsMap.put("isCleanUpNeeded", System.getProperty("cleanup"));
- argsMap.put("isDBMigrationNeeded", System.getProperty("migrateDB"));
- argsMap.put("isRegMigrationNeeded", System.getProperty("migrateReg"));
- argsMap.put("isFileSysMigrationNeeded", System.getProperty("migrateFS"));
-
-
- if (!argsMap.isEmpty()) {
- migrateVersion = argsMap.get("migrateVersion");
- if (argsMap.get("isCleanUpNeeded") != null) {
- cleanupNeeded = Boolean.parseBoolean(argsMap.get("isCleanUpNeeded"));
- }
- if (argsMap.get("isDBMigrationNeeded") != null) {
- isDBMigrationNeeded = Boolean.parseBoolean(argsMap.get("isDBMigrationNeeded"));
- }
- if (argsMap.get("isRegMigrationNeeded") != null) {
- isRegistryMigrationNeeded = Boolean.parseBoolean(argsMap.get("isRegMigrationNeeded"));
- }
- if (argsMap.get("isFileSysMigrationNeeded") != null) {
- isFileSystemMigrationNeeded = Boolean.parseBoolean(argsMap.get("isFileSysMigrationNeeded"));
- }
- }
+ String migrateToVersion = System.getProperty(Constants.ARG_MIGRATE_TO_VERSION);
+ String tenants = System.getProperty(Constants.ARG_MIGRATE_TENANTS);
+ String blackListTenants = System.getProperty(Constants.ARG_MIGRATE_BLACKLIST_TENANTS);
+ boolean migrateAll = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_ALL));
+ boolean cleanupNeeded = Boolean.parseBoolean(System.getProperty(Constants.ARG_CLEANUP));
+ boolean isDBMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_DB));
+ boolean isRegistryMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_REG));
+ boolean isFileSystemMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_FILE_SYSTEM));
+ boolean isStatMigration = Boolean.parseBoolean(System.getProperty(Constants.ARG_MIGRATE_STATS));
try {
- if (migrateVersion != null) {
- if (Constants.VERSION_1_9.equalsIgnoreCase(migrateVersion)) {
- log.info("Migrating WSO2 API Manager 1.8.0 resources to WSO2 API Manager 1.9.0");
+ if (migrateToVersion != null) {
+ if (Constants.VERSION_1_9.equalsIgnoreCase(migrateToVersion)) {
+ log.info("Migrating WSO2 API Manager 1.8.0 to WSO2 API Manager 1.9.0");
// Create a thread and wait till the APIManager DBUtils is initialized
- MigrationClient migrateFrom18to19 = new MigrateFrom18to19();
+ MigrationClient migrateFrom18to19 = new MigrateFrom18to19(tenants, blackListTenants);
//Default operation will migrate all three types of resources
- if (argsMap.get("isDBMigrationNeeded") == null && argsMap.get("isRegMigrationNeeded") == null && argsMap.get("isFileSysMigrationNeeded") == null) {
+ if (migrateAll) {
log.info("Migrating WSO2 API Manager 1.8.0 resources to WSO2 API Manager 1.9.0");
- migrateFrom18to19.databaseMigration(migrateVersion);
+ migrateFrom18to19.databaseMigration(migrateToVersion);
migrateFrom18to19.registryResourceMigration();
migrateFrom18to19.fileSystemMigration();
} else {
//Only performs database migration
- if (isDBMigrationNeeded) {
+ if (isDBMigration) {
log.info("Migrating WSO2 API Manager 1.8.0 databases to WSO2 API Manager 1.9.0");
- migrateFrom18to19.databaseMigration(migrateVersion);
+ migrateFrom18to19.databaseMigration(migrateToVersion);
}
//Only performs registry migration
- if (isRegistryMigrationNeeded) {
+ if (isRegistryMigration) {
log.info("Migrating WSO2 API Manager 1.8.0 registry resources to WSO2 API Manager 1.9.0");
migrateFrom18to19.registryResourceMigration();
}
//Only performs file system migration
- if (isFileSystemMigrationNeeded) {
+ if (isFileSystemMigration) {
log.info("Migrating WSO2 API Manager 1.8.0 file system resources to WSO2 API Manager 1.9.0");
migrateFrom18to19.fileSystemMigration();
}
@@ -137,21 +117,35 @@ protected void activate(ComponentContext context) {
log.info("Old resources cleaned up.");
}
+ if (isStatMigration) {
+ StatDBUtil.initialize();
+ migrateFrom18to19.statsMigration();
+ log.info("Stat migration completed");
+ }
+
if (log.isDebugEnabled()) {
log.debug("API Manager 1.8.0 to 1.9.0 migration successfully completed");
}
} else {
- log.error("The given migrate version " + migrateVersion + " is not supported. Please check the version and try again.");
+ log.error("The given migrate version " + migrateToVersion + " is not supported. Please check the version and try again.");
+
+ }
+ }
+ else { // Migration version not specified
+ if (migrateAll || cleanupNeeded || isDBMigration || isRegistryMigration || isFileSystemMigration) {
+ log.error("The property " + Constants.ARG_MIGRATE_TO_VERSION + " has not been specified . Please specify the property and try again.");
}
}
} catch (APIMigrationException e) {
- log.error("API Management exception occurred while migrating " + e.getMessage());
+ log.error("API Management exception occurred while migrating", e);
} catch (UserStoreException e) {
- log.error("User store exception occurred while migrating " + e.getMessage());
+ log.error("User store exception occurred while migrating", e);
} catch (SQLException e) {
- log.error("SQL exception occurred while migrating " + e.getMessage());
+ log.error("SQL exception occurred while migrating", e);
} catch (Exception e) {
- log.error("Error occurred while initializing data source. " + e.getMessage());
+ log.error("Generic exception occurred while migrating", e);
+ } catch (Throwable t) {
+ log.error("Throwable error", t);
}
log.info("WSO2 API Manager migration component successfully activated.");
}
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
index a26023a8b5..6416abd0ff 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/Constants.java
@@ -18,20 +18,121 @@
public class Constants {
- public static final String VERSION_1_7 = "1.7";
- public static final String VERSION_1_8 = "1.8";
public static final String VERSION_1_9 = "1.9";
public static final String LINE_BREAK = "\\n";
public static final String CONSTRAINT = "constraint";
public static final String ALTER = "alter";
public static final String DELIMITER = ";";
+ public static final String API = "api";
public static final String GOVERNANCE_COMPONENT_REGISTRY_LOCATION = "/repository/components/org.wso2.carbon" +
".governance";
public static final String RXT_PATH = "/repository/resources/rxts/api.rxt";
public static final String DATA_SOURCE_NAME = "DataSourceName";
- //constants for swagger v2
+ // Migration client argument property names
+ public static final String ARG_MIGRATE_TO_VERSION = "migrateToVersion";
+ public static final String ARG_MIGRATE_TENANTS = "tenants";
+ public static final String ARG_MIGRATE_BLACKLIST_TENANTS = "blackListed";
+ public static final String ARG_MIGRATE_ALL = "migrate";
+ public static final String ARG_CLEANUP = "cleanup";
+ public static final String ARG_MIGRATE_DB = "migrateDB";
+ public static final String ARG_MIGRATE_REG = "migrateReg";
+ public static final String ARG_MIGRATE_FILE_SYSTEM = "migrateFS";
+ public static final String ARG_MIGRATE_STATS = "migrateStats";
+
+ // Synapse configuration related
+ public static final String SYNAPSE_API_ROOT_ELEMENT = "api";
+ public static final String SYNAPSE_API_ATTRIBUTE_CONTEXT = "context";
+ public static final String SYNAPSE_API_ATTRIBUTE_VERSION = "version";
+ public static final String SYNAPSE_API_ATTRIBUTE_VERSION_TYPE = "version-type";
+ public static final String SYNAPSE_API_ATTRIBUTE_SOURCE = "source";
+ public static final String SYNAPSE_API_ATTRIBUTE_NAME = "name";
+ public static final String SYNAPSE_API_ATTRIBUTE_EXPRESSION = "expression";
+ public static final String SYNAPSE_API_ATTRIBUTE_CLASS = "class";
+ public static final String SYNAPSE_API_ATTRIBUTE_VALUE = "value";
+ public static final String SYNAPSE_API_ATTRIBUTE_XMLNS = "xmlns";
+ public static final String SYNAPSE_API_ELEMENT_PROPERTY = "property";
+ public static final String SYNAPSE_API_ELEMENT_FILTER = "filter";
+ public static final String SYNAPSE_API_ELEMENT_CLASS = "class";
+ public static final String SYNAPSE_API_ELEMENT_INSEQUENCE = "inSequence";
+ public static final String SYNAPSE_API_ELEMENT_OUTSEQUENCE = "outSequence";
+ public static final String SYNAPSE_API_ELEMENT_HANDLERS = "handlers";
+ public static final String SYNAPSE_API_ELEMENT_HANDLER = "handler";
+ public static final String SYNAPSE_API_ELEMENT_THEN = "then";
+ public static final String SYNAPSE_API_ELEMENT_SEND = "send";
+ public static final String SYNAPSE_API_VALUE_BACKEND_REQUEST_TIME = "api.ut.backendRequestTime";
+ public static final String SYNAPSE_API_VALUE_AM_KEY_TYPE = "$ctx:AM_KEY_TYPE";
+ public static final String SYNAPSE_API_VALUE_EXPRESSION = "get-property('SYSTEM_TIME')";
+ public static final String SYNAPSE_API_VALUE_RESPONSE_HANDLER = "org.wso2.carbon.apimgt.usage.publisher.APIMgtResponseHandler";
+ public static final String SYNAPSE_API_VALUE_CORS_HANDLER = "org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler";
+ public static final String SYNAPSE_API_VALUE_INLINE = "inline";
+ public static final String SYNAPSE_API_VALUE_INLINE_UPPERCASE = "INLINE";
+ public static final String SYNAPSE_API_VALUE_ENPOINT = "ENDPOINT";
+ public static final String SYNAPSE_API_VALUE_VERSION_TYPE_URL = "url";
+ public static final String SYNAPSE_API_VALUE_VERSION_TYPE_CONTEXT = "context";
+ public static final String SYNAPSE_API_XMLNS = "http://ws.apache.org/ns/synapse";
+
+
+ //Swagger v2.0 constants
+ public static final String SWAGGER_X_SCOPE = "x-scope";
+ public static final String SWAGGER_X_AUTH_TYPE = "x-auth-type";
+ public static final String SWAGGER_X_THROTTLING_TIER = "x-throttling-tier";
+ public static final String SWAGGER_AUTH_TYPE = "auth_type";
+ public static final String SWAGGER_THROTTLING_TIER = "throttling_tier";
+ public static final String SWAGGER_X_MEDIATION_SCRIPT = "x-mediation-script";
+ public static final String SWAGGER_X_WSO2_SECURITY = "x-wso2-security";
+ public static final String SWAGGER_X_WSO2_SCOPES = "x-wso2-scopes";
+ public static final String SWAGGER_SCOPE_KEY = "key";
+ public static final String SWAGGER_NAME = "name";
+ public static final String SWAGGER_DESCRIPTION = "description";
+ public static final String SWAGGER_ROLES = "roles";
+ public static final String SWAGGER_TITLE = "title";
+ public static final String SWAGGER_EMAIL = "email";
+ public static final String SWAGGER_URL = "url";
+ public static final String SWAGGER_CONTACT = "contact";
+ public static final String SWAGGER_LICENCE = "license";
+ public static final String SWAGGER_LICENCE_URL = "licenseUrl";
+ public static final String SWAGGER_VER = "version";
+ public static final String SWAGGER_OBJECT_NAME_APIM = "apim";
+ public static final String SWAGGER_PATHS = "paths";
+ public static final String SWAGGER_RESPONSES = "responses";
+ public static final String SWAGGER = "swagger";
+ public static final String SWAGGER_V2 = "2.0";
+ public static final String SWAGGER_INFO = "info";
+ public static final String SWAGGER_REQUIRED_PARAM = "required";
+ public static final String SWAGGER_HOST = "host";
+ public static final String SWAGGER_BASE_PATH = "basePath";
+ public static final String SWAGGER_SCHEMES = "schemes";
+ public static final String SWAGGER_AUTHORIZATIONS = "authorizations";
+ public static final String SWAGGER_SECURITY_DEFINITIONS = "securityDefinitions";
+ public static final String SWAGGER_SCOPES = "scopes";
+ public static final String SWAGGER_TERMS_OF_SERVICE = "termsOfService";
+ public static final String SWAGGER_TERMS_OF_SERVICE_URL = "termsOfServiceUrl";
+ public static final String SWAGGER_PARAM_TYPE_IN = "in";
+ public static final String SWAGGER_OPERATION_ID = "operationId";
+ public static final String SWAGGER_PARAMETERS = "parameters";
+ public static final String SWAGGER_SUMMARY = "summary";
+ public static final String SWAGGER_RESPONSE_200 = "200";
+ public static final String SWAGGER_PARAM_TYPE = "type";
+ public static final String SWAGGER_PARAM_TYPE_BODY = "body";
+ public static final String SWAGGER_BODY_SCHEMA = "schema";
+ public static final String SWAGGER_DEFINITIONS = "definitions";
+ public static final String SWAGGER_REF = "$ref";
+ public static final String SWAGGER_SAMPLE_DEFINITION = "sampleItem";
+
+
+
+
+
+ //database types
+ public static final String DB_TYPE_ORACLE = "oracle";
+ public static final String DB_TYPE_DB2 = "db2";
+ public static final String DB_TYPE_MYSQL = "mysql";
+ public static final String DB_TYPE_MSSQL = "mssql";
+ public static final String DB_TYPE_POSTGRE = "postgre";
+ public static final String DB_TYPE_OPENEDGE = "openedge";
+
//default Swagger v2 response parameter
public static final String DEFAULT_RESPONSE = "{ " +
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
index 37772b56d7..12843caa10 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/ResourceUtil.java
@@ -33,14 +33,12 @@
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.sql.Connection;
import java.sql.SQLException;
public class ResourceUtil {
@@ -91,31 +89,6 @@ public static String getRxtResourceLocation(String apiName, String apiVersion, S
- /**
- * This method is used to get the database driver name
- *
- * @return user database type as a string
- * @throws SQLException
- */
- private static String getDatabaseDriverName() throws SQLException {
- Connection connection = APIMgtDBUtil.getConnection();
- String databaseType;
-
- if (connection.getMetaData().getDriverName().contains("MySQL")) {
- databaseType = "MYSQL";
- } else if (connection.getMetaData().getDriverName().contains("MS SQL") ||
- connection.getMetaData().getDriverName().contains("Microsoft")) {
- databaseType = "MSSQL";
- } else if (connection.getMetaData().getDriverName().contains("H2")) {
- databaseType = "H2";
- } else if (connection.getMetaData().getDriverName().contains("PostgreSQL")) {
- databaseType = "POSTGRESQL";
- } else {
- databaseType = "ORACLE";
- }
- return databaseType;
- }
-
/**
* This method picks the query according to the users database
*
@@ -134,32 +107,27 @@ public static String pickQueryFromResources(String migrateVersion, String queryT
String resourcePath;
- if (migrateVersion.equalsIgnoreCase(Constants.VERSION_1_9)) {
+ if (Constants.VERSION_1_9.equalsIgnoreCase(migrateVersion)) {
//pick from 18to19Migration/sql-scripts
- resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.8.0_to_1.9.0/";
- } else if (migrateVersion.equalsIgnoreCase(Constants.VERSION_1_8)) {
- //pick from 17to18Migration/sql-scripts
- resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.7.0_to_1.8.0/";
- } else if (migrateVersion.equalsIgnoreCase(Constants.VERSION_1_7)) {
- //pick from 16to17Migration/sql-scripts
- resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.6.0_to_1.7.0/";
+ resourcePath = CarbonUtils.getCarbonHome() + File.separator + "migration-scripts" + File.separator + "18-19-migration" + File.separator;
} else {
throw new APIMigrationException("No query picked up for the given migrate version. Please check the migrate version.");
}
if (Constants.CONSTRAINT.equals(queryType)) {
- resourcePath = CarbonUtils.getCarbonHome() + "/dbscripts/migration-1.8.0_to_1.9.0/";
+ resourcePath = CarbonUtils.getCarbonHome() + File.separator + "migration-scripts" + File.separator + "18-19-migration" + File.separator;
//queryTobeExecuted = resourcePath + "drop-fk.sql";
queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + "drop-fk.sql")), "UTF-8");
} else {
- queryTobeExecuted = resourcePath + databaseType + ".sql";
+ queryTobeExecuted = resourcePath + databaseType + ".sql";
//queryTobeExecuted = IOUtils.toString(new FileInputStream(new File(resourcePath + databaseType + ".sql")), "UTF-8");
}
} catch (IOException e) {
throw new APIMigrationException("Error occurred while accessing the sql from resources. " + e);
} catch (Exception e) {
- throw new APIMigrationException("Error occurred while accessing the sql from resources. " + e);
+ //getDatabaseType inherited from DBCreator, which throws generic exception
+ throw new APIMigrationException("Error occurred while searching for database type " + e);
}
return queryTobeExecuted;
@@ -188,18 +156,26 @@ public static void copyNewSequenceToExistingSequences(String sequenceDirectoryFi
try {
String namespace = "http://ws.apache.org/ns/synapse";
String filePath = sequenceDirectoryFilePath + sequenceName + ".xml";
+
+ File sequenceFile = new File(filePath);
+
+ if (!sequenceFile.exists()) {
+ log.debug("Sequence file " + sequenceName + ".xml does not exist");
+ return;
+ }
+
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filePath);
Node sequence = doc.getElementsByTagName("sequence").item(0);
Element corsSequence = doc.createElementNS(namespace, "sequence");
- corsSequence.setAttribute("key", "_cors_request_handler");
+ corsSequence.setAttribute("key", "_cors_request_handler_");
boolean available = false;
for (int i = 0; i < sequence.getChildNodes().getLength(); i++) {
Node tempNode = sequence.getChildNodes().item(i);
if (tempNode.getNodeType() == Node.ELEMENT_NODE &&"sequence".equals(tempNode.getLocalName()) &&
- "_cors_request_handler".equals(tempNode.getAttributes().getNamedItem("key").getTextContent())) {
+ "_cors_request_handler_".equals(tempNode.getAttributes().getNamedItem("key").getTextContent())) {
available = true;
break;
}
@@ -235,48 +211,164 @@ public static void copyNewSequenceToExistingSequences(String sequenceDirectoryFi
/**
* To update synapse API
*
- * @param filePath file path
- * @param implementation new impl
+ * @param document XML document object
+ * @param file synapse file
* @throws APIMigrationException
*/
- public static void updateSynapseAPI(File filePath, String implementation) throws APIMigrationException {
+ public static void updateSynapseAPI(Document document, File file) throws APIMigrationException {
try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- docFactory.setNamespaceAware(true);
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- Document doc = null;
- doc = docBuilder.parse(filePath.getAbsolutePath());
- Node handlers = doc.getElementsByTagName("handlers").item(0);
- Element corsHandler = doc.createElement("handler");
- corsHandler.setAttribute("class", "org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler");
- Element property = doc.createElement("property");
- property.setAttribute("name", "inline");
- property.setAttribute("value", implementation);
- corsHandler.appendChild(property);
- NodeList handlerNodes = doc.getElementsByTagName("handler");
- for (int i = 0; i < handlerNodes.getLength(); i++) {
- Node tempNode = handlerNodes.item(i);
- if ("org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler"
- .equals(tempNode.getAttributes().getNamedItem("class").getTextContent())) {
- handlers.removeChild(tempNode);
- }
- handlers.insertBefore(corsHandler, handlerNodes.item(0));
- }
+ updateAPIAttributes(document, file);
+ updateHandlers(document, file);
+ updateResources(document, file);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
- DOMSource source = new DOMSource(doc);
- StreamResult result = new StreamResult(filePath);
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ DOMSource source = new DOMSource(document);
+ StreamResult result = new StreamResult(file);
transformer.transform(source, result);
- } catch (ParserConfigurationException e) {
- handleException("Could not initiate Document Builder.", e);
} catch (TransformerConfigurationException e) {
handleException("Could not initiate TransformerFactory Builder.", e);
} catch (TransformerException e) {
handleException("Could not transform the source.", e);
- } catch (SAXException e) {
- handleException("SAX exception occurred while parsing the file.", e);
- } catch (IOException e) {
- handleException("IO Exception occurred. Please check the file.", e);
+ }
+ }
+
+ private static void updateAPIAttributes(Document document, File file) {
+ Element apiElement = document.getDocumentElement();
+
+ String versionType = apiElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VERSION_TYPE);
+
+ if (versionType.equals(Constants.SYNAPSE_API_VALUE_VERSION_TYPE_URL)) {
+ String context = apiElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_CONTEXT);
+ String version = apiElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VERSION);
+
+ context = context + "/" + version;
+ apiElement.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_CONTEXT, context);
+ apiElement.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VERSION_TYPE, Constants.SYNAPSE_API_VALUE_VERSION_TYPE_CONTEXT);
+ }
+ }
+
+
+ private static void updateHandlers(Document document, File file) {
+ Element handlersElement = (Element) document.getElementsByTagNameNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_HANDLERS).item(0);
+
+ NodeList handlerNodes = handlersElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_HANDLER);
+
+ for (int i = 0; i < handlerNodes.getLength(); ++i) {
+ Element handler = (Element) handlerNodes.item(i);
+
+ String className = handler.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_CLASS);
+
+ if (className.equals(Constants.SYNAPSE_API_VALUE_CORS_HANDLER)) {
+ handlersElement.removeChild(handler);
+ break;
+ }
+ }
+
+ // Find the inSequence
+ Element inSequenceElement = (Element) document.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_INSEQUENCE).item(0);
+
+ NodeList sendElements = inSequenceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_SEND);
+
+ Element corsHandler = document.createElementNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_HANDLER);
+ corsHandler.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_CLASS, Constants.SYNAPSE_API_VALUE_CORS_HANDLER);
+ Element property = document.createElementNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_PROPERTY);
+ property.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME, Constants.SYNAPSE_API_VALUE_INLINE);
+
+ if (0 < sendElements.getLength()) {
+ property.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VALUE, Constants.SYNAPSE_API_VALUE_ENPOINT);
+ }
+ else {
+ property.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_VALUE, Constants.SYNAPSE_API_VALUE_INLINE_UPPERCASE);
+ }
+
+ corsHandler.appendChild(property);
+
+ handlersElement.insertBefore(corsHandler, handlersElement.getFirstChild());
+
+ }
+
+ private static void updateResources(Document document, File file) throws APIMigrationException {
+ NodeList resourceNodes = document.getElementsByTagName("resource");
+ for (int i = 0; i < resourceNodes.getLength(); i++) {
+ Element resourceElement = (Element) resourceNodes.item(i);
+
+ updateInSequence(resourceElement, document);
+
+ updateOutSequence(resourceElement, document);
+ }
+ }
+
+ private static void updateInSequence(Element resourceElement, Document doc) {
+ // Find the inSequence
+ Element inSequenceElement = (Element) resourceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_INSEQUENCE).item(0);
+
+ // Find the property element in the inSequence
+ NodeList properties = inSequenceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_PROPERTY);
+
+ boolean isBackEndRequestTimeSet = false;
+
+ for (int i = 0; i < properties.getLength(); ++i) {
+ Element propertyElement = (Element) properties.item(i);
+
+ if (propertyElement.hasAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME)) {
+ if (Constants.SYNAPSE_API_VALUE_BACKEND_REQUEST_TIME.equals(propertyElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME))) {
+ isBackEndRequestTimeSet = true;
+ break;
+ }
+ }
+ }
+
+ if (!isBackEndRequestTimeSet) {
+ NodeList filters = inSequenceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_FILTER);
+
+ for (int j = 0; j < filters.getLength(); ++j) {
+ Element filterElement = (Element) filters.item(j);
+
+ if (Constants.SYNAPSE_API_VALUE_AM_KEY_TYPE.equals(filterElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_SOURCE))) {
+ // Only one element can exist in filter mediator
+ Element thenElement = (Element) filterElement.getElementsByTagNameNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_THEN).item(0);
+
+ // At least one element must exist as a child of element
+ Element sendElement = (Element) thenElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_SEND).item(0);
+
+ Element propertyElement = doc.createElementNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_PROPERTY);
+ propertyElement.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME, Constants.SYNAPSE_API_VALUE_BACKEND_REQUEST_TIME);
+ propertyElement.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_EXPRESSION, Constants.SYNAPSE_API_VALUE_EXPRESSION);
+
+ thenElement.insertBefore(propertyElement, sendElement);
+ }
+ }
+ }
+ }
+
+
+ private static void updateOutSequence(Element resourceElement, Document doc) {
+ // Find the outSequence
+ Element outSequenceElement = (Element) resourceElement.getElementsByTagNameNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_OUTSEQUENCE).item(0);
+
+ NodeList classNodes = outSequenceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_CLASS);
+
+ boolean isResponseHandlerSet = false;
+
+ for (int i = 0; i < classNodes.getLength(); ++i) {
+ Element classElement = (Element) classNodes.item(i);
+
+ if (Constants.SYNAPSE_API_VALUE_RESPONSE_HANDLER.equals(classElement.getAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME))) {
+ isResponseHandlerSet = true;
+ break;
+ }
+ }
+
+ if (!isResponseHandlerSet) {
+ // There must be at least one element for an outSequence
+ Element sendElement = (Element) outSequenceElement.getElementsByTagName(Constants.SYNAPSE_API_ELEMENT_SEND).item(0);
+
+ Element classElement = doc.createElementNS(Constants.SYNAPSE_API_XMLNS, Constants.SYNAPSE_API_ELEMENT_CLASS);
+ classElement.setAttribute(Constants.SYNAPSE_API_ATTRIBUTE_NAME, Constants.SYNAPSE_API_VALUE_RESPONSE_HANDLER);
+ classElement.removeAttribute(Constants.SYNAPSE_API_ATTRIBUTE_XMLNS);
+
+ outSequenceElement.insertBefore(classElement, sendElement);
}
}
}
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/StatDBUtil.java b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/StatDBUtil.java
new file mode 100644
index 0000000000..558d79dc67
--- /dev/null
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/java/org/wso2/carbon/apimgt/migration/util/StatDBUtil.java
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2015, 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.migration.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.migration.APIMigrationException;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class StatDBUtil {
+ private static volatile DataSource dataSource = null;
+ private static final String DATA_SOURCE_NAME = "jdbc/WSO2AM_STATS_DB";
+
+ private static final String TABLE_API_DESTINATION_SUMMARY = "API_DESTINATION_SUMMARY";
+ private static final String TABLE_API_FAULT_SUMMARY = "API_FAULT_SUMMARY";
+ private static final String TABLE_API_REQUEST_SUMMARY = "API_REQUEST_SUMMARY";
+ private static final String TABLE_API_RESOURCE_USAGE_SUMMARY = "API_Resource_USAGE_SUMMARY";
+ private static final String TABLE_API_VERSION_USAGE_SUMMARY = "API_VERSION_USAGE_SUMMARY";
+
+ private static final Log log = LogFactory.getLog(StatDBUtil.class);
+
+ public static void initialize() throws APIMigrationException {
+ try {
+ Context ctx = new InitialContext();
+ dataSource = (DataSource) ctx.lookup(DATA_SOURCE_NAME);
+ } catch (NamingException e) {
+ throw new APIMigrationException("Error while looking up the data " +
+ "source: " + DATA_SOURCE_NAME);
+ }
+ }
+
+
+ public static void updateContext() throws APIMigrationException {
+ if (dataSource == null) {
+ throw new APIMigrationException("Stats Data source is not configured properly.");
+ }
+
+ String responseSummarySQL = "UPDATE API_RESPONSE_SUMMARY " +
+ "SET CONTEXT = concat(API_RESPONSE_SUMMARY.CONTEXT,'/'," +
+ "(SELECT DISTINCT(VERSION) FROM WSO2AM_STATS_DB.API_REQUEST_SUMMARY WHERE CONTEXT NOT LIKE concat('%', VERSION))) " +
+ "WHERE API_VERSION = (SELECT DISTINCT(API_VERSION) FROM WSO2AM_STATS_DB.API_REQUEST_SUMMARY WHERE CONTEXT NOT LIKE concat('%', VERSION))";
+
+ executeSQL(responseSummarySQL);
+
+ executeSQL(getCommonUpdateSQL(TABLE_API_DESTINATION_SUMMARY));
+ executeSQL(getCommonUpdateSQL(TABLE_API_FAULT_SUMMARY));
+ executeSQL(getCommonUpdateSQL(TABLE_API_REQUEST_SUMMARY));
+ executeSQL(getCommonUpdateSQL(TABLE_API_RESOURCE_USAGE_SUMMARY));
+ executeSQL(getCommonUpdateSQL(TABLE_API_VERSION_USAGE_SUMMARY));
+ }
+
+ private static String getCommonUpdateSQL(String table) {
+ return "UPDATE " + table + " SET CONTEXT = concat(CONTEXT,'/',VERSION) " +
+ "WHERE CONTEXT NOT LIKE concat('%', VERSION)";
+ }
+
+
+ private static void executeSQL(String sql) {
+ Connection connection = null;
+ Statement statement = null;
+ try {
+ connection = dataSource.getConnection();
+ statement = connection.createStatement();
+ connection.setAutoCommit(false);
+ statement.execute(sql);
+ connection.commit();
+
+ } catch (SQLException e) {
+ log.error("SQLException when executing: " + sql, e);
+ }
+ finally {
+ try {
+ if (statement != null) { statement.close(); }
+ if (connection != null) { connection.close(); }
+ } catch (SQLException e) {
+ log.error("SQLException when closing resource", e);
+ }
+
+ }
+ }
+}
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/constraint/query.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/constraint/drop-fk.sql
similarity index 100%
rename from modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/constraint/query.sql
rename to modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/constraint/drop-fk.sql
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/h2.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/h2.sql
index ae07a78757..715dc21948 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/h2.sql
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/h2.sql
@@ -5,3 +5,28 @@ ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN ALTER COLUMN SCOPE VARCHAR(767);
ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE ALTER COLUMN SCOPE VARCHAR(767);
ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN ALTER COLUMN TOKEN_SCOPE VARCHAR(767);
ALTER TABLE AM_SUBSCRIBER ALTER COLUMN USER_ID VARCHAR(255);
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD CREATE_MODE VARCHAR(30) DEFAULT 'CREATED';
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD TOKEN_SCOPE VARCHAR(256) DEFAULT 'default';
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD INPUTS VARCHAR(256);
+ALTER TABLE AM_APPLICATION ADD GROUP_ID VARCHAR(100);
+ALTER TABLE AM_API ADD CONTEXT_TEMPLATE VARCHAR(256);
+UPDATE AM_API SET CONTEXT_TEMPLATE = CONTEXT WHERE CONTEXT_TEMPLATE IS NULL;
+UPDATE AM_API SET CONTEXT = concat(CONTEXT,concat('/',API_VERSION)) WHERE CONTEXT NOT LIKE concat('%', API_VERSION);
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET TOKEN_SCOPE = concat(TOKEN_SCOPE, concat(' ', 'am_application_scope')) WHERE USER_TYPE = 'APPLICATION' AND TOKEN_SCOPE NOT LIKE '%am_application_scope%';
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET VALIDITY_PERIOD = -2000 WHERE VALIDITY_PERIOD = 9223372036854775807;
+ALTER TABLE AM_API ADD CREATED_BY VARCHAR(100);
+ALTER TABLE AM_API ADD CREATED_TIME TIMESTAMP;
+ALTER TABLE AM_API ADD UPDATED_BY VARCHAR(100);
+ALTER TABLE AM_API ADD UPDATED_TIME TIMESTAMP;
+ALTER TABLE AM_SUBSCRIBER ADD CREATED_BY VARCHAR(100);
+ALTER TABLE AM_SUBSCRIBER ADD CREATED_TIME TIMESTAMP;
+ALTER TABLE AM_SUBSCRIBER ADD UPDATED_BY VARCHAR(100);
+ALTER TABLE AM_SUBSCRIBER ADD UPDATED_TIME TIMESTAMP;
+ALTER TABLE AM_SUBSCRIPTION ADD CREATED_BY VARCHAR(100);
+ALTER TABLE AM_SUBSCRIPTION ADD CREATED_TIME TIMESTAMP;
+ALTER TABLE AM_SUBSCRIPTION ADD UPDATED_BY VARCHAR(100);
+ALTER TABLE AM_SUBSCRIPTION ADD UPDATED_TIME TIMESTAMP;
+ALTER TABLE AM_APPLICATION ADD CREATED_BY VARCHAR(100);
+ALTER TABLE AM_APPLICATION ADD CREATED_TIME TIMESTAMP;
+ALTER TABLE AM_APPLICATION ADD UPDATED_BY VARCHAR(100);
+ALTER TABLE AM_APPLICATION ADD UPDATED_TIME TIMESTAMP;
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mssql.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mssql.sql
index bfbeb01f83..ff4a631f0f 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mssql.sql
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mssql.sql
@@ -1,11 +1,15 @@
+ALTER TABLE AM_SUBSCRIBER ALTER COLUMN USER_ID VARCHAR(255);
+ALTER TABLE AM_APPLICATION ADD GROUP_ID VARCHAR(100);
+ALTER TABLE AM_API ADD CONTEXT_TEMPLATE VARCHAR(256);
ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD CREATE_MODE VARCHAR(30) DEFAULT 'CREATED';
-ALTER TABLE AM_API_LC_EVENT ALTER COLUMN USER_ID VARCHAR(255) NOT NULL;
ALTER TABLE AM_APPLICATION_REGISTRATION ADD TOKEN_SCOPE VARCHAR(256) DEFAULT 'default';
ALTER TABLE AM_APPLICATION_REGISTRATION ADD INPUTS VARCHAR(256);
-ALTER TABLE AM_APPLICATION ADD GROUP_ID VARCHAR(100);
-ALTER TABLE AM_APPLICATION ALTER COLUMN NAME VARCHAR(100);
-ALTER TABLE IDN_OAUTH1A_REQUEST_TOKEN ALTER COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN ALTER COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE ALTER COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN ALTER COLUMN TOKEN_SCOPE VARCHAR(767);
-ALTER TABLE AM_SUBSCRIBER ALTER COLUMN USER_ID VARCHAR(255);
+ALTER TABLE AM_API_LC_EVENT ALTER COLUMN USER_ID VARCHAR(255) NOT NULL;
+UPDATE AM_API SET CONTEXT_TEMPLATE = CONTEXT WHERE CONTEXT_TEMPLATE IS NULL;
+UPDATE AM_API SET CONTEXT = CONTEXT + '/' + API_VERSION WHERE CONTEXT NOT LIKE '%' + API_VERSION;
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET TOKEN_SCOPE = TOKEN_SCOPE + ' ' + 'am_application_scope' WHERE USER_TYPE = 'APPLICATION' AND TOKEN_SCOPE NOT LIKE '%am_application_scope%';
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET VALIDITY_PERIOD = -2000 WHERE VALIDITY_PERIOD = 9223372036854775807;
+ALTER TABLE AM_API ADD CREATED_BY VARCHAR(100), CREATED_TIME DATETIME, UPDATED_BY VARCHAR(100), UPDATED_TIME DATETIME;
+ALTER TABLE AM_SUBSCRIBER ADD CREATED_BY VARCHAR(100), CREATED_TIME DATETIME, UPDATED_BY VARCHAR(100), UPDATED_TIME DATETIME;
+ALTER TABLE AM_SUBSCRIPTION ADD CREATED_BY VARCHAR(100), CREATED_TIME DATETIME, UPDATED_BY VARCHAR(100), UPDATED_TIME DATETIME;
+ALTER TABLE AM_APPLICATION ADD CREATED_BY VARCHAR(100), CREATED_TIME DATETIME, UPDATED_BY VARCHAR(100), UPDATED_TIME DATETIME;
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mysql.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mysql.sql
index 1289cfdbd3..c40ed2fc35 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mysql.sql
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/mysql.sql
@@ -9,3 +9,12 @@ ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN MODIFY COLUMN SCOPE VARCHAR(767);
ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE MODIFY COLUMN SCOPE VARCHAR(767);
ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN MODIFY COLUMN TOKEN_SCOPE VARCHAR(767);
ALTER TABLE AM_SUBSCRIBER MODIFY COLUMN USER_ID VARCHAR(255);
+ALTER TABLE AM_API ADD CONTEXT_TEMPLATE VARCHAR(256);
+UPDATE AM_API SET CONTEXT_TEMPLATE = CONTEXT WHERE CONTEXT_TEMPLATE IS NULL;
+UPDATE AM_API SET CONTEXT = concat(CONTEXT,concat('/',API_VERSION)) WHERE CONTEXT NOT LIKE concat('%', API_VERSION);
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET TOKEN_SCOPE = concat(TOKEN_SCOPE, concat(' ', 'am_application_scope')) WHERE USER_TYPE = 'APPLICATION' AND TOKEN_SCOPE NOT LIKE '%am_application_scope%';
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET VALIDITY_PERIOD = -2000 WHERE VALIDITY_PERIOD = 9223372036854775807;
+ALTER TABLE AM_API ADD (CREATED_BY VARCHAR(100), CREATED_TIME TIMESTAMP, UPDATED_BY VARCHAR(100), UPDATED_TIME TIMESTAMP);
+ALTER TABLE AM_SUBSCRIBER ADD (CREATED_BY VARCHAR(100), CREATED_TIME TIMESTAMP, UPDATED_BY VARCHAR(100), UPDATED_TIME TIMESTAMP);
+ALTER TABLE AM_SUBSCRIPTION ADD (CREATED_BY VARCHAR(100), CREATED_TIME TIMESTAMP, UPDATED_BY VARCHAR(100), UPDATED_TIME TIMESTAMP);
+ALTER TABLE AM_APPLICATION ADD (CREATED_BY VARCHAR(100), CREATED_TIME TIMESTAMP, UPDATED_BY VARCHAR(100), UPDATED_TIME TIMESTAMP);
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/oracle.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/oracle.sql
index e16ad449ae..a02d48f1a4 100644
--- a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/oracle.sql
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/oracle.sql
@@ -1,11 +1,16 @@
-ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD CREATE_MODE VARCHAR(30) DEFAULT 'CREATED';
-ALTER TABLE AM_API_LC_EVENT MODIFY COLUMN USER_ID VARCHAR(255) NOT NULL;
-ALTER TABLE AM_APPLICATION_REGISTRATION ADD TOKEN_SCOPE VARCHAR(256) DEFAULT 'default';
-ALTER TABLE AM_APPLICATION_REGISTRATION ADD INPUTS VARCHAR(256);
-ALTER TABLE AM_APPLICATION ADD COLUMN GROUP_ID VARCHAR(100);
-ALTER TABLE AM_APPLICATION MODIFY COLUMN NAME VARCHAR(100);
-ALTER TABLE IDN_OAUTH1A_REQUEST_TOKEN MODIFY COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH1A_ACCESS_TOKEN MODIFY COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH2_AUTHORIZATION_CODE MODIFY COLUMN SCOPE VARCHAR(767);
-ALTER TABLE IDN_OAUTH2_ACCESS_TOKEN MODIFY COLUMN TOKEN_SCOPE VARCHAR(767);
-ALTER TABLE AM_SUBSCRIBER MODIFY COLUMN USER_ID VARCHAR(255);
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD CREATE_MODE VARCHAR2(30) DEFAULT 'CREATED';
+ALTER TABLE AM_API_LC_EVENT MODIFY USER_ID VARCHAR2(255);
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD TOKEN_SCOPE VARCHAR2(256) DEFAULT 'default';
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD INPUTS VARCHAR2(256);
+ALTER TABLE AM_APPLICATION ADD GROUP_ID VARCHAR2(100);
+ALTER TABLE AM_APPLICATION MODIFY NAME VARCHAR2(100);
+ALTER TABLE AM_SUBSCRIBER MODIFY USER_ID VARCHAR2(255);
+ALTER TABLE AM_API ADD CONTEXT_TEMPLATE VARCHAR2(256);
+UPDATE AM_API SET CONTEXT_TEMPLATE = CONTEXT WHERE CONTEXT_TEMPLATE IS NULL;
+UPDATE AM_API SET CONTEXT = concat(CONTEXT,concat('/',API_VERSION)) WHERE CONTEXT NOT LIKE concat('%', API_VERSION);
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET TOKEN_SCOPE = concat(TOKEN_SCOPE, concat(' ', 'am_application_scope')) WHERE USER_TYPE = 'APPLICATION' AND TOKEN_SCOPE NOT LIKE '%am_application_scope%';
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET VALIDITY_PERIOD = -2000 WHERE VALIDITY_PERIOD = 9223372036854775807;
+ALTER TABLE AM_API ADD (CREATED_BY VARCHAR2(100), CREATED_TIME DATE, UPDATED_BY VARCHAR2(100), UPDATED_TIME DATE);
+ALTER TABLE AM_SUBSCRIBER ADD (CREATED_BY VARCHAR2(100), CREATED_TIME DATE, UPDATED_BY VARCHAR2(100), UPDATED_TIME DATE);
+ALTER TABLE AM_SUBSCRIPTION ADD (CREATED_BY VARCHAR2(100), CREATED_TIME DATE, UPDATED_BY VARCHAR2(100), UPDATED_TIME DATE);
+ALTER TABLE AM_APPLICATION ADD (CREATED_BY VARCHAR2(100), CREATED_TIME DATE, UPDATED_BY VARCHAR2(100), UPDATED_TIME DATE);
diff --git a/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/postgresql.sql b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/postgresql.sql
new file mode 100644
index 0000000000..e1456b5613
--- /dev/null
+++ b/modules/distribution/resources/migration-1.8.0_to_1.9.0/wso2-api-migration-client/src/main/resources/18to19Migration/sql-scripts/postgresql.sql
@@ -0,0 +1,16 @@
+ALTER TABLE AM_SUBSCRIBER ALTER COLUMN USER_ID TYPE VARCHAR(255);
+ALTER TABLE AM_APPLICATION ADD COLUMN GROUP_ID VARCHAR(100);
+ALTER TABLE AM_API ADD COLUMN CONTEXT_TEMPLATE VARCHAR(256);
+ALTER TABLE AM_APPLICATION_KEY_MAPPING ADD COLUMN CREATE_MODE VARCHAR(30) DEFAULT 'CREATED';
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD COLUMN TOKEN_SCOPE VARCHAR(256) DEFAULT 'default';
+ALTER TABLE AM_APPLICATION_REGISTRATION ADD COLUMN INPUTS VARCHAR(256);
+ALTER TABLE AM_API_LC_EVENT ALTER COLUMN USER_ID TYPE VARCHAR(255);
+ALTER TABLE AM_API_LC_EVENT ALTER COLUMN USER_ID SET NOT NULL;
+UPDATE AM_API SET CONTEXT_TEMPLATE = CONTEXT WHERE CONTEXT_TEMPLATE IS NULL;
+UPDATE AM_API SET CONTEXT = CONTEXT || '/' || API_VERSION WHERE CONTEXT NOT LIKE '%' || API_VERSION;
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET TOKEN_SCOPE = TOKEN_SCOPE || ' ' || 'am_application_scope' WHERE USER_TYPE = 'APPLICATION' AND TOKEN_SCOPE NOT LIKE '%am_application_scope%';
+UPDATE IDN_OAUTH2_ACCESS_TOKEN SET VALIDITY_PERIOD = -2000 WHERE VALIDITY_PERIOD = 9223372036854775807;
+ALTER TABLE AM_API ADD CREATED_BY VARCHAR(100), ADD CREATED_TIME DATE, ADD UPDATED_BY VARCHAR(100), ADD UPDATED_TIME DATE;
+ALTER TABLE AM_SUBSCRIBER ADD CREATED_BY VARCHAR(100), ADD CREATED_TIME DATE, ADD UPDATED_BY VARCHAR(100), ADD UPDATED_TIME DATE;
+ALTER TABLE AM_SUBSCRIPTION ADD CREATED_BY VARCHAR(100), ADD CREATED_TIME DATE, ADD UPDATED_BY VARCHAR(100), ADD UPDATED_TIME DATE;
+ALTER TABLE AM_APPLICATION ADD CREATED_BY VARCHAR(100), ADD CREATED_TIME DATE, ADD UPDATED_BY VARCHAR(100), ADD UPDATED_TIME DATE;
\ No newline at end of file
diff --git a/modules/distribution/resources/sql/mysql_cluster.sql b/modules/distribution/resources/sql/mysql_cluster.sql
new file mode 100644
index 0000000000..89376537c3
--- /dev/null
+++ b/modules/distribution/resources/sql/mysql_cluster.sql
@@ -0,0 +1,637 @@
+-- Start of IDN Tables --
+CREATE TABLE IDN_BASE_TABLE (
+ PRODUCT_NAME VARCHAR(20),
+ PRIMARY KEY (PRODUCT_NAME)
+)ENGINE NDB;
+
+INSERT INTO IDN_BASE_TABLE values ('WSO2 Identity Server');
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH_CONSUMER_APPS (
+ CONSUMER_KEY VARCHAR(255),
+ CONSUMER_SECRET VARCHAR(512),
+ USERNAME VARCHAR(255),
+ TENANT_ID INTEGER DEFAULT 0,
+ APP_NAME VARCHAR(255),
+ OAUTH_VERSION VARCHAR(128),
+ CALLBACK_URL VARCHAR(1024),
+ GRANT_TYPES VARCHAR (1024),
+ PRIMARY KEY (CONSUMER_KEY)
+)ENGINE NDB;
+
+CREATE TABLE IDN_OAUTH1A_REQUEST_TOKEN (
+ REQUEST_TOKEN VARCHAR(255),
+ REQUEST_TOKEN_SECRET VARCHAR(512),
+ CONSUMER_KEY VARCHAR(255),
+ CALLBACK_URL VARCHAR(1024),
+ SCOPE VARCHAR(767),
+ AUTHORIZED VARCHAR(128),
+ OAUTH_VERIFIER VARCHAR(512),
+ AUTHZ_USER VARCHAR(512),
+ PRIMARY KEY (REQUEST_TOKEN),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IDN_OAUTH1A_ACCESS_TOKEN (
+ ACCESS_TOKEN VARCHAR(255),
+ ACCESS_TOKEN_SECRET VARCHAR(512),
+ CONSUMER_KEY VARCHAR(255),
+ SCOPE VARCHAR(767),
+ AUTHZ_USER VARCHAR(512),
+ PRIMARY KEY (ACCESS_TOKEN),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IDN_OAUTH2_AUTHORIZATION_CODE (
+ AUTHORIZATION_CODE VARCHAR(255),
+ CONSUMER_KEY VARCHAR(255),
+ CALLBACK_URL VARCHAR(1024),
+ SCOPE VARCHAR(767),
+ AUTHZ_USER VARCHAR(512),
+ TIME_CREATED TIMESTAMP,
+ VALIDITY_PERIOD BIGINT,
+ PRIMARY KEY (AUTHORIZATION_CODE),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IDN_OAUTH2_ACCESS_TOKEN (
+ ACCESS_TOKEN VARCHAR(255),
+ REFRESH_TOKEN VARCHAR(255),
+ CONSUMER_KEY VARCHAR(255),
+ AUTHZ_USER VARCHAR(100),
+ USER_TYPE VARCHAR (25),
+ TIME_CREATED TIMESTAMP DEFAULT 0,
+ VALIDITY_PERIOD BIGINT,
+ TOKEN_SCOPE VARCHAR(767),
+ TOKEN_STATE VARCHAR(25) DEFAULT 'ACTIVE',
+ TOKEN_STATE_ID VARCHAR (255) DEFAULT 'NONE',
+ PRIMARY KEY (ACCESS_TOKEN),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE,
+ CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY, AUTHZ_USER,USER_TYPE,TOKEN_STATE,TOKEN_STATE_ID,TOKEN_SCOPE)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE (
+ SCOPE_ID INT(11) NOT NULL AUTO_INCREMENT,
+ SCOPE_KEY VARCHAR(100) NOT NULL,
+ NAME VARCHAR(255) NULL,
+ DESCRIPTION VARCHAR(512) NULL,
+ TENANT_ID INT(11) NOT NULL DEFAULT 0,
+ ROLES VARCHAR (500) NULL,
+ PRIMARY KEY (SCOPE_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR(255) NOT NULL,
+ SCOPE_ID INTEGER (11) NOT NULL,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IDN_SCIM_GROUP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR(255) NOT NULL,
+ ATTR_NAME VARCHAR(1024) NOT NULL,
+ ATTR_VALUE VARCHAR(1024),
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+CREATE TABLE IDN_SCIM_PROVIDER (
+ CONSUMER_ID VARCHAR(255) NOT NULL,
+ PROVIDER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_PASSWORD VARCHAR(255) NOT NULL,
+ USER_URL VARCHAR(1024) NOT NULL,
+ GROUP_URL VARCHAR(1024),
+ BULK_URL VARCHAR(1024),
+ PRIMARY KEY (CONSUMER_ID,PROVIDER_ID)
+)ENGINE NDB;
+
+CREATE TABLE IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME TIMESTAMP,
+ PRIMARY KEY (USER_NAME, TENANT_ID)
+)ENGINE NDB;
+
+CREATE TABLE IDN_OPENID_USER_RPS (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ RP_URL VARCHAR(255) NOT NULL,
+ TRUSTED_ALWAYS VARCHAR(128) DEFAULT 'FALSE',
+ LAST_VISIT DATE NOT NULL,
+ VISIT_COUNT INTEGER DEFAULT 0,
+ DEFAULT_PROFILE_NAME VARCHAR(255) DEFAULT 'DEFAULT',
+ PRIMARY KEY (USER_NAME, TENANT_ID, RP_URL)
+)ENGINE NDB;
+
+CREATE TABLE IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN TIMESTAMP NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ PRIMARY KEY (HANDLE)
+)ENGINE NDB;
+
+CREATE TABLE IDN_STS_STORE (
+ ID INTEGER AUTO_INCREMENT,
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT BLOB(1024) NOT NULL,
+ CREATE_DATE TIMESTAMP NOT NULL,
+ EXPIRE_DATE TIMESTAMP NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+CREATE TABLE IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
+)ENGINE NDB;
+
+CREATE TABLE IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDN_THRIFT_SESSION (
+ SESSION_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME VARCHAR(255) NOT NULL,
+ LAST_MODIFIED_TIME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (SESSION_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDN_ASSOCIATED_ID (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ IDP_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (ID),
+ UNIQUE(IDP_USER_ID, TENANT_ID, IDP_ID)
+)ENGINE NDB;
+
+-- End of IDN Tables --
+
+
+-- Start of IDN-APPLICATION-MGT Tables--
+
+CREATE TABLE IF NOT EXISTS SP_APP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE(APP_NAME, TENANT_ID);
+
+CREATE TABLE IF NOT EXISTS SP_INBOUND_AUTH (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255) NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_AUTH_STEP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_ROLE_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_PROVISIONING_CONNECTOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ BLOCKING CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID)
+)ENGINE NDB;
+
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '1',
+ IS_PRIMARY CHAR(1) NOT NULL DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE MEDIUMBLOB,
+ CERTIFICATE BLOB,
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR (1) NOT NULL DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR (1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) NOT NULL DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) NOT NULL DEFAULT '0',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME)
+)ENGINE NDB;
+
+INSERT INTO IDP (TENANT_ID, NAME, HOME_REALM_ID) VALUES (-1234, 'LOCAL', 'localhost');
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+INSERT INTO IDP_AUTHENTICATOR (TENANT_ID, IDP_ID, NAME) VALUES (-1234, 1, 'samlsso');
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_CONFIG (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE BLOB,
+ PROPERTY_TYPE CHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_ENTITY (
+ ID INTEGER AUTO_INCREMENT,
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS IDP_LOCAL_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+)ENGINE NDB;
+-- End of IDN-APPLICATION-MGT Tables--
+
+
+-- Start of API-MGT Tables --
+CREATE TABLE IF NOT EXISTS AM_SUBSCRIBER (
+ SUBSCRIBER_ID INTEGER AUTO_INCREMENT,
+ USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ EMAIL_ADDRESS VARCHAR(256) NULL,
+ DATE_SUBSCRIBED TIMESTAMP NOT NULL,
+ PRIMARY KEY (SUBSCRIBER_ID),
+ CREATED_BY VARCHAR(100),
+ CREATED_TIME TIMESTAMP,
+ UPDATED_BY VARCHAR(100),
+ UPDATED_TIME TIMESTAMP,
+ UNIQUE (TENANT_ID,USER_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_APPLICATION (
+ APPLICATION_ID INTEGER AUTO_INCREMENT,
+ NAME VARCHAR(100),
+ SUBSCRIBER_ID INTEGER,
+ APPLICATION_TIER VARCHAR(50) DEFAULT 'Unlimited',
+ CALLBACK_URL VARCHAR(512),
+ DESCRIPTION VARCHAR(512),
+ APPLICATION_STATUS VARCHAR(50) DEFAULT 'APPROVED',
+ GROUP_ID VARCHAR(100),
+ CREATED_BY VARCHAR(100),
+ CREATED_TIME TIMESTAMP,
+ UPDATED_BY VARCHAR(100),
+ UPDATED_TIME TIMESTAMP,
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON DELETE RESTRICT,
+ PRIMARY KEY(APPLICATION_ID),
+ UNIQUE (NAME,SUBSCRIBER_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API (
+ API_ID INTEGER AUTO_INCREMENT,
+ API_PROVIDER VARCHAR(200),
+ API_NAME VARCHAR(200),
+ API_VERSION VARCHAR(30),
+ CONTEXT VARCHAR(256),
+ CONTEXT_TEMPLATE VARCHAR(256),
+ CREATED_BY VARCHAR(100),
+ CREATED_TIME TIMESTAMP,
+ UPDATED_BY VARCHAR(100),
+ UPDATED_TIME TIMESTAMP,
+ PRIMARY KEY(API_ID),
+ UNIQUE (API_PROVIDER,API_NAME,API_VERSION)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_URL_MAPPING (
+ URL_MAPPING_ID INTEGER AUTO_INCREMENT,
+ API_ID INTEGER NOT NULL,
+ HTTP_METHOD VARCHAR(20) NULL,
+ AUTH_SCHEME VARCHAR(50) NULL,
+ URL_PATTERN VARCHAR(512) NULL,
+ THROTTLING_TIER varchar(512) DEFAULT NULL,
+ MEDIATION_SCRIPT BLOB,
+ PRIMARY KEY (URL_MAPPING_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_SUBSCRIPTION (
+ SUBSCRIPTION_ID INTEGER AUTO_INCREMENT,
+ TIER_ID VARCHAR(50),
+ API_ID INTEGER,
+ LAST_ACCESSED TIMESTAMP NULL,
+ APPLICATION_ID INTEGER,
+ SUB_STATUS VARCHAR(50),
+ SUBS_CREATE_STATE VARCHAR(50) DEFAULT 'SUBSCRIBE',
+ CREATED_BY VARCHAR(100),
+ CREATED_TIME TIMESTAMP,
+ UPDATED_BY VARCHAR(100),
+ UPDATED_TIME TIMESTAMP,
+ FOREIGN KEY(APPLICATION_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON DELETE RESTRICT,
+ FOREIGN KEY(API_ID) REFERENCES AM_API(API_ID) ON DELETE RESTRICT,
+ PRIMARY KEY (SUBSCRIPTION_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_SUBSCRIPTION_KEY_MAPPING (
+ SUBSCRIPTION_ID INTEGER,
+ ACCESS_TOKEN VARCHAR(255),
+ KEY_TYPE VARCHAR(512) NOT NULL,
+ FOREIGN KEY(SUBSCRIPTION_ID) REFERENCES AM_SUBSCRIPTION(SUBSCRIPTION_ID) ON DELETE RESTRICT,
+ PRIMARY KEY(SUBSCRIPTION_ID,ACCESS_TOKEN)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_APPLICATION_KEY_MAPPING (
+ APPLICATION_ID INTEGER,
+ CONSUMER_KEY VARCHAR(255),
+ KEY_TYPE VARCHAR(512) NOT NULL,
+ STATE VARCHAR(30) NOT NULL,
+ CREATE_MODE VARCHAR(30) DEFAULT 'CREATED',
+ FOREIGN KEY(APPLICATION_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON DELETE RESTRICT,
+ PRIMARY KEY(APPLICATION_ID,KEY_TYPE)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_LC_EVENT (
+ EVENT_ID INTEGER AUTO_INCREMENT,
+ API_ID INTEGER NOT NULL,
+ PREVIOUS_STATE VARCHAR(50),
+ NEW_STATE VARCHAR(50) NOT NULL,
+ USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ EVENT_DATE TIMESTAMP NOT NULL,
+ FOREIGN KEY(API_ID) REFERENCES AM_API(API_ID) ON DELETE RESTRICT,
+ PRIMARY KEY (EVENT_ID)
+)ENGINE NDB;
+
+CREATE TABLE AM_APP_KEY_DOMAIN_MAPPING (
+ CONSUMER_KEY VARCHAR(255),
+ AUTHZ_DOMAIN VARCHAR(255) DEFAULT 'ALL',
+ PRIMARY KEY (CONSUMER_KEY,AUTHZ_DOMAIN),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_COMMENTS (
+ COMMENT_ID INTEGER AUTO_INCREMENT,
+ COMMENT_TEXT VARCHAR(512),
+ COMMENTED_USER VARCHAR(255),
+ DATE_COMMENTED TIMESTAMP NOT NULL,
+ API_ID INTEGER NOT NULL,
+ PRIMARY KEY (COMMENT_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_RATINGS (
+ RATING_ID INTEGER AUTO_INCREMENT,
+ API_ID INTEGER,
+ RATING INTEGER,
+ SUBSCRIBER_ID INTEGER,
+ FOREIGN KEY(API_ID) REFERENCES AM_API(API_ID) ON DELETE RESTRICT,
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON DELETE RESTRICT,
+PRIMARY KEY (RATING_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_TIER_PERMISSIONS (
+ TIER_PERMISSIONS_ID INTEGER AUTO_INCREMENT,
+ TIER VARCHAR(50) NOT NULL,
+ PERMISSIONS_TYPE VARCHAR(50) NOT NULL,
+ ROLES VARCHAR(512) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY(TIER_PERMISSIONS_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_EXTERNAL_STORES (
+ APISTORE_ID INTEGER AUTO_INCREMENT,
+ API_ID INTEGER,
+ STORE_ID VARCHAR(255) NOT NULL,
+ STORE_DISPLAY_NAME VARCHAR(255) NOT NULL,
+ STORE_ENDPOINT VARCHAR(255) NOT NULL,
+ STORE_TYPE VARCHAR(255) NOT NULL,
+FOREIGN KEY(API_ID) REFERENCES AM_API(API_ID) ON DELETE RESTRICT,
+PRIMARY KEY (APISTORE_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_WORKFLOWS(
+ WF_ID INTEGER AUTO_INCREMENT,
+ WF_REFERENCE VARCHAR(255) NOT NULL,
+ WF_TYPE VARCHAR(255) NOT NULL,
+ WF_STATUS VARCHAR(255) NOT NULL,
+ WF_CREATED_TIME TIMESTAMP DEFAULT 0,
+ WF_UPDATED_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
+ WF_STATUS_DESC VARCHAR(1000),
+ TENANT_ID INTEGER,
+ TENANT_DOMAIN VARCHAR(255),
+ WF_EXTERNAL_REFERENCE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (WF_ID),
+ UNIQUE (WF_EXTERNAL_REFERENCE)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_APPLICATION_REGISTRATION (
+ REG_ID INT AUTO_INCREMENT,
+ SUBSCRIBER_ID INT,
+ WF_REF VARCHAR(255) NOT NULL,
+ APP_ID INT,
+ TOKEN_TYPE VARCHAR(30),
+ TOKEN_SCOPE VARCHAR(256) DEFAULT 'default',
+ INPUTS VARCHAR(1000),
+ ALLOWED_DOMAINS VARCHAR(256),
+ VALIDITY_PERIOD BIGINT,
+ UNIQUE (SUBSCRIBER_ID,APP_ID,TOKEN_TYPE),
+ FOREIGN KEY(SUBSCRIBER_ID) REFERENCES AM_SUBSCRIBER(SUBSCRIBER_ID) ON DELETE RESTRICT,
+ FOREIGN KEY(APP_ID) REFERENCES AM_APPLICATION(APPLICATION_ID) ON DELETE RESTRICT,
+ PRIMARY KEY (REG_ID)
+)ENGINE NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_SCOPES (
+ API_ID INTEGER NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE
+)ENGINE = NDB;
+
+CREATE TABLE IF NOT EXISTS AM_API_DEFAULT_VERSION (
+ DEFAULT_VERSION_ID INT AUTO_INCREMENT,
+ API_NAME VARCHAR(256) NOT NULL ,
+ API_PROVIDER VARCHAR(256) NOT NULL ,
+ DEFAULT_API_VERSION VARCHAR(30) ,
+ PUBLISHED_DEFAULT_API_VERSION VARCHAR(30) ,
+ PRIMARY KEY (DEFAULT_VERSION_ID)
+);
+
+CREATE INDEX IDX_SUB_APP_ID ON AM_SUBSCRIPTION (APPLICATION_ID, SUBSCRIPTION_ID);
diff --git a/modules/features/service/org.wso2.stratos.apimgt.dashboard.ui.feature/pom.xml b/modules/features/service/org.wso2.stratos.apimgt.dashboard.ui.feature/pom.xml
index 339ec907aa..fa72dcb2f0 100644
--- a/modules/features/service/org.wso2.stratos.apimgt.dashboard.ui.feature/pom.xml
+++ b/modules/features/service/org.wso2.stratos.apimgt.dashboard.ui.feature/pom.xml
@@ -22,7 +22,7 @@
org.wso2.am
wso2stratos-am-features
- 2.2.0
+ 2.2.1-SNAPSHOT
../pom.xml
@@ -36,12 +36,12 @@
org.wso2.am
org.wso2.stratos.apimgt.dashboard.ui
- 2.2.0
+ ${apimgt.stratos.version}
org.wso2.carbon
org.wso2.carbon.ui.menu.stratos
- ${stratos.version}
+ 2.2.0
diff --git a/modules/features/service/org.wso2.stratos.apimgt.login.ui.feature/pom.xml b/modules/features/service/org.wso2.stratos.apimgt.login.ui.feature/pom.xml
index 4c18f9f019..5d0afa6584 100644
--- a/modules/features/service/org.wso2.stratos.apimgt.login.ui.feature/pom.xml
+++ b/modules/features/service/org.wso2.stratos.apimgt.login.ui.feature/pom.xml
@@ -22,7 +22,7 @@
org.wso2.am
wso2stratos-am-features
- 2.2.0
+ 2.2.1-SNAPSHOT
../pom.xml
@@ -36,7 +36,7 @@
org.wso2.am
org.wso2.stratos.apimgt.login.ui
- 2.2.0
+ 2.2.1-SNAPSHOT
diff --git a/modules/features/service/org.wso2.stratos.apimgt.styles.feature/pom.xml b/modules/features/service/org.wso2.stratos.apimgt.styles.feature/pom.xml
index 573420e8a9..2791a07a5f 100644
--- a/modules/features/service/org.wso2.stratos.apimgt.styles.feature/pom.xml
+++ b/modules/features/service/org.wso2.stratos.apimgt.styles.feature/pom.xml
@@ -22,7 +22,7 @@
org.wso2.am
wso2stratos-am-features
- 2.2.0
+ 2.2.1-SNAPSHOT
../pom.xml
diff --git a/modules/features/service/org.wso2.stratos.apimgt.utils.feature/pom.xml b/modules/features/service/org.wso2.stratos.apimgt.utils.feature/pom.xml
index 27eca2ea40..7560055140 100644
--- a/modules/features/service/org.wso2.stratos.apimgt.utils.feature/pom.xml
+++ b/modules/features/service/org.wso2.stratos.apimgt.utils.feature/pom.xml
@@ -22,7 +22,7 @@
org.wso2.am
wso2stratos-am-features
- 2.2.0
+ 2.2.1-SNAPSHOT
../pom.xml
diff --git a/modules/features/service/pom.xml b/modules/features/service/pom.xml
index be2c972604..f322d4a0a8 100644
--- a/modules/features/service/pom.xml
+++ b/modules/features/service/pom.xml
@@ -28,7 +28,7 @@
4.0.0
wso2stratos-am-features
- 2.2.0
+ 2.2.1-SNAPSHOT
pom
WSO2 Stratos API Manager - Features Aggregator Module
http://wso2.org
diff --git a/modules/integration/tests-common/integration-test-utils/pom.xml b/modules/integration/tests-common/integration-test-utils/pom.xml
index d8c1b0088b..b62269cad2 100644
--- a/modules/integration/tests-common/integration-test-utils/pom.xml
+++ b/modules/integration/tests-common/integration-test-utils/pom.xml
@@ -33,7 +33,7 @@ under the License.
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.api
diff --git a/modules/integration/tests-integration/tests-backend/pom.xml b/modules/integration/tests-integration/tests-backend/pom.xml
index 25d8783873..3eae07721e 100644
--- a/modules/integration/tests-integration/tests-backend/pom.xml
+++ b/modules/integration/tests-integration/tests-backend/pom.xml
@@ -271,7 +271,7 @@ under the License.
org.wso2.carbon.integration.common.utils
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.api
@@ -288,5 +288,11 @@ under the License.
+
+ com.github.dblock.waffle.wso2
+ waffle-jna
+ 1.6.wso2v2
+ test
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/ChangeEndPointSecurityOfAPITestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/ChangeEndPointSecurityOfAPITestCase.java
index ae0a0a5aab..a7e4024ea2 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/ChangeEndPointSecurityOfAPITestCase.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/ChangeEndPointSecurityOfAPITestCase.java
@@ -107,6 +107,7 @@ public void testInvokeGETResourceWithSecuredEndPointPasswordOnlyNumbersAndLetter
apiCreationRequestBean.setTier(TIER_UNLIMITED);
apiCreationRequestBean.setTiersCollection(TIER_UNLIMITED);
APIIdentifier apiIdentifier = new APIIdentifier(providerName, API_NAME, API_VERSION_1_0_0);
+ apiIdentifier.setTier(TIER_UNLIMITED);
createPublishAndSubscribeToAPI(
apiIdentifier, apiCreationRequestBean, apiPublisherClientUser1, apiStoreClientUser1, APPLICATION_NAME);
String accessToken = generateApplicationKeys(apiStoreClientUser1, APPLICATION_NAME).getAccessToken();
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/PluggableVersioningStrategyTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/PluggableVersioningStrategyTestCase.java
new file mode 100644
index 0000000000..9a311961e6
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/api/lifecycle/PluggableVersioningStrategyTestCase.java
@@ -0,0 +1,131 @@
+/*
+* Copyright (c) 2015, 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.am.integration.tests.api.lifecycle;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException;
+import org.wso2.am.integration.test.utils.bean.APICreationRequestBean;
+import org.wso2.am.integration.test.utils.clients.APIPublisherRestClient;
+import org.wso2.am.integration.test.utils.clients.APIStoreRestClient;
+import org.wso2.carbon.apimgt.api.model.APIIdentifier;
+import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
+import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
+import org.wso2.carbon.logging.view.stub.LogViewerLogViewerException;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class PluggableVersioningStrategyTestCase extends APIManagerLifecycleBaseTest {
+
+ private static final Log log = LogFactory.getLog(PluggableVersioningStrategyTestCase.class);
+
+ private static final String API_NAME = "PluggableVersionTestAPI";
+ private static final String API_CONTEXT = "{version}/PluggableVersionTestAPI";
+ private static final String API_VERSION_1_0_0 = "1.0.0";
+ private static final String INVOKABLE_API_CONTEXT = API_VERSION_1_0_0 + "/PluggableVersionTestAPI";
+ private static final String API_TAGS = "Pluggable, Version, testTag3";
+ private static final String API_DESCRIPTION = "This is test API to test pluggable version strategy";
+ private static final String API_END_POINT_POSTFIX_URL = "jaxrs_basic/services/customers/customerservice/";
+ private static final String APPLICATION_NAME = "PluggableVersionTestApp";
+ private String providerName;
+ private APIIdentifier apiIdentifier;
+ private APIPublisherRestClient apiPublisherClientUser;
+ private APIStoreRestClient apiStoreClientUser;
+ private APICreationRequestBean apiCreationRequestBean;
+ private final static String API_GET_ENDPOINT_METHOD = "/customers/123";
+ private final static String RESPONSE_GET = "123John";
+
+
+ @BeforeClass(alwaysRun = true)
+ public void initialize() throws Exception {
+ super.init();
+ String apiEndPointUrl = gatewayUrls.getWebAppURLHttp() + API_END_POINT_POSTFIX_URL;
+ providerName = publisherContext.getContextTenant().getContextUser().getUserName();
+ String publisherURLHttp = publisherUrls.getWebAppURLHttp();
+ String storeURLHttp = storeUrls.getWebAppURLHttp();
+ apiPublisherClientUser = new APIPublisherRestClient(publisherURLHttp);
+ apiStoreClientUser = new APIStoreRestClient(storeURLHttp);
+ //Login to API Publisher with admin
+ apiPublisherClientUser.login(publisherContext.getContextTenant().getContextUser().getUserName(),
+ publisherContext.getContextTenant().getContextUser().getPassword());
+ //Login to API Store with admin
+ apiStoreClientUser.login(storeContext.getContextTenant().getContextUser().getUserName(),
+ storeContext.getContextTenant().getContextUser().getPassword());
+ apiIdentifier = new APIIdentifier(providerName, API_NAME, API_VERSION_1_0_0);
+
+ apiCreationRequestBean = new APICreationRequestBean(API_NAME, API_CONTEXT, API_VERSION_1_0_0, providerName,
+ new URL(apiEndPointUrl));
+ apiCreationRequestBean.setTags(API_TAGS);
+ apiCreationRequestBean.setDescription(API_DESCRIPTION);
+ apiCreationRequestBean.setTier(TIER_GOLD);
+ apiCreationRequestBean.setTiersCollection(TIER_GOLD);
+ }
+
+ @Test(groups = {"wso2.am"}, description = "This test method tests the pluggable versioning stratergy")
+ public void testPluggableVersioningStratergy() throws APIManagerIntegrationTestException,
+ IOException, LogViewerLogViewerException {
+
+ //Create an application with gold tier
+ apiStoreClientUser.addApplication(APPLICATION_NAME, TIER_GOLD, "", "");
+
+ //Create publish and subscribe an API
+ APIIdentifier apiIdentifier = new APIIdentifier(providerName, API_NAME, API_VERSION_1_0_0);
+ apiIdentifier.setTier(TIER_GOLD);
+ createPublishAndSubscribeToAPI(
+ apiIdentifier, apiCreationRequestBean, apiPublisherClientUser, apiStoreClientUser, APPLICATION_NAME);
+
+ //Add request headers
+ HashMap requestHeadersGet = new HashMap();
+ requestHeadersGet.put("accept", "text/xml");
+
+ //Get the access token
+ String accessToken = generateApplicationKeys(apiStoreClientUser, APPLICATION_NAME).getAccessToken();
+ requestHeadersGet.put("Authorization", "Bearer " + accessToken);
+
+ //Send GET Request
+ HttpResponse httpResponse =
+ HttpRequestUtil.doGet(gatewayWebAppUrl + INVOKABLE_API_CONTEXT + API_GET_ENDPOINT_METHOD,
+ requestHeadersGet);
+ assertEquals(httpResponse.getResponseCode(), HTTP_RESPONSE_CODE_OK, "Invocation fails for GET request");
+ assertTrue(httpResponse.getData().contains(RESPONSE_GET), "Response Data not match for GET request." +
+ " Expected value : " + RESPONSE_GET + " not contains in response data " + httpResponse.getData());
+ }
+
+
+ @AfterClass(alwaysRun = true)
+ public void destroy() throws Exception {
+
+ //Remove application and the subscription
+ if (apiStoreClientUser != null) {
+ apiStoreClientUser.removeApplication(APPLICATION_NAME);
+ }
+
+ //delete the API
+ if (apiPublisherClientUser != null) {
+ apiPublisherClientUser.deleteAPI(API_NAME, API_VERSION_1_0_0, providerName);
+ }
+ }
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/hostobject/HostObjectTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/hostobject/HostObjectTestCase.java
index 59b16dfc16..1a102b8f1e 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/hostobject/HostObjectTestCase.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/hostobject/HostObjectTestCase.java
@@ -45,6 +45,7 @@
import org.wso2.carbon.utils.FileManipulator;
import org.wso2.carbon.utils.ServerConstants;
+import javax.xml.xpath.XPathExpressionException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -62,6 +63,8 @@ public class HostObjectTestCase extends APIMIntegrationBaseTest {
private Log log = LogFactory.getLog(getClass());
private APIPublisherRestClient apiPublisher;
private APIStoreRestClient apiStore;
+ private static boolean isConfigApplied = false;
+ private static ServerConfigurationManager serverConfigurationManager;
@Factory(dataProvider = "userModeDataProvider")
public HostObjectTestCase(TestUserMode userMode) {
@@ -71,6 +74,8 @@ public HostObjectTestCase(TestUserMode userMode) {
@BeforeClass(alwaysRun = true)
public void setEnvironment() throws Exception {
super.init(userMode);
+ serverConfigurationManager =
+ new ServerConfigurationManager(new AutomationContext("APIM", "gateway",TestUserMode.SUPER_TENANT_ADMIN));
/*
If test run in external distributed deployment you need to copy following resources accordingly.
@@ -81,19 +86,19 @@ public void setEnvironment() throws Exception {
*/
String publisherURLHttp = publisherUrls.getWebAppURLHttp();
String storeURLHttp = storeUrls.getWebAppURLHttp();
- ServerConfigurationManager serverConfigurationManager =
- new ServerConfigurationManager(new AutomationContext("APIM", "gateway",
- TestUserMode.SUPER_TENANT_ADMIN));
-
- serverConfigurationManager.applyConfiguration(new File(getAMResourceLocation()
- + File.separator +
- "configFiles/hostobjecttest/" +
- "api-manager.xml"));
- serverConfigurationManager.applyConfiguration(new File(getAMResourceLocation()
- + File.separator +
- "configFiles/tokenTest/" +
- "log4j.properties"));
- super.init(userMode);
+
+ if (!isConfigApplied) {
+ serverConfigurationManager.applyConfigurationWithoutRestart(new File(getAMResourceLocation()
+ + File.separator +
+ "configFiles/hostobjecttest/" +
+ "api-manager.xml"));
+ serverConfigurationManager.applyConfiguration(new File(getAMResourceLocation()
+ + File.separator +
+ "configFiles/tokenTest/" +
+ "log4j.properties"));
+ super.init(userMode);
+ isConfigApplied = true;
+ }
apiPublisher = new APIPublisherRestClient(publisherURLHttp);
apiStore = new APIStoreRestClient(storeURLHttp);
}
@@ -228,10 +233,9 @@ public void testHostObjectTestCase() throws Exception {
responseArrayFromPublisher = finalOutputPublisher.split("==");
isPublisherResponse = responseArrayFromPublisher[30].contains("HostObjectTestAPI");
}
- log.info(finalOutputPublisher);
in.close();
-
}
+ log.info(finalOutputPublisher);
validatePublisherResponseArray(responseArrayFromPublisher);
} catch (IOException e) {
@@ -260,11 +264,9 @@ public void testHostObjectTestCase() throws Exception {
isStoreResponse = responseArrayFromStore[9].contains("HostObjectTestAPI");
}
in.close();
- log.info(finalOutputStore);
}
+ log.info(finalOutputStore);
validateStoreResponseArray(responseArrayFromStore);
-
-
} catch (IOException e) {
log.error("Error while invoking test application to test publisher host object");
} finally {
@@ -287,10 +289,11 @@ public void testAPIProvider() {
@AfterClass(alwaysRun = true)
public void destroy() throws Exception {
apiStore.removeApplication("HostObjectTestAPI-Application");
+ serverConfigurationManager.restoreToLastConfiguration();
super.cleanup();
}
- public static boolean validateStoreResponseArray(String[] array) {
+ public boolean validateStoreResponseArray(String[] array) throws XPathExpressionException {
assertTrue(array[1].contains("true"),
"Error while getting status of billing system from API store host object (isBillingEnabled)");
assertTrue(array[2].contains("https"),
@@ -348,7 +351,7 @@ public static boolean validateStoreResponseArray(String[] array) {
return true;
}
- public static boolean validatePublisherResponseArray(String[] array) {
+ public boolean validatePublisherResponseArray(String[] array) {
assertTrue(array[1].contains("true"),
"Error while validating roles from API store host object (validateRoles)");
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/jwt/JWTTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/jwt/JWTTestCase.java
index ca472c7b75..34b6ce471c 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/jwt/JWTTestCase.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/jwt/JWTTestCase.java
@@ -27,18 +27,27 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.am.admin.clients.user.RemoteUserStoreManagerServiceClient;
+import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException;
import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest;
import org.wso2.am.integration.test.utils.bean.*;
import org.wso2.am.integration.test.utils.clients.APIPublisherRestClient;
import org.wso2.am.integration.test.utils.clients.APIStoreRestClient;
import org.wso2.am.integration.test.utils.generic.APIMTestCaseUtils;
import org.wso2.am.integration.test.utils.monitor.utils.WireMonitorServer;
+import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
+import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
import org.wso2.carbon.integration.common.admin.client.UserManagementClient;
import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager;
+import javax.xml.xpath.XPathExpressionException;
import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
@@ -53,15 +62,15 @@ public class JWTTestCase extends APIMIntegrationBaseTest {
private WireMonitorServer server;
int hostPort = 9988;
- private String APIName = "JWTTokenTestAPI";
- private String APIContext = "tokenTest";
+ private String apiName = "JWTTokenTestAPI";
+ private String apiContext = "tokenTest";
private String tags = "token, jwt";
private String wireMonitorURL = "";
private String description = "This is test API create by API manager integration test";
private String providerName = "admin";
- private String APIVersion = "1.0.0";
- private String ApplicationName = "APILifeCycleTestAPI-application";
- private String APITier = "Gold";
+ private String apiVersion = "1.0.0";
+ private String applicationName = "APILifeCycleTestAPI-application";
+ private String apiTier = "Gold";
@BeforeClass(alwaysRun = true)
public void setEnvironment() throws Exception {
@@ -90,6 +99,12 @@ public void setEnvironment() throws Exception {
server = new WireMonitorServer(hostPort);
server.setReadTimeOut(300);
server.start();
+
+ String gatewaySessionCookie = createSession(gatewayContext);
+ //Load the back-end dummy API
+ loadSynapseConfigurationFromClasspath(
+ "artifacts" + File.separator + "AM" + File.separator + "synapseconfigs" + File.separator + "rest" +
+ File.separator + "dummy_api.xml", gatewayContext, gatewaySessionCookie);
}
@AfterClass(alwaysRun = true)
@@ -100,22 +115,24 @@ public void destroy() throws Exception {
serverConfigurationManager.restoreToLastConfiguration();
}
- private void addAPI() throws Exception {
+ private void addAPI(String apiName, String apiVersion, String apiContext, String description, String endpointURL,
+ String tags, String providerName)
+ throws APIManagerIntegrationTestException, MalformedURLException, XPathExpressionException {
APIPublisherRestClient apiPublisher = new APIPublisherRestClient(publisherURLHttp);
apiPublisher.login(publisherContext.getContextTenant().getContextUser().getUserName(),
publisherContext.getContextTenant().getContextUser().getPassword());
- APIRequest apiRequest = new APIRequest(APIName, APIContext, new URL(wireMonitorURL));
+ APIRequest apiRequest = new APIRequest(apiName, apiContext, new URL(endpointURL));
apiRequest.setTags(tags);
apiRequest.setDescription(description);
- apiRequest.setVersion(APIVersion);
+ apiRequest.setVersion(apiVersion);
apiRequest.setVisibility("public");
apiRequest.setProvider(providerName);
apiPublisher.addAPI(apiRequest);
- APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(APIName, providerName,
+ APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(apiName, providerName,
APILifeCycleState.PUBLISHED);
apiPublisher.changeAPILifeCycleStatus(updateRequest);
@@ -144,19 +161,19 @@ public void testEnableJWTAndClaims() throws Exception {
// restart the server since updated claims not picked unless cache expired
serverConfigurationManager.restartGracefully();
- addAPI();
+ addAPI(apiName, apiVersion, apiContext,description,wireMonitorURL,tags,providerName);
APIStoreRestClient apiStoreRestClient = new APIStoreRestClient(storeURLHttp);
apiStoreRestClient.login(storeContext.getContextTenant().getContextUser().getUserName(),
storeContext.getContextTenant().getContextUser().getPassword());
- apiStoreRestClient.addApplication(ApplicationName, APITier, "", "this-is-test");
- SubscriptionRequest subscriptionRequest = new SubscriptionRequest(APIName,
+ apiStoreRestClient.addApplication(applicationName, apiTier, "", "this-is-test");
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(apiName,
storeContext.getContextTenant().getContextUser().getUserName());
- subscriptionRequest.setApplicationName(ApplicationName);
+ subscriptionRequest.setApplicationName(applicationName);
apiStoreRestClient.subscribe(subscriptionRequest);
- APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(ApplicationName);
+ APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(applicationName);
String responseString = apiStoreRestClient.generateApplicationKey(generateAppKeyRequest).getData();
JSONObject response = new JSONObject(responseString);
String accessToken = response.getJSONObject("data").getJSONObject("key").get("accessToken").toString();
@@ -202,6 +219,64 @@ public void testEnableJWTAndClaims() throws Exception {
assertTrue("JWT claim invalid claim received", bExceptionOccured);
}
+ /**
+ * This test case is a test for the fix fix for APIMANAGER-3912, where jwt claims are attempted to retrieve from
+ * an invalidated cache and hence failed. In carbon 4.2 products cache invalidation timeout is not configurable
+ * and is hardcoded to 15 mins. So the test case will take approximately 15mins to complete and it will delay the
+ * product build unnecessarily, hence the test case is disabled.
+ *
+ */
+ @Test(groups = { "wso2.am" }, description = "JWT Token generation when JWT caching is enabled", enabled = false)
+ public void testAPIAccessWhenJWTCachingEnabledTestCase()
+ throws APIManagerIntegrationTestException, XPathExpressionException, IOException, JSONException,
+ InterruptedException {
+
+ String applicationName = "JWTTokenCacheTestApp";
+ String apiName = "JWTTokenCacheTestAPI";
+ String apiContext = "JWTTokenCacheTestAPI";
+ String apiVersion = "1.0.0";
+ String description = "JWTTokenCacheTestAPI description";
+ String endpointURL = gatewayUrls.getWebAppURLNhttp() + "response";
+ String apiTier = "Gold";
+ String tags = "token,jwt,cache";
+ int waitingSecs = 900;
+
+ addAPI(apiName, apiVersion, apiContext, description, endpointURL, tags, providerName);
+
+ APIStoreRestClient apiStoreRestClient = new APIStoreRestClient(storeURLHttp);
+ apiStoreRestClient.login(storeContext.getContextTenant().getContextUser().getUserName(),
+ storeContext.getContextTenant().getContextUser().getPassword());
+
+ apiStoreRestClient.addApplication(applicationName, apiTier, "", "this-is-test");
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(apiName,
+ storeContext.getContextTenant().getContextUser().getUserName());
+ subscriptionRequest.setApplicationName(applicationName);
+ apiStoreRestClient.subscribe(subscriptionRequest);
+
+ APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(applicationName);
+ String responseString = apiStoreRestClient.generateApplicationKey(generateAppKeyRequest).getData();
+ JSONObject response = new JSONObject(responseString);
+ String accessToken = response.getJSONObject("data").getJSONObject("key").get("accessToken").toString();
+
+ String url = gatewayUrls.getWebAppURLNhttp() + apiContext + "/" + apiVersion;
+
+ Map headers = new HashMap();
+ headers.put("Authorization", "Bearer " + accessToken);
+ //Invoke the API
+ HttpResponse httpResponse = HttpRequestUtil.doGet(url, headers);
+ assertEquals("GET request failed for " + url, 200, httpResponse.getResponseCode());
+
+ //Wait till cache is invalidated
+ log.info("Waiting " + waitingSecs + " sec(s) till claims local cache is invalidated");
+ Thread.sleep(waitingSecs * 1000);
+
+ //Second attempt to invoke the API.
+ httpResponse = HttpRequestUtil.doGet(url, headers);
+ assertEquals("GET request failed for " + url +
+ ". Most probably due to a failed invalidated cache access to retrieve JWT claims.", 200,
+ httpResponse.getResponseCode());
+ }
+
private void checkDefaultUserClaims(JSONObject jsonObject) throws JSONException {
String claim = jsonObject.getString("iss");
assertTrue("JWT assertion is invalid", claim.contains("wso2.org/products/am"));
@@ -279,13 +354,13 @@ public void testSpecificUserJWTClaims() throws Exception {
APIStoreRestClient apiStoreRestClient = new APIStoreRestClient(storeURLHttp);
apiStoreRestClient.login(subscriberUser, password);
- apiStoreRestClient.addApplication(ApplicationName, APITier, "", "this-is-test");
- SubscriptionRequest subscriptionRequest = new SubscriptionRequest(APIName,
+ apiStoreRestClient.addApplication(applicationName, apiTier, "", "this-is-test");
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(apiName,
providerName);
- subscriptionRequest.setApplicationName(ApplicationName);
+ subscriptionRequest.setApplicationName(applicationName);
apiStoreRestClient.subscribe(subscriptionRequest);
- APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(ApplicationName);
+ APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(applicationName);
String responseString = apiStoreRestClient.generateApplicationKey(generateAppKeyRequest).getData();
JSONObject response = new JSONObject(responseString);
accessToken = response.getJSONObject("data").getJSONObject("key").get("accessToken").toString();
@@ -335,10 +410,10 @@ public void testTenantUserJWTClaims() throws Exception {
apiPublisherRestClient.login(tenantUser, password);
- APIRequest apiRequest = new APIRequest(APIName, APIContext, new URL(wireMonitorURL));
+ APIRequest apiRequest = new APIRequest(apiName, apiContext, new URL(wireMonitorURL));
apiRequest.setTags(tags);
apiRequest.setDescription(description);
- apiRequest.setVersion(APIVersion);
+ apiRequest.setVersion(apiVersion);
apiRequest.setWsdl("https://svn.wso2.org/repos/wso2/carbon/platform/trunk/products" +
"/bps/modules/samples/product/src/main/resources/bpel/2.0/MyRoleMexTestProcess/echo.wsdl");
apiRequest.setVisibility("public");
@@ -346,20 +421,20 @@ public void testTenantUserJWTClaims() throws Exception {
apiRequest.setProvider(provider);
apiPublisherRestClient.addAPI(apiRequest);
- APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(APIName, provider,
+ APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(apiName, provider,
APILifeCycleState.PUBLISHED);
apiPublisherRestClient.changeAPILifeCycleStatus(updateRequest);
APIStoreRestClient apiStoreRestClient = new APIStoreRestClient(storeURLHttp);
apiStoreRestClient.login(tenantUser, password);
- apiStoreRestClient.addApplication(ApplicationName, APITier, "", "this-is-test");
- SubscriptionRequest subscriptionRequest = new SubscriptionRequest(APIName,
+ apiStoreRestClient.addApplication(applicationName, apiTier, "", "this-is-test");
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(apiName,
provider);
- subscriptionRequest.setApplicationName(ApplicationName);
+ subscriptionRequest.setApplicationName(applicationName);
apiStoreRestClient.subscribe(subscriptionRequest);
- APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(ApplicationName);
+ APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator(applicationName);
String responseString = apiStoreRestClient.generateApplicationKey(generateAppKeyRequest).getData();
JSONObject response = new JSONObject(responseString);
accessToken = response.getJSONObject("data").getJSONObject("key").get("accessToken").toString();
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/APIMANAGER4033CheckAuthTypeTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/APIMANAGER4033CheckAuthTypeTestCase.java
new file mode 100644
index 0000000000..7ae2597f35
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/APIMANAGER4033CheckAuthTypeTestCase.java
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 2015, 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.am.integration.tests.other;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException;
+import org.wso2.am.integration.test.utils.bean.APILifeCycleState;
+import org.wso2.am.integration.test.utils.bean.APILifeCycleStateRequest;
+import org.wso2.am.integration.test.utils.bean.APIRequest;
+import org.wso2.am.integration.test.utils.clients.APIPublisherRestClient;
+import org.wso2.am.integration.tests.api.lifecycle.APIManagerLifecycleBaseTest;
+import org.wso2.carbon.apimgt.api.model.APIIdentifier;
+import org.wso2.carbon.authenticator.stub.LoginAuthenticationExceptionException;
+import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
+import org.xml.sax.SAXException;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.xpath.XPathExpressionException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+
+public class APIMANAGER4033CheckAuthTypeTestCase extends APIManagerLifecycleBaseTest {
+ private APIPublisherRestClient apiPublisher;
+ private String apiEndPointUrl;
+ APIIdentifier apiIdentifier;
+
+ private static final String TEST_DATA_APINAME = "APIMANAGER4033";
+ private static final String TEST_DATA_APICONTEXT = "apimanager4033";
+ private static final String TEST_DATA_TAGS = "4033, auth_type";
+ private static final String TEST_DATA_API_DESCRIPTION = "This is test API created to test Auth Type";
+ private static final String TEST_DATA_API_PROVIDER_NAME = "admin";
+ private static final String TEST_DATA_API_VERSION = "1.0.0";
+ private static final String API_END_POINT_POSTFIX_URL = "jaxrs_basic/services/customers/customerservice/";
+ private static final String TEST_DATA_ENDPOINT_TYPE = "nonsecured";
+ private static final String TEST_DATA_RESOURCE_METHOD = "GET";
+ private static final String TEST_DATA_RESOURCE_METHOD_ENDPOINT_TYPE = "Any";
+ private static final String TEST_DATA_EXPECTED_ENDPOINT_TYPE = "Application & Application User";
+ private static final String TEST_DATA_RESOURCE_METHOD_ENDPOINT_THROTTLING = "Unlimited";
+ private static final String TEST_DATA_API_VISIBILITY = "public";
+ private static final String TEST_DATA_URI_TEMPLATE = "*";
+
+
+ @BeforeClass(alwaysRun = true)
+ public void setEnvironment() throws APIManagerIntegrationTestException, IOException,
+ XPathExpressionException, URISyntaxException, SAXException, XMLStreamException,
+ LoginAuthenticationExceptionException {
+ super.init();
+ apiEndPointUrl = gatewayUrls.getWebAppURLHttp() + API_END_POINT_POSTFIX_URL;
+ String publisherURLHttp = publisherUrls.getWebAppURLHttp();
+ apiPublisher = new APIPublisherRestClient(publisherURLHttp);
+ }
+
+ @Test(groups = {"wso2.am"}, description = "API Auth type test case")
+ public void testAuthTypeOfCreatedAPI() throws Exception {
+
+ apiIdentifier = new APIIdentifier(TEST_DATA_API_PROVIDER_NAME, TEST_DATA_APINAME, TEST_DATA_API_VERSION);
+ //login to the publisher
+ apiPublisher.login(publisherContext.getContextTenant().getContextUser().getUserName(),
+ publisherContext.getContextTenant().getContextUser().getPassword());
+
+ //set api details to the API being published
+ APIRequest apiRequest = new APIRequest(TEST_DATA_APINAME, TEST_DATA_APICONTEXT, new URL(apiEndPointUrl));
+ apiRequest.setTags(TEST_DATA_TAGS);
+ apiRequest.setDescription(TEST_DATA_API_DESCRIPTION);
+ apiRequest.setVersion(TEST_DATA_API_VERSION);
+ apiRequest.setEndpointType(TEST_DATA_ENDPOINT_TYPE);
+
+ apiRequest.setResourceCount("0");
+ apiRequest.setResourceMethod(TEST_DATA_RESOURCE_METHOD);
+ apiRequest.setUriTemplate(TEST_DATA_URI_TEMPLATE);
+ apiRequest.setResourceMethodAuthType(TEST_DATA_RESOURCE_METHOD_ENDPOINT_TYPE);
+ apiRequest.setResourceMethodThrottlingTier(TEST_DATA_RESOURCE_METHOD_ENDPOINT_THROTTLING);
+ apiRequest.setVisibility(TEST_DATA_API_VISIBILITY);
+ apiRequest.setRoles(TEST_DATA_API_PROVIDER_NAME);
+
+ //Add API
+ apiPublisher.addAPI(apiRequest);
+
+ //Update API
+ APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(TEST_DATA_APINAME,
+ TEST_DATA_API_PROVIDER_NAME, APILifeCycleState.PUBLISHED);
+ apiPublisher.changeAPILifeCycleStatus(updateRequest);
+
+ //getAPIManagePage
+ HttpResponse managePage = apiPublisher.getAPIManagePage(TEST_DATA_APINAME, TEST_DATA_API_PROVIDER_NAME,
+ TEST_DATA_API_VERSION);
+ Assert.assertTrue(managePage.getData().contains(TEST_DATA_EXPECTED_ENDPOINT_TYPE),
+ "Resource method endpoint type not set properly.");
+
+ }
+
+
+ @AfterClass(alwaysRun = true)
+ public void cleanUpArtifacts() throws APIManagerIntegrationTestException {
+ deleteAPI(apiIdentifier, apiPublisher);
+ }
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/NTLMTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/NTLMTestCase.java
new file mode 100644
index 0000000000..53829e1697
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/NTLMTestCase.java
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+*
+* WSO2 Inc. 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.am.integration.tests.other;
+
+import org.apache.axiom.util.base64.Base64Utils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONObject;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest;
+import org.wso2.am.integration.test.utils.bean.APPKeyRequestGenerator;
+import org.wso2.am.integration.test.utils.clients.APIStoreRestClient;
+import waffle.apache.NegotiateAuthenticator;
+import waffle.util.Base64;
+import waffle.windows.auth.IWindowsCredentialsHandle;
+import waffle.windows.auth.impl.WindowsAccountImpl;
+import waffle.windows.auth.impl.WindowsCredentialsHandleImpl;
+import waffle.windows.auth.impl.WindowsSecurityContextImpl;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.Assert.assertNotNull;
+
+public class NTLMTestCase extends APIMIntegrationBaseTest {
+ private APIStoreRestClient apiStore;
+ static NegotiateAuthenticator _authenticator = null;
+
+ @BeforeClass(alwaysRun = true)
+ public void setEnvironment() throws Exception {
+ super.init();
+ String storeURLHttp = storeUrls.getWebAppURLHttp();
+ apiStore = new APIStoreRestClient(storeURLHttp);
+ }
+
+ @Test(groups = {"wso2.am"}, description = "This test method only runs on windows environment.We exchange NTLM " +
+ "token for access_token")
+ public void testGenerateNTLMTokensTestCase() throws Exception {
+
+ String securityPackage = "Negotiate";
+ _authenticator = new NegotiateAuthenticator();
+ String clientToken;
+ IWindowsCredentialsHandle clientCredentials;
+ WindowsSecurityContextImpl clientContext;
+ // client credentials handle
+ clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
+ clientCredentials.initialize();
+ // initial client security context
+ clientContext = new WindowsSecurityContextImpl();
+ clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
+
+ clientContext.setCredentialsHandle(clientCredentials.getHandle());
+ clientContext.setSecurityPackage(securityPackage);
+ clientContext.initialize(null, null, WindowsAccountImpl.getCurrentUsername());
+ //NTLM token.
+ clientToken = Base64.encode(clientContext.getToken());
+ apiStore.login(storeContext.getContextTenant().getContextUser().getUserName(),
+ storeContext.getContextTenant().getContextUser().getPassword());
+ apiStore.addApplication("NTLM", "Unlimited", "some_url", "NewApp");
+
+ //Generate production token and invoke with that
+ APPKeyRequestGenerator generateAppKeyRequest = new APPKeyRequestGenerator("NTLM");
+ String responseString = apiStore.generateApplicationKey(generateAppKeyRequest).getData();
+ JSONObject jsonResponse = new JSONObject(responseString);
+
+ // get Consumer Key and Consumer Secret
+ String consumerKey = jsonResponse.getJSONObject("data").getJSONObject("key").getString("consumerKey");
+ String consumerSecret = jsonResponse.getJSONObject("data").getJSONObject("key").getString("consumerSecret");
+
+ Thread.sleep(4000);
+ HttpClient httpclient = new DefaultHttpClient();
+ byte[] userKey = (consumerKey + ":" + consumerSecret).getBytes();
+ String encoding = Base64Utils.encode(userKey);
+ URL tokenEndpointURL = new URL(gatewayUrls.getWebAppURLNhttp() + "token");
+ HttpPost httppost = new HttpPost(String.valueOf(tokenEndpointURL));
+ httppost.setHeader("Authorization", "Basic " + encoding);
+ List paramVals = new ArrayList();
+ paramVals.add(new BasicNameValuePair("grant_type", "iwa:ntlm"));
+ paramVals.add(new BasicNameValuePair("windows_token", clientToken));
+ HttpResponse response;
+ httppost.setEntity(new UrlEncodedFormEntity(paramVals, "UTF-8"));
+ response = httpclient.execute(httppost);
+ HttpEntity entity = response.getEntity();
+ responseString = EntityUtils.toString(entity, "UTF-8");
+ JSONObject accessTokenGenerationResponse = new JSONObject(responseString);
+ String accessToken = accessTokenGenerationResponse.getString("access_token");
+ assertNotNull(accessToken, "Error while getting access token.. access token is empty");
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void destroy() throws Exception {
+ super.cleanUp(gatewayContext.getContextTenant().getTenantAdmin().getUserName(),
+ gatewayContext.getContextTenant().getContextUser().getPassword(),
+ storeUrls.getWebAppURLHttp(), publisherUrls.getWebAppURLHttp());
+ }
+}
\ No newline at end of file
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/ReadOnlySecondaryUserStoreAPITokenGenerationTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/ReadOnlySecondaryUserStoreAPITokenGenerationTestCase.java
new file mode 100644
index 0000000000..ed46edc8c7
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/ReadOnlySecondaryUserStoreAPITokenGenerationTestCase.java
@@ -0,0 +1,213 @@
+/*
+*Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+*
+*WSO2 Inc. 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.am.integration.tests.other;
+
+import org.apache.axis2.AxisFault;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONObject;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest;
+import org.wso2.am.integration.test.utils.bean.APILifeCycleState;
+import org.wso2.am.integration.test.utils.bean.APILifeCycleStateRequest;
+import org.wso2.am.integration.test.utils.bean.APIRequest;
+import org.wso2.am.integration.test.utils.bean.SubscriptionRequest;
+import org.wso2.am.integration.test.utils.bean.APPKeyRequestGenerator;
+import org.wso2.am.integration.test.utils.clients.APIPublisherRestClient;
+import org.wso2.am.integration.test.utils.clients.APIStoreRestClient;
+import org.wso2.carbon.integration.common.admin.client.AuthenticatorClient;
+import org.wso2.carbon.integration.common.admin.client.UserManagementClient;
+import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager;
+
+import java.io.File;
+import java.net.URL;
+
+/*
+* This class test the token generation for the APIs subscribed from an ReadOnly External Store
+* */
+public class ReadOnlySecondaryUserStoreAPITokenGenerationTestCase extends APIMIntegrationBaseTest {
+
+ private static final Log log = LogFactory.getLog(ReadOnlySecondaryUserStoreAPITokenGenerationTestCase.class);
+
+ private APIPublisherRestClient apiPublisher;
+ private APIStoreRestClient apiStore;
+ private static String apiProvider;
+ private String gatewaySessionCookie;
+
+ private ServerConfigurationManager serverConfigurationManager;
+ private UserManagementClient userMgtClient;
+ private UserManagementClient testUserMgtClient;
+ private AuthenticatorClient authenticatorClient;
+ private String newUserName = "CAT.COM/chamalee";
+ private String newUserRole = "CAT.COM/userStoreSubscriber";
+
+ private String newUserPassword = "password";
+ private String backendURL;
+
+ private static final String API_NAME = "JDBCSecStoreTestAPI";
+ private static final String API_VERSION = "1.0.0";
+ private static final String APP_NAME = "chamsApp";
+
+ @BeforeClass(alwaysRun = true)
+ public void setEnvironment() throws Exception {
+
+ super.init();
+ //change the user-mgt.xml configuration
+ String userMgtXml = getAMResourceLocation() + File.separator + "configFiles/externalstore/user-mgt.xml";
+ serverConfigurationManager = new ServerConfigurationManager(gatewayContext);
+ serverConfigurationManager.applyConfiguration(new File(userMgtXml));
+ }
+
+ @Test(groups = "wso2.am", description = "Read only External Store Token Generation")
+ public void addUserIntoJDBCUserStore() throws Exception {
+
+ gatewaySessionCookie = createSession(gatewayContext);
+ backendURL = gatewayContext.getContextUrls().getBackEndUrl();
+
+ userMgtClient = new UserManagementClient(backendURL, gatewaySessionCookie);
+ authenticatorClient = new AuthenticatorClient(gatewayContext.getContextUrls().getBackEndUrl());
+
+ //add Role
+ userMgtClient.addRole(newUserRole, null, new String[]{"/permission/admin/login"
+ , "/permission/admin/manage/api/subscribe"});
+ Assert.assertTrue(userMgtClient.roleNameExists(newUserRole), "Role name doesn't exists");
+
+ //add User
+ userMgtClient.addUser(newUserName, newUserPassword, new String[]{newUserRole}, null);
+ Assert.assertTrue(userMgtClient.userNameExists(newUserRole, newUserName), "User name doesn't exists");
+
+ String sessionCookie = authenticatorClient.login(newUserName, newUserPassword, "localhost");
+ Assert.assertTrue(sessionCookie.contains("JSESSIONID"), "Session Cookie not found. Login failed");
+
+
+ //change the user-mgt.xml file with read only property
+ String userMgtReadOnlyXml = getAMResourceLocation() + File.separator
+ + "configFiles/externalstore/user-mgt-readonly.xml";
+ String targetReadOnlyXML = serverConfigurationManager.getCarbonHome() + "/repository/conf/user-mgt.xml";
+
+ serverConfigurationManager = new ServerConfigurationManager(gatewayContext);
+ serverConfigurationManager.applyConfiguration(new File(userMgtReadOnlyXml), new File(targetReadOnlyXML));
+
+ //create a new gateway session cookie since server is restarted
+ String newGatewaySessionCookie = createSession(gatewayContext);
+
+ //check for AxisFault when adding roles to the read only user store
+ testUserMgtClient = new UserManagementClient(backendURL, newGatewaySessionCookie);
+ AuthenticatorClient testAuthenticatorClient = new AuthenticatorClient(gatewayContext.getContextUrls().getBackEndUrl());
+
+ try{
+ testUserMgtClient.addRole("CAT.COM/testRole", null, new String[]{"/permission/admin/login"
+ , "/permission/admin/manage/api/subscribe"});
+
+ }catch (AxisFault axisFault) {
+ log.info("The Exception is expected since adding roles is disabled when user store is readonly.");
+ }
+ Assert.assertEquals(testUserMgtClient.roleNameExists("CAT.COM/testRole"), false,
+ "User Store is still not readonly");
+
+ //Load the back-end dummy API
+ loadSynapseConfigurationFromClasspath("artifacts" + File.separator + "AM"
+ + File.separator + "synapseconfigs" + File.separator + "rest"
+ + File.separator + "dummy_api.xml", gatewayContext, newGatewaySessionCookie);
+
+ //add an API
+ String apiContext = "test";
+ String tags = "testing";
+ String url = gatewayUrls.getWebAppURLNhttp() + "response";
+ String description = "This is a test API created by API manager integration test";
+
+ apiPublisher = new APIPublisherRestClient(publisherUrls.getWebAppURLHttp());
+ apiStore = new APIStoreRestClient(storeUrls.getWebAppURLHttp());
+ apiProvider = publisherContext.getSuperTenant().getContextUser().getUserName();
+
+ apiPublisher.login("admin", "admin");
+
+ APIRequest apiRequest = new APIRequest(API_NAME, apiContext, new URL(url));
+ apiRequest.setTags(tags);
+ apiRequest.setDescription(description);
+ apiRequest.setVersion(API_VERSION);
+ apiRequest.setProvider(apiProvider);
+ apiRequest.setSandbox(url);
+
+ apiPublisher.addAPI(apiRequest);
+
+ //publish the API
+ APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(API_NAME, apiProvider,
+ APILifeCycleState.PUBLISHED);
+ apiPublisher.changeAPILifeCycleStatus(updateRequest);
+
+ authenticatorClient.logOut();
+
+ //go to store with external store user credentials
+ apiStore.login(newUserName, newUserPassword);
+
+ //create application
+ apiStore.addApplication(APP_NAME, "Unlimited", "some_url", "NewApp");
+
+ //subscribed the API
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(API_NAME, apiProvider);
+ subscriptionRequest.setApplicationName(APP_NAME);
+
+ apiStore.subscribe(subscriptionRequest);
+
+ //Generate sandbox Token
+ APPKeyRequestGenerator generateAppKeyRequestSandBox = new APPKeyRequestGenerator(APP_NAME);
+ generateAppKeyRequestSandBox.setKeyType("SANDBOX");
+ String responseStringSandBox =
+ apiStore.generateApplicationKey(generateAppKeyRequestSandBox).getData();
+ JSONObject responseSandBox = new JSONObject(responseStringSandBox);
+ Assert.assertEquals(responseSandBox.getJSONObject("data").equals(null), false, "Generating SANDBOX key failed");
+
+ String sandBoxAccessToken =
+ responseSandBox.getJSONObject("data").getJSONObject("key").get("accessToken")
+ .toString();
+ Assert.assertEquals(sandBoxAccessToken.isEmpty(), false, "SANDBOX access token is Empty");
+
+
+ APPKeyRequestGenerator generateAppKeyRequestProduction = new APPKeyRequestGenerator(APP_NAME);
+ generateAppKeyRequestProduction.setKeyType("PRODUCTION");
+
+ String responseStringProduction =
+ apiStore.generateApplicationKey(generateAppKeyRequestProduction).getData();
+ JSONObject responseProduction = new JSONObject(responseStringProduction);
+ Assert.assertEquals(responseProduction.getJSONObject("data").equals(null), false,
+ "Generating production key failed");
+
+ String productionAccessToken =
+ responseProduction.getJSONObject("data").getJSONObject("key").get("accessToken")
+ .toString();
+ Assert.assertEquals(productionAccessToken.isEmpty(), false, "Production access token is Empty");
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void destroy() throws Exception {
+
+ //removing APIs and Applications
+ super.cleanUp(gatewayContext.getContextTenant().getTenantAdmin().getUserName(),
+ gatewayContext.getContextTenant().getContextUser().getPassword(),
+ storeUrls.getWebAppURLHttp(), publisherUrls.getWebAppURLHttp());
+
+ //restore configuration
+ serverConfigurationManager.restoreToLastConfiguration();
+ log.info("Restored configuration");
+ }
+}
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/RelativeUrlLocationHeaderTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/RelativeUrlLocationHeaderTestCase.java
new file mode 100644
index 0000000000..826c15fcdb
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/other/RelativeUrlLocationHeaderTestCase.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. 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.am.integration.tests.other;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONException;
+import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException;
+import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest;
+
+import org.wso2.am.integration.test.utils.bean.APILifeCycleState;
+import org.wso2.am.integration.test.utils.bean.APILifeCycleStateRequest;
+import org.wso2.am.integration.test.utils.bean.APIRequest;
+import org.wso2.am.integration.test.utils.bean.APPKeyRequestGenerator;
+import org.wso2.am.integration.test.utils.bean.SubscriptionRequest;
+import org.wso2.am.integration.test.utils.clients.APIPublisherRestClient;
+import org.wso2.am.integration.test.utils.clients.APIStoreRestClient;
+
+import org.json.JSONObject;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
+import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
+import javax.xml.xpath.XPathExpressionException;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test to check the Http 201 response when location header is a relative URL
+ */
+public class RelativeUrlLocationHeaderTestCase extends APIMIntegrationBaseTest {
+
+ private static final Log log = LogFactory.getLog(RelativeUrlLocationHeaderTestCase.class);
+
+ private APIPublisherRestClient apiPublisher;
+ private APIStoreRestClient apiStore;
+
+ @BeforeClass(alwaysRun = true)
+ public void setEnvironment() throws Exception {
+ super.init();
+ String gatewaySessionCookie = createSession(gatewayContext);
+ //Initialize publisher and store.
+ apiPublisher = new APIPublisherRestClient(publisherUrls.getWebAppURLHttp());
+ apiStore = new APIStoreRestClient(storeUrls.getWebAppURLHttp());
+
+ //Load the back-end dummy API
+ loadSynapseConfigurationFromClasspath("artifacts" + File.separator + "AM"
+ + File.separator + "synapseconfigs" + File.separator + "rest"
+ + File.separator + "dummy_api_relative_url_loc_header.xml", gatewayContext, gatewaySessionCookie);
+ }
+
+ @Test(groups = "wso2.am", description = "Check functionality of the API for relative URL location header")
+ public void testAPIWithRelativeUrlLocationHeader() throws Exception {
+
+ try {
+ apiPublisher.login(publisherContext.getContextTenant().getContextUser().getUserName(),
+ publisherContext.getContextTenant().getContextUser().getPassword());
+ } catch (APIManagerIntegrationTestException e) {
+ log.error("APIManagerIntegrationTestException " + e.getMessage());
+ Assert.assertTrue(false);
+ } catch (XPathExpressionException e) {
+ log.error("XPathExpressionException " + e.getMessage());
+ Assert.assertTrue(false);
+ }
+
+ String apiName = "RelativeUrlLocationHeaderAPI";
+ String apiVersion = "1.0.0";
+ String apiContext = "/relative";
+ String endpointUrl = gatewayUrls.getWebAppURLNhttp() + "response/1.0.0";
+
+ String appName = "RelativeLocHeaderAPP";
+
+ //Create the api creation request object
+ APIRequest apiRequest = null;
+ try {
+ apiRequest = new APIRequest(apiName, apiContext, new URL(endpointUrl));
+ } catch (APIManagerIntegrationTestException e) {
+ log.error("Error creating APIRequest " + e.getMessage());
+ Assert.assertTrue(false);
+ } catch (MalformedURLException e) {
+ log.error("Invalid URL " + gatewayUrls.getWebAppURLNhttp() + "response", e);
+ Assert.assertTrue(false);
+ }
+
+ apiRequest.setVersion(apiVersion);
+ apiRequest.setTiersCollection("Unlimited");
+ apiRequest.setTier("Unlimited");
+
+ //Add the API using the API publisher.
+ try {
+ apiPublisher.addAPI(apiRequest);
+
+ APILifeCycleStateRequest updateRequest = new APILifeCycleStateRequest(apiName,
+ publisherContext.getContextTenant().getContextUser().getUserName(),
+ APILifeCycleState.PUBLISHED);
+ //Publish the API
+ apiPublisher.changeAPILifeCycleStatus(updateRequest);
+
+ //Login to the API Store
+ apiStore.login(storeContext.getContextTenant().getContextUser().getUserName(),
+ storeContext.getContextTenant().getContextUser().getPassword());
+
+ //Add an Application in the Store.
+ apiStore.addApplication(appName, "Unlimited", "", "");
+
+ //Subscribe the API to the application
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest(apiName, apiVersion,
+ storeContext.getContextTenant().getContextUser().getUserName(),
+ appName, "Unlimited");
+ apiStore.subscribe(subscriptionRequest);
+
+ APPKeyRequestGenerator generateAppKeyRequestProduction = new APPKeyRequestGenerator(appName);
+ generateAppKeyRequestProduction.setKeyType("PRODUCTION");
+
+ String responseString =
+ apiStore.generateApplicationKey(generateAppKeyRequestProduction).getData();
+ JSONObject responseProduction = new JSONObject(responseString);
+ Assert.assertEquals(responseProduction.getJSONObject("data").equals(null), false,
+ "Generating production key failed");
+
+ String accessToken =
+ responseProduction.getJSONObject("data").getJSONObject("key").get("accessToken")
+ .toString();
+ Assert.assertEquals(accessToken.isEmpty(), false, "Production access token is Empty");
+
+ //Send GET Request
+
+ Map requestHeadersGet = new HashMap();
+ requestHeadersGet.put("accept", "text/xml");
+
+ requestHeadersGet.put("Authorization", "Bearer " + accessToken);
+
+ HttpResponse httpResponse = HttpRequestUtil.doGet(endpointUrl + "/" + apiVersion, requestHeadersGet);
+
+ Assert.assertEquals(httpResponse.getResponseCode(), 201, "Response Code Mismatched");
+
+ } catch (APIManagerIntegrationTestException e) {
+ log.error("APIManagerIntegrationTestException " + e.getMessage(), e);
+ Assert.assertTrue(false);
+ } catch (JSONException e) {
+ log.error("Error parsing JSON to get access token " + e.getMessage(), e);
+ Assert.assertTrue(false);
+ } catch (XPathExpressionException e) {
+ log.error("XPathExpressionException " + e.getMessage(), e);
+ Assert.assertTrue(false);
+ } catch (IOException e) {
+ log.error("IOException " + e.getMessage(), e);
+ Assert.assertTrue(false);
+ }
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void destroy() throws Exception {
+
+ //removing APIs and Applications
+ super.cleanUp(gatewayContext.getContextTenant().getTenantAdmin().getUserName(),
+ gatewayContext.getContextTenant().getContextUser().getPassword(),
+ storeUrls.getWebAppURLHttp(), publisherUrls.getWebAppURLHttp());
+
+ log.info("Cleaned up API Manager");
+ }
+
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt-readonly.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt-readonly.xml
new file mode 100644
index 0000000000..4837a0eb5e
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt-readonly.xml
@@ -0,0 +1,372 @@
+
+
+
+
+
+ true
+ admin
+
+ admin
+ admin
+
+ everyone
+ jdbc/WSO2CarbonDB
+
+
+
+
+
+
+ org.wso2.carbon.user.core.tenant.JDBCTenantManager
+ false
+ 100
+ false
+ default
+ SHA-256
+ true
+ true
+ true
+ false
+ ^[\S]{5,30}$
+ ^[\S]{5,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ true
+ 100
+ 100
+ false
+ false
+
+
+
+
+
+ org.wso2.carbon.user.core.tenant.JDBCTenantManager
+ 100
+ false
+ default
+ SHA-256
+ true
+ true
+ true
+ true
+ false
+ ^[\S]{5,30}$
+ ^[\S]{5,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ true
+ 100
+ 100
+ false
+ false
+ cat.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /permission
+ true
+
+
+
+
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt.xml
new file mode 100644
index 0000000000..418b17abb6
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/externalstore/user-mgt.xml
@@ -0,0 +1,372 @@
+
+
+
+
+
+ true
+ admin
+
+ admin
+ admin
+
+ everyone
+ jdbc/WSO2CarbonDB
+
+
+
+
+
+
+ org.wso2.carbon.user.core.tenant.JDBCTenantManager
+ false
+ 100
+ false
+ default
+ SHA-256
+ true
+ true
+ true
+ false
+ ^[\S]{5,30}$
+ ^[\S]{5,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ true
+ 100
+ 100
+ false
+ false
+
+
+
+
+
+ org.wso2.carbon.user.core.tenant.JDBCTenantManager
+ false
+ 100
+ false
+ default
+ SHA-256
+ true
+ true
+ true
+ false
+ ^[\S]{5,30}$
+ ^[\S]{5,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ ^[^~!#$;%^*+={}\\|\\\\<>,\'\"]{3,30}$
+ ^[\S]{3,30}$
+ true
+ 100
+ 100
+ false
+ false
+ cat.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /permission
+ true
+
+
+
+
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/hostobjecttest/api-manager.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/hostobjecttest/api-manager.xml
index 8ac0b3dc50..b5cbb4e0d2 100755
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/hostobjecttest/api-manager.xml
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/configFiles/hostobjecttest/api-manager.xml
@@ -468,8 +468,8 @@
Store1
http://localhost:9763/store
- admin@wso2.com
- admin
+ user1@tenantdomain1.com
+ test123
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testPublisherTenant.jag b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testPublisherTenant.jag
index 36b5ab32b8..f861d1bf9a 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testPublisherTenant.jag
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testPublisherTenant.jag
@@ -111,7 +111,7 @@ print("==");
var tierData = {};
tierData["tierName"] = "Gold";
tierData["permissiontype"] = "Deny";
-tierData["roles"] = "admin@wso2.com";
+tierData["roles"] = "admin";
//26
print(publisherHostObj.updateTierPermissions(tierData));
print("==");
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStore.jag b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStore.jag
index a183dd5973..bad2c6a76f 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStore.jag
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStore.jag
@@ -98,7 +98,7 @@ print("==");

print(storeHostObj.updateApplicationTier("DefaultApplication","gold","admin"));

print("==");

//24
-print(storeHostObj.updateApplication("DefaultApplicationTest","DefaultApplication","admin","gold","test-url","updated-application"));

+print(storeHostObj.updateApplication("DefaultApplication","DefaultApplication","admin","gold","test-url","updated-application"));

print("==");

//25
print(storeHostObj.validateWFPermission("Basic YWRtaW46YWRtaW4="));
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStoreTenant.jag b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStoreTenant.jag
index 70abf19384..5789257154 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStoreTenant.jag
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/jaggery/testStoreTenant.jag
@@ -98,7 +98,7 @@ print("==");

print(storeHostObj.updateApplicationTier("DefaultApplication","gold","admin@wso2.com"));

print("==");

//24
-print(storeHostObj.updateApplication("DefaultApplicationTest","DefaultApplication","admin@wso2.com","gold","test-url","updated-application"));

+print(storeHostObj.updateApplication("DefaultApplication","DefaultApplication","admin@wso2.com","gold","test-url","updated-application"));

print("==");

//25
print(storeHostObj.validateWFPermission("Basic YWRtaW46YWRtaW4="));
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/synapseconfigs/rest/dummy_api_relative_url_loc_header.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/synapseconfigs/rest/dummy_api_relative_url_loc_header.xml
new file mode 100644
index 0000000000..e66585d8ce
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/AM/synapseconfigs/rest/dummy_api_relative_url_loc_header.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $1
+ Status report
+ Runtime Error
+ $2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The default main sequence for API manager - Returns 404 Not Found
+
+
+
+
+
+
+
+
+
+ 403
+ Status report
+ Forbidden
+ Unsupported Transport [ $2 ]. The requested resource (/$1) is not
+ available.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 404
+ Status report
+ Not Found
+ The requested resource (/$1) is not available.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Received Request
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
index 72a10254a5..ebbb789281 100755
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
@@ -47,6 +47,7 @@
+
@@ -83,15 +84,20 @@
-
-
+
+
+
+
+
diff --git a/modules/integration/tests-ui-integration/pom.xml b/modules/integration/tests-ui-integration/pom.xml
index e4d89d84d8..a5e36ae1fc 100644
--- a/modules/integration/tests-ui-integration/pom.xml
+++ b/modules/integration/tests-ui-integration/pom.xml
@@ -74,6 +74,12 @@ under the License.
usedefaultlisteners
false
+
+ download.location
+
+ ${basedir}/target
+
+
${basedir}/target/security-verifier/
${basedir}/target/emma
${basedir}/src/test/resources/instrumentation.txt
diff --git a/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER3366MultipleGatewayPublishTestCase.java b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER3366MultipleGatewayPublishTestCase.java
index b2edef06bf..cc4b473a76 100644
--- a/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER3366MultipleGatewayPublishTestCase.java
+++ b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER3366MultipleGatewayPublishTestCase.java
@@ -1,5 +1,3 @@
-
-
/*
*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
@@ -21,6 +19,8 @@
*/
package org.wso2.am.integration.ui.tests;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -35,6 +35,7 @@
import org.wso2.carbon.utils.CarbonUtils;
import java.io.BufferedReader;
+import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
@@ -44,7 +45,8 @@ public class APIMANAGER3366MultipleGatewayPublishTestCase extends APIMIntegratio
private static final String API_URL = "http://gdata.youtube.com/feeds/api/standardfeeds";
private static final String API_METHOD = "/most_popular";
private String accessHTTPURL;
- WebDriverWait wait;
+ private static final Log log = LogFactory.getLog(APIMANAGER3366MultipleGatewayPublishTestCase.class);
+ WebDriverWait wait;
String carbonLogFilePath = CarbonUtils.getCarbonLogsPath() + "/wso2carbon.log";
@BeforeClass(alwaysRun = true)
@@ -224,18 +226,36 @@ public void tearDown() throws Exception {
driver.quit();
}
- private boolean isAPIPublished(String apiName, String version) throws IOException {
- BufferedReader input = new BufferedReader(new FileReader(carbonLogFilePath));
- String lastLine = null, line;
+ private boolean isAPIPublished(String apiName, String version) {
+ BufferedReader input = null;
+ boolean status = false;
+ try {
+ input = new BufferedReader(new FileReader(carbonLogFilePath));
+ String lastLine = null, line;
- while ((line = input.readLine()) != null) {
- lastLine = line;
- }
- input.close();
- if (lastLine != null && (lastLine.contains("INFO {org.apache.synapse.rest.API}"))) {
- return true;
- } else {
- return false;
- }
- }
+ while ((line = input.readLine()) != null) {
+ lastLine = line;
+ }
+ if (lastLine != null && (lastLine.contains("INFO {org.apache.synapse.rest.API}"))) {
+ status = true;
+ } else {
+ status = false;
+ }
+ } catch (FileNotFoundException e) {
+ String msg = "Couldn't find the " + carbonLogFilePath;
+ log.error(msg, e);
+ } catch (IOException e) {
+ String msg = "Couldn't Read the " + carbonLogFilePath;
+ log.error(msg, e);
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ //Ignore
+ }
+ }
+ }
+ return status;
+ }
}
diff --git a/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER4006SampleApiDeploymentTestCase.java b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER4006SampleApiDeploymentTestCase.java
new file mode 100644
index 0000000000..f1883d75d0
--- /dev/null
+++ b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIMANAGER4006SampleApiDeploymentTestCase.java
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright (c) 2015, 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.am.integration.ui.tests;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.firefox.FirefoxProfile;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.base.APIMIntegrationConstants;
+import org.wso2.am.integration.ui.tests.util.APIMTestConstants;
+import org.wso2.carbon.automation.engine.context.AutomationContext;
+import org.wso2.carbon.automation.test.utils.common.TestConfigurationProvider;
+import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager;
+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+
+import java.io.File;
+
+/**
+ * This test case evaluates whether the WSDL file of provided SOAP endpoint
+ * can be downloaded from both API publisher and store in super tenant and tenant modes.
+ */
+public class APIMANAGER4006SampleApiDeploymentTestCase extends APIMIntegrationUiTestBase {
+ protected AutomationContext gatewayContext;
+ private ServerConfigurationManager configManagerApiManager;
+ private WebDriver driver;
+ private WebDriverWait wait;
+ private final String SUPER_TENANT_USERNAME = "admin";
+ private final String SUPER_TENANT_PASSWORD = "admin";
+ private final String TENANT_DOMAIN_NAME = "wso2.com";
+ private final String TENANT_USERNAME = "testuser11";
+ private final String TENANT_PASSWORD = "testuser11";
+
+ private static final Log log = LogFactory.getLog(APIMANAGER4006SampleApiDeploymentTestCase.class);
+
+ @BeforeClass(alwaysRun = true)
+ public void initialize() throws Exception {
+ init();
+
+ //create gateway server instance based on configuration given at automation.xml
+ gatewayContext =
+ new AutomationContext(APIMIntegrationConstants.AM_PRODUCT_GROUP_NAME,
+ APIMIntegrationConstants.AM_GATEWAY_INSTANCE, userMode);
+ configManagerApiManager = new ServerConfigurationManager(gatewayContext);
+ configManagerApiManager.applyConfiguration(
+ new File(TestConfigurationProvider.getResourceLocation() + File.separator + "artifacts" + File.separator +
+ "AM" + File.separator + "configFiles" + File.separator + "apim4006test" + File.separator +
+ "api-manager.xml"));
+ }
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws Exception {
+ FirefoxProfile firefoxProfile = new FirefoxProfile();
+ firefoxProfile.setPreference("browser.download.folderList", 2);
+ firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
+ firefoxProfile.setPreference("browser.download.dir", System.getProperty("download.location"));
+ firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);
+ //Set browser settings to automatically download wsdl files
+ firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/force-download");
+ driver = new FirefoxDriver(firefoxProfile);
+ wait = new WebDriverWait(driver, 60);
+ }
+
+ @Test(groups = "wso2.am", priority = 1, description = "Deploy sample API when unlimited tier unavailable" +
+ " in super tenant mode")
+ public void testDeploySampleAPISuperTenantUser() {
+ deploySampleAPI(SUPER_TENANT_USERNAME, SUPER_TENANT_PASSWORD, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ }
+
+ @Test(groups = "wso2.am", priority = 2, description = "Deploy sample API when unlimited tier unavailable" +
+ " in tenant mode")
+ public void testDeploySampleAPITenantUser() {
+ deploySampleAPI(TENANT_USERNAME, TENANT_PASSWORD, TENANT_DOMAIN_NAME);
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void tearDown() throws Exception {
+ driver.quit();
+ //remove added APIs from all tenants
+ super.cleanUp(SUPER_TENANT_USERNAME, SUPER_TENANT_PASSWORD, storeUrls.getWebAppURLHttp(),
+ publisherUrls.getWebAppURLHttp());
+ super.cleanUp(TENANT_USERNAME + APIMTestConstants.EMAIL_DOMAIN_SEPARATOR + TENANT_DOMAIN_NAME, TENANT_PASSWORD,
+ storeUrls.getWebAppURLHttp(), publisherUrls.getWebAppURLHttp());
+ //restore modified configurations to previous status
+ configManagerApiManager.restoreToLastConfiguration();
+ }
+
+ /**
+ * Deploy sample API when Unlimited tier is not available
+ *
+ * @param username Username to log into publisher
+ * @param password Password of the user
+ * @param domain tenant domain of the user
+ */
+ private void deploySampleAPI(String username, String password, String domain) {
+ try {
+ driver.get(getPublisherURL());
+ } catch (Exception e) { //This exception doesn't need to be thrown since the test case gets failed
+ // if an exception occurs.
+ log.error("couldn't retrieve publisher url", e);
+ }
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("loginButton")));
+ if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(domain)) {
+ driver.findElement(By.id("username")).
+ sendKeys(username + APIMTestConstants.EMAIL_DOMAIN_SEPARATOR + domain);
+ } else {
+ driver.findElement(By.id("username")).sendKeys(username);
+ }
+ driver.findElement(By.id("pass")).sendKeys(password);
+ driver.findElement(By.id("loginButton")).click();
+ log.info("After publisher login");
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Add")));
+ driver.findElement(By.id("deploy_sample1")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("WeatherAPI")));
+ driver.findElement(By.linkText("WeatherAPI")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("viewLink")));
+ driver.findElement(By.id("viewLink")).click();
+ String assignedTier = driver.findElement(By.id("tierAvb")).getText();
+
+ publisherLogout();
+
+ Assert.assertEquals(assignedTier, "Gold", "Sample API deployment failed");
+ }
+
+ /**
+ * Logout from the publisher
+ */
+ private void publisherLogout() {
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("userMenu")));
+ driver.findElement(By.id("userMenu")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("button.btn.btn-danger")));
+ driver.findElement(By.cssSelector("button.btn.btn-danger")).click();
+ log.info("After publisher logout");
+ }
+
+}
diff --git a/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIWsdlDownloadTestCase.java b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIWsdlDownloadTestCase.java
new file mode 100644
index 0000000000..297b07202d
--- /dev/null
+++ b/modules/integration/tests-ui-integration/src/test/java/org/wso2/am/integration/ui/tests/APIWsdlDownloadTestCase.java
@@ -0,0 +1,351 @@
+/*
+ *
+ * Copyright (c) 2015, 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.am.integration.ui.tests;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.firefox.FirefoxProfile;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.Select;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.wso2.am.integration.test.utils.base.APIMIntegrationConstants;
+import org.wso2.am.integration.ui.tests.util.APIMTestConstants;
+import org.wso2.carbon.automation.engine.context.AutomationContext;
+import org.wso2.carbon.automation.test.utils.common.FileManager;
+import org.wso2.carbon.automation.test.utils.common.TestConfigurationProvider;
+import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager;
+import org.wso2.carbon.tenant.mgt.stub.TenantMgtAdminServiceExceptionException;
+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+
+import javax.xml.xpath.XPathExpressionException;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * This test case evaluates whether the WSDL file of provided SOAP endpoint
+ * can be downloaded from both API publisher and store in super tenant and tenant modes.
+ */
+public class APIWsdlDownloadTestCase extends APIMIntegrationUiTestBase {
+ protected AutomationContext gatewayContext;
+ private ServerConfigurationManager configManagerDB, configManagerMasterDatasource, configManagerReg;
+ private WebDriver driver;
+ private WebDriverWait wait;
+ private final String SUPER_TENANT_DOMAIN_NAME = "carbon.super";
+ private final String SUPER_TENANT_USERNAME = "admin";
+ private final String SUPER_TENANT_PASSWORD = "admin";
+ private final String TENANT_DOMAIN_NAME = "wso2.com";
+ private final String TENANT_USERNAME = "testuser11";
+ private final String TENANT_PASSWORD = "testuser11";
+ private final String TEST_API_NAME = "AZ176";
+
+ private static final Log log = LogFactory.getLog(APIWsdlDownloadTestCase.class);
+
+ @BeforeClass(alwaysRun = true)
+ public void initialize() throws Exception {
+ init();
+
+ //create gateway server instance based on configuration given at automation.xml
+ gatewayContext =
+ new AutomationContext(APIMIntegrationConstants.AM_PRODUCT_GROUP_NAME,
+ APIMIntegrationConstants.AM_GATEWAY_INSTANCE, userMode);
+ configManagerDB = new ServerConfigurationManager(gatewayContext);
+ configManagerDB.applyConfigurationWithoutRestart(
+ new File(TestConfigurationProvider.getResourceLocation() + File.separator + "artifacts" + File.separator +
+ "AM" + File.separator + "configFiles" + File.separator + "wsdldownloadtest" + File.separator +
+ "WSO2REG_DB.h2.db"),
+ new File(System.getProperty("carbon.home") + File.separator + "repository" + File.separator +
+ "database" + File.separator + "WSO2REG_DB.h2.db"), false);
+ configManagerMasterDatasource = new ServerConfigurationManager(gatewayContext);
+ configManagerMasterDatasource.applyConfigurationWithoutRestart(
+ new File(TestConfigurationProvider.getResourceLocation() + File.separator + "artifacts" + File.separator +
+ "AM" + File.separator + "configFiles" + File.separator + "wsdldownloadtest" + File.separator +
+ "master-datasources.xml"),
+ new File(System.getProperty("carbon.home") + File.separator + "repository" + File.separator +
+ "conf" + File.separator + "datasources" + File.separator + "master-datasources.xml"), true);
+ configManagerReg = new ServerConfigurationManager(gatewayContext);
+ configManagerReg.applyConfigurationWithoutRestart(
+ new File(TestConfigurationProvider.getResourceLocation() + File.separator + "artifacts" + File.separator +
+ "AM" + File.separator + "configFiles" + File.separator + "wsdldownloadtest" + File.separator +
+ "registry.xml"),
+ new File(System.getProperty("carbon.home") + File.separator + "repository" + File.separator +
+ "conf" + File.separator + "registry.xml"), true);
+ //init is required to apply to modified configurations to the server
+ init();
+ }
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws Exception {
+ FirefoxProfile firefoxProfile = new FirefoxProfile();
+ firefoxProfile.setPreference("browser.download.folderList", 2);
+ firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
+ firefoxProfile.setPreference("browser.download.dir", System.getProperty("download.location"));
+ firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);
+ //Set browser settings to automatically download wsdl files
+ firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/force-download");
+ driver = new FirefoxDriver(firefoxProfile);
+ wait = new WebDriverWait(driver, 60);
+ }
+
+ @Test(groups = "wso2.am", priority = 1, description = "Download WSDL from publisher in super tenant mode")
+ public void testDownloadWSDLFromPublisherSuperTenantUser()
+ throws InterruptedException, IOException {
+ createAPIWithWSDLEndpoint(TEST_API_NAME, SUPER_TENANT_USERNAME, SUPER_TENANT_PASSWORD,
+ MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ downloadWSDLFromPublisher(SUPER_TENANT_USERNAME, SUPER_TENANT_DOMAIN_NAME, TEST_API_NAME);
+ }
+
+ @Test(groups = "wso2.am", priority = 2, description = "Download WSDL from store in super tenant mode",
+ dependsOnMethods = { "testDownloadWSDLFromPublisherSuperTenantUser" })
+ public void testDownloadWSDLFromStoreSuperTenantUser() throws IOException, InterruptedException {
+ downloadWSDLFromStore(SUPER_TENANT_USERNAME, SUPER_TENANT_PASSWORD, SUPER_TENANT_DOMAIN_NAME, TEST_API_NAME);
+ }
+
+ @Test(groups = "wso2.am", priority = 3, description = "Download WSDL from publisher in tenant mode",
+ dependsOnMethods = { "testDownloadWSDLFromStoreSuperTenantUser" })
+ public void testDownloadFromPublisherTenantUser()
+ throws TenantMgtAdminServiceExceptionException, InterruptedException, IOException,
+ XPathExpressionException {
+ createAPIWithWSDLEndpoint(TEST_API_NAME, TENANT_USERNAME, TENANT_PASSWORD, TENANT_DOMAIN_NAME);
+ downloadWSDLFromPublisher(TENANT_USERNAME, TENANT_DOMAIN_NAME, TEST_API_NAME);
+ }
+
+ @Test(groups = "wso2.am", priority = 4, description = "Download WSDL from store in tenant mode",
+ dependsOnMethods = { "testDownloadFromPublisherTenantUser" })
+ public void testDownloadFromStoreTenantUser() throws IOException, InterruptedException {
+ downloadWSDLFromStore(TENANT_USERNAME, TENANT_PASSWORD, TENANT_DOMAIN_NAME, TEST_API_NAME);
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void tearDown() throws Exception {
+ driver.quit();
+ //remove added APIs from all tenants
+ super.cleanUp(SUPER_TENANT_USERNAME, SUPER_TENANT_PASSWORD, storeUrls.getWebAppURLHttp(),
+ publisherUrls.getWebAppURLHttp());
+ super.cleanUp(TENANT_USERNAME + APIMTestConstants.EMAIL_DOMAIN_SEPARATOR + TENANT_DOMAIN_NAME, TENANT_PASSWORD,
+ storeUrls.getWebAppURLHttp(), publisherUrls.getWebAppURLHttp());
+ //restore modified configurations to previous status
+ configManagerReg.restoreToLastConfiguration();
+ configManagerMasterDatasource.restoreToLastConfiguration();
+ FileManager.deleteFile(System.getProperty("carbon.home") + File.separator + "repository" + File.separator +
+ "database" + File.separator + "WSO2REG_DB.h2.db");
+ }
+
+ /**
+ * Create api with a WSDL endpoint
+ *
+ * @param apiName api name
+ * @param username username to login to publisher
+ * @param password password of the user
+ * @param domain domain of the user
+ */
+ private void createAPIWithWSDLEndpoint(String apiName, String username, String password, String domain)
+ throws InterruptedException {
+ try {
+ driver.get(getPublisherURL());
+ } catch (Exception e) {
+ log.error("couldn't retrieve publisher url", e);
+ }
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("loginButton")));
+ if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(domain)) {
+ driver.findElement(By.id("username")).
+ sendKeys(username + APIMTestConstants.EMAIL_DOMAIN_SEPARATOR + domain);
+ } else {
+ driver.findElement(By.id("username")).sendKeys(username);
+ }
+ driver.findElement(By.id("pass")).sendKeys(password);
+ driver.findElement(By.id("loginButton")).click();
+ log.info("After publisher login");
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Add")));
+ driver.findElement(By.linkText("Add")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("create-new-api")));
+ driver.findElement(By.xpath("(//input[@name='create-api'])[2]")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("startFromExistingSOAPEndpoint")));
+ driver.findElement(By.id("wsdl-url")).clear();
+ driver.findElement(By.id("wsdl-url")).sendKeys("http://www.webservicex.com/globalweather.asmx?WSDL");
+ driver.findElement(By.id("startFromExistingSOAPEndpoint")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("go_to_implement")));
+ driver.findElement(By.id("name")).clear();
+ driver.findElement(By.id("name")).sendKeys(apiName);
+ driver.findElement(By.id("context")).clear();
+ driver.findElement(By.id("context")).sendKeys(apiName);
+ driver.findElement(By.id("version")).clear();
+ driver.findElement(By.id("version")).sendKeys("1.0.0");
+ driver.findElement(By.id("go_to_implement")).click();
+ log.info("After API design");
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@value='#managed-api']")));
+ driver.findElement(By.xpath("//div[@value='#managed-api']")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("go_to_manage")));
+ driver.findElement(By.id("jsonform-0-elt-production_endpoints")).clear();
+ driver.findElement(By.id("jsonform-0-elt-production_endpoints")).sendKeys(storeUrls.getWebAppURLHttp());
+ driver.findElement(By.id("jsonform-0-elt-sandbox_endpoints")).clear();
+ driver.findElement(By.id("jsonform-0-elt-sandbox_endpoints")).sendKeys(storeUrls.getWebAppURLHttp());
+ driver.findElement(By.id("go_to_manage")).click();
+ log.info("After API manage");
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("publish_api")));
+ driver.findElement(By.xpath("//button[@type='button']")).click();
+ driver.findElement(By.xpath("//input[@value='Gold']")).click();
+ driver.findElement(By.id("publish_api")).click();
+ log.info("After API publish");
+ }
+
+ /**
+ * Logout from the publisher
+ */
+ private void publisherLogout() {
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("userMenu")));
+ driver.findElement(By.id("userMenu")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("button.btn.btn-danger")));
+ driver.findElement(By.cssSelector("button.btn.btn-danger")).click();
+ log.info("After publisher logout");
+ }
+
+ /**
+ * Download WSDL file from the publisher
+ *
+ * @param username username to login to store
+ * @param tenant domain of the login user
+ * @param apiName api name of the published api
+ * @throws java.io.IOException if downloaded file couldn't found
+ * @throws InterruptedException If an interruption occurs in the threads
+ */
+ private void downloadWSDLFromPublisher(String username, String tenant, String apiName)
+ throws IOException, InterruptedException {
+
+ String tenantUnawareUsername;
+ //Set the domain name for non super tenant users
+ if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenant)) {
+ tenantUnawareUsername = username.concat("-AT-" + tenant);
+ } else {
+ tenantUnawareUsername = username;
+ }
+
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Go to Overview")));
+ driver.findElement(By.linkText("Go to Overview")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("lifecyclesLink")));
+ driver.findElement(By.id("lifecyclesLink")).click();
+
+ //Change api status to published if it is not already set
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("editStatus")));
+ Select status = new Select(driver.findElement(By.id("editStatus")));
+ if (!"PUBLISHED".equals(status.getFirstSelectedOption().getText())) {
+ status.selectByVisibleText("PUBLISHED");
+ }
+
+ driver.findElement(By.id("updateStateButton")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("viewLink")));
+ driver.findElement(By.id("viewLink")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("/" + tenantUnawareUsername + "--" +
+ apiName + "1.0.0.wsdl")));
+ //Download wsdl by clicking its link
+ driver.findElement(By.linkText("/" + tenantUnawareUsername + "--" + apiName + "1.0.0.wsdl")).click();
+ File file = new File(
+ System.getProperty("download.location") + File.separator + tenantUnawareUsername + "--" + apiName +
+ "1.0.0.wsdl");
+ while (!file.exists()) {
+ Thread.sleep(1000);
+ }
+ //check whether downloaded file is readable
+ boolean isReadableFile = file.canRead();
+ file.delete();
+ //Logout from publisher once the test is completed
+ publisherLogout();
+ Assert.assertEquals(isReadableFile, true, "Download WSDL from publisher failed");
+ }
+
+ /**
+ * Download WSDL file from API Store
+ *
+ * @param username username to login to store
+ * @param password password of the user
+ * @param tenant domain of the login user
+ * @param apiName api name of the published api
+ * @throws java.io.IOException if downloaded file couldn't found
+ * @throws InterruptedException If an interruption occurs in the threads
+ */
+ private void downloadWSDLFromStore(String username, String password, String tenant, String apiName)
+ throws IOException, InterruptedException {
+ try {
+ driver.get(getStoreURL() + "?tenant=" + tenant);
+ } catch (Exception e) {
+ log.error("Couldn't retrieve store url of api manager");
+ }
+
+ Thread.sleep(2000);
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-link")));
+ WebElement login = driver.findElement(By.id("login-link"));
+ String tenantUnawareUsername = null;
+ if (login != null) {
+ login.click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("loginBtn")));
+ if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenant)) {
+ driver.findElement(By.id("username")).sendKeys(username + "@" + tenant);
+ tenantUnawareUsername = username.concat("-AT-" + tenant);
+ } else {
+ driver.findElement(By.id("username")).sendKeys(username);
+ tenantUnawareUsername = username;
+ }
+ driver.findElement(By.id("password")).clear();
+ driver.findElement(By.id("password")).sendKeys(password);
+ driver.findElement(By.id("loginBtn")).click();
+ log.info("After store login");
+ }
+
+ long waitTime = 30000; // Wait only for 30s until the
+ long targetWaitTime = System.currentTimeMillis() + waitTime;
+
+ while ((!driver.getPageSource().contains(apiName + "-1.0.0")) && System.currentTimeMillis() < targetWaitTime) {
+ Thread.sleep(500); // Waiting 0.5 second to check API is visible on UI
+ driver.navigate().refresh();
+ }
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText(apiName + "-1.0.0")));
+ driver.findElement(By.linkText(apiName + "-1.0.0")).click();
+ driver.findElement(By.linkText("Overview")).click();
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Download WSDL")));
+ driver.findElement(By.linkText("Download WSDL")).click();
+ File file = new File(
+ System.getProperty("download.location") + File.separator + tenantUnawareUsername + "--" + apiName +
+ "1.0.0.wsdl");
+ while (!file.exists()) {
+ Thread.sleep(1000);
+ }
+ boolean isReadableFile = file.canRead();
+ file.delete();
+ //Logout from store once the test is completed
+ storeLogout(username);
+ Assert.assertEquals(isReadableFile, true, "Download WSDL from store failed");
+ }
+
+ /**
+ * Logout from the store
+ */
+ private void storeLogout(String username) throws InterruptedException {
+ wait.until(ExpectedConditions.visibilityOfElementLocated(By.partialLinkText(username)));
+ driver.findElement(By.partialLinkText(username)).click();
+ driver.findElement(By.id("logout-link")).click();
+ log.info("After store logout");
+ }
+}
diff --git a/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/apim4006test/api-manager.xml b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/apim4006test/api-manager.xml
new file mode 100755
index 0000000000..004950cd4b
--- /dev/null
+++ b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/apim4006test/api-manager.xml
@@ -0,0 +1,512 @@
+
+
+ jdbc/WSO2AM_DB
+
+
+ Synapse
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://${carbon.local.ip}:${mgt.transport.https.port}${carbon.context}/services/
+
+ ${admin.username}
+
+ ${admin.password}
+
+
+
+
+
+ X-JWT-Assertion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.wso2.carbon.apimgt.impl.token.JWTGenerator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Production and Sandbox
+ Description of environment
+
+ https://${carbon.local.ip}:${mgt.transport.https.port}${carbon.context}/services/
+
+ ${admin.username}
+
+ ${admin.password}
+
+ http://${carbon.local.ip}:${http.nio.port},https://${carbon.local.ip}:${https.nio.port}
+
+
+
+
+ true
+
+
+ true
+
+
+ referer
+
+
+
+
+ false
+
+
+
+
+
+ false
+
+
+ org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageDataBridgeDataPublisher
+
+
+ false
+
+
+
+ org.wso2.apimgt.statistics.request
+ 1.0.0
+
+
+ org.wso2.apimgt.statistics.response
+ 1.0.0
+
+
+ org.wso2.apimgt.statistics.fault
+ 1.0.0
+
+
+ org_wso2_apimgt_statistics_destination
+ 1.0.0
+ bam-profile
+
+
+ org.wso2.apimgt.statistics.throttle
+ 1.0.0
+
+
+ org.wso2.apimgt.statistics.workflow
+ 1.0.0
+
+
+
+
+
+
+
+
+ https://${carbon.local.ip}:${mgt.transport.https.port}${carbon.context}/services/
+
+
+ ${admin.username}
+
+
+ ${admin.password}
+
+ false
+
+
+
+ false
+
+
+
+ ThriftClient
+ 10397
+ 10000
+ 10397
+
+ true
+
+
+ am_application_scope
+
+
+ org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler
+
+
+
+
+
+
+
+
+ /oauth2/token
+
+
+ https://${carbon.local.ip}:${https.nio.port}/revoke
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+ true
+ false
+ https://${carbon.local.ip}:${mgt.transport.https.port}/store
+
+ false
+
+ false
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+
+ false
+
+
+
+
+ false
+ https://${carbon.local.ip}:${mgt.transport.https.port}/publisher
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+ /resource
+ admin
+ 1.0.0
+ none
+ none
+ Any
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ *
+
+
+ GET,PUT,POST,DELETE,OPTIONS
+
+
+ authorization,Access-Control-Allow-Origin,Content-Type
+
+
+
+
+
diff --git a/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/WSO2REG_DB.h2.db b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/WSO2REG_DB.h2.db
new file mode 100644
index 0000000000..638e244237
Binary files /dev/null and b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/WSO2REG_DB.h2.db differ
diff --git a/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/master-datasources.xml b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/master-datasources.xml
new file mode 100644
index 0000000000..a39a3aaa8e
--- /dev/null
+++ b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/master-datasources.xml
@@ -0,0 +1,97 @@
+
+
+
+ org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader
+
+
+
+
+
+ WSO2_CARBON_DB
+ The datasource used for registry and user manager
+
+ jdbc/WSO2CarbonDB
+
+
+
+ jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE
+ wso2carbon
+ wso2carbon
+ org.h2.Driver
+ 50
+ 60000
+ true
+ SELECT 1
+ 30000
+
+
+
+
+
+ WSO2_REG_DB
+ The datasource used for registry and user manager
+
+ jdbc/WSO2RegDB
+
+
+
+ jdbc:h2:repository/database/WSO2REG_DB;DB_CLOSE_ON_EXIT=FALSE
+ wso2carbon
+ wso2carbon
+ org.h2.Driver
+ 50
+ 60000
+ true
+ SELECT 1
+ 30000
+
+
+
+
+
+ WSO2AM_DB
+ The datasource used for API Manager database
+
+ jdbc/WSO2AM_DB
+
+
+
+ jdbc:h2:repository/database/WSO2AM_DB;DB_CLOSE_ON_EXIT=FALSE
+ wso2carbon
+ wso2carbon
+ false
+ org.h2.Driver
+ 50
+ 60000
+ true
+ SELECT 1
+ 30000
+
+
+
+
+
+ WSO2AM_STATS_DB
+ The datasource used for getting statistics to API Manager
+
+ jdbc/WSO2AM_STATS_DB
+
+
+
+ jdbc:h2:;AUTO_SERVER=TRUE
+ wso2carbon
+ wso2carbon
+ false
+ org.h2.Driver
+ 50
+ 60000
+ true
+ SELECT 1
+ 30000
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/registry.xml b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/registry.xml
new file mode 100644
index 0000000000..4d3a82308b
--- /dev/null
+++ b/modules/integration/tests-ui-integration/src/test/resources/artifacts/AM/configFiles/wsdldownloadtest/registry.xml
@@ -0,0 +1,346 @@
+
+
+
+
+
+ wso2registry
+ false
+ true
+ /
+
+
+
+
+ jdbc/WSO2CarbonDB
+
+
+
+ jdbc/WSO2RegDB
+
+
+
+
+
+
+ wso2reg
+ wso2reg
+ false
+ true
+ /
+
+
+
+
+
+ wso2reg
+ /_system/config/integrate
+
+
+
+ wso2reg
+ /_system/governance/integrate
+
+
+
+
+
+
+ .*
+
+
+
+
+
+
+
+ .*
+
+
+
+
+
+
+
+ true
+
+ /trunk/schemas/
+
+
+ /trunk/wsdls/
+
+
+ /trunk/policies/
+
+
+
+ application/wsdl+xml
+
+
+
+
+
+
+ application/wsdl+xml
+ application/xsd+xml
+ 50
+ true
+
+ 3
+
+ /trunk/schemas/
+
+
+ /trunk/wsdls/
+
+
+ application/vnd.wso2.governance-archive
+
+
+
+
+
+
+
+ 1.0.0-SNAPSHOT
+ true
+
+ dev
+ qa
+ live
+
+
+ application/vnd.wso2-service+xml
+
+
+
+
+
+
+
+ application/vnd.wso2-service+xml
+
+
+
+
+
+
+
+
+ /_system/governance/event/topics/registry/notifications/.*
+
+
+
+
+
+
+
+
+ Created
+ Tested
+ Deployed
+
+
+ application/vnd.wso2-smart-link
+
+
+
+
+
+
+
+ /trunk/policies/
+
+
+ application/policy+xml
+
+
+
+
+
+
+
+ true
+
+ /trunk/schemas/
+
+
+ application/x-xsd+xml
+
+
+
+
+
+
+
+ application/vnd.wso2-hyperlink
+
+
+
+
+
+
+ application/vnd.wso2.endpoint
+
+ /trunk/endpoints/
+
+
+
+
+
+
+
+ application/vnd.wso2-uri+xml
+
+
+
+
+
+
+
+ .*
+
+
+
+
+
+
+ .*
+
+
+
+
+
+
+ workflow-config
+
+
+
+
+
+
+
+
+
+
+
+ 60
+ 2
+
+ 50
+
+ 10
+
+ /_system/local/repository/components/org.wso2.carbon.registry/indexing/lastaccesstime
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+ /trunk/services/
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/org.wso2.stratos.apimgt.dashboard.ui/pom.xml b/modules/org.wso2.stratos.apimgt.dashboard.ui/pom.xml
index c9094dbeec..c5cf6c9770 100644
--- a/modules/org.wso2.stratos.apimgt.dashboard.ui/pom.xml
+++ b/modules/org.wso2.stratos.apimgt.dashboard.ui/pom.xml
@@ -25,7 +25,7 @@
4.0.0
org.wso2.stratos.apimgt.dashboard.ui
- 2.2.0
+ 2.2.1-SNAPSHOT
bundle
WSO2 Stratos API Manager - Dashboard UI
diff --git a/modules/org.wso2.stratos.apimgt.login.ui/pom.xml b/modules/org.wso2.stratos.apimgt.login.ui/pom.xml
index ce1860b8ae..d72ea71a2f 100644
--- a/modules/org.wso2.stratos.apimgt.login.ui/pom.xml
+++ b/modules/org.wso2.stratos.apimgt.login.ui/pom.xml
@@ -26,7 +26,7 @@
4.0.0
org.wso2.stratos.apimgt.login.ui
- 2.2.0
+ 2.2.1-SNAPSHOT
bundle
WSO2 AM - Login User Interface
diff --git a/modules/p2-profile/product/pom.xml b/modules/p2-profile/product/pom.xml
index 5161ac13b9..27f0458e85 100644
--- a/modules/p2-profile/product/pom.xml
+++ b/modules/p2-profile/product/pom.xml
@@ -268,6 +268,25 @@
+
+ 13-unpack-kernel-patch
+ test
+
+ unpack
+
+
+
+
+ org.wso2.carbon
+ WSO2-CARBON-PATCH-4.2.0
+ 0012
+ zip
+ true
+ target
+
+
+
+
@@ -393,7 +412,7 @@
org.jaggeryjs.modules:ws.feature:1.1.0
org.wso2.carbon.apimgt:org.wso2.carbon.apimgt.feature:${apimgt.feature.version}
- org.wso2.am:org.wso2.stratos.apimgt.dashboard.ui.feature:${stratos.version}
+ org.wso2.am:org.wso2.stratos.apimgt.dashboard.ui.feature:${apimgt.stratos.version}
org.wso2.carbon:org.wso2.carbon.registry.extensions.feature:4.2.1
@@ -765,7 +784,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
@@ -1190,7 +1209,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
@@ -1544,7 +1563,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
@@ -1935,7 +1954,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
@@ -2365,7 +2384,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
@@ -2787,7 +2806,7 @@
org.wso2.stratos.apimgt.dashboard.ui.feature.group
- ${stratos.version}
+ ${apimgt.stratos.version}
org.wso2.carbon.event.server.feature.group
diff --git a/nested-categories/gateway-manager/pom.xml b/nested-categories/gateway-manager/pom.xml
index 60e92046f0..fca2b0648e 100644
--- a/nested-categories/gateway-manager/pom.xml
+++ b/nested-categories/gateway-manager/pom.xml
@@ -124,7 +124,7 @@
org.wso2.carbon.um.ws.service.server:4.2.2
org.wso2.carbon.user.mgt:4.2.3
org.wso2.carbon.xfer:${carbon.platform.version}
- org.wso2.stratos.apimgt.dashboard.ui:${stratos.version}
+ org.wso2.stratos.apimgt.dashboard.ui:${apimgt.stratos.version}
org.wso2.carbon.bam.message.tracer.handler:4.2.3
diff --git a/nested-categories/publisher/pom.xml b/nested-categories/publisher/pom.xml
index 1938e27d9e..70a64b8819 100644
--- a/nested-categories/publisher/pom.xml
+++ b/nested-categories/publisher/pom.xml
@@ -107,7 +107,7 @@
org.wso2.carbon.user.mgt:4.2.3
org.wso2.carbon.webapp.mgt:4.2.2
org.wso2.carbon.xfer:${carbon.platform.version}
- org.wso2.stratos.apimgt.dashboard.ui:${stratos.version}
+ org.wso2.stratos.apimgt.dashboard.ui:${apimgt.stratos.version}
org.wso2.carbon.registry.contentsearch:4.2.2
org.apache.synapse.wso2:2.1.2-wso2v6
org.apache.synapse.transport.nhttp:2.1.2-wso2v6
diff --git a/nested-categories/store/pom.xml b/nested-categories/store/pom.xml
index d2d2d563ab..36236ef29a 100644
--- a/nested-categories/store/pom.xml
+++ b/nested-categories/store/pom.xml
@@ -107,7 +107,7 @@
org.wso2.carbon.user.mgt:4.2.3
org.wso2.carbon.webapp.mgt:4.2.2
org.wso2.carbon.xfer:${carbon.platform.version}
- org.wso2.stratos.apimgt.dashboard.ui:${stratos.version}
+ org.wso2.stratos.apimgt.dashboard.ui:${apimgt.stratos.version}
org.wso2.carbon.registry.contentsearch:4.2.2
org.wso2.carbon.identity.oauth.common:4.2.3
org.apache.synapse.wso2:2.1.2-wso2v6
diff --git a/pom.xml b/pom.xml
index 9814ac682e..9199d64b67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -425,9 +425,9 @@
${apimserver.version}
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.api
- 1.2.3
+ ${apimgt.api.version}
org.codehaus.jettison.wso2
@@ -446,9 +446,9 @@
${carbon.platform.version}
- org.wso2.carbon
+ org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.hostobjects
- 1.2.2
+ ${apimgt.api.version}
commons-digester
@@ -775,7 +775,7 @@
1.9.1-SNAPSHOT
1.2.5-SNAPSHOT
1.2.5-SNAPSHOT
- 4.2.6
+ 4.2.7-SNAPSHOT
UTF-8
1.2.13
1.1.1
@@ -804,7 +804,7 @@
1.2.1.wso2v1
1.6.1.wso2v10
2.2.5.wso2v1
- 2.2.0
+ 2.2.1-SNAPSHOT
140
132
2.2.0.v201112011158