org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient.java

Source

/*
 * Copyright (c) 2015, 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.device.mgt.iot.controlqueue.xmpp;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
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.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class XmppServerClient {

    private static final Log log = LogFactory.getLog(XmppServerClient.class);
    private static final String XMPP_SERVER_API_CONTEXT = "/plugins/restapi/v1";
    private static final String XMPP_USERS_API = "/users";
    private static final String XMPP_SESSIONS_API = "/sessions";
    @SuppressWarnings("unused")
    private static final String XMPP_GROUPS_API = "/groups";
    @SuppressWarnings("unused")
    private static final String APPLICATION_JSON_MT = "application/json";
    private static final String DEVICEMGT_CONFIG_FILE = "devicemgt-config.xml";
    private static final String APPLICATION_JSON = "application/json";
    private String xmppEndpoint;
    private String xmppUsername;
    private String xmppPassword;
    private boolean xmppEnabled = false;

    public XmppServerClient() {
    }

    public void initControlQueue() {
        xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
        xmppUsername = XmppConfig.getInstance().getXmppUsername();
        xmppPassword = XmppConfig.getInstance().getXmppPassword();
        xmppEnabled = XmppConfig.getInstance().isEnabled();
    }

    public boolean createXMPPAccount(XmppAccount newUserAccount) throws DeviceControllerException {
        if (xmppEnabled) {
            String xmppUsersAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API;
            if (log.isDebugEnabled()) {
                log.debug("The Create-UserAccount Endpoint URL of the XMPP Server is set to: "
                        + xmppUsersAPIEndpoint);
            }

            String encodedString = xmppUsername + ":" + xmppPassword;
            encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
            String authorizationHeader = "Basic " + encodedString;
            String jsonRequest = "{\n" + "    \"username\": \"" + newUserAccount.getUsername() + "\","
                    + "    \"password\": \"" + newUserAccount.getPassword() + "\"," + "    \"name\": \""
                    + newUserAccount.getAccountName() + "\"," + "    \"email\": \"" + newUserAccount.getEmail()
                    + "\"," + "    \"properties\": {" + "        \"property\": [" + "            {"
                    + "                \"@key\": \"console.rows_per_page\","
                    + "                \"@value\": \"user-summary=8\"" + "            }," + "            {"
                    + "                \"@key\": \"console.order\","
                    + "                \"@value\": \"session-summary=1\"" + "            }" + "        ]" + "    }"
                    + "}";

            StringEntity requestEntity;
            try {
                requestEntity = new StringEntity(jsonRequest, APPLICATION_JSON, StandardCharsets.UTF_8.toString());
            } catch (UnsupportedEncodingException e) {
                return false;
            }

            URL xmppUserApiUrl;
            try {
                xmppUserApiUrl = new URL(xmppUsersAPIEndpoint);
            } catch (MalformedURLException e) {
                String errMsg = "Malformed XMPP URL + " + xmppUsersAPIEndpoint;
                log.error(errMsg);
                throw new DeviceControllerException(errMsg);
            }
            HttpClient httpClient;
            try {
                httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
            } catch (Exception e) {
                log.error("Error on getting a http client for port :" + xmppUserApiUrl.getPort() + " protocol :"
                        + xmppUserApiUrl.getProtocol());
                return false;
            }

            HttpPost httpPost = new HttpPost(xmppUsersAPIEndpoint);
            httpPost.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
            httpPost.setEntity(requestEntity);

            try {
                HttpResponse httpResponse = httpClient.execute(httpPost);

                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
                    String response = IoTUtil.getResponseString(httpResponse);
                    String errorMsg = "XMPP Server returned status: '"
                            + httpResponse.getStatusLine().getStatusCode() + "' for account creation with error:\n"
                            + response;
                    log.error(errorMsg);
                    throw new DeviceControllerException(errorMsg);
                } else {
                    EntityUtils.consume(httpResponse.getEntity());
                    return true;
                }
            } catch (IOException e) {
                String errorMsg = "Error occured whilst trying a 'POST' at : " + xmppUsersAPIEndpoint;
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

        } else {
            log.warn(String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE));
            return false;
        }
    }

    public boolean doesXMPPUserAccountExist(String username) throws DeviceControllerException {
        if (xmppEnabled) {
            String xmppCheckUserAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API + "/"
                    + username;
            if (log.isDebugEnabled()) {
                log.debug("The Check-User-Account Endpoint URL of the XMPP Server is set to: "
                        + xmppCheckUserAPIEndpoint);
            }

            String encodedString = xmppUsername + ":" + xmppPassword;
            encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
            String authorizationHeader = "Basic " + encodedString;

            URL xmppUserApiUrl;
            try {
                xmppUserApiUrl = new URL(xmppCheckUserAPIEndpoint);
            } catch (MalformedURLException e) {
                String errMsg = "Malformed XMPP URL + " + xmppCheckUserAPIEndpoint;
                log.error(errMsg);
                throw new DeviceControllerException(errMsg, e);
            }

            HttpClient httpClient;
            try {
                httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
            } catch (Exception e) {
                String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort()
                        + " protocol :" + xmppUserApiUrl.getProtocol();
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

            HttpGet httpGet = new HttpGet(xmppCheckUserAPIEndpoint);
            httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);

            try {
                HttpResponse httpResponse = httpClient.execute(httpGet);

                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String response = IoTUtil.getResponseString(httpResponse);
                    if (log.isDebugEnabled()) {
                        log.debug("XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode()
                                + "' for checking existence of account [" + username + "] with message:\n"
                                + response + "\nProbably, an account with this username does not exist.");
                    }
                    return false;
                }

            } catch (IOException e) {
                String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppCheckUserAPIEndpoint;
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

            if (log.isDebugEnabled()) {
                log.debug("XMPP Server already has an account for the username - [" + username + "].");
            }
            return true;
        } else {
            String warnMsg = String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE);
            log.warn(warnMsg);
            throw new DeviceControllerException(warnMsg);
        }
    }

    public JSONArray getAllCurrentUserSessions() throws DeviceControllerException {
        if (xmppEnabled) {
            JSONArray xmppSessions;
            String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API;

            if (log.isDebugEnabled()) {
                log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint);
            }

            String encodedString = xmppUsername + ":" + xmppPassword;
            encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
            String authorizationHeader = "Basic " + encodedString;

            URL xmppUserApiUrl;
            try {
                xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint);
            } catch (MalformedURLException e) {
                String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint;
                log.error(errMsg);
                throw new DeviceControllerException(errMsg, e);
            }

            HttpClient httpClient;
            try {
                httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
            } catch (Exception e) {
                String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort()
                        + " protocol :" + xmppUserApiUrl.getProtocol();
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

            HttpGet httpGet = new HttpGet(xmppSessionsAPIEndpoint);
            httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
            httpGet.addHeader(HttpHeaders.ACCEPT, APPLICATION_JSON);

            try {
                HttpResponse httpResponse = httpClient.execute(httpGet);

                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String errorMsg = "XMPP Server returned status: '"
                            + httpResponse.getStatusLine().getStatusCode()
                            + "' for checking current XMPP Sessions.";
                    log.error(errorMsg);
                    throw new DeviceControllerException(errorMsg);
                }

                String response = IoTUtil.getResponseString(httpResponse);
                xmppSessions = new JSONObject(response).getJSONArray("session");
                return xmppSessions;

            } catch (IOException e) {
                String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppSessionsAPIEndpoint;
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

        } else {
            String warnMsg = String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE);
            log.warn(warnMsg);
            throw new DeviceControllerException(warnMsg);
        }
    }

    public void deleteCurrentXmppSessions() throws DeviceControllerException {
        JSONArray xmppSessionsArray;
        try {
            xmppSessionsArray = getAllCurrentUserSessions();
        } catch (DeviceControllerException e) {
            if (e.getMessage().contains(DEVICEMGT_CONFIG_FILE)) {
                log.warn(String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE));
                return;
            } else {
                throw e;
            }
        }

        if (xmppSessionsArray.length() != 0) {
            String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API;
            String encodedString = xmppUsername + ":" + xmppPassword;
            encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
            String authorizationHeader = "Basic " + encodedString;

            if (log.isDebugEnabled()) {
                log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint);
            }

            URL xmppUserApiUrl;
            try {
                xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint);
            } catch (MalformedURLException e) {
                String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint;
                log.error(errMsg);
                throw new DeviceControllerException(errMsg, e);
            }

            HttpClient httpClient;
            try {
                httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
            } catch (Exception e) {
                String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort()
                        + " protocol :" + xmppUserApiUrl.getProtocol();
                log.error(errorMsg);
                throw new DeviceControllerException(errorMsg, e);
            }

            for (int i = 0; i < xmppSessionsArray.length(); i++) {

                String sessionName = xmppSessionsArray.getJSONObject(i).getString("username");
                String xmppUserSessionsAPIEndpoint = xmppSessionsAPIEndpoint + "/" + sessionName;

                HttpDelete httpDelete = new HttpDelete(xmppUserSessionsAPIEndpoint);
                httpDelete.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);

                try {
                    HttpResponse httpResponse = httpClient.execute(httpDelete);

                    if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                        String errorMsg = "XMPP Server returned status: '"
                                + httpResponse.getStatusLine().getStatusCode()
                                + "' for checking current XMPP Sessions.";
                        log.error(errorMsg);
                        throw new DeviceControllerException(errorMsg);
                    }

                } catch (IOException e) {
                    String errorMsg = "Error occured whilst trying a 'DELETE' user-session [" + sessionName + "] "
                            + "at : " + xmppUserSessionsAPIEndpoint;
                    log.error(errorMsg);
                    throw new DeviceControllerException(errorMsg, e);
                }
            }
        }
    }
}