Java tutorial
/* BigBlueButton - http://www.bigbluebutton.org Copyright (c) 2008-2013 by respective authors (see below). All rights reserved. BigBlueButton is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>. Author: Jesus Federico <jesus@blindsidenetworks.com> */ package org.bigbluebutton.impl; import org.bigbluebutton.api.BBBException; import org.bigbluebutton.api.BBBProxy; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.apache.commons.codec.digest.DigestUtils; import org.apache.log4j.Logger; public class BBBProxyImpl implements BBBProxy { private static final Logger log = Logger.getLogger(BBBProxyImpl.class); String endpoint; String secret; BBBProxyImpl() { log.info("Creting BBBProxyImpl()"); this.endpoint = DEFAULT_ENDPOINT; this.secret = DEFAULT_SECRET; } BBBProxyImpl(String endpoint, String secret) { log.info("Creting BBBProxyImpl(" + endpoint + ", " + secret + ")"); if (endpoint == null || endpoint.equals("")) { this.endpoint = DEFAULT_ENDPOINT; } else { if (!endpoint.substring(endpoint.length() - 1).equals("/")) endpoint += "/"; this.endpoint = endpoint; } if (secret == null || secret.equals("")) { this.secret = DEFAULT_SECRET; } else { this.secret = secret; } } public void setEndpoint(String endpoint) { if (!endpoint.substring(endpoint.length() - 1).equals("/")) endpoint += "/"; this.endpoint = endpoint; } public void setSecret(String secret) { this.secret = secret; } public static String getVersion(String endpoint, String secret) throws BBBException { log.info("Executing getVersion"); String version; if (!endpoint.substring(endpoint.length() - 1).equals("/")) endpoint += "/"; Map<String, Object> response = doAPICall(endpoint + API_SERVERPATH); String returnCode = (String) response.get("returncode"); log.debug("returnCode: " + returnCode); if (returnCode == null || !returnCode.equals(BBBProxy.APIRESPONSE_SUCCESS)) { log.debug(BBBException.MESSAGEKEY_UNREACHABLE + ": Unreachable server. BigBlueButton server version can not be verified."); throw new BBBException(BBBException.MESSAGEKEY_UNREACHABLE, "Unreachable server. BigBlueButton server version can not be verified."); } else { version = (String) response.get("version"); if (version == null || version == "") { log.debug(BBBException.MESSAGEKEY_INVALIDRESPONSE + ": Invalid response. Server version was not received."); throw new BBBException(BBBException.MESSAGEKEY_INVALIDRESPONSE, "Invalid response. Server version was not received."); } } return version; } //////////////////// /** Make an API call */ public static Map<String, Object> doAPICall(String query) { Map<String, Object> response = new HashMap<String, Object>(); StringBuilder urlStr = new StringBuilder(query); try { // open connection log.debug("doAPICall.call: " + query); URL url = new URL(urlStr.toString()); HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setUseCaches(false); httpConnection.setDoOutput(true); httpConnection.setRequestMethod("GET"); httpConnection.connect(); int responseCode = httpConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // read response InputStreamReader isr = null; BufferedReader reader = null; StringBuilder xml = new StringBuilder(); try { isr = new InputStreamReader(httpConnection.getInputStream(), "UTF-8"); reader = new BufferedReader(isr); String line = reader.readLine(); while (line != null) { if (!line.startsWith("<?xml version=\"1.0\"?>")) xml.append(line.trim()); line = reader.readLine(); } } finally { if (reader != null) reader.close(); if (isr != null) isr.close(); } httpConnection.disconnect(); // parse response log.debug("doAPICall.responseXml: " + xml); //Patch to fix the NaN error String stringXml = xml.toString(); stringXml = stringXml.replaceAll(">.\\s+?<", "><"); DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder; try { docBuilder = docBuilderFactory.newDocumentBuilder(); Document dom = null; dom = docBuilder.parse(new InputSource(new StringReader(stringXml))); response = getNodesAsMap(dom, "response"); log.debug("doAPICall.responseMap: " + response); String returnCode = (String) response.get("returncode"); if (BBBProxy.APIRESPONSE_FAILED.equals(returnCode)) { log.debug("doAPICall." + (String) response.get("messageKey") + ": Message=" + (String) response.get("message")); } } catch (ParserConfigurationException e) { log.debug("Failed to initialise BaseProxy: " + e.getMessage()); } } else { log.debug("doAPICall.HTTPERROR: Message=" + "BBB server responded with HTTP status code " + responseCode); } } catch (IOException e) { log.debug("doAPICall.IOException: Message=" + e.getMessage()); } catch (SAXException e) { log.debug("doAPICall.SAXException: Message=" + e.getMessage()); } catch (IllegalArgumentException e) { log.debug("doAPICall.IllegalArgumentException: Message=" + e.getMessage()); } catch (Exception e) { log.debug("doAPICall.Exception: Message=" + e.getMessage()); } return response; } /** Get all nodes under the specified element tag name as a Java map */ protected static Map<String, Object> getNodesAsMap(Document dom, String elementTagName) { Node firstNode = dom.getElementsByTagName(elementTagName).item(0); return processNode(firstNode); } protected static Map<String, Object> processNode(Node _node) { Map<String, Object> map = new HashMap<String, Object>(); NodeList responseNodes = _node.getChildNodes(); for (int i = 0; i < responseNodes.getLength(); i++) { Node node = responseNodes.item(i); String nodeName = node.getNodeName().trim(); if (node.getChildNodes().getLength() == 1 && (node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.TEXT_NODE || node.getChildNodes().item(0).getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE)) { String nodeValue = node.getTextContent(); map.put(nodeName, nodeValue != null ? nodeValue.trim() : null); } else if (node.getChildNodes().getLength() == 0 && node.getNodeType() != org.w3c.dom.Node.TEXT_NODE && node.getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE) { map.put(nodeName, ""); } else if (node.getChildNodes().getLength() >= 1 && node.getChildNodes().item(0).getChildNodes().item(0) .getNodeType() != org.w3c.dom.Node.TEXT_NODE && node.getChildNodes().item(0).getChildNodes().item(0) .getNodeType() != org.w3c.dom.Node.CDATA_SECTION_NODE) { List<Object> list = new ArrayList<Object>(); for (int c = 0; c < node.getChildNodes().getLength(); c++) { Node n = node.getChildNodes().item(c); list.add(processNode(n)); } map.put(nodeName, list); } else { map.put(nodeName, processNode(node)); } } return map; } ///////////// public String getVersionURL() { return this.endpoint + API_SERVERPATH; } public String getCreateURL(Map<String, String> params) { String qs = ""; qs += PARAM_NAME + "=" + params.get(PARAM_NAME); qs += "&" + PARAM_MEETING_ID + "=" + params.get(PARAM_MEETING_ID); qs += "&" + PARAM_MODERATOR_PW + "=" + params.get(PARAM_MODERATOR_PW); qs += "&" + PARAM_ATTENDEE_PW + "=" + params.get(PARAM_ATTENDEE_PW); qs += params.containsKey(PARAM_WELCOME) ? "&" + PARAM_WELCOME + "=" + params.get(PARAM_WELCOME) : ""; qs += params.containsKey(PARAM_LOGOUT_URL) ? "&" + PARAM_LOGOUT_URL + "=" + params.get(PARAM_LOGOUT_URL) : ""; Integer voiceBridge = Integer .valueOf(params.containsKey(PARAM_VOICE_BRIDGE) ? params.get(PARAM_VOICE_BRIDGE) : "0"); voiceBridge = (voiceBridge == null || voiceBridge == 0) ? 70000 + new Random(System.currentTimeMillis()).nextInt(10000) : voiceBridge; qs += "&" + PARAM_VOICE_BRIDGE + "=" + voiceBridge.toString(); qs += params.containsKey(PARAM_DIAL_NUMBER) ? "&" + PARAM_DIAL_NUMBER + "=" + params.get(PARAM_DIAL_NUMBER) : ""; qs += params.containsKey(PARAM_DURATION) ? "&" + PARAM_DURATION + "=" + params.get(PARAM_DURATION) : ""; qs += getCheckSumParameterForQuery(APICALL_CREATE, qs); return this.endpoint + API_SERVERPATH + APICALL_CREATE + "?" + qs; } public String getJoinURL(Map<String, String> params) { String qs = ""; qs += PARAM_FULL_NAME + "=" + params.get(PARAM_FULL_NAME); qs += "&" + PARAM_MEETING_ID + "=" + params.get(PARAM_MEETING_ID); qs += "&" + PARAM_PASSWORD + "=" + params.get(PARAM_PASSWORD); qs += params.containsKey(PARAM_CREATE_TIME) ? "&" + PARAM_CREATE_TIME + "=" + params.get(PARAM_CREATE_TIME) : ""; qs += params.containsKey(PARAM_USER_ID) ? "&" + PARAM_USER_ID + "=" + params.get(PARAM_USER_ID) : ""; qs += getCheckSumParameterForQuery(APICALL_JOIN, qs); return this.endpoint + API_SERVERPATH + APICALL_JOIN + "?" + qs; } public String getIsMeetingRunningURL(Map<String, String> params) { String qs = ""; qs += PARAM_MEETING_ID + "=" + params.get(PARAM_MEETING_ID); qs += getCheckSumParameterForQuery(APICALL_ISMEETINGRUNNING, qs); return this.endpoint + API_SERVERPATH + APICALL_ISMEETINGRUNNING + "?" + qs; } public String getEndURL(Map<String, String> params) { String qs = ""; qs += PARAM_MEETING_ID + "=" + params.get(PARAM_MEETING_ID); qs += "&" + PARAM_PASSWORD + "=" + params.get(PARAM_PASSWORD); qs += getCheckSumParameterForQuery(APICALL_END, qs); return this.endpoint + API_SERVERPATH + APICALL_END + "?" + qs; } public String getGetMeetingInfoURL(Map<String, String> params) { String qs = ""; qs += PARAM_MEETING_ID + "=" + params.get(PARAM_MEETING_ID); qs += "&" + PARAM_PASSWORD + "=" + params.get(PARAM_PASSWORD); qs += getCheckSumParameterForQuery(APICALL_GETMEETINGINFO, qs); return this.endpoint + API_SERVERPATH + APICALL_GETMEETINGINFO + "?" + qs; } public String getGetMeetingsURL() { String qs = ""; qs = "random=xyz"; qs = getCheckSumParameterForQuery(APICALL_GETMEETINGS, qs); return this.endpoint + API_SERVERPATH + APICALL_GETMEETINGS + "?" + qs; } public String getStringEncoded(String string) { String stringEncoded = ""; try { stringEncoded = URLEncoder.encode(string, PARAMETERENCODING); } catch (Exception e) { } return stringEncoded; } /** Creates the checksum parameter to be included as part of the endpoint */ protected String getCheckSumParameterForQuery(String apiCall, String queryString) { if (this.secret != null) return "&checksum=" + DigestUtils.shaHex(apiCall + queryString + this.secret); else return ""; } public String getGetRecordingsURL(Map<String, String> params) { return null; } public String getPublishRecordingsURL(Map<String, String> params) { return null; } public String getDeleteRecordingsURL(Map<String, String> params) { return null; } }