<commit_before>/*
 * (C) Copyright 2017-2020 OpenVidu (https://openvidu.io)
 *
 * 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 io.openvidu.java.client;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

public class OpenVidu {

	private static final Logger log = LoggerFactory.getLogger(OpenVidu.class);

	private String secret;
	protected String hostname;
	protected HttpClient httpClient;
	protected Map<String, Session> activeSessions = new ConcurrentHashMap<>();

	protected final static String API_PATH = "openvidu/api";
	protected final static String API_SESSIONS = API_PATH + "/sessions";
	protected final static String API_TOKENS = API_PATH + "/tokens";
	protected final static String API_RECORDINGS = API_PATH + "/recordings";
	protected final static String API_RECORDINGS_START = API_RECORDINGS + "/start";
	protected final static String API_RECORDINGS_STOP = API_RECORDINGS + "/stop";

	/**
	 * @param hostname URL where your instance of OpenVidu Server is up an running.
	 *                 It must be the full URL (e.g.
	 *                 <code>https://172.16.17.32:1234/</code>)
	 * 
	 * @param secret   Secret used on OpenVidu Server initialization
	 */
	public OpenVidu(String hostname, String secret) {

		this.hostname = hostname;

		if (!this.hostname.endsWith("/")) {
			this.hostname += "/";
		}

		this.secret = secret;

		TrustStrategy trustStrategy = new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				return true;
			}
		};

		CredentialsProvider provider = new BasicCredentialsProvider();
		UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("OPENVIDUAPP", this.secret);
		provider.setCredentials(AuthScope.ANY, credentials);

		SSLContext sslContext;

		try {
			sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
			throw new RuntimeException(e);
		}

		RequestConfig.Builder requestBuilder = RequestConfig.custom();
		requestBuilder = requestBuilder.setConnectTimeout(30000);
		requestBuilder = requestBuilder.setConnectionRequestTimeout(30000);

		this.httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestBuilder.build())
				.setConnectionTimeToLive(30, TimeUnit.SECONDS).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
				.setSSLContext(sslContext).setDefaultCredentialsProvider(provider).build();
	}

	/**
	 * Creates an OpenVidu session with the default settings
	 * 
	 * @return The created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException
	 */
	public Session createSession() throws OpenViduJavaClientException, OpenViduHttpException {
		Session s = new Session(this);
		this.activeSessions.put(s.getSessionId(), s);
		return s;
	}

	/**
	 * Creates an OpenVidu session
	 * 
	 * @param properties The specific configuration for this session
	 * 
	 * @return The created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException       Value returned from
	 *                                     {@link io.openvidu.java.client.OpenViduHttpException#getStatus()}
	 *                                     <ul>
	 *                                     <li><code>409</code>: you are trying to
	 *                                     assign an already-in-use custom sessionId
	 *                                     to the session. See
	 *                                     {@link io.openvidu.java.client.SessionProperties#customSessionId()}</li>
	 *                                     </ul>
	 */
	public Session createSession(SessionProperties properties)
			throws OpenViduJavaClientException, OpenViduHttpException {
		Session s = new Session(this, properties);
		this.activeSessions.put(s.getSessionId(), s);
		return s;
	}

	/**
	 * Starts the recording of a {@link io.openvidu.java.client.Session}
	 *
	 * @param sessionId  The sessionId of the session you want to start recording
	 * @param properties The configuration for this recording
	 *
	 * @return The new created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException       Value returned from
	 *                                     {@link io.openvidu.java.client.OpenViduHttpException#getStatus()}
	 *                                     <ul>
	 *                                     <li><code>404</code>: no session exists
	 *                                     for the passed <i>sessionId</i></li>
	 *                                     <li><code>406</code>: the session has no
	 *                                     connected participants</li>
	 *                                     <li><code>422</code>: "resolution"
	 *                                     parameter exceeds acceptable values (for
	 *                                     both width and height, min 100px and max
	 *                                     1999px) or trying to start a recording
	 *                                     with both "hasAudio" and "hasVideo" to
	 *                                     false</li>
	 *                                     <li><code>409</code>: the session is not
	 *                                     configured for using
	 *                                     {@link io.openvidu.java.client.MediaMode#ROUTED}
	 *                                     or it is already being recorded</li>
	 *                                     <li><code>501</code>: OpenVidu Server
	 *                                     recording module is disabled
	 *                                     (<i>OPENVIDU_RECORDING</i> property set
	 *                                     to <i>false</i>)</li>
	 *                                     </ul>
	 */
	public Recording startRecording(String sessionId, RecordingProperties properties)
			throws OpenViduJavaClientException, OpenViduHttpException {

		HttpPost request = new HttpPost(this.hostname + API_RECORDINGS_START);

		JsonObject json = properties.toJson();
		json.addProperty("session", sessionId);

		StringEntity params = null;
		try {
			params = new StringEntity(json.toString());
		} catch (UnsupportedEncodingException e1) {
			throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
		}<commit_msg>openvidu-java-client: encode HttpEntity with UTF-8<commit_after>/*
 * (C) Copyright 2017-2020 OpenVidu (https://openvidu.io)
 *
 * 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 io.openvidu.java.client;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

public class OpenVidu {

	private static final Logger log = LoggerFactory.getLogger(OpenVidu.class);

	private String secret;
	protected String hostname;
	protected HttpClient httpClient;
	protected Map<String, Session> activeSessions = new ConcurrentHashMap<>();

	protected final static String API_PATH = "openvidu/api";
	protected final static String API_SESSIONS = API_PATH + "/sessions";
	protected final static String API_TOKENS = API_PATH + "/tokens";
	protected final static String API_RECORDINGS = API_PATH + "/recordings";
	protected final static String API_RECORDINGS_START = API_RECORDINGS + "/start";
	protected final static String API_RECORDINGS_STOP = API_RECORDINGS + "/stop";

	/**
	 * @param hostname URL where your instance of OpenVidu Server is up an running.
	 *                 It must be the full URL (e.g.
	 *                 <code>https://172.16.17.32:1234/</code>)
	 * 
	 * @param secret   Secret used on OpenVidu Server initialization
	 */
	public OpenVidu(String hostname, String secret) {

		this.hostname = hostname;

		if (!this.hostname.endsWith("/")) {
			this.hostname += "/";
		}

		this.secret = secret;

		TrustStrategy trustStrategy = new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				return true;
			}
		};

		CredentialsProvider provider = new BasicCredentialsProvider();
		UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("OPENVIDUAPP", this.secret);
		provider.setCredentials(AuthScope.ANY, credentials);

		SSLContext sslContext;

		try {
			sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
			throw new RuntimeException(e);
		}

		RequestConfig.Builder requestBuilder = RequestConfig.custom();
		requestBuilder = requestBuilder.setConnectTimeout(30000);
		requestBuilder = requestBuilder.setConnectionRequestTimeout(30000);

		this.httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestBuilder.build())
				.setConnectionTimeToLive(30, TimeUnit.SECONDS).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
				.setSSLContext(sslContext).setDefaultCredentialsProvider(provider).build();
	}

	/**
	 * Creates an OpenVidu session with the default settings
	 * 
	 * @return The created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException
	 */
	public Session createSession() throws OpenViduJavaClientException, OpenViduHttpException {
		Session s = new Session(this);
		this.activeSessions.put(s.getSessionId(), s);
		return s;
	}

	/**
	 * Creates an OpenVidu session
	 * 
	 * @param properties The specific configuration for this session
	 * 
	 * @return The created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException       Value returned from
	 *                                     {@link io.openvidu.java.client.OpenViduHttpException#getStatus()}
	 *                                     <ul>
	 *                                     <li><code>409</code>: you are trying to
	 *                                     assign an already-in-use custom sessionId
	 *                                     to the session. See
	 *                                     {@link io.openvidu.java.client.SessionProperties#customSessionId()}</li>
	 *                                     </ul>
	 */
	public Session createSession(SessionProperties properties)
			throws OpenViduJavaClientException, OpenViduHttpException {
		Session s = new Session(this, properties);
		this.activeSessions.put(s.getSessionId(), s);
		return s;
	}

	/**
	 * Starts the recording of a {@link io.openvidu.java.client.Session}
	 *
	 * @param sessionId  The sessionId of the session you want to start recording
	 * @param properties The configuration for this recording
	 *
	 * @return The new created session
	 * 
	 * @throws OpenViduJavaClientException
	 * @throws OpenViduHttpException       Value returned from
	 *                                     {@link io.openvidu.java.client.OpenViduHttpException#getStatus()}
	 *                                     <ul>
	 *                                     <li><code>404</code>: no session exists
	 *                                     for the passed <i>sessionId</i></li>
	 *                                     <li><code>406</code>: the session has no
	 *                                     connected participants</li>
	 *                                     <li><code>422</code>: "resolution"
	 *                                     parameter exceeds acceptable values (for
	 *                                     both width and height, min 100px and max
	 *                                     1999px) or trying to start a recording
	 *                                     with both "hasAudio" and "hasVideo" to
	 *                                     false</li>
	 *                                     <li><code>409</code>: the session is not
	 *                                     configured for using
	 *                                     {@link io.openvidu.java.client.MediaMode#ROUTED}
	 *                                     or it is already being recorded</li>
	 *                                     <li><code>501</code>: OpenVidu Server
	 *                                     recording module is disabled
	 *                                     (<i>OPENVIDU_RECORDING</i> property set
	 *                                     to <i>false</i>)</li>
	 *                                     </ul>
	 */
	public Recording startRecording(String sessionId, RecordingProperties properties)
			throws OpenViduJavaClientException, OpenViduHttpException {

		HttpPost request = new HttpPost(this.hostname + API_RECORDINGS_START);

		JsonObject json = properties.toJson();
		json.addProperty("session", sessionId);

		StringEntity params = null;
		params = new StringEntity(json.toString(), "UTF-8");
{'fraction_non_alphanumeric': 0.09018312818973281, 'fraction_numerical': 0.00870609426598619, 'mean_word_length': 2.641451683428072, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 79, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 62, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4742166', 'n_tokens_mistral': 4706, 'n_tokens_neox': 4317, 'n_words': 1115}