-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
RecordFormatSelector.java
206 lines (188 loc) · 7.79 KB
/
RecordFormatSelector.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.impl.store.format;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.helpers.Service;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory;
import org.neo4j.kernel.impl.logging.LogService;
import org.neo4j.kernel.impl.logging.NullLogService;
import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV2_0;
import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV2_1;
import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV2_2;
import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV2_3;
import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV3_0;
import org.neo4j.logging.Log;
import static java.util.Arrays.asList;
import static org.neo4j.helpers.collection.Iterables.concat;
import static org.neo4j.helpers.collection.Iterables.map;
/**
* Selects record format that will be used in a database.
* Support two types of selection : config based or automatic.
* <p>
* Automatic selection is used by various tools and tests that should pretend being format independent (for
* example backup)
*/
public class RecordFormatSelector
{
private static final RecordFormats DEFAULT_AUTOSELECT_FORMAT = LowLimitV3_0.RECORD_FORMATS;
private static final Iterable<RecordFormats> KNOWN_FORMATS = asList(
LowLimitV2_0.RECORD_FORMATS,
LowLimitV2_1.RECORD_FORMATS,
LowLimitV2_2.RECORD_FORMATS,
LowLimitV2_3.RECORD_FORMATS,
LowLimitV3_0.RECORD_FORMATS
);
/**
* Select record formats based on provided format name in
* {@link GraphDatabaseFacadeFactory.Configuration#record_format} property
*
* @param config database configuration
* @param logService logging service
* @return configured record formats
* @throws IllegalArgumentException if requested format not found
*/
public static RecordFormats select( Config config, LogService logService )
{
String recordFormat = configuredRecordFormat( config );
RecordFormats formats = loadRecordFormat( recordFormat );
if ( formats == null )
{
handleMissingFormat( recordFormat, logService );
}
logSelectedFormat( logService, formats );
return formats;
}
/**
* Select record formats based on provided format name in
* {@link GraphDatabaseFacadeFactory.Configuration#record_format} property
* If property not specified provided defaultFormat will be return instead.
*
* @param config database configuration
* @param defaultFormat default format
* @param logService logging service
* @return configured or default record format
* @throws IllegalArgumentException if requested format not found
*/
public static RecordFormats select( Config config, RecordFormats defaultFormat, LogService logService )
{
RecordFormats selectedFormat = defaultFormat;
String recordFormat = configuredRecordFormat( config );
if ( StringUtils.isNotEmpty( recordFormat ) )
{
selectedFormat = selectSpecificFormat( recordFormat, logService );
}
logSelectedFormat( logService, selectedFormat );
return selectedFormat;
}
/**
* Select record formats for provided store version.
*
* @param storeVersion store version to find format for
* @return record formats
* @throws IllegalArgumentException if format for specified store version not found
*/
public static RecordFormats selectForVersion( String storeVersion )
{
Iterable<RecordFormats> currentFormats =
map( RecordFormats.Factory::newInstance, Service.load( RecordFormats.Factory.class ) );
for ( RecordFormats format : concat( KNOWN_FORMATS, currentFormats ) )
{
if ( format.storeVersion().equals( storeVersion ) )
{
return format;
}
}
throw new IllegalArgumentException( "Unknown store version '" + storeVersion + "'" );
}
/**
* Select {@link #DEFAULT_AUTOSELECT_FORMAT} record format.
*
* @return selected record format.
*/
public static RecordFormats autoSelectFormat()
{
return autoSelectFormat( Config.empty(), NullLogService.getInstance() );
}
/**
* Select configured record format based on available services in class path.
* Specific format can be specified by {@link GraphDatabaseFacadeFactory.Configuration#record_format} property.
* <p>
* If format is not specified {@link #DEFAULT_AUTOSELECT_FORMAT} will be used.
*
* @param config - configuration parameters
* @param logService - logging service
* @return - selected record format.
* @throws IllegalArgumentException if specific requested format not found
*/
public static RecordFormats autoSelectFormat( Config config, LogService logService )
{
String recordFormat = configuredRecordFormat( config );
RecordFormats recordFormats = StringUtils.isNotEmpty( recordFormat ) ?
selectSpecificFormat( recordFormat, logService ) :
DEFAULT_AUTOSELECT_FORMAT;
logSelectedFormat( logService, recordFormats );
return recordFormats;
}
private static RecordFormats selectSpecificFormat( String recordFormat, LogService logService )
{
RecordFormats formats = loadRecordFormat( recordFormat );
if ( formats == null )
{
return handleMissingFormat( recordFormat, logService );
}
return formats;
}
private static RecordFormats loadRecordFormat( String recordFormat )
{
if ( StringUtils.isNotEmpty( recordFormat ) )
{
if ( LowLimitV3_0.NAME.equals( recordFormat ) )
{
return LowLimitV3_0.RECORD_FORMATS;
}
RecordFormats.Factory formatFactory = Service.loadSilently( RecordFormats.Factory.class, recordFormat );
if ( formatFactory != null )
{
return formatFactory.newInstance();
}
}
return null;
}
private static void logSelectedFormat( LogService logService, RecordFormats formats )
{
String selectionMessage =
String.format( "Select %s as record format implementation.", formats.getClass().getName() );
getLog( logService ).warn( selectionMessage );
}
private static RecordFormats handleMissingFormat( String recordFormat, LogService logService )
{
getLog( logService ).warn( "Record format with key '" + recordFormat + "' not found." );
throw new IllegalArgumentException( "No record format found with the name '" + recordFormat + "'." );
}
private static Log getLog( LogService logService )
{
return logService.getInternalLog( RecordFormatSelector.class );
}
private static String configuredRecordFormat( Config config )
{
return config.get( GraphDatabaseFacadeFactory.Configuration.record_format );
}
}