org.loklak.api.iot.NetmonPushServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.loklak.api.iot.NetmonPushServlet.java

Source

/**
 * FreifunkNodePushServlet
 * Copyright 16.07.2015 by Dang Hai An, @zyzo
 * <p/>
 * This library 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.1 of the License, or (at your option) any later version.
 * <p/>
 * This library 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.
 * <p/>
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program in the file lgpl21.txt
 * If not, see <http://www.gnu.org/licenses/>.
 */
package org.loklak.api.iot;

import org.eclipse.jetty.util.log.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import org.loklak.data.DAO;
import org.loklak.geo.LocationSource;
import org.loklak.harvester.JsonFieldConverter;
import org.loklak.http.ClientConnection;
import org.loklak.http.RemoteAccess;
import org.loklak.objects.SourceType;
import org.loklak.server.Query;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

public class NetmonPushServlet extends HttpServlet {

    private static final long serialVersionUID = 1423618084632135238L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        Query post = RemoteAccess.evaluate(request);
        String remoteHash = Integer.toHexString(Math.abs(post.getClientHost().hashCode()));

        // manage DoS
        if (post.isDoS_blackout()) {
            response.sendError(503, "your request frequency is too high");
            return;
        }

        String url = post.get("url", "");
        if (url == null || url.length() == 0) {
            response.sendError(400, "your request does not contain an url to your data object");
            return;
        }
        String screen_name = post.get("screen_name", "");
        if (screen_name == null || screen_name.length() == 0) {
            response.sendError(400, "your request does not contain required screen_name parameter");
            return;
        }

        JSONArray nodesList = new JSONArray();
        byte[] xmlText;
        try {
            xmlText = ClientConnection.download(url);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = builder.parse(new InputSource(new StringReader(new String(xmlText))));
            NodeList routerList = document.getElementsByTagName("router");
            for (int i = 0; i < routerList.getLength(); i++) {
                JSONObject node = convertDOMNodeToMap(routerList.item(i));
                if (node != null)
                    nodesList.put(node);
            }
        } catch (Exception e) {
            Log.getLog().warn(e);
            response.sendError(400, "error reading json file from url");
            return;
        }

        JsonFieldConverter converter = new JsonFieldConverter(
                JsonFieldConverter.JsonConversionSchemaEnum.NETMON_NODE);
        JSONArray nodes = converter.convert(nodesList);

        for (Object node_obj : nodes) {
            JSONObject node = (JSONObject) node_obj;
            if (!node.has("text")) {
                node.put("text", "");
            }
            node.put("source_type", SourceType.NETMON.toString());
            if (!node.has("user")) {
                node.put("user", new JSONObject());
            }

            List<Object> location_point = new ArrayList<>();
            location_point.add(0, Double.parseDouble((String) node.get("latitude")));
            location_point.add(1, Double.parseDouble((String) node.get("longitude")));
            node.put("location_point", location_point);
            node.put("location_mark", location_point);
            node.put("location_source", LocationSource.USER.name());
            try {
                node.put("id_str", PushServletHelper.computeMessageId(node, SourceType.NETMON));
            } catch (Exception e) {
                DAO.log("Problem computing id" + e.getMessage());
                continue;
            }
            try {
                JSONObject user = (JSONObject) node.get("user");
                user.put("screen_name", computeUserId(user.get("update_date"), user.get("id"), SourceType.NETMON));
            } catch (Exception e) {
                DAO.log("Problem computing user id : " + e.getMessage());
            }
        }

        PushReport pushReport = PushServletHelper.saveMessagesAndImportProfile(nodes, Arrays.hashCode(xmlText),
                post, SourceType.NETMON, screen_name);

        String res = PushServletHelper.buildJSONResponse(post.get("callback", ""), pushReport);
        response.getOutputStream().println(res);
        DAO.log(request.getServletPath() + " -> records = " + pushReport.getRecordCount() + ", new = "
                + pushReport.getNewCount() + ", known = " + pushReport.getKnownCount() + ", from host hash "
                + remoteHash);

    }

    private static JSONObject convertDOMNodeToMap(Node node) {
        Node directChild = node.getFirstChild();
        if (directChild == null) {
            return null;
        }
        JSONObject result = new JSONObject(true);
        while (directChild != null) {
            if (directChild.getChildNodes().getLength() == 1
                    && directChild.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE) {
                result.put(directChild.getNodeName(), directChild.getChildNodes().item(0).getTextContent());
            } else {
                result.put(directChild.getNodeName(), convertDOMNodeToMap(directChild));
            }
            directChild = directChild.getNextSibling();
        }
        return result;
    }

    private static String computeUserId(Object mtime, Object initialId, SourceType sourceType) throws Exception {
        if (mtime == null) {
            throw new Exception("mtime field is missing");
        }
        boolean hasId = initialId != null && !initialId.equals("");
        return sourceType.toString() + "_" + (hasId ? initialId + "_" : "") + mtime;
    }
}