Commit 2c768900 authored by Holger Bergunde's avatar Holger Bergunde Committed by holger.bergunde

OF-490 added various features. set to version 1.1.0 alpha

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@12947 b35dd754-fafc-0310-a699-88a17e54d16e
parent 635a188b
......@@ -2,7 +2,7 @@
<html>
<head>
<title>Remote Roster Plugin Changelog</title>
<title>GoJara Plugin Changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
......@@ -41,9 +41,19 @@
<body>
<h1>
Remote Roster Plugin Changelog
GoJara Plugin Changelog
</h1>
<p><b>1.1 Alpha</b> -- Jan 6, 2012</p>
<ul>
<li>Added feature to limit gateways to specific user group</li>
<li>Capture packets to create statistics</li>
<li>Added live logging</li>
<li>Renamed to GoJara</li>
</ul>
<p><b>1.0 Alpha</b> -- Dec 12, 2011</p>
<ul>
......
......@@ -4,11 +4,13 @@
<class>org.jivesoftware.openfire.plugin.RemoteRosterPlugin</class>
<name>Remote Roster</name>
<name>GoJara</name>
<description>ProtoXEP-xxxx: Remote Roster Management support</description>
<author>Holger Bergunde and Daniel Henninger</author>
<version>1.0.0 Alpha</version>
<date>12/06/2011</date>
<version>1.1.0 Alpha</version>
<date>01/06/2012</date>
<databaseKey>gojara</databaseKey>
<databaseVersion>0</databaseVersion>
<minServerVersion>3.7.0</minServerVersion>
<!-- Admin console entries -->
......
......@@ -2,7 +2,7 @@
<html>
<head>
<title>Remote Roster Plugin Readme</title>
<title>GoJara Plugin Readme</title>
<style type="text/css">
BODY {
font-size : 100%;
......@@ -52,7 +52,7 @@
<h1>
Remote Roster Plugin Readme
GoJara Plugin Readme
</h1>
<h2>Overview</h2>
......@@ -78,7 +78,7 @@ remoteRoster.jar file over the existing file.</p>
<h2>Configuration</h2>
<p>The Remote Roster plugin can be configured under "Server"-"Server Settings"-"Remote Roster".</p>
<p>The GoJara plugin can be configured under "Server"-"Server Settings"-"GoJara".</p>
</body>
</html>
\ No newline at end of file
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID Integer Identity NOT NULL,
messageDate bigint(20) NOT NULL,
messageType VARCHAR(255) NOT NULL,
fromJID VARCHAR(255) NOT NULL,
toJID VARCHAR(255) NOT NULL,
component VARCHAR(255) NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
CREATE TABLE ofGojaraStatistics (
logID bigint(20) NOT NULL AUTO_INCREMENT,
messageDate bigint(20) NOT NULL,
messageType tinytext NOT NULL,
fromJID text NOT NULL,
toJID text NOT NULL,
component text NOT NULL,
PRIMARY KEY (logID)
);
INSERT INTO ofVersion (name, version) VALUES ('gojara', 0);
rr.summary.title=Remote Roster
\ No newline at end of file
rr.summary.title=GoJara
\ No newline at end of file
......@@ -46,6 +46,8 @@ public class RemoteRosterPlugin implements Plugin {
pluginManager = manager;
manageExternalComponents();
listenToSettings();
}
private void manageExternalComponents()
......
package org.jivesoftware.openfire.plugin.database;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.log4j.Logger;
import org.jivesoftware.database.DbConnectionManager;
public class DatabaseManager {
private static Logger Log = Logger.getLogger(DatabaseManager.class);
private static volatile DatabaseManager _myself;
private static final String COUNT_LOG_ENTRIES = "SELECT count(*) FROM ofGojaraStatistics";
private static final String COUNT_PACKAGES_ODLER = "SELECT count(*) FROM `ofGojaraStatistics` WHERE messageType like ? AND component = ? AND messageDate > ?";
private static final String GET_ALL_LOGS = "SELECT * FROM ofGojaraStatistics ORDER BY logID desc";
// private static final String MOST_ACTIVE = "SELECT toJID, count(logID) AS counter FROM `ofGojaraStatistics` GROUP by toJID ORDER BY counter DESC";
private static final String ADD_NEW_LOG = "INSERT INTO ofGojaraStatistics(messageDate, messageType, fromJID, toJId, component) VALUES(?,?,?,?,?)";
private static final String CLEAN_OLD_DATA = "DELETE FROM `ofGojaraStatistics` WHERE messageDate < ?";
private static final String GET_LOGS_DATE_LIMIT_COMPONENT = "SELECT * FROM `ofGojaraStatistics` WHERE messageDate > ? AND component LIKE ? ORDER BY messageDate DESC LIMIT ?";
private DatabaseManager() {
TimerTask task = new TimerTask() {
@Override
public void run() {
cleanOldLogEntries();
}
};
Timer timer = new Timer();
timer.schedule(task, 2 * 60 * 1000, 2 * 60 * 1000);
}
/**
* Singleton for Databasemanager, because we only need one.
*
* @return the Databasemanager
*/
public static DatabaseManager getInstance() {
if (_myself == null) {
synchronized (DatabaseManager.class) {
if (_myself == null)
_myself = new DatabaseManager();
}
}
return _myself;
}
/**
* Returns a list of LogEntry's ordered by date desc
*
* @param olderThan
* unix timestamp in ms
* @param limit
* num of rows max
* @param component
* the specified subdomain of the logged component
* @return Collection of LogEntry
*/
public Collection<LogEntry> getLogsByDateAndLimit(long olderThan, int limit, String component) {
List<LogEntry> result = new ArrayList<LogEntry>();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_LOGS_DATE_LIMIT_COMPONENT);
pstmt.setLong(1, olderThan);
pstmt.setString(2, component);
pstmt.setInt(3, limit);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String from = rs.getString(4);
String to = rs.getString(5);
String type = rs.getString(3);
long date = rs.getLong(2);
LogEntry res = new LogEntry(from, to, type, date);
result.add(res);
}
pstmt.close();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return result;
}
public void cleanOldLogEntries() {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(CLEAN_OLD_DATA);
pstmt.setLong(1, System.currentTimeMillis() - 60 * 60 * 1000);
int rows = pstmt.executeUpdate();
Log.debug("Cleaned statistic database. Affected rows: " + rows);
pstmt.close();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
public void addNewLogEntry(String component, String type, String from, String to) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(ADD_NEW_LOG);
pstmt.setLong(1, System.currentTimeMillis());
pstmt.setString(2, type);
pstmt.setString(3, from);
pstmt.setString(4, to);
pstmt.setString(5, component);
pstmt.executeUpdate();
pstmt.close();
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
public List<String> getAllLogs() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<String> _result = new ArrayList<String>();
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_ALL_LOGS);
rs = pstmt.executeQuery();
while (rs.next()) {
String from = rs.getString(4);
String to = rs.getString(5);
String type = rs.getString(3);
String component = rs.getString(6);
Timestamp date = rs.getTimestamp(2);
String res = "From: " + from + " To: " + to + " Type: " + type + " Timestamp: " + date.toString()
+ "Component: " + component;
_result.add(res);
}
}
catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return _result;
}
public int getLogSize() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(COUNT_LOG_ENTRIES);
rs = pstmt.executeQuery();
rs.next();
return rs.getInt(1);
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return 0;
}
public int getPacketCount(String component, Class packetClass) {
return getPacketCountOlderThan(component, packetClass, 60);
}
public int getPacketCountOlderThan(String component, Class packetClass, int minutes) {
String classname = packetClass.getName();
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(COUNT_PACKAGES_ODLER);
pstmt.setString(1, "%" + classname + "");
pstmt.setString(2, component);
pstmt.setLong(3, System.currentTimeMillis() - minutes * 60 * 1000);
rs = pstmt.executeQuery();
rs.next();
return rs.getInt(1);
} catch (SQLException sqle) {
Log.error(sqle);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return 0;
}
}
package org.jivesoftware.openfire.plugin.database;
/**
*
* This class represents a log entry for the gojara plugin
*
*
* @author holger.bergunde
*
*/
public class LogEntry {
private String _from;
private String _to;
private String _type;
private long _date;
public LogEntry(String from, String to, String type, long date) {
_from = from;
_to = to;
_type = type;
_date = date;
}
public String getFrom() {
return _from;
}
public String getTo() {
return _to;
}
public String getType() {
return _type;
}
/**
* Date of logentry
*
* @return date in unixtimestamp milliseconds
*/
public long getDate() {
return _date;
}
}
......@@ -3,11 +3,13 @@ package org.jivesoftware.openfire.plugin.interceptor;
import java.util.HashSet;
import java.util.Set;
import org.apache.log4j.Logger;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
public abstract class AbstractInterceptorHandler {
private static Logger Log = Logger.getLogger(AbstractInterceptorHandler.class);
private String _subdomain;
private boolean _isRunning = false;
private Set<PacketInterceptor> _interceptors = new HashSet<PacketInterceptor>();
......@@ -36,7 +38,7 @@ public abstract class AbstractInterceptorHandler {
public void start()
{
System.out.println("Start handling message interceptors for gateway " + _subdomain);
Log.debug("Start handling message interceptors for gateway " + _subdomain);
_isRunning = true;
for (PacketInterceptor interceptor : _interceptors) {
_iManager.addInterceptor(interceptor);
......@@ -45,7 +47,7 @@ public abstract class AbstractInterceptorHandler {
public void stop()
{
System.out.println("Stop handling message interceptors for gateway " + _subdomain);
Log.debug("Stop handling message interceptors for gateway " + _subdomain);
if (!_isRunning)
return;
_isRunning = false;
......
......@@ -13,13 +13,13 @@ import org.jivesoftware.openfire.session.Session;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
public class DiscoPackageInterceptor implements PacketInterceptor {
public class DiscoPackageInterceptorHandler implements PacketInterceptor {
private PermissionManager _permissions;
private String _subDomain;
private String _host;
public DiscoPackageInterceptor(String subdomain) {
public DiscoPackageInterceptorHandler(String subdomain) {
_permissions = new PermissionManager();
_subDomain = subdomain;
XMPPServer server = XMPPServer.getInstance();
......
......@@ -3,9 +3,11 @@ package org.jivesoftware.openfire.plugin.interceptor;
public class GatewayInterceptorHandler extends AbstractInterceptorHandler {
public GatewayInterceptorHandler(String subdomain) {
super(subdomain);
DiscoPackageInterceptor discoInterceptor = new DiscoPackageInterceptor(subdomain);
DiscoPackageInterceptorHandler discoInterceptor = new DiscoPackageInterceptorHandler(subdomain);
RemotePackageInterceptor remoteRosterInterceptor = new RemotePackageInterceptor(subdomain);
StatisticPackageInterceptor statisticInterceptor = new StatisticPackageInterceptor(subdomain);
addInterceptor(remoteRosterInterceptor);
addInterceptor(discoInterceptor);
addInterceptor(statisticInterceptor);
}
}
package org.jivesoftware.openfire.plugin.interceptor;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.database.DatabaseManager;
import org.jivesoftware.openfire.session.Session;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
public class StatisticPackageInterceptor implements PacketInterceptor {
private String _subdomain;
private DatabaseManager _db;
public StatisticPackageInterceptor(String subdomain) {
_subdomain = subdomain;
_db = DatabaseManager.getInstance();
}
@Override
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
throws PacketRejectedException {
JID from = packet.getFrom();
JID to = packet.getTo();
if (from != null && to != null && processed && incoming) {
if (from.toString().contains(_subdomain) || to.toString().contains(_subdomain)) {
/*
* Spectrum sends a Ping to itself through the server to check
* if the server is alive. We ignore that for statistics
*/
if (to.toString().equals(from.toString()) && to.toString().equals(_subdomain))
return;
String type = packet.getClass().getName();
_db.addNewLogEntry(_subdomain, type, from.toString(), to.toString());
}
}
}
}
package org.jivesoftware.openfire.plugin.servlet;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Element;
import org.dom4j.tree.DefaultElement;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
public class SearchGroupServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String param = req.getParameter("search");
Element root = new DefaultElement("result");
if (param != null && param.length() > 0) {
GroupManager manager = GroupManager.getInstance();
Collection<Group> groups = manager.getGroups();
for (Group gr : groups) {
if (gr.getName().startsWith(param)) {
root.addElement("item").addText(gr.getName());
}
}
}
resp.getOutputStream().write(root.asXML().getBytes());
resp.getOutputStream().close();
}
}
package org.jivesoftware.openfire.plugin.servlet;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jivesoftware.openfire.plugin.database.DatabaseManager;
import org.jivesoftware.openfire.plugin.database.LogEntry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class StatisticsServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = -6872070494892162304L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DatabaseManager db = DatabaseManager.getInstance();
String component = req.getParameter("component");
String fromString = req.getParameter("date");
/*
* { "packets": [ { "type": "IQ", "from": "holger" }, { "type":
* "Message", "from": "babett", "to": "holger", "date": "1243235344" } ]
* }
*/
int msgCnt = 0;
int iqCnt = 0;
int presenceCnt = 0;
int rosterCnt = 0;
JSONObject root = new JSONObject();
if (component != null && fromString != null) {
JSONArray packetArray = new JSONArray();
try {
root.put("packets", packetArray);
int limit = 40;
long from = Long.valueOf(fromString);
Collection<LogEntry> queryResult = db.getLogsByDateAndLimit(from, limit, component);
for (LogEntry entry : queryResult) {
JSONObject packet = new JSONObject();
packet.put("type", entry.getType()).put("to", entry.getTo()).put("from", entry.getFrom())
.put("date", entry.getDate());
packetArray.put(packet);
if (entry.getType().contains("IQ")) {
iqCnt++;
} else if (entry.getType().contains("Message")) {
msgCnt++;
} else if (entry.getType().contains("Roster")) {
rosterCnt++;
} else if (entry.getType().contains("Presence")) {
presenceCnt++;
}
}
JSONObject numbers = new JSONObject();
numbers.put("msg", msgCnt);
numbers.put("iq", iqCnt);
numbers.put("presence", presenceCnt);
numbers.put("roster", rosterCnt);
root.put("numbers", numbers);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
resp.getOutputStream().write(root.toString().getBytes());
resp.getOutputStream().close();
}
}
<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<servlet>
<servlet-name>stats</servlet-name>
<servlet-class>org.jivesoftware.openfire.plugin.servlet.StatisticsServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>searchGroup</servlet-name>
<servlet-class>org.jivesoftware.openfire.plugin.servlet.SearchGroupServlet</servlet-class>
</servlet>
<!-- Servlet mappings -->
<servlet-mapping>
<servlet-name>stats</servlet-name>
<url-pattern>/stats</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>searchGroup</servlet-name>
<url-pattern>/groups</url-pattern>
</servlet-mapping>
</web-app>
@CHARSET "ISO-8859-1";
.header {
width: 100%;
background-color: gray;
color: white;
padding: 3px;
font-weight: bold;
font-size: 14;
}
.graph {
margin-top: 10px;
width: 100%;
height: 300px;
margin-bottom: 25px;
}
.div-main {
background: #F5F5F5 url(../../../images/jive-body-contentbox-bg.gif) repeat-x
scroll center top;
border: 1px solid #DCDCDC;
margin: 5px;
padding: 10px 10px;
float: left;
}
body table {
font-family: arial, helvetica, sans-serif;
font-size: 13;
}
#logTable {
background-color: #B3B3B3;
width: 100%;
border-spacing: 1px;
border: 1px;
border-style: solid;
border-color: #383838;
}
#logTable thead th {
border-bottom: 1px;
border-style: solid;
text-align: center;
width: 25%;
}
#logTable tfoot tr {
font-weight: bold;
text-align: center;
}
\ No newline at end of file
@CHARSET "ISO-8859-1";
.suggest_link {
background-color: #FFFFFF;
padding: 2px 6px 2px 6px;
......@@ -11,52 +10,100 @@
padding: 2px 6px 2px 6px;
}
.grouptable {
border-spacing:0px;
}
#search_suggest {
position: absolute;
background-color: #FFFFFF;
text-align: left;
border: 1px solid #000000;
display:none;
display: none;
}
.slider {
margin-left:1%;
padding-top:0px;
background-color:rgb(230,230,230);
border-color:#CCCCCC rgb(204, 204, 204);
color:white;
width:58%;
margin-left: 48px;
padding-top: 0px;
background-color: rgb(230, 230, 230);
border-color: #CCCCCC rgb(204, 204, 204);
color: white;
width: 550px;
border-style: solid;
border-width: 1px;
border-top:none;
border-top: none;
display: none;
}
}
.sildeHeader {
background-color: #D4D2D2;
color: #000000;
padding-left: 5px;
padding-top: 2px;
padding-bottom: 2px;
border-bottom-color: gray;
border-bottom-width: 1px;
border-bottom-style: solid;
font-weight: bold;
}
.logtable {
border-left:6px;
width: 550px;
height: 100%;
border-spacing: 0px;
}
#loghead{
background-color:#DEDCDC;
font-weight: bold;
color:#404040;
}
#logodd {
background-color:#F0F0F0;
}
#logeven {
background-color:#E9E9E9;
}
#logfoot {
background-color:#DEDCDC;
}
div.graph {
width: 250px;
height: 150px;
float: right;
}
.gatewayHeader {
width:60%;
background-color:#EEEEEE;
border-color:#CCCCCC rgb(204, 204, 204);
border-style:solid solid solid;
border-width:1px 1px 1px;
width: 600px;
background-color: #EEEEEE;
border-color: #CCCCCC rgb(204, 204, 204);
border-style: solid solid solid;
border-width: 1px 1px 1px;
}
.gatewayName {
padding-left: 10px;
}
.gatewayIcon {
.gatewayIcon {
border-left: 1px;
}
}
.gatewayCheckbox {
width: 20px;
}
.configTable {
width: 80%;
}
width: 100%;
border-spacing:0px;
}
.configTable1Column {
width: 50%;
......@@ -68,32 +115,44 @@
}
#permissions {
margin-left:1%;
padding-top:0px;
background-color:rgb(230,230,230);
border-color:#CCCCCC rgb(204, 204, 204);
color:white;
width:58%;
margin-left: 1%;
padding-top: 0px;
background-color: rgb(230, 230, 230);
border-color: #CCCCCC rgb(204, 204, 204);
color: white;
width: 58%;
border-style: solid;
border-width: 1px;
border-top:none;
border-top: none;
display: none;
}
.permissionTableColumn
{
.permissionTableColumn {
width: 50%;
}
.ajaxloading {
padding-left: 4px;
padding-top: 3px;
}
}
.permissionTitle {
color:black;
size:+2;
color: black;
size: +2;
}
dt {
width: 50px;
}
.hbg-bar {
padding-left: 5px;
background-color: #369;
color: #fff;
font-weight: bold;
}
.hbg-title {
text-align: center;
font-weight: bold;
}
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*
* Horizontal Bar Graph for jQuery
* version 0.1a
*
* http://www.dumpsterdoggy.com/plugins/horiz-bar-graph
*
* Copyright (c) 2009 Chris Missal
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*/
(function($) {
$.fn.horizontalBarGraph = function(options) {
var opts = $.extend({}, $.fn.horizontalBarGraph.defaults, options);
this.children("dt,dd").each(function(i) {
var el = $(this);
if(el.is("dt")) {
el.css({display: "block", float: "left", clear: "left"}).addClass("hbg-label"); return;
} else {
(isTitleDD(el) && opts.hasTitles ? createTitle : createBar)(el, opts);
}
setBarHover(el, opts);
});
tryShowTitle(this);
if(opts.animated) {
createShowButton(opts, this).insertBefore(this);
}
if(opts.colors.length) {
setColors(this.children("dd"), opts);
}
if(opts.hoverColors.length) {
setHoverColors(this.children("dd"), opts);
}
scaleGraph(this);
return this;
};
function scaleGraph(graph) {
var maxWidth = 0;
graph.children("dt").each(function() {
maxWidth = Math.max($(this).width(), maxWidth);
}).css({width: maxWidth+"px"});
}
function setBarHover(bar, opts) {
bar.hover(function() {
bar.addClass("hbg-bar-hover");
}, function() {
bar.removeClass("hbg-bar-hover");
});
}
function createShowButton(opts, graph) {
var button = $("<span />").text(opts.button).addClass("hbg-show-button");
button.click(function() {
graph.children("dd").show('slow', function() { button.fadeOut('normal'); });
});
return button;
}
function createBar(e, opts) {
var val = e.text();
e.css({marginLeft: e.prev().is("dt") ? "5px" : "0px", width: Math.floor(val/opts.interval)+"px"});
e.html($("<span/>").html(val).addClass("hbg-value"));
applyOptions(e, opts);
}
function createTitle(e, opts) {
var title = e.text();
e.prev().attr("title", title);
e.remove();
}
function tryShowTitle(graph) {
var title = graph.attr("title");
if(title) {
$("<div/>").text(title).addClass("hbg-title").insertBefore(graph);
graph.css({overflow: "hidden"});
}
}
function setColors(bars, opts) {
var i = 0;
bars.each(function() {
var c = i++ % opts.colors.length;
$(this).css({backgroundColor: opts.colors[c]});
});
}
function setHoverColors(bars, opts) {
var i = 0;
bars.each(function(i) {
var bar = $(this);
var c = bar.css("background-color");
var hc = opts.hoverColors[i++ % opts.hoverColors.length];
bar.hover(function() {
$(this).css({backgroundColor: hc});
}, function() {
$(this).css({backgroundColor: c});
});
});
}
function applyOptions(e, opts) {
e.css({float: "left"}).addClass("hbg-bar");
if(opts.animated) { e.hide(); }
}
function isTitleDD(e) {
return (e.is(":even") && e.prev().is("dd"));
}
$.fn.horizontalBarGraph.defaults = {
interval: 1,
hasTitles: false,
animated: false,
button: 'Show Values',
colors: [],
hoverColors: []
};
})(jQuery);
$(document).ready(function() {
drawGraph();
window.setInterval("pollStats()", 1000);
})
var dataIq = [];
var dataMsg = [];
var dataPres = [];
var dataRost = [];
var id = 0;
function drawGraph() {
var options = {
lines : {
show : true
},
points : {
show : false
},
yaxis : {
min : 0
},
xaxis : {
show : false
},
grid : {
backgroundColor : {
colors : [ "#fff", "lightgray" ]
}
}
// xaxis: { tickDecimals: 0, tickSize: 1 }
};
var placeholder = $(".graph");
if (dataIq.length > 50) {
dataIq = dataIq.slice(dataIq.length - 50, dataIq.length - 1);
dataMsg = dataMsg.slice(dataMsg.length - 50, dataMsg.length - 1);
dataPres = dataPres.slice(dataPres.length - 50, dataPres.length - 1);
dataRost = dataRost.slice(dataRost.length - 50, dataRost.length - 1);
}
$.plot($(".graph"), [ {
label : "IQ",
data : dataIq
}, {
label : "Messages",
data : dataMsg
}, {
label : "Roster",
data : dataRost
}, {
label : "Presence",
data : dataPres
} ], options);
// $.plot(placeholder, d1, options);
}
function pollStats() {
var myDate = $('#lastPoll').html();
if (myDate.length < 1) {
myDate = $('#logSince').html();
}
var firstDate = $('#timeStamp:first').html();
if (firstDate == null) {
firstDate = $('#logSince').html();
}
updateData(firstDate);
}
function updateData(lastDate) {
var callback = function(data, textStatus, jqXHR) {
var i = 0;
dataIq.push([ id, data.numbers.iq ]);
dataMsg.push([ id, data.numbers.msg ]);
dataPres.push([ id, data.numbers.presence ]);
dataRost.push([ id, data.numbers.roster ]);
id++;
while (data.packets[i] != null) {
var color = "#DEDEDE";
if (i % 2 == 0) {
color = "#EBEBEB";
}
$('.tableBegin:first').after(
'<tr style="background-color:' + color
+ ';"><td id="timeStamp">' + data.packets[i].date
+ '</td><td>' + data.packets[i].type + '</td><td>'
+ data.packets[i].from + '</td><td>'
+ data.packets[i].to + '</td></tr>');
i++;
}
}
drawGraph();
$.ajax({
url : 'stats?component=xmpp.dew08299&date=' + lastDate,
dataType : 'json',
data : '',
success : callback
});
}
This diff is collapsed.
function searchSuggest(object) {
document.getElementById('search_suggest' + object).innerHTML = '';
var str = escape(document.getElementById('groupSearch' + object).value);
$("#ajaxloading" + object).html("<img src=\"images/ajax-loader.gif\">");
var request = new http();
var f = function(obj) {
var ss = document.getElementById('search_suggest' + object);
var resp = obj.responseXML.documentElement.getElementsByTagName('item');
if (resp.length > 0) {
for ( var i = 0; i < resp.length; i++) {
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML,'
+ object + ');" ';
suggest += 'class="suggest_link">' + resp[i].textContent
+ '</div>';
ss.innerHTML += suggest;
}
$("#search_suggest" + object).show("slow");
} else {
$("#search_suggest" + object).hide("slow");
}
};
request.callback = f;
request.load('groups?search=' + str);
}
// Mouse over function
function suggestOver(div_value) {
div_value.className = 'suggest_link_over';
}
// Mouse out function
function suggestOut(div_value) {
div_value.className = 'suggest_link';
}
// Click function
function setSearch(value, object) {
document.getElementById("groupSearch" + object).value = value;
// document.getElementById('search_suggest').innerHTML = '';
$("#search_suggest" + object).hide("slow");
checkIfExists(value, object);
}
function checkIfExists(value, object) {
var str = value;
var request = new http();
var f = function(obj) {
var ss = document.getElementById('search_suggest' + object);
var resp = obj.responseXML.documentElement.getElementsByTagName('item');
for ( var i = 0; i < resp.length; i++) {
var stri = String(str);
var respStr = String(resp[i].textContent);
if (stri == respStr) {
$("#ajaxloading" + object).html(
"<img src=\"images/correct-16x16.png\">");
break;
}
}
};
request.callback = f;
request.load('groups?search=' + str);
}
$(document).ready(function() {
$(".browser-data").horizontalBarGraph({
interval : 1
});
var i = 0;
while ($('#logiq' + i).html() != null) {
var iqs = $('#logiq'+i).html();
var msg = $('#logmsg'+i).html();
var roster = $('#logroster'+i).html();
var presence = $('#logpresence'+i).html();
var data = [ {
label : "IQ",
data : parseInt(iqs)
}, {
label : "Messages",
data : parseInt(msg)
}, {
label : "Roster",
data : parseInt(roster)
}, {
label : "Presence",
data : parseInt(presence)
} ];
$.plot($("#pie"+i), data,
{
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 3/5,
formatter: function(label, series){
return '<div style="font-size:8pt;text-align:center;padding:2px;color:white;background-color:rgba(100,100,100,0.5);">'+label+'<br/>'+Math.round(series.percent)+'%</div>';
},
background: {
opacity: 0.5,
color: 'gray'
}
}
}
},
legend: {
show: false
}
});
++i;
}
})
function slideToggle(value) {
$(value).slideToggle();
}
<%@page import="org.jivesoftware.openfire.plugin.PermissionManager"%>
<%@ page import="org.dom4j.tree.DefaultElement"%>
<%@ page import="org.jivesoftware.openfire.group.GroupManager"%>
<%@ page import="org.jivesoftware.openfire.group.Group"%>
<%@ page import="org.jivesoftware.openfire.session.ComponentSession"%>
<%@ page import="java.util.Collection"%>
<%@ page import="org.jivesoftware.openfire.SessionManager"%>
<%@ page import="org.jivesoftware.util.JiveGlobals"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.List"%>
<%@ page import="org.jivesoftware.openfire.plugin.database.DatabaseManager"%>
<%@ page import="org.jivesoftware.util.ParamUtils"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt"%>
<%
// webManager.init(request, response, session, application, out);
boolean componentSet = request.getParameter("component") != null;
String component = "";
if (componentSet) {
component = request.getParameter("component");
}
%>
<html>
<head>
<title>Live logs <%=componentSet ? "for " + component : ""%></title>
<meta name="decorator" content="none" />
<link href="./css/liveStats.css" rel="stylesheet" type="text/css">
<script src="./js/http.js" type="text/javascript"></script>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/liveStats.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript" src="./js/jquery.flot.js"></script>
</head>
<body>
<div class="div-main">
<div class="header">
Live statistics for
<%=componentSet ? component : "NOT SET"%></div>
<div class="graph">Here should appear your stats</div>
<table id="logTable">
<thead>
<tr>
<th>Date</th>
<th>Type</th>
<th>From</th>
<th>To</th>
</tr>
</thead>
<tbody class="tableBegin">
</tbody>
<tfoot>
<tr>
<td colspan="4">Live logging since <span id="logSince"><%=System.currentTimeMillis()%></span> Last poll <span
id="lastPoll"></span></td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>
\ No newline at end of file
......@@ -9,6 +9,7 @@
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.List"%>
<%@ page import="org.jivesoftware.openfire.plugin.database.DatabaseManager"%>
<%@ page import="org.jivesoftware.util.ParamUtils"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt"%>
......@@ -24,6 +25,7 @@
boolean sparkDiscoInfo = sparkdiscoParam == null ? false : sparkdiscoParam.equals("true");
String[] componentsEnabled = request.getParameterValues("enabledComponents[]");
PermissionManager _pmanager = new PermissionManager();
DatabaseManager _db;
Map<String, String> errors = new HashMap<String, String>();
if (save) {
......@@ -49,17 +51,22 @@
SessionManager sessionManager = webManager.getSessionManager();
Collection<ComponentSession> sessions = sessionManager.getComponentSessions();
_db = DatabaseManager.getInstance();
%>
<html>
<head>
<title><fmt:message key="rr.summary.title" /></title>
<link href="rr.css" rel="stylesheet" type="text/css">
<script src="http.js" type="text/javascript"></script>
<script src="jquery.js" type="text/javascript"></script>
<script src="rr.js" type="text/javascript"></script>
<script src="jquery.sparkline.js" type="text/javascript"></script>
<link href="./css/rr.css" rel="stylesheet" type="text/css">
<script src="./js/http.js" type="text/javascript"></script>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/rr.js" type="text/javascript"></script>
<script src="./js/jquery.sparkline.js" type="text/javascript"></script>
<script src="./js/jquery.horiz-bar-graph.js" type="text/javascript"></script>
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="./js/excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="./js/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="./js/jquery.flot.pie.js"></script>
<meta name="pageID" content="remoteRoster" />
<meta name="helpPage" content="" />
......@@ -122,6 +129,12 @@
continue;
}
gatewayFound = true;
long incoming = componentSession.getNumClientPackets();
long outgoing = componentSession.getNumServerPackets();
long both = incoming + outgoing;
int incomingPercent = (int) (incoming * 100 / both);
int outgoingPercent = (int) (outgoing * 100 / both);
%>
<table class="gatewayHeader">
<tbody>
......@@ -133,37 +146,46 @@
: ""%> />
</td>
<td class="gatewayName"><%=componentSession.getExternalComponent().getName()%></td>
<td class="gatewayIcons"><img src="images/info-16x16.png" id="showConfig"
onclick="slideToggle('#config<%=i%>')"> <img src="images/permissions-16x16.png" id="showPermissions"
onclick="slideToggle('#permission<%=i%>')"> <img src="images/log-16x16.png"></td>
<td class="gatewayIcons"><img src="images/log-16x16.png" onclick="slideToggle('#logs<%=i%>')"><img
src="images/permissions-16x16.png" id="showPermissions" onclick="slideToggle('#permission<%=i%>')"><img
src="images/info-16x16.png" id="showConfig" onclick="slideToggle('#config<%=i%>')"></td>
</tr>
</tbody>
</table>
<div id="config<%=i%>" class="slider">
<div class="sildeHeader">Information</div>
<table class="configTable">
<tbody>
<tr>
<td class="configTable1Column">Domain:</td>
<tr id="logodd">
<td width="200px">Domain:</td>
<td><%=componentSession.getExternalComponent().getInitialSubdomain()%></td>
</tr>
<tr>
<td class="configTable1Column">Status:</td>
<tr id="logeven">
<td>Status:</td>
<td>Online</td>
</tr>
<tr>
<td class="configTable1Column">Packages Send/Received:</td>
<td><%=componentSession.getNumServerPackets()%> / <%=componentSession.getNumClientPackets()%><div id="inlinesparkline<%=i%>">1,4,4,7,5,9,10</div></td>
<tr id="logodd">
<td>Packages Send/Received:</td>
<td><dl class="browser-data" title="">
<dt>Incoming</dt>
<dd><%=incomingPercent%></dd>
<dt>Outgoing</dt>
<dd><%=outgoingPercent%></dd>
</dl></td>
</tr>
</tbody>
</table>
</div>
<div id="permission<%=i%>" class="slider">
> <span class="permissionTitle">You can limit the access to the external component to an existing group</span>)
<div class="sildeHeader">Access control</div>
<table class="groupTable">
<tbody>
<tr id="loghead">
<td colspan="3">You can limit the access to the external component to an existing group</td>
</tr>
<tr>
<td class="permissionTableColumn">Groupname:</td>
<td><input type="text" id="groupSearch<%=i%>"
<td><input class="groupInput" type="text" id="groupSearch<%=i%>"
name="input_group.<%=componentSession.getExternalComponent().getInitialSubdomain()%>" alt="Find Groups"
onkeyup="searchSuggest('<%=i%>');" autocomplete="off"
value="<%=_pmanager.getGroupForGateway(componentSession.getExternalComponent().getInitialSubdomain())%>">
......@@ -171,10 +193,62 @@
<td style="vertical-align: top;">
<div class="ajaxloading" id="ajaxloading<%=i%>"></div>
</td>
</tr>
</tbody>
</table>
</div>
<div id="logs<%=i%>" class="slider">
<%
int iqs = _db.getPacketCount(componentSession.getExternalComponent().getInitialSubdomain(),
Class.forName("org.xmpp.packet.IQ"));
int msgs = _db.getPacketCount(componentSession.getExternalComponent().getInitialSubdomain(),
Class.forName("org.xmpp.packet.Message"));
int rosters = _db.getPacketCount(componentSession.getExternalComponent().getInitialSubdomain(),
Class.forName("org.xmpp.packet.Roster"));
int presences = _db.getPacketCount(componentSession.getExternalComponent().getInitialSubdomain(),
Class.forName("org.xmpp.packet.Presence"));
%>
<div class="sildeHeader">Logs & Statistics</div>
<table class="logtable">
<tfoot>
<tr id="logfoot">
<td colspan="2">Packages being logged for 60 minutes</td>
<td><a style="float: right;"
onClick="window.open('liveStats.jsp?component=<%=componentSession.getExternalComponent().getInitialSubdomain()%>','mywindow','width=1200,height=700')">Show
realtime Log</a>
</tr>
</tfoot>
<tbody>
<tr id="loghead">
<td width="200px">Paket type</td>
<td width="100px">Number</td>
<td></td>
</tr>
<tr id="logodd">
<td>IQ</td>
<td id="logiq<%=i%>"><%=iqs%></td>
<td rowspan="5"><div id="pie<%=i%>" class="graph"></div></td>
</tr>
<tr id="logeven">
<td>Messages</td>
<td id="logmsg<%=i%>"><%=msgs%></td>
</tr>
<tr id="logodd">
<td>Roster</td>
<td id="logroster<%=i%>"><%=rosters%></td>
</tr>
<tr id="logeven">
<td>Presence</td>
<td id="logpresence<%=i%>"><%=presences%></td>
</tr>
<tr id="logodd">
<td><span style="font-weight: bold;">Total:</span></td>
<td><span style="font-weight: bold;"><%=iqs + msgs + rosters + presences%></span></td>
</tr>
</tbody>
</table>
</div>
......
function searchSuggest(object) {
document.getElementById('search_suggest'+object).innerHTML = '';
var str = escape(document.getElementById('groupSearch'+object).value);
$("#ajaxloading"+object).html("<img src=\"images/ajax-loader.gif\">");
var request = new http();
var f = function(obj) {
console.log(obj);
var ss = document.getElementById('search_suggest'+object);
var resp = obj.responseXML.documentElement
.getElementsByTagName('item');
if (resp.length > 0) {
for ( var i = 0; i < resp.length; i++) {
console.log(resp[i].textContent);
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML,'+object+');" ';
suggest += 'class="suggest_link">' + resp[i].textContent
+ '</div>';
ss.innerHTML += suggest;
}
$("#search_suggest"+object).show("slow");
} else {
$("#search_suggest"+object).hide("slow");
}
};
request.callback = f;
request.load('searchGroup.jsp?search=' + str);
}
// Mouse over function
function suggestOver(div_value) {
div_value.className = 'suggest_link_over';
}
// Mouse out function
function suggestOut(div_value) {
div_value.className = 'suggest_link';
}
// Click function
function setSearch(value, object) {
document.getElementById("groupSearch"+object).value = value;
// document.getElementById('search_suggest').innerHTML = '';
$("#search_suggest"+object).hide("slow");
checkIfExists(value,object);
}
function checkIfExists(value, object) {
var str = value;
var request = new http();
var f = function(obj) {
console.log(obj);
var ss = document.getElementById('search_suggest'+object);
var resp = obj.responseXML.documentElement.getElementsByTagName('item');
for ( var i = 0; i < resp.length; i++) {
var stri = String(str);
var respStr = String(resp[i].textContent);
if (stri == respStr) {
$("#ajaxloading"+object)
.html("<img src=\"images/correct-16x16.png\">");
break;
}
}
};
request.callback = f;
request.load('searchGroup.jsp?search=' + str);
}
$(document).ready(function () {
console.log("bind da");
var myvalues = [10,8,5,7,4,4,1];
$('#inlinesparkline0').sparkline();
})
function slideToggle(value)
{
$(value).slideToggle();
}
<?xml version="1.0" encoding="UTF-8" ?>
<%@page import="org.dom4j.tree.DefaultElement"%>
<%@page import="org.dom4j.*"%>
<%@ page language="java" contentType="text/xml" pageEncoding="ISO-8859-1"%>
<%@ page import="org.jivesoftware.openfire.group.GroupManager"%>
<%@ page import="org.jivesoftware.openfire.group.Group"%>
<%@ page import="java.util.Collection"%>
<%
String param = request.getParameter("search");
Element root = new DefaultElement("result");
if (param != null && param.length() > 0)
{
GroupManager manager = GroupManager.getInstance();
Collection<Group> groups = manager.getGroups();
for (Group gr : groups)
{
if (gr.getName().startsWith(param))
{
root.addElement("item").addText(gr.getName());
}
}
}
out.write(root.asXML());
%>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment