Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
1 result

DataSID.java

Blame
  • DataSID.java 17.55 KiB
    /*
     * Copyright (C) 2004-2011 Centro de Computacao Cientifica e Software Livre
     * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
     *
     * This file is part of datasid
     *
     * 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 2
     * 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, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
     * USA.
     */
    package br.ufpr.c3sl.datasid;
    
    import java.io.*;
    import java.util.*;
    import java.util.regex.*;
    import java.text.SimpleDateFormat;
    import java.text.ParseException;
    import java.math.BigInteger;
    
    import java.sql.Timestamp;
    import java.sql.SQLException;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.Types;
    
    import javax.naming.InitialContext;
    import javax.sql.DataSource;
    import javax.xml.bind.*;
    import javax.xml.bind.util.ValidationEventCollector;
    import javax.xml.bind.helpers.DefaultValidationEventHandler;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
    import javax.xml.transform.stream.StreamSource;
    
    public class DataSID {
        // enum does not work as expected inside an axis web service
        // using simple constants instead
        private static final int LINUX = 0;
        private static final int WINDOWS = 1;
    
        private static final int ERROR = 0;
        private static final int WARNING = 1;
        private static final int INFO = 2;
        private static final int DEBUG = 3;
    
        private Properties prop;
    
        private File xml_inventory_schema;
        private File xml_net_usage_schema;
    
        private String linux_agent_version;
        private String linux_agent_update_link;
    
        private String windows_agent_version;
        private String windows_agent_update_link;
    
        public DataSID() throws IOException {
            try {
                this.prop = new Properties();
                this.prop.load(new FileInputStream("../conf/webservice.properties"));
            }
            catch (IOException e) {
                System.err.println("Failed to load webservice.properties.");
                throw e;
            }
    
            this.xml_inventory_schema = new File(this.prop.getProperty("xml_inventory_schema",
                "../conf/collected-data.xsd"));
            this.xml_net_usage_schema = new File(this.prop.getProperty("xml_net_usage_schema",
                "../conf/net-collected-data.xsd"));
    
            this.linux_agent_version = this.prop.getProperty("linux_agent_version", "1.0.0");
            this.linux_agent_update_link = this.prop.getProperty("linux_agent_update_link",
                        "http://bisimmcdev.c3sl.ufpr.br/download/datasid-1.0.0-update.run");
    
            this.windows_agent_version = this.prop.getProperty("windows_agent_version", "1.0.0");
            this.windows_agent_update_link = this.prop.getProperty("windows_agent_update_link",
                        "http://bisimmcdev.c3sl.ufpr.br/download/datasid-1.0.0-update.exe");
        }
    
    
        /**
         * Returns the name of the log level
         *
         * @author                  Eduardo Luis Buratti
         * @param       level       Log level
         */
        private static String logLevelName(int level) {
            if (level == ERROR) return "ERROR";
            else if (level == WARNING) return "WARNING";
            else if (level == INFO) return "INFO";
            else if (level == DEBUG) return "DEBUG";
            else return "NULL";
        }
    
        /**
         * Write messages to the log
         *
         * @author                  Eduardo Luis Buratti
         * @param       level       Log level
         * @param       msg         Message
         */
        private static void log(int level, String msg) {
            System.out.println(getTimestamp() + " [DataSidWS][" + logLevelName(level) + "]: " + msg);
        }
    
        /**
         * Returns a string representing the current date
         *
         * @author                  Eduardo Luis Buratti
         * @return                  String
         */
        private static String getDate() {
            Calendar date = Calendar.getInstance(); // gets current date
    
            int year = date.get(Calendar.YEAR);
            int month = date.get(Calendar.MONTH);
            int day = date.get(Calendar.DATE);
    
            /* NOTE: Calendar.MONTH field value is 0-based. e.g: 0 is January */
            month++;
    
            return year + "-" + month + "-" + day;
        }
    
        /**
         * Returns current timestamp
         *
         * @author                  Eduardo Luis Buratti
         * @return                  String
         */
        private static String getTimestamp() {
            // gets the current time
            java.util.Date date = new java.util.Date();
            long milisecs = date.getTime();
    
            // generates timestamp string
            Timestamp timestamp = new Timestamp(milisecs);
            return timestamp.toString();
        }
    
        /**
         * Return a string with current agent version.
         *
         * @author                  Eduardo Luis Buratti
         * @param       OS          Integer of OS Type
         * @return                  String
         */
        public String getAgentVersion(int OS) {
            switch(OS){
                case LINUX:
                    return this.linux_agent_version;
                case WINDOWS:
                    return this.windows_agent_version;
                default:
                    return "ERROR: invalid OS";
            }
    
        }
    
        /**
         * Return a string that contains a link to download the newest version of
         * agent.
         *
         * @author                  Eduardo Luis Buratti
         * @param       OS          Integer of OS Type
         * @return                  String
         */
        public String getUpdateLink(int OS)
        {
            switch(OS){
                case LINUX:
                    return this.linux_agent_update_link;
                case WINDOWS:
                    return this.windows_agent_update_link;
                default:
                    return "ERROR: invalid OS";
            }
        }
    
        /**
         * Receive an XML string which has the inventory data to be parsed and
         * inserted into database. Return "Success" string if insertion operation
         * is successful. Any other errors will throw exceptions.
         *
         * @author                 Eduardo Luis Buratti
         * @param     xmlData      XML string of inventory
         * @return                 String
         */
        public String setInventory(String xmlData) {
            try {
                InitialContext cxt = new InitialContext();
                DataSource ds = (DataSource) cxt.lookup("java:/comp/env/jdbc/simmc");
                if (ds == null)
                    throw new Exception("Data source not found!");
    
                Connection con = ds.getConnection();
                if (con == null)
                    throw new Exception("Failed to get a database connection!");
    
                SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
                Schema schema = factory.newSchema(this.xml_inventory_schema);
    
                JAXBContext context = JAXBContext.newInstance(CollectedData.class);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                unmarshaller.setSchema(schema);
    
                // Strip spaces in the beginning of the xml
                xmlData = xmlData.replaceAll("^\\s+", "");
    
                // transform the xml string into a InputStream
                InputStream is = new ByteArrayInputStream(xmlData.getBytes());
    
                // Decode the XML into a Java Object
                JAXBElement<CollectedData> element = (JAXBElement<CollectedData>) unmarshaller.unmarshal(new StreamSource(is), CollectedData.class);
                CollectedData collected = element.getValue();
                // contact_date = current date
                Calendar cal = Calendar.getInstance();
                java.sql.Date contactDate = new java.sql.Date(cal.getTimeInMillis());
    
                PreparedStatement st = createInventoryStatement(con, collected, contactDate);
                st.executeUpdate();
    
                List<User> users = collected.getUserHistory().getUser();
                int idpoint = collected.getPointInfo().getIdpoint().intValue();
                List<Interface> interfaces = collected.getInterfaces().getInterface();
                org.postgresql.util.PGobject macaddr = new org.postgresql.util.PGobject();
                macaddr.setType("macaddr");
                macaddr.setValue(interfaces.get(0).getMacAddress());
    
                for(User user: users) {
                    st = createUserHistoryStatement(con, contactDate, idpoint,
                        macaddr, user.getName(), user.getLogin(), user.getLogout());
                    st.executeUpdate();
                }
                con.close();
    
                log(INFO, "setInventory(idpoint=" + collected.getPointInfo().getIdpoint() +
                            ", macaddr=" + interfaces.get(0).getMacAddress() + ")");
    
                return "Success";
            } catch (Exception e) {
                log(ERROR, e.getMessage() + " " + xmlData);
                e.printStackTrace();
                return "ERROR: " + e.getMessage();
            }
        }
    
        private PreparedStatement createInventoryStatement(Connection con, CollectedData collectedData, java.sql.Date contactDate) throws SQLException, ParseException {
            final String query = "INSERT INTO telecenter_inventory " +
                "(contact_date, machine_type, id_point, macaddr, agent_version, " +
                " os_type, os_distro, os_kernel, " +
                " processor, memory, " +
                " disk1_model, disk1_size, disk1_used, " +
                " disk2_model, disk2_size, disk2_used, " +
                " extra_hds, mirror_timestamp, amount_users " +
                ") VALUES " +
                "(?, ?, ?, ?, ?, " +
                " ?, ?, ?, " +
                " ?, ?, " +
                " ?, ?, ?, " +
                " ?, ?, ?, " +
                " ?, ?, ? " +
                " );";
    
            PreparedStatement st = con.prepareStatement(query);
    
            List<Interface> interfaces = collectedData.getInterfaces().getInterface();
    
            Inventory inventory = collectedData.getInventory();
            List<Disk> disks = inventory.getDisks().getDisk();
            PointInfo pointInfo = collectedData.getPointInfo();
    
            // contact_date
            st.setDate(1, contactDate);
    
            // machine_type
            if(collectedData.getMachineType().compareTo("client") == 0)
                st.setInt(2, 0);
            else
                st.setInt(2, 1);
    
            // idpoint
            st.setInt(3, pointInfo.getIdpoint().intValue());
    
            // macaddr
            org.postgresql.util.PGobject macaddr = new org.postgresql.util.PGobject();
            macaddr.setType("macaddr");
            macaddr.setValue(interfaces.get(0).getMacAddress());
            st.setObject(4, macaddr);
    
            // versao
            st.setString(5, collectedData.getAgentVersion());
    
            // os_type
            st.setString(6, inventory.getOs());
    
            // os_distro
            st.setString(7, inventory.getDistro());
    
            // os_kernel
            st.setString(8, inventory.getKernel());
    
            // processor
            st.setString(9, inventory.getProcessor());
    
            // memory
            st.setInt(10, inventory.getMemory().intValue());
    
            // disk1_model
            st.setString(11, disks.get(0).getModel());
    
            // disk1_size
            st.setInt(12, disks.get(0).getSize().intValue());
    
            // disk1_used
            st.setInt(13, disks.get(0).getUsed().intValue());
    
            if (disks.size() > 1) {
                // disk2_model
                st.setString(14, disks.get(1).getModel());
    
                // disk2_size
                st.setInt(15, disks.get(1).getSize().intValue());
    
                // disk2_used
                st.setInt(16, disks.get(1).getUsed().intValue());
            }
            else {
                // disk2_model
                st.setNull(14, Types.VARCHAR);
    
                // disk2_size
                st.setNull(15, Types.INTEGER);
    
                // disk2_used
                st.setNull(16, Types.INTEGER);
            }
    
            // extra_hds
            st.setInt(17, (disks.size() > 2) ? (disks.size() - 2) : 0);
    
    
            // mirrors_timestamp
            if(collectedData.getMirrorsTimestamp().compareTo(" ") == 0)
                st.setTimestamp(18, null);
            else {
                SimpleDateFormat dt = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.US);
                Date ts = dt.parse(collectedData.getMirrorsTimestamp());
                st.setTimestamp(18, new java.sql.Timestamp(ts.getTime()));
            }
    
            // user_count
            st.setInt(19, pointInfo.getUserCount().intValue());
    
            return st;
        }
    
        private PreparedStatement createUserHistoryStatement(Connection con, java.sql.Date contactDate,
                int id_point, Object macaddr, String name, String login, String logout) throws SQLException {
            final String query = "INSERT INTO telecenter_user " +
                "(contact_date, id_point, macaddr, name, login, logout) VALUES " +
                "(?, ?, ?, ?, ?, ?);";
    
            PreparedStatement st = con.prepareStatement(query);
    
            st.setDate(1, contactDate);
    
            st.setInt(2, id_point);
    
            st.setObject(3, macaddr);
    
            st.setString(4, name);
    
            try {
                st.setTime(5, java.sql.Time.valueOf(login));
            } catch (Exception e) {
                st.setTime(5, null);
            }
    
            try {
                st.setTime(6, java.sql.Time.valueOf(logout));
            } catch (Exception e) {
                st.setTime(6, null);
            }
    
            return st;
        }
    
        /**
         * Receive an XML string which has the inventory data to be parsed and
         * inserted into database. Return "Success" string if insertion operation
         * is successful. Any other errors will throw exceptions.
         *
         * @author                 Eduardo Luis Buratti
         * @param     xmlData      XML string of inventory
         * @return                 String
         */
        public String setNetUsage(String xmlData)
        {
            try {
                InitialContext cxt = new InitialContext();
                DataSource ds = (DataSource) cxt.lookup("java:/comp/env/jdbc/simmc");
                if (ds == null)
                    throw new Exception("Data source not found!");
    
                Connection con = ds.getConnection();
                if (con == null)
                    throw new Exception("Failed to get a database connection!");
    
                SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
                Schema schema = factory.newSchema(this.xml_net_usage_schema);
    
                JAXBContext context = JAXBContext.newInstance(NetCollectedData.class);
                Unmarshaller unmarshaller = context.createUnmarshaller();
                unmarshaller.setSchema(schema);
    
                // Strip spaces in the beginning of the xml
                xmlData = xmlData.replaceAll("^\\s+", "");
    
                // transform the xml string into a InputStream
                InputStream is = new ByteArrayInputStream(xmlData.getBytes());
    
                // Decode the XML into a Java Object
                JAXBElement<NetCollectedData> element = (JAXBElement<NetCollectedData>) unmarshaller.unmarshal(new StreamSource(is), NetCollectedData.class);
                NetCollectedData netCollectedData = element.getValue();
    
                List<Interface> interfaces = netCollectedData.getInterfaces().getInterface();
    
                // contact_date = current date
                Calendar cal = Calendar.getInstance();
                java.sql.Date contactDate = new java.sql.Date(cal.getTimeInMillis());
                // macaddr
                org.postgresql.util.PGobject macaddr = new org.postgresql.util.PGobject();
                macaddr.setType("macaddr");
                macaddr.setValue(interfaces.get(0).getMacAddress());
    
                List<NetUse> netUses = netCollectedData.getBandwidthUsage().getNetuse();
    
                for(NetUse netUse : netUses) {
                    PreparedStatement st = createNetUsageStatement(con, contactDate,
                     netCollectedData.getIdPoint(), (Object)macaddr,
                     netUse.getDate(), netUse.getTime(), netUse.getRx().getRxBytes(),
                     netUse.getRx().getRxPackets(), netUse.getTx().getTxBytes(),
                     netUse.getTx().getTxPackets());
                    st.executeUpdate();
                }
                con.close();
    
                log(DEBUG, "setNetUsage(idpoint=" + netCollectedData.getIdPoint() +
                            ", macaddr=" + interfaces.get(0).getMacAddress() + ")");
                return "Success";
            } catch (Exception e) {
                log(ERROR, e.getMessage() + " " + xmlData);
                e.printStackTrace();
                return "ERROR: " + e.getMessage();
            }
        }
    
        private PreparedStatement createNetUsageStatement(Connection con, java.sql.Date contactDate,
                BigInteger idpoint, Object macaddr, String collect_date, String collect_time, long down_bytes,
                BigInteger down_packages, long up_bytes, BigInteger up_packages) throws SQLException {
            final String query = "INSERT INTO net_usage " +
                "(contact_date, id_point, macaddr, collect_date, collect_time, " +
                "down_bytes, down_packages, up_bytes, up_packages, ip, city_code) VALUES " +
                "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
    
            PreparedStatement st = con.prepareStatement(query);
    
            st.setDate(1, contactDate);
    
            st.setInt(2, idpoint.intValue());
    
            st.setObject(3, macaddr);
    
            st.setDate(4, java.sql.Date.valueOf(collect_date));
    
            st.setTime(5, java.sql.Time.valueOf(collect_time));
    
            st.setLong(6, down_bytes);
    
            st.setInt(7, down_packages.intValue());
    
            st.setLong(8, up_bytes);
    
            st.setInt(9, up_packages.intValue());
    
            st.setObject(10, null);
    
            st.setString(11, null);
    
            return st;
        }
    }