<commit_before>/*
 *  Copyright (c) 2020, 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.carbon.apimgt.rest.api.publisher.v1.common.mappings;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.StringUtils;
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.ExceptionCodes;
import org.wso2.carbon.apimgt.api.dto.CertificateMetadataDTO;
import org.wso2.carbon.apimgt.api.dto.ClientCertificateDTO;
import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.APIProduct;
import org.wso2.carbon.apimgt.api.model.Identifier;
import org.wso2.carbon.apimgt.impl.importexport.APIImportExportException;
import org.wso2.carbon.apimgt.impl.importexport.ExportFormat;
import org.wso2.carbon.apimgt.impl.importexport.ImportExportConstants;
import org.wso2.carbon.apimgt.impl.importexport.utils.APIAndAPIProductCommonUtil;
import org.wso2.carbon.apimgt.impl.importexport.utils.CommonUtil;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIDTO;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIEndpointSecurityDTO;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIProductDTO;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * This Class Used for API Controller related operations.
 */
public class APIControllerUtil {

    private static final Log log = LogFactory.getLog(APIAndAPIProductCommonUtil.class);

    /**
     * Method will check the archive and extract environment related params.
     *
     * @param pathToArchive String of the archive project
     * @return JsonObject of environment parameters
     * @throws IOException
     */
    public static JsonObject resolveAPIControllerEnvParams(String pathToArchive) throws IOException {

        String jsonParamsContent;
        jsonParamsContent = ImportUtils
                .getFileContentAsJson(pathToArchive + ImportExportConstants.INTERMEDIATE_PARAMS_FILE_LOCATION);
        if (StringUtils.isEmpty(jsonParamsContent)) {
            return null;
        }
        JsonElement paramsElement = new JsonParser().parse(jsonParamsContent);
        return paramsElement.getAsJsonObject();
    }

    /**
     * Method retrieve the params configurations dependent APIs of an API Product.
     *
     * @param path Path of the archive project
     * @return JsonObject of environment parameters of the dependent APIs
     * @throws IOException If an error occurs when resolving API controller environment parameters
     */
    public static JsonObject getDependentAPIsParams(String path) throws IOException {

        JsonObject paramsConfigObject = APIControllerUtil.resolveAPIControllerEnvParams(path);
        JsonObject dependentAPIsParams = null;
        if (paramsConfigObject != null && paramsConfigObject.has(ImportExportConstants.DEPENDENT_APIS_FIELD)) {
            dependentAPIsParams = paramsConfigObject.get(ImportExportConstants.DEPENDENT_APIS_FIELD).getAsJsonObject();
        }
        return dependentAPIsParams;
    }

    /**
     * Method retrieve the params configurations for a dependent API of an API Product specified by the.
     * API directory name
     *
     * @param dependentAPIsParams Env params array of dependent APIs of the API Product
     * @param apiDirectoryName    Dependent API directory name
     * @return JsonObject of environment parameters of the dependent API
     */
    public static JsonObject getDependentAPIParams(JsonObject dependentAPIsParams, String apiDirectoryName) {

        if (dependentAPIsParams.has(apiDirectoryName)) {
            return dependentAPIsParams.get(apiDirectoryName).getAsJsonObject();
        }
        return null;
    }

    /**
     * This method will be used to add Extracted environment parameters to the imported Api object.
     *
     * @param pathToArchive  Path to API or API Product archive
     * @param importedApiDto APIDTO object to be imported
     * @param envParams      Env params object with required parameters
     * @return API Updated API Object
     * @throws APIManagementException If an error occurs merging env parameters with api
     */
    public static APIDTO injectEnvParamsToAPI(APIDTO importedApiDto, JsonObject envParams, String pathToArchive)
            throws APIManagementException {

        if (envParams == null || envParams.isJsonNull()) {
            return importedApiDto;
        }

        API importedApi = APIMappingUtil.fromDTOtoAPI(importedApiDto, importedApiDto.getProvider());

        // if endpointType field is not specified in the params file, it will be considered as HTTP/REST
        JsonElement endpointTypeElement = envParams.get(ImportExportConstants.ENDPOINT_TYPE_FIELD);
        String endpointType = null;
        if (endpointTypeElement != null) {
            endpointType = endpointTypeElement.getAsString();
        } else {
            endpointType = ImportExportConstants.REST_TYPE_ENDPOINT;
        }

        //Handle multiple end points
        JsonObject jsonObject = setupMultipleEndpoints(envParams, endpointType);
        ObjectMapper mapper = new ObjectMapper();
        HashMap<String, Object> endpointConfig;
        try {
            endpointConfig = mapper.readValue(jsonObject.toString(), HashMap.class);
        } catch (JsonProcessingException e) {
            String errorMessage = "Error while reading endpointConfig information in the params file.";
            throw new APIManagementException(errorMessage, e, ExceptionCodes.ERROR_READING_PARAMS_FILE);
        }
        importedApiDto.setEndpointConfig(endpointConfig);

        //handle gateway environments
        if (envParams.get(ImportExportConstants.GATEWAY_ENVIRONMENTS_FIELD) != null) {
            List<String> environments = setupGatewayEnvironments(
                    envParams.get(ImportExportConstants.GATEWAY_ENVIRONMENTS_FIELD).getAsJsonArray());
            importedApiDto.setGatewayEnvironments(environments);
        }

        //handle mutualSSL certificates
        handleMutualSslCertificates(envParams, importedApiDto, null, importedApi.getId(), pathToArchive);

        //handle endpoint certificates
        JsonElement endpointCertificates = envParams.get(ImportExportConstants.ENDPOINT_CERTIFICATES_FIELD);
        if (endpointCertificates != null) {
            try {
                String jsonString = endpointCertificates.toString();
                handleEndpointCertificates(new JsonParser().parse(jsonString).getAsJsonArray(), pathToArchive);
            } catch (IOException e) {
                //Error is logged and when generating certificate details and certs in the archive
                String errorMessage = "Error while generating meta information of client certificates from path.";
                throw new APIManagementException(errorMessage, e, ExceptionCodes.ERROR_READING_PARAMS_FILE);
            }
        }

        //handle security configs
        JsonElement securityConfigs = envParams.get(ImportExportConstants.ENDPOINT_SECURITY_FIELD);
        if (securityConfigs != null) {
            handleEndpointSecurityConfigs(envParams, importedApiDto);
        }

        // handle available subscription policies
        JsonElement policies = envParams.get(ImportExportConstants.POLICIES_FIELD);
        if (policies != null && !policies.isJsonNull()) {
            handleSubscriptionPolicies(policies, importedApiDto, null);
        }
        return importedApiDto;
    }

    /**
     * This method will be used to generate ClientCertificates and meta information related to client certs.
     *
     * @param envParams             Env params object with required parameters
     * @param importedApiDto        Imported API DTO (this will be null for API Products)
     * @param importedApiProductDto Imported API Product DTO (this will be null for APIs)
     * @param identifier            API Identifier/API Product Identifier of the imported API/API Product
     * @param pathToArchive         String of the archive project
     * @throws APIManagementException If an error while generating client certificate information
     */
    private static void handleMutualSslCertificates(JsonObject envParams, APIDTO importedApiDto,
                                                    APIProductDTO importedApiProductDto, Identifier identifier,
                                                    String pathToArchive)
            throws APIManagementException {

        JsonElement clientCertificates = envParams.get(ImportExportConstants.MUTUAL_SSL_CERTIFICATES_FIELD);
        if (clientCertificates != null) {<commit_msg>Convert endpointConfig integer values to strings<commit_after>/*
 *  Copyright (c) 2020, 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.carbon.apimgt.rest.api.publisher.v1.common.mappings;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.StringUtils;
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.ExceptionCodes;
import org.wso2.carbon.apimgt.api.dto.CertificateMetadataDTO;
import org.wso2.carbon.apimgt.api.dto.ClientCertificateDTO;
import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.api.model.APIIdentifier;
import org.wso2.carbon.apimgt.api.model.APIProduct;
import org.wso2.carbon.apimgt.api.model.Identifier;
import org.wso2.carbon.apimgt.impl.importexport.APIImportExportException;
import org.wso2.carbon.apimgt.impl.importexport.ExportFormat;
import org.wso2.carbon.apimgt.impl.importexport.ImportExportConstants;
import org.wso2.carbon.apimgt.impl.importexport.utils.APIAndAPIProductCommonUtil;
import org.wso2.carbon.apimgt.impl.importexport.utils.CommonUtil;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIDTO;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIEndpointSecurityDTO;
import org.wso2.carbon.apimgt.rest.api.publisher.v1.dto.APIProductDTO;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * This Class Used for API Controller related operations.
 */
public class APIControllerUtil {

    private static final Log log = LogFactory.getLog(APIAndAPIProductCommonUtil.class);

    /**
     * Method will check the archive and extract environment related params.
     *
     * @param pathToArchive String of the archive project
     * @return JsonObject of environment parameters
     * @throws IOException
     */
    public static JsonObject resolveAPIControllerEnvParams(String pathToArchive) throws IOException {

        String jsonParamsContent;
        jsonParamsContent = ImportUtils
                .getFileContentAsJson(pathToArchive + ImportExportConstants.INTERMEDIATE_PARAMS_FILE_LOCATION);
        if (StringUtils.isEmpty(jsonParamsContent)) {
            return null;
        }
        JsonElement paramsElement = new JsonParser().parse(jsonParamsContent);
        return paramsElement.getAsJsonObject();
    }

    /**
     * Method retrieve the params configurations dependent APIs of an API Product.
     *
     * @param path Path of the archive project
     * @return JsonObject of environment parameters of the dependent APIs
     * @throws IOException If an error occurs when resolving API controller environment parameters
     */
    public static JsonObject getDependentAPIsParams(String path) throws IOException {

        JsonObject paramsConfigObject = APIControllerUtil.resolveAPIControllerEnvParams(path);
        JsonObject dependentAPIsParams = null;
        if (paramsConfigObject != null && paramsConfigObject.has(ImportExportConstants.DEPENDENT_APIS_FIELD)) {
            dependentAPIsParams = paramsConfigObject.get(ImportExportConstants.DEPENDENT_APIS_FIELD).getAsJsonObject();
        }
        return dependentAPIsParams;
    }

    /**
     * Method retrieve the params configurations for a dependent API of an API Product specified by the.
     * API directory name
     *
     * @param dependentAPIsParams Env params array of dependent APIs of the API Product
     * @param apiDirectoryName    Dependent API directory name
     * @return JsonObject of environment parameters of the dependent API
     */
    public static JsonObject getDependentAPIParams(JsonObject dependentAPIsParams, String apiDirectoryName) {

        if (dependentAPIsParams.has(apiDirectoryName)) {
            return dependentAPIsParams.get(apiDirectoryName).getAsJsonObject();
        }
        return null;
    }

    /**
     * This method will be used to add Extracted environment parameters to the imported Api object.
     *
     * @param pathToArchive  Path to API or API Product archive
     * @param importedApiDto APIDTO object to be imported
     * @param envParams      Env params object with required parameters
     * @return API Updated API Object
     * @throws APIManagementException If an error occurs merging env parameters with api
     */
    public static APIDTO injectEnvParamsToAPI(APIDTO importedApiDto, JsonObject envParams, String pathToArchive)
            throws APIManagementException {

        if (envParams == null || envParams.isJsonNull()) {
            return importedApiDto;
        }

        API importedApi = APIMappingUtil.fromDTOtoAPI(importedApiDto, importedApiDto.getProvider());

        // if endpointType field is not specified in the params file, it will be considered as HTTP/REST
        JsonElement endpointTypeElement = envParams.get(ImportExportConstants.ENDPOINT_TYPE_FIELD);
        String endpointType = null;
        if (endpointTypeElement != null) {
            endpointType = endpointTypeElement.getAsString();
        } else {
            endpointType = ImportExportConstants.REST_TYPE_ENDPOINT;
        }

        //Handle multiple end points
        JsonObject jsonObject = setupMultipleEndpoints(envParams, endpointType);
        ObjectMapper mapper = new ObjectMapper();
        HashMap<String, Object> endpointConfig;
        try {
            endpointConfig = mapper.readValue(jsonObject.toString(), HashMap.class);
            convertValuesToStrings(endpointConfig);
        } catch (JsonProcessingException e) {
            String errorMessage = "Error while reading endpointConfig information in the params file.";
            throw new APIManagementException(errorMessage, e, ExceptionCodes.ERROR_READING_PARAMS_FILE);
        }
        importedApiDto.setEndpointConfig(endpointConfig);

        //handle gateway environments
        if (envParams.get(ImportExportConstants.GATEWAY_ENVIRONMENTS_FIELD) != null) {
            List<String> environments = setupGatewayEnvironments(
                    envParams.get(ImportExportConstants.GATEWAY_ENVIRONMENTS_FIELD).getAsJsonArray());
            importedApiDto.setGatewayEnvironments(environments);
        }

        //handle mutualSSL certificates
        handleMutualSslCertificates(envParams, importedApiDto, null, importedApi.getId(), pathToArchive);

        //handle endpoint certificates
        JsonElement endpointCertificates = envParams.get(ImportExportConstants.ENDPOINT_CERTIFICATES_FIELD);
        if (endpointCertificates != null) {
            try {
                String jsonString = endpointCertificates.toString();
                handleEndpointCertificates(new JsonParser().parse(jsonString).getAsJsonArray(), pathToArchive);
            } catch (IOException e) {
                //Error is logged and when generating certificate details and certs in the archive
                String errorMessage = "Error while generating meta information of client certificates from path.";
                throw new APIManagementException(errorMessage, e, ExceptionCodes.ERROR_READING_PARAMS_FILE);
            }
        }

        //handle security configs
        JsonElement securityConfigs = envParams.get(ImportExportConstants.ENDPOINT_SECURITY_FIELD);
        if (securityConfigs != null) {
            handleEndpointSecurityConfigs(envParams, importedApiDto);
        }

        // handle available subscription policies
        JsonElement policies = envParams.get(ImportExportConstants.POLICIES_FIELD);
        if (policies != null && !policies.isJsonNull()) {
            handleSubscriptionPolicies(policies, importedApiDto, null);
        }
        return importedApiDto;
    }

    /**
     * This method will be used to convert any integer values to strings in a particular map of values.
     *
     * @param keyValuePairs Map to be validated and converted
     */
    private static void convertValuesToStrings(Map<String, Object> keyValuePairs) {
        Iterator it = keyValuePairs.entrySet().iterator();
        while (it.hasNext()) {
            HashMap.Entry pair = (HashMap.Entry) it.next();
            if (pair.getValue() instanceof Integer && pair.getKey() instanceof String) {
                keyValuePairs.replace(pair.getKey().toString(), pair.getValue().toString());
            }
            if (pair.getValue() instanceof Map) {
                convertValuesToStrings((Map) pair.getValue());
            }
        }
    }

    /**
     * This method will be used to generate ClientCertificates and meta information related to client certs.
     *
     * @param envParams             Env params object with required parameters
     * @param importedApiDto        Imported API DTO (this will be null for API Products)
     * @param importedApiProductDto Imported API Product DTO (this will be null for APIs)
     * @param identifier            API Identifier/API Product Identifier of the imported API/API Product
     * @param pathToArchive         String of the archive project
     * @throws APIManagementException If an error while generating client certificate information
     */
    private static void handleMutualSslCertificates(JsonObject envParams, APIDTO importedApiDto,
                                                    APIProductDTO importedApiProductDto, Identifier identifier,
                                                    String pathToArchive)
            throws APIManagementException {

        JsonElement clientCertificates = envParams.get(ImportExportConstants.MUTUAL_SSL_CERTIFICATES_FIELD);
        if (clientCertificates != null) {
{'fraction_non_alphanumeric': 0.07324636967757814, 'fraction_numerical': 0.0032488309131183855, 'mean_word_length': 3.2289758534554536, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2411668', 'n_tokens_mistral': 5284, 'n_tokens_neox': 5244, 'n_words': 1428}