Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
af89cdb0
Commit
af89cdb0
authored
Jul 12, 2012
by
Jeremy C. Reed
Browse files
[master]Merge branch 'master' of
ssh://git.bind10.isc.org/var/bind10/git/bind10
parents
220c1dff
0684f354
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/lib/datasrc/client_list.cc
View file @
af89cdb0
...
...
@@ -16,6 +16,7 @@
#include
"client.h"
#include
"factory.h"
#include
"memory_datasrc.h"
#include
"logger.h"
#include
<memory>
#include
<boost/foreach.hpp>
...
...
@@ -30,11 +31,19 @@ namespace datasrc {
ConfigurableClientList
::
DataSourceInfo
::
DataSourceInfo
(
DataSourceClient
*
data_src_client
,
const
DataSourceClientContainerPtr
&
container
,
bool
has
C
ache
)
:
const
DataSourceClientContainerPtr
&
container
,
bool
has
_c
ache
)
:
data_src_client_
(
data_src_client
),
container_
(
container
)
{
if
(
hasCache
)
{
if
(
has_cache
)
{
cache_
.
reset
(
new
InMemoryClient
);
}
}
ConfigurableClientList
::
DataSourceInfo
::
DataSourceInfo
(
bool
has_cache
)
:
data_src_client_
(
NULL
)
{
if
(
has_cache
)
{
cache_
.
reset
(
new
InMemoryClient
);
}
}
...
...
@@ -58,49 +67,92 @@ ConfigurableClientList::configure(const Element& config, bool allow_cache) {
if
(
paramConf
==
ConstElementPtr
())
{
paramConf
.
reset
(
new
NullElement
());
}
// TODO: Special-case the master files type.
// Ask the factory to create the data source for us
const
DataSourcePair
ds
(
this
->
getDataSourceClient
(
type
,
paramConf
));
const
bool
want_cache
(
allow_cache
&&
dconf
->
contains
(
"cache-enable"
)
&&
dconf
->
get
(
"cache-enable"
)
->
boolValue
());
// And put it into the vector
new_data_sources
.
push_back
(
DataSourceInfo
(
ds
.
first
,
ds
.
second
,
want_cache
));
if
(
type
==
"MasterFiles"
)
{
// In case the cache is not allowed, we just skip the master
// files (at least for now)
if
(
!
allow_cache
)
{
// We're not going to load these zones. Issue warnings about it.
const
map
<
string
,
ConstElementPtr
>
zones_files
(
paramConf
->
mapValue
());
for
(
map
<
string
,
ConstElementPtr
>::
const_iterator
it
(
zones_files
.
begin
());
it
!=
zones_files
.
end
();
++
it
)
{
LOG_WARN
(
logger
,
DATASRC_LIST_NOT_CACHED
).
arg
(
it
->
first
).
arg
(
rrclass_
);
}
continue
;
}
if
(
!
want_cache
)
{
isc_throw
(
ConfigurationError
,
"The cache must be enabled "
"for the MasterFiles type"
);
}
new_data_sources
.
push_back
(
DataSourceInfo
(
true
));
}
else
{
// Ask the factory to create the data source for us
const
DataSourcePair
ds
(
this
->
getDataSourceClient
(
type
,
paramConf
));
// And put it into the vector
new_data_sources
.
push_back
(
DataSourceInfo
(
ds
.
first
,
ds
.
second
,
want_cache
));
}
if
(
want_cache
)
{
if
(
!
dconf
->
contains
(
"cache-zones"
))
{
if
(
!
dconf
->
contains
(
"cache-zones"
)
&&
type
!=
"MasterFiles"
)
{
isc_throw
(
isc
::
NotImplemented
,
"Auto-detection of zones "
"to cache is not yet implemented, supply "
"cache-zones parameter"
);
// TODO: Auto-detect list of all zones in the
// data source.
}
const
ConstElementPtr
zones
(
dconf
->
get
(
"cache-zones"
));
// List the zones we are loading
vector
<
string
>
zones_origins
;
if
(
type
==
"MasterFiles"
)
{
const
map
<
string
,
ConstElementPtr
>
zones_files
(
paramConf
->
mapValue
());
for
(
map
<
string
,
ConstElementPtr
>::
const_iterator
it
(
zones_files
.
begin
());
it
!=
zones_files
.
end
();
++
it
)
{
zones_origins
.
push_back
(
it
->
first
);
}
}
else
{
const
ConstElementPtr
zones
(
dconf
->
get
(
"cache-zones"
));
for
(
size_t
i
(
0
);
i
<
zones
->
size
();
++
i
)
{
zones_origins
.
push_back
(
zones
->
get
(
i
)
->
stringValue
());
}
}
const
shared_ptr
<
InMemoryClient
>
cache
(
new_data_sources
.
back
().
cache_
);
const
DataSourceClient
*
const
client
(
new_data_sources
.
back
().
data_src_client_
);
for
(
size_t
i
(
0
);
i
<
zones
->
size
();
++
i
)
{
const
Name
origin
(
zones
->
get
(
i
)
->
stringValue
());
const
DataSourceClient
::
FindResult
zone
(
client
->
findZone
(
origin
));
if
(
zone
.
code
!=
result
::
SUCCESS
)
{
// The data source does not contain the zone, it can't
// be cached.
isc_throw
(
ConfigurationError
,
"Unable to cache "
"non-existent zone "
<<
origin
);
}
for
(
vector
<
string
>::
const_iterator
it
(
zones_origins
.
begin
());
it
!=
zones_origins
.
end
();
++
it
)
{
const
Name
origin
(
*
it
);
shared_ptr
<
InMemoryZoneFinder
>
finder
(
new
InMemoryZoneFinder
(
zone
.
zone_finder
->
getClass
(),
origin
));
ZoneIteratorPtr
iterator
(
client
->
getIterator
(
origin
));
if
(
!
iterator
)
{
isc_throw
(
isc
::
Unexpected
,
"Got NULL iterator for "
"zone "
<<
origin
);
InMemoryZoneFinder
(
rrclass_
,
origin
));
if
(
type
==
"MasterFiles"
)
{
finder
->
load
(
paramConf
->
get
(
*
it
)
->
stringValue
());
}
else
{
ZoneIteratorPtr
iterator
;
try
{
iterator
=
client
->
getIterator
(
origin
);
}
catch
(
const
DataSourceError
&
)
{
isc_throw
(
ConfigurationError
,
"Unable to cache "
"non-existent zone "
<<
origin
);
}
if
(
!
iterator
)
{
isc_throw
(
isc
::
Unexpected
,
"Got NULL iterator for "
"zone "
<<
origin
);
}
finder
->
load
(
*
iterator
);
}
finder
->
load
(
*
iterator
);
cache
->
addZone
(
finder
);
}
}
...
...
src/lib/datasrc/client_list.h
View file @
af89cdb0
...
...
@@ -16,6 +16,7 @@
#define DATASRC_CONTAINER_H
#include
<dns/name.h>
#include
<dns/rrclass.h>
#include
<cc/data.h>
#include
<exceptions/exceptions.h>
...
...
@@ -186,6 +187,12 @@ typedef boost::shared_ptr<const ClientList> ConstClientListPtr;
/// inherited except for tests.
class
ConfigurableClientList
:
public
ClientList
{
public:
/// \brief Constructor
///
/// \param rrclass For which class the list should work.
ConfigurableClientList
(
const
isc
::
dns
::
RRClass
&
rrclass
)
:
rrclass_
(
rrclass
)
{}
/// \brief Exception thrown when there's an error in configuration.
class
ConfigurationError
:
public
Exception
{
public:
...
...
@@ -229,16 +236,11 @@ public:
///
/// \todo The content yet to be defined.
struct
DataSourceInfo
{
/// \brief Default constructor.
///
/// Don't use directly. It is here so the structure can live in
/// a vector.
DataSourceInfo
()
:
data_src_client_
(
NULL
)
{}
// Plays a role of default constructor too (for vector)
DataSourceInfo
(
bool
has_cache
=
false
);
DataSourceInfo
(
DataSourceClient
*
data_src_client
,
const
DataSourceClientContainerPtr
&
container
,
bool
has
C
ache
);
bool
has
_c
ache
);
DataSourceClient
*
data_src_client_
;
DataSourceClientContainerPtr
container_
;
boost
::
shared_ptr
<
InMemoryClient
>
cache_
;
...
...
@@ -286,6 +288,8 @@ public:
/// it might be, so it is just made public (there's no real reason to
/// hide it).
const
DataSources
&
getDataSources
()
const
{
return
(
data_sources_
);
}
private:
const
isc
::
dns
::
RRClass
rrclass_
;
};
}
// namespace datasrc
...
...
src/lib/datasrc/datasrc_messages.mes
View file @
af89cdb0
...
...
@@ -298,6 +298,13 @@ not contain RRs the requested type. AN NXRRSET indication is returned.
A debug message indicating that a query for the given name and RR type is being
processed.
% DATASRC_LIST_NOT_CACHED zone %1/%2 not cached, cache disabled globally. Will not be available.
The process disabled caching of RR data completely. However, the given zone
is provided as a master file and it can be served from memory cache only.
Therefore, the zone will not be available for this process. If this is
a problem, you should move the zone to some database backend (sqlite3, for
example) and use it from there.
% DATASRC_MEM_ADD_RRSET adding RRset '%1/%2' into zone '%3'
Debug information. An RRset is being added to the in-memory data source.
...
...
src/lib/datasrc/tests/client_list_unittest.cc
View file @
af89cdb0
...
...
@@ -45,7 +45,7 @@ public:
Name
getOrigin
()
const
{
return
(
origin_
);
}
// The rest is not to be called, so just have them
RRClass
getClass
()
const
{
return
(
RRClass
::
IN
()
);
isc_throw
(
isc
::
NotImplemented
,
"Not implemented"
);
}
shared_ptr
<
Context
>
find
(
const
Name
&
,
const
RRType
&
,
const
FindOptions
)
...
...
@@ -106,6 +106,8 @@ public:
type_
(
type
),
configuration_
(
configuration
)
{
EXPECT_NE
(
"MasterFiles"
,
type
)
<<
"MasterFiles is a special case "
"and it never should be created as a data source client"
;
if
(
configuration_
->
getType
()
==
Element
::
list
)
{
for
(
size_t
i
(
0
);
i
<
configuration_
->
size
();
++
i
)
{
zones
.
insert
(
Name
(
configuration_
->
get
(
i
)
->
stringValue
()));
...
...
@@ -148,7 +150,12 @@ public:
}
else
if
(
name
==
Name
(
"null.org"
))
{
return
(
ZoneIteratorPtr
());
}
else
{
return
(
ZoneIteratorPtr
(
new
Iterator
(
name
)));
FindResult
result
(
findZone
(
name
));
if
(
result
.
code
==
isc
::
datasrc
::
result
::
SUCCESS
)
{
return
(
ZoneIteratorPtr
(
new
Iterator
(
name
)));
}
else
{
isc_throw
(
DataSourceError
,
"No such zone"
);
}
}
}
const
string
type_
;
...
...
@@ -162,6 +169,9 @@ private:
// some methods to dig directly in the internals, for the tests.
class
TestedList
:
public
ConfigurableClientList
{
public:
TestedList
(
const
RRClass
&
rrclass
)
:
ConfigurableClientList
(
rrclass
)
{}
DataSources
&
getDataSources
()
{
return
(
data_sources_
);
}
// Overwrite the list's method to get a data source with given type
// and configuration. We mock the data source and don't create the
...
...
@@ -210,7 +220,7 @@ class ListTest : public ::testing::Test {
public:
ListTest
()
:
// The empty list corresponds to a list with no elements inside
list_
(
new
TestedList
()),
list_
(
new
TestedList
(
RRClass
::
IN
()
)),
config_elem_
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
test_type
\"
,"
...
...
@@ -498,6 +508,47 @@ TEST_F(ListTest, wrongConfig) {
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: 13}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
x
\"
,
\"
cache-enable
\"
: true,
\"
cache-zones
\"
: {}}]"
,
// Some bad inputs for MasterFiles special case
// It must have the cache enabled
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {}}]"
,
// No cache-zones allowed here
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: true,"
"
\"
param
\"
: {},
\"
cache-zones
\"
: []}]"
,
// Some bad types of params
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: []}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: 13}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: true}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: null}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
:
\"
x
\"
}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {
\"
.
\"
: 13}}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {
\"
.
\"
: true}}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {
\"
.
\"
: null}}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {
\"
.
\"
: []}}]"
,
"[{
\"
type
\"
:
\"
test_type
\"
,
\"
params
\"
: 13}, "
"{
\"
type
\"
:
\"
MasterFiles
\"
,
\"
cache-enable
\"
: false,"
"
\"
params
\"
: {
\"
.
\"
: {}}}]"
,
NULL
};
// Put something inside to see it survives the exception
...
...
@@ -611,6 +662,8 @@ TEST_F(ListTest, cacheZones) {
EXPECT_EQ
(
result
::
SUCCESS
,
cache
->
findZone
(
Name
(
"example.org"
)).
code
);
EXPECT_EQ
(
result
::
SUCCESS
,
cache
->
findZone
(
Name
(
"example.com"
)).
code
);
EXPECT_EQ
(
result
::
NOTFOUND
,
cache
->
findZone
(
Name
(
"example.cz"
)).
code
);
EXPECT_EQ
(
RRClass
::
IN
(),
cache
->
findZone
(
Name
(
"example.org"
)).
zone_finder
->
getClass
());
// These are cached and answered from the cache
positiveResult
(
list_
->
find
(
Name
(
"example.com."
)),
ds_
[
0
],
...
...
@@ -670,4 +723,28 @@ TEST_F(ListTest, badCache) {
checkDS
(
0
,
"test_type"
,
"{}"
,
false
);
}
TEST_F
(
ListTest
,
masterFiles
)
{
const
ConstElementPtr
elem
(
Element
::
fromJSON
(
"["
"{"
"
\"
type
\"
:
\"
MasterFiles
\"
,"
"
\"
cache-enable
\"
: true,"
"
\"
params
\"
: {"
"
\"
.
\"
:
\"
"
TEST_DATA_DIR
"/root.zone
\"
"
" }"
"}]"
));
list_
->
configure
(
*
elem
,
true
);
// It has only the cache
EXPECT_EQ
(
static_cast
<
const
DataSourceClient
*>
(
NULL
),
list_
->
getDataSources
()[
0
].
data_src_client_
);
// And it can search
positiveResult
(
list_
->
find
(
Name
(
"."
)),
ds_
[
0
],
Name
(
"."
),
true
,
"com"
,
true
);
// If cache is not enabled, nothing is loaded
list_
->
configure
(
*
elem
,
false
);
EXPECT_EQ
(
0
,
list_
->
getDataSources
().
size
());
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment