com.amossys.hooker.reporting.NetworkEventSenderThread.java Source code

Java tutorial

Introduction

Here is the source code for com.amossys.hooker.reporting.NetworkEventSenderThread.java

Source

/*----------------------------------------------------------------------------+
 *|                                                                           |
 *|                          Android's Hooker                                 |
 *|                                                                           |
 *+---------------------------------------------------------------------------+
 *| Copyright (C) 2011 Georges Bossert and Dimitri Kirchner                   |
 *| This program is free software: you can redistribute it and/or modify      |
 *| it under the terms of the GNU General Public License as published by      |
 *| the Free Software Foundation, either version 3 of the License, or         |
 *| (at your option) any later version.                                       |
 *|                                                                           |
 *| This program 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 General Public License for more details.                              |
 *|                                                                           |
 *| You should have received a copy of the GNU General Public License         |
 *| along with this program. If not, see <http://www.gnu.org/licenses/>.      |
 *+---------------------------------------------------------------------------+
 *| @url      : http://www.amossys.fr                                         |
 *| @contact  : android-hooker@amossys.fr                                     |
 *| @sponsors : Amossys, http://www.amossys.fr                                |
 *+---------------------------------------------------------------------------+
 */

package com.amossys.hooker.reporting;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import java.util.Queue;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import com.amossys.hooker.SubstrateMain;
import com.amossys.hooker.common.InterceptEvent;

/**
 * @author Georges Bossert
 * 
 */
public class NetworkEventSenderThread implements Runnable {

    private static final int VERY_LONG_SLEEP_TIME = 2000;

    /**
     * Long sleep time (when connection fails with remote server)
     */
    private static final int LONG_SLEEP_TIME = 1000;

    /**
     * Short sleep time (when no event is available)
     */
    private static final int SHORT_SLEEP_TIME = 300;

    // Events to send
    private Queue<InterceptEvent> events;

    // The HttpClient
    private HttpClient httpClient;
    // Target URI
    private URI targetURI;

    // Flag to raise if you want this thread to stop
    private boolean finish;

    private int nbErrors = 0;

    private String esIndex;
    private String esDoctype;

    private String host;
    private int port;

    public NetworkEventSenderThread(String host, int port, String esIndex, String esDoctype,
            Queue<InterceptEvent> events) {
        this.events = events;
        this.host = host;
        this.port = port;
        this.esIndex = esIndex;
        this.esDoctype = esDoctype;

        this.httpClient = new DefaultHttpClient();
        this.finish = false;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {

        if (this.events == null) {
            SubstrateMain.log("EventSenderThread (" + Thread.currentThread().getPriority()
                    + ") fails to start since no Queue is available. ");
            return;
        }

        SubstrateMain.log("EventSenderThread (" + Thread.currentThread().getPriority() + ") has started.");

        int sleepTime;

        while (!this.isFinish()) {

            sleepTime = 0;

            // !!!
            // This may cause a problem when we launch from Snapshot. We have to be careful that snapshot 
            // doesn't have any IDXP
            // Retrieves the current id XP
            //this.idXP = fetchIDXPFromSdcard();

            InterceptEvent eventToSend = this.events.poll();
            if (eventToSend != null) {
                if (!this.send(eventToSend)) {
                    this.events.add(eventToSend);
                    sleepTime = LONG_SLEEP_TIME;
                    nbErrors++;
                }
            } else {
                sleepTime = SHORT_SLEEP_TIME;
            }

            if ((nbErrors > 10) && (nbErrors % 5 == 0)) {
                SubstrateMain.log("[E] Too many network errors, we stop the thread...");
                sleepTime = VERY_LONG_SLEEP_TIME;
            }

            if (sleepTime > 0) {
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    SubstrateMain.log("[E] Error while sleeping the EventSenderThread", e);
                }
            }
        }
    }

    public void stopThread() {
        this.finish = true;
    }

    public boolean send(InterceptEvent event) {

        try {
            this.targetURI = new URI("http://" + host + ":" + port + "/" + this.esIndex.toLowerCase() + "/"
                    + this.esDoctype.toLowerCase() + "?parent=" + event.getIDXP() + "&op_type=create");
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        SubstrateMain.log("Sending Event to " + this.targetURI);

        boolean result = false;
        StringEntity se;
        try {
            se = new StringEntity(event.toJson());

            HttpPost httpPost = new HttpPost(this.targetURI);
            httpPost.setEntity(se);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            // Executes POST request to the given URL
            HttpResponse httpResponse = this.httpClient.execute(httpPost);

            // Receives response as inputStream
            InputStream inputStream = httpResponse.getEntity().getContent();

            // Converts inputStream to string
            // TODO: we should parse the elasticsearch result
            result = inputStream != null;

            SubstrateMain.log("Event succesfully sent !");

            if (inputStream != null) {
                inputStream.close();
            }

        } catch (UnsupportedEncodingException e) {
            SubstrateMain.log(
                    "Impossible to send data to remote database due to encoding issues (" + e.getMessage() + ")",
                    e);
        } catch (IOException e) {
            SubstrateMain.log(
                    "Impossible to connect to the remote database, check the connectivity (" + e.getMessage() + ")",
                    e);
        }
        return result;
    }

    /**
     * @return the finish
     */
    public boolean isFinish() {
        return finish;
    }

}