Commit b34bf286 authored by Naoki Kambe's avatar Naoki Kambe
Browse files

Merge branch 'trac917'

Conflicts:
	ChangeLog
parents 120946aa b79e0ef1
xxx. [func] naokikambe
b10-stats-httpd was updated. In addition of the access to all
statistics items of all modules, the specified item or the items of the
specified module name can be accessed. For example, the URI requested
by using the feature is showed as "/bind10/statistics/xml/Auth" or
"/bind10/statistics/xml/Auth/queries.tcp". The list of all possible
module names and all possible item names can be showed in the root
document, whose URI is "/bind10/statistics/xml". This change is not
only for the XML documents but also is for the XSD and XSL documents.
(Trac #917, git TBD)
318. [func] stephen
Add C++ API for accessing zone difference information in database-based
data sources.
......
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="$xsl_url_path"?>
<!--
- Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
<stats:stats_data version="1.0"
xmlns:stats="$xsd_namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="$xsd_namespace $xsd_url_path">
$xml_string
</stats:stats_data>
$xml_string
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
<schema targetNamespace="$xsd_namespace"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:stats="$xsd_namespace">
<annotation>
<documentation xml:lang="en">XML schema of the statistics
data in BIND 10</documentation>
</annotation>
<element name="stats_data">
<annotation>
<documentation>A set of statistics data</documentation>
</annotation>
<complexType>
$xsd_string
<attribute name="version" type="token" use="optional" default="1.0">
<annotation>
<documentation>Version number of syntax</documentation>
</annotation>
</attribute>
</complexType>
</element>
</schema>
$xsd_string
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
xmlns:stats="$xsd_namespace">
xmlns:bind10="$xsd_namespace">
<xsl:output method="html" encoding="UTF-8"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system=" http://www.w3.org/TR/html4/loose.dtd " />
......@@ -42,14 +26,7 @@ td.title {
</head>
<body>
<h1>BIND 10 Statistics</h1>
<table>
<tr>
<th>Owner</th>
<th>Title</th>
<th>Value</th>
</tr>
<xsl:apply-templates />
</table>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
......
......@@ -246,12 +246,12 @@ class Stats:
self.update_statistics_data()
if owner and name:
try:
return self.statistics_data[owner][name]
return {owner:{name:self.statistics_data[owner][name]}}
except KeyError:
pass
elif owner:
try:
return self.statistics_data[owner]
return {owner: self.statistics_data[owner]}
except KeyError:
pass
elif name:
......@@ -360,9 +360,9 @@ class Stats:
if owner:
try:
if name:
return isc.config.create_answer(0, schema_byname[owner][name])
return isc.config.create_answer(0, {owner:[schema_byname[owner][name]]})
else:
return isc.config.create_answer(0, schema[owner])
return isc.config.create_answer(0, {owner:schema[owner]})
except KeyError:
pass
else:
......
This diff is collapsed.
......@@ -55,6 +55,12 @@ response will be sent back, and the specific error is printed. This
is an error condition that likely points to a module that is not
responding correctly to statistic requests.
% STATHTTPD_SERVER_DATAERROR HTTP server data error: %1
An internal error occurred while handling an HTTP request. An HTTP 404
response will be sent back, and the specific error is printed. This
is an error condition that likely points the specified data
corresponding to the requested URI is incorrect.
% STATHTTPD_SERVER_INIT_ERROR HTTP server initialization error: %1
There was a problem initializing the HTTP server in the stats-httpd
module upon receiving its configuration data. The most likely cause
......
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
PYTESTS = b10-stats_test.py b10-stats-httpd_test.py
EXTRA_DIST = $(PYTESTS) test_utils.py
CLEANFILES = test_utils.pyc msgq_socket_test
CLEANFILES = test_utils.pyc
# If necessary (rare cases), explicitly specify paths to dynamic libraries
# required by loadable python modules.
......
This diff is collapsed.
......@@ -226,7 +226,7 @@ class TestStats(unittest.TestCase):
'show', 'Stats',
params={ 'owner' : 'Boss',
'name' : 'boot_time' }),
(0, self.const_datetime))
(0, {'Boss': {'boot_time': self.const_datetime}}))
self.assertEqual(
send_command(
'set', 'Stats',
......@@ -238,7 +238,7 @@ class TestStats(unittest.TestCase):
'show', 'Stats',
params={ 'owner' : 'Boss',
'name' : 'boot_time' }),
(0, self.const_datetime))
(0, {'Boss': {'boot_time': self.const_datetime}}))
self.assertEqual(
send_command('status', 'Stats'),
(0, "Stats is up. (PID " + str(os.getpid()) + ")"))
......@@ -321,25 +321,25 @@ class TestStats(unittest.TestCase):
my_statistics_data = self.stats.get_statistics_data()
self.assertTrue('Stats' in my_statistics_data)
self.assertTrue('Boss' in my_statistics_data)
self.assertTrue('boot_time' in my_statistics_data['Boss'])
my_statistics_data = self.stats.get_statistics_data(owner='Stats')
self.assertTrue('report_time' in my_statistics_data)
self.assertTrue('boot_time' in my_statistics_data)
self.assertTrue('last_update_time' in my_statistics_data)
self.assertTrue('timestamp' in my_statistics_data)
self.assertTrue('lname' in my_statistics_data)
self.assertTrue('Stats' in my_statistics_data)
self.assertTrue('report_time' in my_statistics_data['Stats'])
self.assertTrue('boot_time' in my_statistics_data['Stats'])
self.assertTrue('last_update_time' in my_statistics_data['Stats'])
self.assertTrue('timestamp' in my_statistics_data['Stats'])
self.assertTrue('lname' in my_statistics_data['Stats'])
self.assertRaises(stats.StatsError, self.stats.get_statistics_data, owner='Foo')
my_statistics_data = self.stats.get_statistics_data(owner='Stats')
self.assertTrue('boot_time' in my_statistics_data)
my_statistics_data = self.stats.get_statistics_data(owner='Stats', name='report_time')
self.assertEqual(my_statistics_data, self.const_default_datetime)
self.assertEqual(my_statistics_data['Stats']['report_time'], self.const_default_datetime)
my_statistics_data = self.stats.get_statistics_data(owner='Stats', name='boot_time')
self.assertEqual(my_statistics_data, self.const_default_datetime)
self.assertEqual(my_statistics_data['Stats']['boot_time'], self.const_default_datetime)
my_statistics_data = self.stats.get_statistics_data(owner='Stats', name='last_update_time')
self.assertEqual(my_statistics_data, self.const_default_datetime)
self.assertEqual(my_statistics_data['Stats']['last_update_time'], self.const_default_datetime)
my_statistics_data = self.stats.get_statistics_data(owner='Stats', name='timestamp')
self.assertEqual(my_statistics_data, 0.0)
self.assertEqual(my_statistics_data['Stats']['timestamp'], 0.0)
my_statistics_data = self.stats.get_statistics_data(owner='Stats', name='lname')
self.assertEqual(my_statistics_data, '')
self.assertEqual(my_statistics_data, {'Stats': {'lname':''}})
self.assertRaises(stats.StatsError, self.stats.get_statistics_data,
owner='Stats', name='Bar')
self.assertRaises(stats.StatsError, self.stats.get_statistics_data,
......@@ -385,10 +385,25 @@ class TestStats(unittest.TestCase):
1, "specified arguments are incorrect: owner: Foo, name: bar"))
self.assertEqual(self.stats.command_show(owner='Auth'),
isc.config.create_answer(
0, {'queries.tcp': 0, 'queries.udp': 0}))
0, {'Auth':{ 'queries.udp': 0,
'queries.tcp': 0,
'queries.perzone': [{ 'zonename': 'test1.example',
'queries.udp': 1,
'queries.tcp': 2 },
{ 'zonename': 'test2.example',
'queries.udp': 3,
'queries.tcp': 4 }] }}))
self.assertEqual(self.stats.command_show(owner='Auth', name='queries.udp'),
isc.config.create_answer(
0, 0))
0, {'Auth': {'queries.udp':0}}))
self.assertEqual(self.stats.command_show(owner='Auth', name='queries.perzone'),
isc.config.create_answer(
0, {'Auth': {'queries.perzone': [{ 'zonename': 'test1.example',
'queries.udp': 1,
'queries.tcp': 2 },
{ 'zonename': 'test2.example',
'queries.udp': 3,
'queries.tcp': 4 }]}}))
orig_get_timestamp = stats.get_timestamp
orig_get_datetime = stats.get_datetime
stats.get_timestamp = lambda : self.const_timestamp
......@@ -396,7 +411,7 @@ class TestStats(unittest.TestCase):
self.assertEqual(stats.get_timestamp(), self.const_timestamp)
self.assertEqual(stats.get_datetime(), self.const_datetime)
self.assertEqual(self.stats.command_show(owner='Stats', name='report_time'), \
isc.config.create_answer(0, self.const_datetime))
isc.config.create_answer(0, {'Stats': {'report_time':self.const_datetime}}))
self.assertEqual(self.stats.statistics_data['Stats']['timestamp'], self.const_timestamp)
self.assertEqual(self.stats.statistics_data['Stats']['boot_time'], self.const_default_datetime)
stats.get_timestamp = orig_get_timestamp
......@@ -442,9 +457,12 @@ class TestStats(unittest.TestCase):
self.assertTrue('item_format' in item)
schema = value['Auth']
self.assertEqual(len(schema), 2)
self.assertEqual(len(schema), 3)
for item in schema:
self.assertTrue(len(item) == 6)
if item['item_type'] == 'list':
self.assertEqual(len(item), 7)
else:
self.assertEqual(len(item), 6)
self.assertTrue('item_name' in item)
self.assertTrue('item_type' in item)
self.assertTrue('item_optional' in item)
......@@ -455,10 +473,10 @@ class TestStats(unittest.TestCase):
(rcode, value) = isc.config.ccsession.parse_answer(
self.stats.command_showschema(owner='Stats'))
self.assertEqual(rcode, 0)
self.assertFalse('Stats' in value)
self.assertTrue('Stats' in value)
self.assertFalse('Boss' in value)
self.assertFalse('Auth' in value)
for item in value:
for item in value['Stats']:
self.assertTrue(len(item) == 6 or len(item) == 7)
self.assertTrue('item_name' in item)
self.assertTrue('item_type' in item)
......@@ -472,19 +490,19 @@ class TestStats(unittest.TestCase):
(rcode, value) = isc.config.ccsession.parse_answer(
self.stats.command_showschema(owner='Stats', name='report_time'))
self.assertEqual(rcode, 0)
self.assertFalse('Stats' in value)
self.assertTrue('Stats' in value)
self.assertFalse('Boss' in value)
self.assertFalse('Auth' in value)
self.assertTrue(len(value) == 7)
self.assertTrue('item_name' in value)
self.assertTrue('item_type' in value)
self.assertTrue('item_optional' in value)
self.assertTrue('item_default' in value)
self.assertTrue('item_title' in value)
self.assertTrue('item_description' in value)
self.assertTrue('item_format' in value)
self.assertEqual(value['item_name'], 'report_time')
self.assertEqual(value['item_format'], 'date-time')
self.assertEqual(len(value['Stats'][0]), 7)
self.assertTrue('item_name' in value['Stats'][0])
self.assertTrue('item_type' in value['Stats'][0])
self.assertTrue('item_optional' in value['Stats'][0])
self.assertTrue('item_default' in value['Stats'][0])
self.assertTrue('item_title' in value['Stats'][0])
self.assertTrue('item_description' in value['Stats'][0])
self.assertTrue('item_format' in value['Stats'][0])
self.assertEqual(value['Stats'][0]['item_name'], 'report_time')
self.assertEqual(value['Stats'][0]['item_format'], 'date-time')
self.assertEqual(self.stats.command_showschema(owner='Foo'),
isc.config.create_answer(
......@@ -494,7 +512,7 @@ class TestStats(unittest.TestCase):
1, "specified arguments are incorrect: owner: Foo, name: bar"))
self.assertEqual(self.stats.command_showschema(owner='Auth'),
isc.config.create_answer(
0, [{
0, {'Auth': [{
"item_default": 0,
"item_description": "A number of total query counts which all auth servers receive over TCP since they started initially",
"item_name": "queries.tcp",
......@@ -509,17 +527,121 @@ class TestStats(unittest.TestCase):
"item_optional": False,
"item_title": "Queries UDP",
"item_type": "integer"
}]))
},
{
"item_name": "queries.perzone",
"item_type": "list",
"item_optional": False,
"item_default": [
{
"zonename" : "test1.example",
"queries.udp" : 1,
"queries.tcp" : 2
},
{
"zonename" : "test2.example",
"queries.udp" : 3,
"queries.tcp" : 4
}
],
"item_title": "Queries per zone",
"item_description": "Queries per zone",
"list_item_spec": {
"item_name": "zones",
"item_type": "map",
"item_optional": False,
"item_default": {},
"map_item_spec": [
{
"item_name": "zonename",
"item_type": "string",
"item_optional": False,
"item_default": "",
"item_title": "Zonename",
"item_description": "Zonename"
},
{
"item_name": "queries.udp",
"item_type": "integer",
"item_optional": False,
"item_default": 0,
"item_title": "Queries UDP per zone",
"item_description": "A number of UDP query counts per zone"
},
{
"item_name": "queries.tcp",
"item_type": "integer",
"item_optional": False,
"item_default": 0,
"item_title": "Queries TCP per zone",
"item_description": "A number of TCP query counts per zone"
}
]
}
}]}))
self.assertEqual(self.stats.command_showschema(owner='Auth', name='queries.tcp'),
isc.config.create_answer(
0, {
0, {'Auth': [{
"item_default": 0,
"item_description": "A number of total query counts which all auth servers receive over TCP since they started initially",
"item_name": "queries.tcp",
"item_optional": False,
"item_title": "Queries TCP",
"item_type": "integer"
}))
}]}))
self.assertEqual(self.stats.command_showschema(owner='Auth', name='queries.perzone'),
isc.config.create_answer(
0, {'Auth':[{
"item_name": "queries.perzone",
"item_type": "list",
"item_optional": False,
"item_default": [
{
"zonename" : "test1.example",
"queries.udp" : 1,
"queries.tcp" : 2
},
{
"zonename" : "test2.example",
"queries.udp" : 3,
"queries.tcp" : 4
}
],
"item_title": "Queries per zone",
"item_description": "Queries per zone",
"list_item_spec": {
"item_name": "zones",
"item_type": "map",
"item_optional": False,
"item_default": {},
"map_item_spec": [
{
"item_name": "zonename",
"item_type": "string",
"item_optional": False,
"item_default": "",
"item_title": "Zonename",
"item_description": "Zonename"
},
{
"item_name": "queries.udp",
"item_type": "integer",
"item_optional": False,
"item_default": 0,
"item_title": "Queries UDP per zone",
"item_description": "A number of UDP query counts per zone"
},
{
"item_name": "queries.tcp",
"item_type": "integer",
"item_optional": False,
"item_default": 0,
"item_title": "Queries TCP per zone",
"item_description": "A number of TCP query counts per zone"
}
]
}
}]}))
self.assertEqual(self.stats.command_showschema(owner='Stats', name='bar'),
isc.config.create_answer(
......
......@@ -232,6 +232,57 @@ class MockAuth:
"item_default": 0,
"item_title": "Queries UDP",
"item_description": "A number of total query counts which all auth servers receive over UDP since they started initially"
},
{
"item_name": "queries.perzone",
"item_type": "list",
"item_optional": false,
"item_default": [
{
"zonename" : "test1.example",
"queries.udp" : 1,
"queries.tcp" : 2
},
{
"zonename" : "test2.example",
"queries.udp" : 3,
"queries.tcp" : 4
}
],
"item_title": "Queries per zone",
"item_description": "Queries per zone",
"list_item_spec": {
"item_name": "zones",
"item_type": "map",
"item_optional": false,
"item_default": {},
"map_item_spec": [
{
"item_name": "zonename",
"item_type": "string",
"item_optional": false,
"item_default": "",
"item_title": "Zonename",
"item_description": "Zonename"
},
{
"item_name": "queries.udp",
"item_type": "integer",
"item_optional": false,
"item_default": 0,
"item_title": "Queries UDP per zone",
"item_description": "A number of UDP query counts per zone"
},
{
"item_name": "queries.tcp",
"item_type": "integer",
"item_optional": false,
"item_default": 0,
"item_title": "Queries TCP per zone",
"item_description": "A number of TCP query counts per zone"
}
]
}
}
]
}
......@@ -251,6 +302,11 @@ class MockAuth:
self.got_command_name = ''
self.queries_tcp = 3
self.queries_udp = 2
self.queries_per_zone = [{
'zonename': 'test1.example',
'queries.tcp': 5,
'queries.udp': 4
}]
def run(self):
self.mccs.start()
......@@ -273,7 +329,8 @@ class MockAuth:
if command == 'sendstats':
params = { "owner": "Auth",
"data": { 'queries.tcp': self.queries_tcp,
'queries.udp': self.queries_udp } }
'queries.udp': self.queries_udp,
'queries.per-zone' : self.queries_per_zone } }
return send_command("set", "Stats", params=params, session=self.cc_session)
return isc.config.create_answer(1, "Unknown Command")
......
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