Skip to content

Commit 1489794

Browse files
committed
add MetaCPAN::ESConfig module to centralize ES config
Centralize Elasticsearch configuration in MetaCPAN::ESConfig. Allow overridden values from the main config file. This module is not meant to have any behavior aside from holding the configuration.
1 parent 6974280 commit 1489794

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed

lib/MetaCPAN/ESConfig.pm

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
use v5.20;
2+
use warnings;
3+
use experimental qw(signatures postderef);
4+
5+
package MetaCPAN::ESConfig;
6+
7+
use Carp qw(croak);
8+
use Const::Fast qw(const);
9+
use Exporter qw(import);
10+
use MetaCPAN::Util qw(root_dir);
11+
use Module::Runtime qw(require_module $module_name_rx);
12+
use Cpanel::JSON::XS ();
13+
use Hash::Merge::Simple qw(merge);
14+
use MetaCPAN::Server::Config ();
15+
use Const::Fast qw(const);
16+
17+
const my %config => merge(
18+
{
19+
aliases => {
20+
'cpan' => 'cpan_v1_01',
21+
},
22+
indexes => {
23+
_default => {
24+
settings =>
25+
'MetaCPAN::Script::Mapping::DeployStatement::mapping()',
26+
},
27+
},
28+
documents => {
29+
author => {
30+
index => 'cpan_v1_01',
31+
type => 'author',
32+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Author',
33+
model => 'MetaCPAN::Document::Author',
34+
},
35+
cve => {
36+
index => 'cve',
37+
type => 'cve',
38+
mapping => 'MetaCPAN::Script::Mapping::CVE',
39+
model => 'MetaCPAN::Document::CVE',
40+
},
41+
contributor => {
42+
index => 'contributor',
43+
type => 'contributor',
44+
mapping => 'MetaCPAN::Script::Mapping::Contributor',
45+
model => 'MetaCPAN::Document::Contributor',
46+
},
47+
cover => {
48+
index => 'cover',
49+
type => 'cover',
50+
mapping => 'MetaCPAN::Script::Mapping::Cover',
51+
model => 'MetaCPAN::Document::Cover',
52+
},
53+
distribution => {
54+
index => 'cpan_v1_01',
55+
type => 'distribution',
56+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Distribution',
57+
model => 'MetaCPAN::Document::Distribution',
58+
},
59+
favorite => {
60+
index => 'cpan_v1_01',
61+
type => 'favorite',
62+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Favorite',
63+
model => 'MetaCPAN::Document::Favorite',
64+
},
65+
file => {
66+
index => 'cpan_v1_01',
67+
type => 'file',
68+
mapping => 'MetaCPAN::Script::Mapping::CPAN::File',
69+
model => 'MetaCPAN::Document::File',
70+
},
71+
mirror => {
72+
index => 'cpan_v1_01',
73+
type => 'mirror',
74+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Mirror',
75+
model => 'MetaCPAN::Document::Mirror',
76+
},
77+
package => {
78+
index => 'cpan_v1_01',
79+
type => 'package',
80+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Package',
81+
model => 'MetaCPAN::Document::Package',
82+
},
83+
permission => {
84+
index => 'cpan_v1_01',
85+
type => 'permission',
86+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Permission',
87+
model => 'MetaCPAN::Document::Permission',
88+
},
89+
release => {
90+
index => 'cpan_v1_01',
91+
type => 'release',
92+
mapping => 'MetaCPAN::Script::Mapping::CPAN::Release',
93+
model => 'MetaCPAN::Document::Release',
94+
},
95+
96+
account => {
97+
index => 'user',
98+
type => 'account',
99+
mapping => 'MetaCPAN::Script::Mapping::User::Account',
100+
model => 'MetaCPAN::Model::User::Account',
101+
},
102+
identity => {
103+
index => 'user',
104+
type => 'identity',
105+
mapping => 'MetaCPAN::Script::Mapping::User::Identity',
106+
model => 'MetaCPAN::Model::User::Identity',
107+
},
108+
session => {
109+
index => 'user',
110+
type => 'session',
111+
mapping => 'MetaCPAN::Script::Mapping::User::Session',
112+
model => 'MetaCPAN::Model::User::Session',
113+
},
114+
},
115+
},
116+
MetaCPAN::Server::Config::config()->{elasticsearch} || {},
117+
)->%*;
118+
119+
{
120+
use Moo;
121+
}
122+
123+
has indexes => (
124+
is => 'ro',
125+
required => 1,
126+
);
127+
128+
has aliases => (
129+
is => 'ro',
130+
default => sub { {} },
131+
);
132+
133+
has documents => (
134+
is => 'ro',
135+
required => 1,
136+
);
137+
138+
sub _load_es_data ( $location, $def_sub = 'mapping' ) {
139+
my $data;
140+
141+
if ( ref $location ) {
142+
$data = $location;
143+
}
144+
elsif ( $location
145+
=~ /\A($module_name_rx)(?:::([0-9a-zA-Z_]+)\(\)|->($module_name_rx))?\z/
146+
)
147+
{
148+
my ( $module, $sub, $method ) = ( $1, $2, $3 );
149+
require_module $module;
150+
if ($method) {
151+
$data = $module->$method;
152+
}
153+
else {
154+
$sub ||= $def_sub;
155+
no strict 'refs';
156+
my $code = \&{"${module}::${sub}"};
157+
die "can't find $location"
158+
if !defined &$code;
159+
$data = $code->();
160+
}
161+
}
162+
else {
163+
my $abs_path = File::Spec->rel2abs( $location, root_dir() );
164+
open my $fh, '<', $abs_path
165+
or die "can't open mapping file $abs_path: $!";
166+
$data = do { local $/; <$fh> };
167+
}
168+
169+
return $data
170+
if ref $data;
171+
172+
return Cpanel::JSON::XS::decode_json($data);
173+
}
174+
175+
sub mapping ( $self, $doc ) {
176+
my $doc_data = $self->documents->{$doc}
177+
or croak "unknown document $doc";
178+
return _load_es_data( $doc_data->{mapping}, 'mapping' );
179+
}
180+
181+
sub index_settings ( $self, $index ) {
182+
my $indexes = $self->indexes;
183+
my $index_data = exists $indexes->{$index} && $indexes->{$index};
184+
my $settings
185+
= $index_data
186+
&& exists $index_data->{settings}
187+
&& $index_data->{settings};
188+
if ( !$settings ) {
189+
my $default_data
190+
= exists $indexes->{_default} && $indexes->{_default};
191+
$settings
192+
= $default_data
193+
&& exists $default_data->{settings}
194+
&& $default_data->{settings};
195+
}
196+
return {}
197+
if !$settings;
198+
return _load_es_data($settings);
199+
}
200+
201+
sub doc_path ( $self, $doc ) {
202+
my $doc_data = $self->documents->{$doc}
203+
or croak "unknown document $doc";
204+
return (
205+
( $doc_data->{index} ? ( index => $doc_data->{index} ) : () ),
206+
( $doc_data->{type} ? ( type => $doc_data->{type} ) : () ),
207+
);
208+
}
209+
210+
our @EXPORT_OK = qw(
211+
es_config
212+
es_doc_path
213+
);
214+
215+
my $single = __PACKAGE__->new(%config);
216+
sub es_config : prototype() {$single}
217+
sub es_doc_path ($doc) { $single->doc_path($doc) }
218+
219+
1;

0 commit comments

Comments
 (0)