Select Git revision
DataSID.java
-
Eduardo L. Buratti authored
Signed-off-by:
Eduardo L. Buratti <elb09@c3sl.ufpr.br>
Eduardo L. Buratti authoredSigned-off-by:
Eduardo L. Buratti <elb09@c3sl.ufpr.br>
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;
}
}