package org.mconf.bbb.api;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class JoinServiceBase {
public static final int E_OK = 0;
public static final int E_CHECKSUM_NOT_INFORMED = 1;
public static final int E_INVALID_CHECKSUM = 2;
public static final int E_INVALID_TIMESTAMP = 3;
public static final int E_EMPTY_SECURITY_KEY = 4;
public static final int E_MISSING_PARAM_MEETINGID = 5;
public static final int E_MISSING_PARAM_FULLNAME = 6;
public static final int E_MISSING_PARAM_PASSWORD = 7;
public static final int E_MISSING_PARAM_TIMESTAMP = 8;
public static final int E_INVALID_URL = 9;
public static final int E_SERVER_UNREACHABLE = 10;
public static final int E_MOBILE_NOT_SUPPORTED = 11;
public static final int E_UNKNOWN_ERROR = 12;
public static final int E_CANNOT_GET_CONFIGXML = 13;
private static final Logger log = LoggerFactory.getLogger(JoinServiceBase.class);
protected JoinedMeeting joinedMeeting = null;
protected String serverUrl = "";
protected int serverPort = 0;
protected Meetings meetings = new Meetings();
protected boolean loaded = false;
protected ApplicationService appService = null;
private BbbServerConfig serverConfig = null;
public abstract String getVersion();
protected abstract String getCreateMeetingUrl(String meetingID);
protected abstract String getLoadUrl();
protected abstract String getJoinUrl(Meeting meeting, String name, boolean moderator);
protected abstract String getDemoPath();
protected String getFullDemoPath() {
return getFullServerUrl() + getDemoPath();
}
private String getFullServerUrl() {
return serverUrl + ":" + serverPort;
}
public int createMeeting(String meetingID) {
String createUrl = getFullDemoPath() + getCreateMeetingUrl(meetingID);
log.debug("create URL: {}", createUrl);
String response = "Unknown error";
try {
response = getUrl(createUrl);
} catch (Exception e) {
e.printStackTrace();
log.error("Can't get the url {}", createUrl);
}
if (meetingID.equals(response))
return E_OK;
else {
log.error("create response: {}", response);
return E_SERVER_UNREACHABLE;
}
}
public int load() { //.
String loadUrl = getFullDemoPath() + getLoadUrl();
log.debug("getMeetings URL: " + loadUrl);
int returnCode;
loaded = false;
try {
returnCode = meetings.parse(getUrl(loadUrl));
} catch (Exception e) {
e.printStackTrace();
log.info("Can't connect to {}", loadUrl);
return E_SERVER_UNREACHABLE;
}
if(returnCode == E_OK) {
log.debug(meetings.toString());
loaded = true;
}
return returnCode;
}
public int join(String meetingID, String name, boolean moderator) { //.
if (!loaded)
return E_SERVER_UNREACHABLE;
for (Meeting meeting : meetings.getMeetings()) {
if (meeting.getMeetingID().equals(meetingID))
return join(meeting, name, moderator);
}
return E_SERVER_UNREACHABLE;
}
public int join(Meeting meeting, String name, boolean moderator) {
return join(getFullDemoPath() + getJoinUrl(meeting, name, moderator));
}
private int join(String joinUrl) { //.
joinedMeeting = new JoinedMeeting();
try {
String joinResponse = getUrl(joinUrl);
log.debug("join response: {}", joinResponse);
joinedMeeting.parse(joinResponse);
} catch (Exception e) {
e.printStackTrace();
log.error("Can't join the url {}", joinUrl);
return E_SERVER_UNREACHABLE;
}
return joinResponse();
}
private int joinResponse() {
if (joinedMeeting.getReturncode().equals("SUCCESS")) {
if (joinedMeeting.getServer().length() != 0)
appService = new ApplicationService(joinedMeeting.getServer());
else
appService = new ApplicationService(serverUrl, getVersion());
return E_OK;
} else {
if (joinedMeeting.getMessage() != null)
log.error(joinedMeeting.getMessage());
return E_SERVER_UNREACHABLE;
}
}
public int standardJoin(String joinUrl) {
joinedMeeting = new JoinedMeeting();
try {
HttpClient client = new DefaultHttpClient();
HttpGet method = new HttpGet(joinUrl);
HttpContext context = new BasicHttpContext();
HttpResponse httpResponse = client.execute(method, context);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
log.debug("HTTP GET {} return {}", joinUrl, httpResponse.getStatusLine().getStatusCode());
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
ExecutionContext.HTTP_REQUEST);
if (!currentReq.getURI().getPath().equals("/client/BigBlueButton.html")) {
log.warn("It was redirected to {} instead of /client/BigBlueButton.html: the server was branded" +
" and the HTML name was changed, or it's an error. However, it will continue processing", currentReq.getURI().getPath());
}
HttpHost currentHost = (HttpHost) context.getAttribute(
ExecutionContext.HTTP_TARGET_HOST);
String enterUrl = currentHost.toURI() + "/bigbluebutton/api/enter";
// have to modify the answer of the api/enter in case when the join
// message is answered by another host (proxy)
String enterResponse = getUrl(client, enterUrl).replace("</response>", "<server>" + currentHost.toURI() + "</server></response>");
joinedMeeting.parse(enterResponse);
} catch (Exception e) {
e.printStackTrace();
log.error("Can't join the url {}", joinUrl);
return E_SERVER_UNREACHABLE;
}
return joinResponse();
}
public JoinedMeeting getJoinedMeeting() {
return joinedMeeting;
}
public void resetJoinedMeeting() {
joinedMeeting=null;
}
public List<Meeting> getMeetings() {
return meetings.getMeetings();
}
public int getPort() {
return serverPort;
}
public String getApiServerUrl() {
return serverUrl;
}
public ApplicationService getApplicationService() {
return appService;
}
public void setServer(String serverUrl) {
Pattern pattern = Pattern.compile("(.*):(\\d*)");
Matcher matcher = pattern.matcher(serverUrl);
if (matcher.matches()) {
this.serverUrl = matcher.group(1);
this.serverPort = Integer.parseInt(matcher.group(2));
} else {
this.serverUrl = serverUrl;
this.serverPort = 80;
}
}
public Meeting getMeetingByName(String meetingName) {
for(Meeting meeting : meetings.getMeetings()) {
if(meeting.getMeetingName().equals(meetingName))
return meeting;
}
return null;
}
public Meeting getMeetingByID(String meetingID) {
for(Meeting meeting : meetings.getMeetings()) {
if(meeting.getMeetingID().equals(meetingID))
return meeting;
}
return null;
}
public int setServerConfiguration()
{
String configAddress = "http://" + appService.getServerUrl() + ":" + Integer.toString(appService.getServerPort()) + "/client/conf/config.xml";
log.debug("Trying to fetch {}", configAddress);
try
{
serverConfig = new BbbServerConfig(getUrl(configAddress));
}
catch (Exception e)
{
log.error("Couldn't get config.xml");
return E_CANNOT_GET_CONFIGXML;
}
return E_OK;
}
public BbbServerConfig getServerConfiguration()
{
return serverConfig;
}
protected static String getUrl(String url) throws IOException, ClientProtocolException {
HttpClient client = new DefaultHttpClient();
return getUrl(client, url);
}
protected static String getUrl(HttpClient client, String url) throws IOException, ClientProtocolException {
HttpGet method = new HttpGet(url);
HttpResponse httpResponse = client.execute(method);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
log.debug("HTTP GET {} return {}", url, httpResponse.getStatusLine().getStatusCode());
return EntityUtils.toString(httpResponse.getEntity()).trim();
}
protected static String checksum(String s) {
String checksum = "";
try {
checksum = DigestUtils.sha256Hex(s);
} catch (Exception e) {
e.printStackTrace();
}
return checksum;
}
protected static String urlEncode(String s) {
try {
return URLEncoder.encode(s, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}