<commit_before>/**
 * This file was automatically generated by the Mule Development Kit
 */
package com.mulesoft.module.googlesearch;

import com.mulesoft.module.googlesearch.model.SearchConfiguration;
import com.mulesoft.module.googlesearch.model.SearchType;
import org.apache.commons.lang.StringUtils;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.annotations.Configurable;
import org.mule.api.annotations.Mime;
import org.mule.api.annotations.Module;
import org.mule.api.annotations.Processor;
import org.mule.api.annotations.lifecycle.Start;
import org.mule.api.annotations.param.Default;
import org.mule.api.annotations.param.Optional;
import org.mule.api.endpoint.OutboundEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;

/**
 * Google custom search Module.
 *
 * @author <NAME>.
 */
@Module(name = "google-search", schemaVersion = "1.0.0-SNAPSHOT", friendlyName = "Google Custom Search Module")
public class GoogleSearchModule {

    private static final Logger logger = LoggerFactory.getLogger(GoogleSearchModule.class);


    private static final String API_URL = "https://www.googleapis.com/customsearch/v1";

    /**
     * API Key obtained from Google's API Console.
     */
    @Configurable
    private String apiKey;

    /**
     * This requires a custom search engine to be created prior the use of module.
     * This parameter represents the custom search engine ID.
     */
    @Configurable
    @Optional
    @Default("")
    private String searchEngineId;

    /**
     * This requires a custom search engine to be created prior the use of module.
     * This parameter represents the custom search engine URL.
     */
    @Configurable
    @Optional
    @Default("")
    private String searchEngineUrl;

    private HashMap<String, String> connectorConfigs;

    /**
     * Perform module initialization.
     */
    @Start
    public void initializeConfiguration() {
        connectorConfigs = new HashMap<String, String>();

        connectorConfigs.put("key", apiKey);

        if (StringUtils.isBlank(searchEngineId) && StringUtils.isBlank(searchEngineUrl)) {
            throw new IllegalArgumentException("You must configure either searchEngineId or searchEngineUrl");
        }

        if (StringUtils.isNotBlank(searchEngineId) && StringUtils.isNotBlank(searchEngineUrl)) {
            throw new IllegalArgumentException("You must configure a reference to the custom search engine.");
        }

        addIfNotBlank(connectorConfigs, "cx", searchEngineId);
        addIfNotBlank(connectorConfigs, "cref", searchEngineUrl);
    }


    /**
     * Custom processor
     * <p/>
     * {@sample.xml ../../../doc/GoogleSearchModule-connector.xml.sample google-search:search}
     *
     * @param event               The current Mule Event.
     * @param query               The search query to send to google search.
     * @param siteSearch          The site where to search.
     * @param searchType          The type of the search to be performed.
     * @param searchConfiguration Configuration for this google search.
     * @return The JSON result as returned by the google custom search API.
     */
    @Processor
    @Inject
    @Mime("application/json")
    public String search(MuleEvent event, String query, @Optional @Default("") String siteSearch,
                         @Optional @Default("WEB_SEARCH") SearchType searchType, @Optional SearchConfiguration searchConfiguration) {

        MuleContext context = event.getMuleContext();

        MuleMessage message = event.getMessage();

        HashMap<String, String> searchParams = buildSearchParams(query, siteSearch, searchType, searchConfiguration);

        String apiUrl = buildSearchUrl(searchParams);

        try {
            OutboundEndpoint endpoint = context.getEndpointFactory().getOutboundEndpoint(apiUrl);

            //configure the message.
            message.setOutboundProperty("http.method", "GET");

            MuleEvent responseEvent = endpoint.process(event);

            MuleMessage responseMessage = responseEvent.getMessage();

            validateResponse(responseMessage);

            //return the payload.
            return responseEvent.getMessage().getPayload(String.class);
        } catch (MuleException e) {
            logger.error("Error while querying the google custom search API", e);
        }
        return null;
    }

    private String buildSearchUrl(HashMap<String, String> searchParams) {
        StringBuilder ret = new StringBuilder(API_URL);

        ret.append("?");

        try {

            for (String key : searchParams.keySet()) {
                //we want to urlencode the parameters and the values.
                ret.append(URLEncoder.encode(key, "UTF-8"));
                ret.append("=");
                ret.append(searchParams.get(key));
                ret.append("&");
            }
        } catch (UnsupportedEncodingException ex) {
            logger.error("Unsupported Encoding???", ex);
        }

        //remove the final &
        ret.deleteCharAt(ret.length() - 1);

        return ret.toString();
    }


    protected static void validateResponse(MuleMessage msg) {
        String statusCode = msg.getInboundProperty("http.status");

        if (!StringUtils.equals("200", statusCode)) {
            throw new IllegalStateException("API responded with unsuccessful status: " + statusCode);
        }

        String contentType = msg.getInboundProperty("Content-Type");

        if (!StringUtils.startsWith(contentType, "application/json")) {
            throw new IllegalStateException("API responded with unsuccessful content type: " + contentType);
        }
    }


    private HashMap<String, String> buildSearchParams(String query, String siteSearch, SearchType searchType, SearchConfiguration searchConfiguration) {<commit_msg>Added a little logging of the message when it gets validated<commit_after>/**
 * This file was automatically generated by the Mule Development Kit
 */
package com.mulesoft.module.googlesearch;

import com.mulesoft.module.googlesearch.model.SearchConfiguration;
import com.mulesoft.module.googlesearch.model.SearchType;
import org.apache.commons.lang.StringUtils;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.annotations.Configurable;
import org.mule.api.annotations.Mime;
import org.mule.api.annotations.Module;
import org.mule.api.annotations.Processor;
import org.mule.api.annotations.lifecycle.Start;
import org.mule.api.annotations.param.Default;
import org.mule.api.annotations.param.Optional;
import org.mule.api.endpoint.OutboundEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;

/**
 * Google custom search Module.
 *
 * @author <NAME>.
 */
@Module(name = "google-search", schemaVersion = "1.0.0-SNAPSHOT", friendlyName = "Google Custom Search Module")
public class GoogleSearchModule {

    private static final Logger logger = LoggerFactory.getLogger(GoogleSearchModule.class);


    private static final String API_URL = "https://www.googleapis.com/customsearch/v1";

    /**
     * API Key obtained from Google's API Console.
     */
    @Configurable
    private String apiKey;

    /**
     * This requires a custom search engine to be created prior the use of module.
     * This parameter represents the custom search engine ID.
     */
    @Configurable
    @Optional
    @Default("")
    private String searchEngineId;

    /**
     * This requires a custom search engine to be created prior the use of module.
     * This parameter represents the custom search engine URL.
     */
    @Configurable
    @Optional
    @Default("")
    private String searchEngineUrl;

    private HashMap<String, String> connectorConfigs;

    /**
     * Perform module initialization.
     */
    @Start
    public void initializeConfiguration() {
        connectorConfigs = new HashMap<String, String>();

        connectorConfigs.put("key", apiKey);

        if (StringUtils.isBlank(searchEngineId) && StringUtils.isBlank(searchEngineUrl)) {
            throw new IllegalArgumentException("You must configure either searchEngineId or searchEngineUrl");
        }

        if (StringUtils.isNotBlank(searchEngineId) && StringUtils.isNotBlank(searchEngineUrl)) {
            throw new IllegalArgumentException("You must configure a reference to the custom search engine.");
        }

        addIfNotBlank(connectorConfigs, "cx", searchEngineId);
        addIfNotBlank(connectorConfigs, "cref", searchEngineUrl);
    }


    /**
     * Custom processor
     * <p/>
     * {@sample.xml ../../../doc/GoogleSearchModule-connector.xml.sample google-search:search}
     *
     * @param event               The current Mule Event.
     * @param query               The search query to send to google search.
     * @param siteSearch          The site where to search.
     * @param searchType          The type of the search to be performed.
     * @param searchConfiguration Configuration for this google search.
     * @return The JSON result as returned by the google custom search API.
     */
    @Processor
    @Inject
    @Mime("application/json")
    public String search(MuleEvent event, String query, @Optional @Default("") String siteSearch,
                         @Optional @Default("WEB_SEARCH") SearchType searchType, @Optional SearchConfiguration searchConfiguration) {

        MuleContext context = event.getMuleContext();

        MuleMessage message = event.getMessage();

        HashMap<String, String> searchParams = buildSearchParams(query, siteSearch, searchType, searchConfiguration);

        String apiUrl = buildSearchUrl(searchParams);

        try {
            OutboundEndpoint endpoint = context.getEndpointFactory().getOutboundEndpoint(apiUrl);

            //configure the message.
            message.setOutboundProperty("http.method", "GET");

            MuleEvent responseEvent = endpoint.process(event);

            MuleMessage responseMessage = responseEvent.getMessage();

            validateResponse(responseMessage);

            //return the payload.
            return responseEvent.getMessage().getPayload(String.class);
        } catch (MuleException e) {
            logger.error("Error while querying the google custom search API", e);
        }
        return null;
    }

    private String buildSearchUrl(HashMap<String, String> searchParams) {
        StringBuilder ret = new StringBuilder(API_URL);

        ret.append("?");

        try {

            for (String key : searchParams.keySet()) {
                //we want to urlencode the parameters and the values.
                ret.append(URLEncoder.encode(key, "UTF-8"));
                ret.append("=");
                ret.append(searchParams.get(key));
                ret.append("&");
            }
        } catch (UnsupportedEncodingException ex) {
            logger.error("Unsupported Encoding???", ex);
        }

        //remove the final &
        ret.deleteCharAt(ret.length() - 1);

        return ret.toString();
    }


    protected static void validateResponse(MuleMessage msg) {
        String statusCode = msg.getInboundProperty("http.status");

        if (logger.isDebugEnabled()) {
            logger.debug("Payload to validate:");
            logger.debug(msg.getPayload().toString());
        }

        if (!StringUtils.equals("200", statusCode)) {
            throw new IllegalStateException("API responded with unsuccessful status: " + statusCode);
        }

        String contentType = msg.getInboundProperty("Content-Type");

        if (!StringUtils.startsWith(contentType, "application/json")) {
            throw new IllegalStateException("API responded with unsuccessful content type: " + contentType);
        }
    }


    private HashMap<String, String> buildSearchParams(String query, String siteSearch, SearchType searchType, SearchConfiguration searchConfiguration) {
{'fraction_non_alphanumeric': 0.09886547811993517, 'fraction_numerical': 0.0017828200972447325, 'mean_word_length': 2.9140501110053916, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2893966', 'n_tokens_mistral': 3245, 'n_tokens_neox': 3156, 'n_words': 852}